OSDN Git Service

Music app unbundling prep: add SortCursor to the music app, make
[android-x86/packages-apps-Music.git] / src / com / android / music / MediaPlaybackActivity.java
index 1f7b404..baf1442 100644 (file)
@@ -18,24 +18,28 @@ package com.android.music;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.app.KeyguardManager;
 import android.app.SearchManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.media.AudioManager;
-import android.media.MediaFile;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.MediaStore;
 import android.text.Layout;
@@ -65,7 +69,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     
     private boolean mOneShot = false;
     private boolean mSeeking = false;
-    private boolean mTrackball;
+    private boolean mDeviceHasDpad;
     private long mStartSeekPos = 0;
     private long mLastSeekEventTime;
     private IMediaPlaybackService mService = null;
@@ -78,7 +82,6 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     private Worker mAlbumArtWorker;
     private AlbumArtHandler mAlbumArtHandler;
     private Toast mToast;
-    private boolean mRelaunchAfterConfigChange;
     private int mTouchSlop;
 
     public MediaPlaybackActivity()
@@ -129,8 +132,8 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         mNextButton.setRepeatListener(mFfwdListener, 260);
         seekmethod = 1;
 
-        mTrackball = true; /* (See bug 1044348) (getResources().getConfiguration().navigation == 
-            Resources.Configuration.NAVIGATION_TRACKBALL);*/
+        mDeviceHasDpad = (getResources().getConfiguration().navigation ==
+            Configuration.NAVIGATION_DPAD);
         
         mQueueButton = (ImageButton) findViewById(R.id.curplaylist);
         mQueueButton.setOnClickListener(mQueueListener);
@@ -146,7 +149,6 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         mProgress.setMax(1000);
         
         if (icicle != null) {
-            mRelaunchAfterConfigChange = icicle.getBoolean("configchange");
             mOneShot = icicle.getBoolean("oneshot");
         } else {
             mOneShot = getIntent().getBooleanExtra("oneshot", false);
@@ -268,24 +270,55 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         String artist;
         String album;
         String song;
+        long audioid;
         
         try {
             artist = mService.getArtistName();
             album = mService.getAlbumName();
             song = mService.getTrackName();
+            audioid = mService.getAudioId();
         } catch (RemoteException ex) {
             return true;
+        } catch (NullPointerException ex) {
+            // we might not actually have the service yet
+            return true;
         }
-        
+
+        if (MediaStore.UNKNOWN_STRING.equals(album) &&
+                MediaStore.UNKNOWN_STRING.equals(artist) &&
+                song != null &&
+                song.startsWith("recording")) {
+            // not music
+            return false;
+        }
+
+        if (audioid < 0) {
+            return false;
+        }
+
+        Cursor c = MusicUtils.query(this,
+                ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioid),
+                new String[] {MediaStore.Audio.Media.IS_MUSIC}, null, null, null);
+        boolean ismusic = true;
+        if (c != null) {
+            if (c.moveToFirst()) {
+                ismusic = c.getInt(0) != 0;
+            }
+            c.close();
+        }
+        if (!ismusic) {
+            return false;
+        }
+
         boolean knownartist =
-            (artist != null) && !MediaFile.UNKNOWN_STRING.equals(artist);
+            (artist != null) && !MediaStore.UNKNOWN_STRING.equals(artist);
 
         boolean knownalbum =
-            (album != null) && !MediaFile.UNKNOWN_STRING.equals(album);
+            (album != null) && !MediaStore.UNKNOWN_STRING.equals(album);
         
         if (knownartist && view.equals(mArtistName.getParent())) {
             title = artist;
-            query = artist.toString();
+            query = artist;
             mime = MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE;
         } else if (knownalbum && view.equals(mAlbumName.getParent())) {
             title = album;
@@ -296,7 +329,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
             }
             mime = MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE;
         } else if (view.equals(mTrackName.getParent()) || !knownartist || !knownalbum) {
-            if ((song == null) || MediaFile.UNKNOWN_STRING.equals(song)) {
+            if ((song == null) || MediaStore.UNKNOWN_STRING.equals(song)) {
                 // A popup of the form "Search for null/'' using ..." is pretty
                 // unhelpful, plus, we won't find any way to buy it anyway.
                 return true;
@@ -439,12 +472,12 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         mHandler.removeMessages(REFRESH);
         unregisterReceiver(mStatusListener);
         MusicUtils.unbindFromService(this);
+        mService = null;
         super.onStop();
     }
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
-        outState.putBoolean("configchange", getChangingConfigurations() != 0);
         outState.putBoolean("oneshot", mOneShot);
         super.onSaveInstanceState(outState);
     }
@@ -493,20 +526,24 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-        // Don't show the menu items if we got launched by path/filedescriptor, since
-        // those tend to not be in the media database.
-        if (MusicUtils.getCurrentAudioId() >= 0) {
-            if (!mOneShot) {
-                menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
-                menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
-            }
+        // Don't show the menu items if we got launched by path/filedescriptor, or
+        // if we're in one shot mode. In most cases, these menu items are not
+        // useful in those modes, so for consistency we never show them in these
+        // modes, instead of tailoring them to the specific file being played.
+        if (MusicUtils.getCurrentAudioId() >= 0 && !mOneShot) {
+            menu.add(0, GOTO_START, 0, R.string.goto_start).setIcon(R.drawable.ic_menu_music_library);
+            menu.add(0, PARTY_SHUFFLE, 0, R.string.party_shuffle); // icon will be set in onPrepareOptionsMenu()
             SubMenu sub = menu.addSubMenu(0, ADD_TO_PLAYLIST, 0,
                     R.string.add_to_playlist).setIcon(android.R.drawable.ic_menu_add);
-            MusicUtils.makePlaylistMenu(this, sub);
-            menu.add(0, USE_AS_RINGTONE, 0, R.string.ringtone_menu_short).setIcon(R.drawable.ic_menu_set_as_ringtone);
-            menu.add(0, DELETE_ITEM, 0, R.string.delete_item).setIcon(R.drawable.ic_menu_delete);
+            // these next two are in a separate group, so they can be shown/hidden as needed
+            // based on the keyguard state
+            menu.add(1, USE_AS_RINGTONE, 0, R.string.ringtone_menu_short)
+                    .setIcon(R.drawable.ic_menu_set_as_ringtone);
+            menu.add(1, DELETE_ITEM, 0, R.string.delete_item)
+                    .setIcon(R.drawable.ic_menu_delete);
+            return true;
         }
-        return true;
+        return false;
     }
 
     @Override
@@ -522,6 +559,16 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 item.setTitle(R.string.party_shuffle);
             }
         }
+
+        item = menu.findItem(ADD_TO_PLAYLIST);
+        if (item != null) {
+            SubMenu sub = item.getSubMenu();
+            MusicUtils.makePlaylistMenu(this, sub);
+        }
+
+        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+        menu.setGroupVisible(1, !km.inKeyguardRestrictedInputMode());
+
         return true;
     }
 
@@ -533,9 +580,8 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 case GOTO_START:
                     intent = new Intent();
                     intent.setClass(this, MusicBrowserActivity.class);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                            | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                     startActivity(intent);
+                    finish();
                     break;
                 case USE_AS_RINGTONE: {
                     // Set the system setting to make this the current ringtone
@@ -545,14 +591,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                     return true;
                 }
                 case PARTY_SHUFFLE:
-                    if (mService != null) {
-                        int shuffle = mService.getShuffleMode();
-                        if (shuffle == MediaPlaybackService.SHUFFLE_AUTO) {
-                            mService.setShuffleMode(MediaPlaybackService.SHUFFLE_NONE);
-                        } else {
-                            mService.setShuffleMode(MediaPlaybackService.SHUFFLE_AUTO);
-                        }
-                    }
+                    MusicUtils.togglePartyShuffle();
                     setShuffleButtonImage();
                     break;
                     
@@ -564,21 +603,21 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 }
 
                 case PLAYLIST_SELECTED: {
-                    int [] list = new int[1];
+                    long [] list = new long[1];
                     list[0] = MusicUtils.getCurrentAudioId();
-                    int playlist = item.getIntent().getIntExtra("playlist", 0);
+                    long playlist = item.getIntent().getLongExtra("playlist", 0);
                     MusicUtils.addToPlaylist(this, list, playlist);
                     return true;
                 }
                 
                 case DELETE_ITEM: {
                     if (mService != null) {
-                        int [] list = new int[1];
+                        long [] list = new long[1];
                         list[0] = MusicUtils.getCurrentAudioId();
                         Bundle b = new Bundle();
                         b.putString("description", getString(R.string.delete_song_desc,
                                 mService.getTrackName()));
-                        b.putIntArray("items", list);
+                        b.putLongArray("items", list);
                         intent = new Intent();
                         intent.setClass(this, DeleteItems.class);
                         intent.putExtras(b);
@@ -601,7 +640,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
             case NEW_PLAYLIST:
                 Uri uri = intent.getData();
                 if (uri != null) {
-                    int [] list = new int[1];
+                    long [] list = new long[1];
                     list[0] = MusicUtils.getCurrentAudioId();
                     int playlist = Integer.parseInt(uri.getLastPathSegment());
                     MusicUtils.addToPlaylist(this, list, playlist);
@@ -654,6 +693,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
 
     private boolean seekMethod1(int keyCode)
     {
+        if (mService == null) return false;
         for(int x=0;x<10;x++) {
             for(int y=0;y<3;y++) {
                 if(keyboard[y][x] == keyCode) {
@@ -710,7 +750,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
             switch(keyCode)
             {
                 case KeyEvent.KEYCODE_DPAD_LEFT:
-                    if (mTrackball) {
+                    if (!useDpadMusicControl()) {
                         break;
                     }
                     if (mService != null) {
@@ -731,7 +771,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                     mPosOverride = -1;
                     return true;
                 case KeyEvent.KEYCODE_DPAD_RIGHT:
-                    if (mTrackball) {
+                    if (!useDpadMusicControl()) {
                         break;
                     }
                     if (mService != null) {
@@ -753,6 +793,15 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         return super.onKeyUp(keyCode, event);
     }
 
+    private boolean useDpadMusicControl() {
+        if (mDeviceHasDpad && (mPrevButton.isFocused() ||
+                mNextButton.isFocused() ||
+                mPauseButton.isFocused())) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event)
     {
@@ -789,7 +838,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 return true;
 
             case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (mTrackball) {
+                if (!useDpadMusicControl()) {
                     break;
                 }
                 if (!mPrevButton.hasFocus()) {
@@ -798,7 +847,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 scanBackward(repcnt, event.getEventTime() - event.getDownTime());
                 return true;
             case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (mTrackball) {
+                if (!useDpadMusicControl()) {
                     break;
                 }
                 if (!mNextButton.hasFocus()) {
@@ -988,12 +1037,14 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 filename = uri.toString();
             }
             try {
-                mOneShot = true;
-                if (! mRelaunchAfterConfigChange) {
-                    mService.stop();
-                    mService.openfile(filename);
-                    mService.play();
+                if (! ContentResolver.SCHEME_CONTENT.equals(scheme) ||
+                        ! MediaStore.AUTHORITY.equals(uri.getAuthority())) {
+                    mOneShot = true;
                 }
+                mService.stop();
+                mService.openFile(filename, mOneShot);
+                mService.play();
+                setIntent(new Intent());
             } catch (Exception ex) {
                 Log.d("MediaPlaybackActivity", "couldn't start playback: " + ex);
             }
@@ -1007,9 +1058,6 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     private ServiceConnection osc = new ServiceConnection() {
             public void onServiceConnected(ComponentName classname, IBinder obj) {
                 mService = IMediaPlaybackService.Stub.asInterface(obj);
-                if (MusicUtils.sService == null) {
-                    MusicUtils.sService = mService;
-                }
                 startPlayback();
                 try {
                     // Assume something is playing when the service says it is,
@@ -1208,6 +1256,15 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         }
     };
 
+    private static class AlbumSongIdWrapper {
+        public long albumid;
+        public long songid;
+        AlbumSongIdWrapper(long aid, long sid) {
+            albumid = aid;
+            songid = sid;
+        }
+    }
+    
     private void updateTrackInfo() {
         if (mService == null) {
             return;
@@ -1219,31 +1276,34 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
                 return;
             }
             
-            if (mService.getAudioId() < 0 && path.toLowerCase().startsWith("http://")) {
+            long songid = mService.getAudioId(); 
+            if (songid < 0 && path.toLowerCase().startsWith("http://")) {
+                // Once we can get album art and meta data from MediaPlayer, we
+                // can show that info again when streaming.
                 ((View) mArtistName.getParent()).setVisibility(View.INVISIBLE);
                 ((View) mAlbumName.getParent()).setVisibility(View.INVISIBLE);
                 mAlbum.setVisibility(View.GONE);
                 mTrackName.setText(path);
                 mAlbumArtHandler.removeMessages(GET_ALBUM_ART);
-                mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, -1, 0).sendToTarget();
+                mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, new AlbumSongIdWrapper(-1, -1)).sendToTarget();
             } else {
                 ((View) mArtistName.getParent()).setVisibility(View.VISIBLE);
                 ((View) mAlbumName.getParent()).setVisibility(View.VISIBLE);
                 String artistName = mService.getArtistName();
-                if (MediaFile.UNKNOWN_STRING.equals(artistName)) {
+                if (MediaStore.UNKNOWN_STRING.equals(artistName)) {
                     artistName = getString(R.string.unknown_artist_name);
                 }
                 mArtistName.setText(artistName);
                 String albumName = mService.getAlbumName();
-                int albumid = mService.getAlbumId();
-                if (MediaFile.UNKNOWN_STRING.equals(albumName)) {
+                long albumid = mService.getAlbumId();
+                if (MediaStore.UNKNOWN_STRING.equals(albumName)) {
                     albumName = getString(R.string.unknown_album_name);
                     albumid = -1;
                 }
                 mAlbumName.setText(albumName);
                 mTrackName.setText(mService.getTrackName());
                 mAlbumArtHandler.removeMessages(GET_ALBUM_ART);
-                mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, albumid, 0).sendToTarget();
+                mAlbumArtHandler.obtainMessage(GET_ALBUM_ART, new AlbumSongIdWrapper(albumid, songid)).sendToTarget();
                 mAlbum.setVisibility(View.VISIBLE);
             }
             mDuration = mService.duration();
@@ -1254,22 +1314,24 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     }
     
     public class AlbumArtHandler extends Handler {
-        private int mAlbumId = -1;
+        private long mAlbumId = -1;
         
         public AlbumArtHandler(Looper looper) {
             super(looper);
         }
+        @Override
         public void handleMessage(Message msg)
         {
-            int albumid = msg.arg1;
+            long albumid = ((AlbumSongIdWrapper) msg.obj).albumid;
+            long songid = ((AlbumSongIdWrapper) msg.obj).songid;
             if (msg.what == GET_ALBUM_ART && (mAlbumId != albumid || albumid < 0)) {
                 // while decoding the new image, show the default album art
                 Message numsg = mHandler.obtainMessage(ALBUM_ART_DECODED, null);
                 mHandler.removeMessages(ALBUM_ART_DECODED);
                 mHandler.sendMessageDelayed(numsg, 300);
-                Bitmap bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, albumid);
+                Bitmap bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, songid, albumid);
                 if (bm == null) {
-                    bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, -1);
+                    bm = MusicUtils.getArtwork(MediaPlaybackActivity.this, songid, -1);
                     albumid = -1;
                 }
                 if (bm != null) {
@@ -1282,7 +1344,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         }
     }
     
-    private class Worker implements Runnable {
+    private static class Worker implements Runnable {
         private final Object mLock = new Object();
         private Looper mLooper;