OSDN Git Service

Backport changes 7e94887988990e98b5c7738f393e10afa0d8ddb8 and fb5674fd0aa46a186dba929...
authorMarco Nelissen <marcone@google.com>
Wed, 27 Jan 2010 23:35:43 +0000 (15:35 -0800)
committerMarco Nelissen <marcone@google.com>
Wed, 27 Jan 2010 23:39:20 +0000 (15:39 -0800)
from Music2, to make it easier to share code between the two.

src/com/android/music/AlbumBrowserActivity.java
src/com/android/music/ArtistAlbumBrowserActivity.java
src/com/android/music/MediaPickerActivity.java
src/com/android/music/MediaPlaybackActivity.java
src/com/android/music/MusicBrowserActivity.java
src/com/android/music/MusicUtils.java
src/com/android/music/PlaylistBrowserActivity.java
src/com/android/music/QueryBrowserActivity.java
src/com/android/music/StreamStarter.java
src/com/android/music/TrackBrowserActivity.java

index d73cbcc..efea53b 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.ListActivity;
 import android.app.SearchManager;
 import android.content.AsyncQueryHandler;
@@ -75,6 +77,7 @@ public class AlbumBrowserActivity extends ListActivity
     private final static int SEARCH = CHILD_MENU_BASE;
     private static int mLastListPosCourse = -1;
     private static int mLastListPosFine = -1;
+    private ServiceToken mToken;
 
     public AlbumBrowserActivity()
     {
@@ -94,7 +97,7 @@ public class AlbumBrowserActivity extends ListActivity
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
-        MusicUtils.bindToService(this, this);
+        mToken = MusicUtils.bindToService(this, this);
 
         IntentFilter f = new IntentFilter();
         f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
@@ -160,7 +163,7 @@ public class AlbumBrowserActivity extends ListActivity
                 mLastListPosFine = cv.getTop();
             }
         }
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         // If we have an adapter and didn't send it off to another activity yet, we should
         // close its cursor, which we do by assigning a null cursor to it. Doing this
         // instead of closing the cursor directly keeps the framework from accessing
index 359c464..c0d52fb 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
 import com.android.music.QueryBrowserActivity.QueryListAdapter.QueryHandler;
 
 import android.app.ExpandableListActivity;
@@ -77,6 +78,7 @@ public class ArtistAlbumBrowserActivity extends ExpandableListActivity
     private final static int SEARCH = CHILD_MENU_BASE;
     private static int mLastListPosCourse = -1;
     private static int mLastListPosFine = -1;
+    private ServiceToken mToken;
 
     /** Called when the activity is first created. */
     @Override
@@ -91,7 +93,7 @@ public class ArtistAlbumBrowserActivity extends ExpandableListActivity
             mCurrentArtistId = icicle.getString("selectedartist");
             mCurrentArtistName = icicle.getString("selectedartistname");
         }
-        MusicUtils.bindToService(this, this);
+        mToken = MusicUtils.bindToService(this, this);
 
         IntentFilter f = new IntentFilter();
         f.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
@@ -163,7 +165,7 @@ public class ArtistAlbumBrowserActivity extends ExpandableListActivity
             }
         }
         
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         // If we have an adapter and didn't send it off to another activity yet, we should
         // close its cursor, which we do by assigning a null cursor to it. Doing this
         // instead of closing the cursor directly keeps the framework from accessing
index c06ea29..ed67ab3 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.ListActivity;
 import android.content.Context;
 import android.content.Intent;
@@ -36,6 +38,7 @@ import java.util.ArrayList;
 
 public class MediaPickerActivity extends ListActivity implements MusicUtils.Defs
 {
+    private ServiceToken mToken;
 
     public MediaPickerActivity()
     {
@@ -57,13 +60,13 @@ public class MediaPickerActivity extends ListActivity implements MusicUtils.Defs
         } else {
             setTitle(mFirstYear + "-" + mLastYear);
         }
-        MusicUtils.bindToService(this);
+        mToken = MusicUtils.bindToService(this);
         init();
     }
 
     @Override
     public void onDestroy() {
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         super.onDestroy();
         if (mCursor != null) {
             mCursor.close();
index baf1442..c417eb2 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.KeyguardManager;
@@ -83,6 +85,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
     private AlbumArtHandler mAlbumArtHandler;
     private Toast mToast;
     private int mTouchSlop;
+    private ServiceToken mToken;
 
     public MediaPlaybackActivity()
     {
@@ -471,7 +474,7 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         }
         mHandler.removeMessages(REFRESH);
         unregisterReceiver(mStatusListener);
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         mService = null;
         super.onStop();
     }
@@ -487,7 +490,8 @@ public class MediaPlaybackActivity extends Activity implements MusicUtils.Defs,
         super.onStart();
         paused = false;
 
-        if (false == MusicUtils.bindToService(this, osc)) {
+        mToken = MusicUtils.bindToService(this, osc);
+        if (mToken == null) {
             // something went wrong
             mHandler.sendEmptyMessage(QUIT);
         }
index d82cdff..1c4a9d1 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -27,6 +29,8 @@ import android.os.RemoteException;
 public class MusicBrowserActivity extends Activity
     implements MusicUtils.Defs {
 
+    private ServiceToken mToken;
+
     public MusicBrowserActivity() {
     }
 
@@ -47,13 +51,15 @@ public class MusicBrowserActivity extends Activity
         
         String shuf = getIntent().getStringExtra("autoshuffle");
         if ("true".equals(shuf)) {
-            bindService((new Intent()).setClass(this, MediaPlaybackService.class), autoshuffle, 0);
+            mToken = MusicUtils.bindToService(this, autoshuffle);
         }
     }
 
     @Override
     public void onDestroy() {
-        MusicUtils.unbindFromService(this);
+        if (mToken != null) {
+            MusicUtils.unbindFromService(mToken);
+        }
         super.onDestroy();
     }
 
index ed9a3bf..d1314bf 100644 (file)
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
@@ -53,6 +54,7 @@ import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.MenuItem.OnMenuItemClickListener;
 import android.widget.TabWidget;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -150,25 +152,36 @@ public class MusicUtils {
     public static IMediaPlaybackService sService = null;
     private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
 
-    public static boolean bindToService(Context context) {
+    public static class ServiceToken {
+        ContextWrapper mWrappedContext;
+        ServiceToken(ContextWrapper context) {
+            mWrappedContext = context;
+        }
+    }
+
+    public static ServiceToken bindToService(Context context) {
         return bindToService(context, null);
     }
 
-    public static boolean bindToService(Context context, ServiceConnection callback) {
-        context.startService(new Intent(context, MediaPlaybackService.class));
+    public static ServiceToken bindToService(Context context, ServiceConnection callback) {
+        ContextWrapper cw = new ContextWrapper(context);
+        cw.startService(new Intent(cw, MediaPlaybackService.class));
         ServiceBinder sb = new ServiceBinder(callback);
-        sConnectionMap.put(context, sb);
-        return context.bindService((new Intent()).setClass(context,
-                MediaPlaybackService.class), sb, 0);
+        if (cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)) {
+            sConnectionMap.put(cw, sb);
+            return new ServiceToken(cw);
+        }
+        return null;
     }
-    
-    public static void unbindFromService(Context context) {
-        ServiceBinder sb = (ServiceBinder) sConnectionMap.remove(context);
+
+    public static void unbindFromService(ServiceToken token) {
+        ContextWrapper cw = token.mWrappedContext;
+        ServiceBinder sb = sConnectionMap.remove(cw);
         if (sb == null) {
             Log.e("MusicUtils", "Trying to unbind for unknown Context");
             return;
         }
-        context.unbindService(sb);
+        cw.unbindService(sb);
         if (sConnectionMap.isEmpty()) {
             // presumably there is nobody interested in the service at this point,
             // so don't hang on to the ServiceConnection
@@ -282,7 +295,7 @@ public class MusicUtils {
     }
 
     private final static long [] sEmptyList = new long[0];
-    
+
     public static long [] getSongListForCursor(Cursor cursor) {
         if (cursor == null) {
             return sEmptyList;
@@ -509,6 +522,34 @@ public class MusicUtils {
         } catch (RemoteException ex) {
         }
     }
+
+    private static ContentValues[] sContentValuesCache = null;
+
+    /**
+     * @param ids The source array containing all the ids to be added to the playlist
+     * @param offset Where in the 'ids' array we start reading
+     * @param len How many items to copy during this pass
+     * @param base The play order offset to use for this pass
+     */
+    private static void makeInsertItems(long[] ids, int offset, int len, int base) {
+        // adjust 'len' if would extend beyond the end of the source array
+        if (offset + len > ids.length) {
+            len = ids.length - offset;
+        }
+        // allocate the ContentValues array, or reallocate if it is the wrong size
+        if (sContentValuesCache == null || sContentValuesCache.length != len) {
+            sContentValuesCache = new ContentValues[len];
+        }
+        // fill in the ContentValues array with the right values for this pass
+        for (int i = 0; i < len; i++) {
+            if (sContentValuesCache[i] == null) {
+                sContentValuesCache[i] = new ContentValues();
+            }
+
+            sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
+            sContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[offset + i]);
+        }
+    }
     
     public static void addToPlaylist(Context context, long [] ids, long playlistid) {
         if (ids == null) {
@@ -517,7 +558,6 @@ public class MusicUtils {
             Log.e("MusicBase", "ListSelection null");
         } else {
             int size = ids.length;
-            ContentValues values [] = new ContentValues[size];
             ContentResolver resolver = context.getContentResolver();
             // need to determine the number of items currently in the playlist,
             // so the play_order field can be maintained.
@@ -529,15 +569,13 @@ public class MusicUtils {
             cur.moveToFirst();
             int base = cur.getInt(0);
             cur.close();
-
-            for (int i = 0; i < size; i++) {
-                values[i] = new ContentValues();
-                values[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + i));
-                values[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[i]);
+            int numinserted = 0;
+            for (int i = 0; i < size; i += 1000) {
+                makeInsertItems(ids, i, 1000, base);
+                numinserted += resolver.bulkInsert(uri, sContentValuesCache);
             }
-            resolver.bulkInsert(uri, values);
             String message = context.getResources().getQuantityString(
-                    R.plurals.NNNtrackstoplaylist, size, Integer.valueOf(size));
+                    R.plurals.NNNtrackstoplaylist, numinserted, numinserted);
             Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
             //mLastPlaylistSelected = playlistid;
         }
index a582e61..8c79e64 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.ListActivity;
 import android.content.AsyncQueryHandler;
 import android.content.BroadcastReceiver;
@@ -72,6 +74,7 @@ public class PlaylistBrowserActivity extends ListActivity
     private static int mLastListPosFine = -1;
 
     private boolean mCreateShortcut;
+    private ServiceToken mToken;
 
     public PlaylistBrowserActivity()
     {
@@ -92,7 +95,7 @@ public class PlaylistBrowserActivity extends ListActivity
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
-        MusicUtils.bindToService(this, new ServiceConnection() {
+        mToken = MusicUtils.bindToService(this, new ServiceConnection() {
             public void onServiceConnected(ComponentName classname, IBinder obj) {
                 if (Intent.ACTION_VIEW.equals(action)) {
                     long id = Long.parseLong(intent.getExtras().getString("playlist"));
@@ -180,7 +183,7 @@ public class PlaylistBrowserActivity extends ListActivity
                 mLastListPosFine = cv.getTop();
             }
         }
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         // If we have an adapter and didn't send it off to another activity yet, we should
         // close its cursor, which we do by assigning a null cursor to it. Doing this
         // instead of closing the cursor directly keeps the framework from accessing
index 896ca8f..977650c 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.ListActivity;
 import android.app.SearchManager;
 import android.content.AsyncQueryHandler;
@@ -66,6 +68,7 @@ implements MusicUtils.Defs, ServiceConnection
     private QueryListAdapter mAdapter;
     private boolean mAdapterSent;
     private String mFilterString = "";
+    private ServiceToken mToken;
 
     public QueryBrowserActivity()
     {
@@ -78,7 +81,7 @@ implements MusicUtils.Defs, ServiceConnection
         super.onCreate(icicle);
         setVolumeControlStream(AudioManager.STREAM_MUSIC);
         mAdapter = (QueryListAdapter) getLastNonConfigurationInstance();
-        MusicUtils.bindToService(this, this);
+        mToken = MusicUtils.bindToService(this, this);
         // defer the real work until we're bound to the service
     }
 
@@ -195,7 +198,7 @@ implements MusicUtils.Defs, ServiceConnection
 
     @Override
     public void onDestroy() {
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         unregisterReceiver(mScanListener);
         // If we have an adapter and didn't send it off to another activity yet, we should
         // close its cursor, which we do by assigning a null cursor to it. Doing this
index a43dbf5..e823ee2 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -34,6 +36,8 @@ import android.widget.Toast;
 
 public class StreamStarter extends Activity
 {
+    private ServiceToken mToken;
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -53,7 +57,7 @@ public class StreamStarter extends Activity
     public void onResume() {
         super.onResume();
 
-        MusicUtils.bindToService(this, new ServiceConnection() {
+        mToken = MusicUtils.bindToService(this, new ServiceConnection() {
             public void onServiceConnected(ComponentName classname, IBinder obj) {
                 try {
                     IntentFilter f = new IntentFilter();
@@ -111,7 +115,7 @@ public class StreamStarter extends Activity
             }
         }
         unregisterReceiver(mStatusListener);
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         super.onPause();
     }
 }
index cfece30..39bdeed 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.music;
 
+import com.android.music.MusicUtils.ServiceToken;
+
 import android.app.ListActivity;
 import android.app.SearchManager;
 import android.content.AsyncQueryHandler;
@@ -97,6 +99,7 @@ public class TrackBrowserActivity extends ListActivity
     private static int mLastListPosCourse = -1;
     private static int mLastListPosFine = -1;
     private boolean mUseLastListPos = false;
+    private ServiceToken mToken;
 
     public TrackBrowserActivity()
     {
@@ -171,7 +174,7 @@ public class TrackBrowserActivity extends ListActivity
             mAdapter.setActivity(this);
             setListAdapter(mAdapter);
         }
-        MusicUtils.bindToService(this, this);
+        mToken = MusicUtils.bindToService(this, this);
 
         // don't set the album art until after the view has been layed out
         mTrackList.post(new Runnable() {
@@ -248,7 +251,7 @@ public class TrackBrowserActivity extends ListActivity
                 mLastListPosFine = cv.getTop();
             }
         }
-        MusicUtils.unbindFromService(this);
+        MusicUtils.unbindFromService(mToken);
         try {
             if ("nowplaying".equals(mPlaylist)) {
                 unregisterReceiverSafe(mNowPlayingListener);