OSDN Git Service

Use a sequence number for thumbnail callback.
authorYao Chen <yaochen@google.com>
Wed, 23 Jul 2014 22:04:48 +0000 (15:04 -0700)
committerYao Chen <yaochen@google.com>
Thu, 24 Jul 2014 21:40:40 +0000 (21:40 +0000)
Change-Id: I27888cd0437b4f654cb29371b7d86b9341d84ae9

media/java/android/media/browse/IMediaBrowserService.aidl
media/java/android/media/browse/IMediaBrowserServiceCallbacks.aidl
media/java/android/media/browse/MediaBrowser.java
media/java/android/media/browse/MediaBrowserService.java

index 177bd1b..5126f6b 100644 (file)
@@ -18,5 +18,6 @@ oneway interface IMediaBrowserService {
 
     void addSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
     void removeSubscription(in Uri uri, IMediaBrowserServiceCallbacks callbacks);
-    void loadThumbnail(in Uri uri, int width, int height, IMediaBrowserServiceCallbacks callbacks);
+    void loadThumbnail(in int seqNum, in Uri uri, int width, int height,
+            IMediaBrowserServiceCallbacks callbacks);
 }
\ No newline at end of file
index 1f03a1a..f6d5dae 100644 (file)
@@ -24,5 +24,5 @@ oneway interface IMediaBrowserServiceCallbacks {
     void onConnect(in Uri root, in MediaSession.Token session, in Bundle extras);
     void onConnectFailed();
     void onLoadChildren(in Uri uri, in ParceledListSlice list);
-    void onLoadThumbnail(in Uri uri, int width, int height, in Bitmap bitmap);
+    void onLoadThumbnail(int seqNum, in Bitmap bitmap);
 }
index d17f95d..f6ea360 100644 (file)
@@ -33,6 +33,7 @@ import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.SparseArray;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -40,6 +41,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -65,8 +67,8 @@ public final class MediaBrowser {
     private final Handler mHandler = new Handler();
     private final ArrayMap<Uri,Subscription> mSubscriptions =
             new ArrayMap<Uri, MediaBrowser.Subscription>();
-    private final ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>> mThumbnailCallbacks =
-            new ArrayMap<ThumbnailRequest, HashSet<ThumbnailCallback>>();
+    private final SparseArray<ThumbnailRequest> mThumbnailRequests =
+            new SparseArray<ThumbnailRequest>();
 
     private int mState = CONNECT_STATE_DISCONNECTED;
     private MediaServiceConnection mServiceConnection;
@@ -75,6 +77,7 @@ public final class MediaBrowser {
     private Uri mRootUri;
     private MediaSession.Token mMediaSessionToken;
     private Bundle mExtras;
+    private int mNextSeq;
 
     /**
      * Creates a media browser for the specified media browse service.
@@ -367,21 +370,20 @@ public final class MediaBrowser {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                HashSet<ThumbnailCallback> callbackSet;
-                ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
-                callbackSet = mThumbnailCallbacks.get(request);
-                if (callbackSet != null) {
-                    callbackSet.add(callback);
-                    mThumbnailCallbacks.put(request, callbackSet);
-                    // same request has been sent. we will wait for the callback.
-                    return;
+                for (int i = 0; i < mThumbnailRequests.size(); i++) {
+                    ThumbnailRequest existingRequest = mThumbnailRequests.valueAt(i);
+                    if (existingRequest.isSameRequest(uri, width, height)) {
+                        existingRequest.addCallback(callback);
+                        return;
+                    }
                 }
-                callbackSet = new HashSet<ThumbnailCallback>();
-                callbackSet.add(callback);
-                mThumbnailCallbacks.put(request, callbackSet);
+                final int seq = mNextSeq++;
+                ThumbnailRequest request = new ThumbnailRequest(seq, uri, width, height);
+                request.addCallback(callback);
+                mThumbnailRequests.put(seq, request);
                 if (mState == CONNECT_STATE_CONNECTED) {
                     try {
-                        mServiceBinder.loadThumbnail(uri, width, height, mServiceCallbacks);
+                        mServiceBinder.loadThumbnail(seq, uri, width, height, mServiceCallbacks);
                     } catch (RemoteException e) {
                         // Process is crashing.  We will disconnect, and upon reconnect we will
                         // automatically reload the thumbnails. So nothing to do here.
@@ -449,17 +451,17 @@ public final class MediaBrowser {
                     }
                 }
 
-                for (ThumbnailRequest request : mThumbnailCallbacks.keySet()) {
+                for (int i = 0; i < mThumbnailRequests.size(); i++) {
+                    ThumbnailRequest request = mThumbnailRequests.valueAt(i);
                     try {
-                        mServiceBinder.loadThumbnail(request.uri, request.width, request.height,
-                                mServiceCallbacks);
+                        mServiceBinder.loadThumbnail(request.mSeq, request.mUri,
+                                request.mWidth, request.mHeight, mServiceCallbacks);
                     } catch (RemoteException e) {
                         // Process is crashing.  We will disconnect, and upon reconnect we will
                         // automatically reload. So nothing to do here.
-                        Log.d(TAG, "loadThumbnail failed with RemoteException uri=" + request.uri);
+                        Log.d(TAG, "loadThumbnail failed with RemoteException request=" + request);
                     }
                 }
-
             }
         });
     }
@@ -527,7 +529,7 @@ public final class MediaBrowser {
     }
 
     private final void onLoadThumbnail(final IMediaBrowserServiceCallbacks callback,
-            final ThumbnailRequest request, final Bitmap bitmap) {
+            final int seqNum, final Bitmap bitmap) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -537,16 +539,16 @@ public final class MediaBrowser {
                     return;
                 }
 
-                Set<ThumbnailCallback> callbackSet = mThumbnailCallbacks.get(request);
-                if (callbackSet == null) {
-                    Log.d(TAG, "onLoadThumbnail called for request=" + request +
-                            " but the callback is not registered");
+                ThumbnailRequest request = mThumbnailRequests.get(seqNum);
+                if (request == null) {
+                    Log.d(TAG, "onLoadThumbnail called for seqNum=" + seqNum + " request="
+                            + request + " but the request is not registered");
                     return;
                 }
-                for (ThumbnailCallback thumbnailCallback : callbackSet) {
-                    thumbnailCallback.onThumbnailLoaded(request.uri, bitmap);
+                mThumbnailRequests.delete(seqNum);
+                for (ThumbnailCallback thumbnailCallback : request.getCallbacks()) {
+                    thumbnailCallback.onThumbnailLoaded(request.mUri, bitmap);
                 }
-                mThumbnailCallbacks.remove(request);
             }
         });
     }
@@ -651,47 +653,66 @@ public final class MediaBrowser {
     }
 
     private static class ThumbnailRequest {
-        Uri uri;
-        int width;
-        int height;
-        ThumbnailRequest(@NonNull Uri uri, int width, int height) {
+        final int mSeq;
+        final Uri mUri;
+        final int mWidth;
+        final int mHeight;
+        final List<ThumbnailCallback> mCallbacks;
+
+        /**
+         * Constructs a thumbnail request.
+         * @param seq The unique sequence number assigned to the request by the media browser.
+         * @param uri The Uri for the thumbnail.
+         * @param width The width for the thumbnail.
+         * @param height The height for the thumbnail.
+         */
+        ThumbnailRequest(int seq, @NonNull Uri uri, int width, int height) {
             if (uri == null) {
                 throw new IllegalArgumentException("thumbnail uri cannot be null");
             }
-            this.uri = uri;
-            this.width = width;
-            this.height = height;
+            this.mSeq = seq;
+            this.mUri = uri;
+            this.mWidth = width;
+            this.mHeight = height;
+            mCallbacks = new ArrayList<ThumbnailCallback>();
         }
 
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof ThumbnailRequest)) return false;
-
-            ThumbnailRequest that = (ThumbnailRequest) o;
-
-            if (height != that.height) return false;
-            if (width != that.width) return false;
-            if (!uri.equals(that.uri)) return false;
-
-            return true;
+        /**
+         * Adds a callback to the thumbnail request.
+         * If the callback already exists, it will not be added again.
+         */
+        public void addCallback(@NonNull ThumbnailCallback callback) {
+            if (callback == null) {
+                throw new IllegalArgumentException("callback cannot be null in ThumbnailRequest");
+            }
+            if (!mCallbacks.contains(callback)) {
+                mCallbacks.add(callback);
+            }
         }
 
-        @Override
-        public int hashCode() {
-            int result = uri.hashCode();
-            result = 31 * result + width;
-            result = 31 * result + height;
-            return result;
+        /**
+         * Checks if the thumbnail request has the same uri, width, and height as the given values.
+         */
+        public boolean isSameRequest(@Nullable Uri uri, int width, int height) {
+            return Objects.equals(mUri, uri) && mWidth == width && mHeight == height;
         }
 
         @Override
         public String toString() {
-            return "ThumbnailRequest{" +
-                    "uri=" + uri +
-                    ", width=" + width +
-                    ", height=" + height +
-                    '}';
+            final StringBuilder sb = new StringBuilder("ThumbnailRequest{");
+            sb.append("uri=").append(mUri);
+            sb.append(", width=").append(mWidth);
+            sb.append(", height=").append(mHeight);
+            sb.append(", seq=").append(mSeq);
+            sb.append('}');
+            return sb.toString();
+        }
+
+        /**
+         * Gets an unmodifiable view of the list of callbacks associated with the request.
+         */
+        public List<ThumbnailCallback> getCallbacks() {
+            return Collections.unmodifiableList(mCallbacks);
         }
     }
 
@@ -822,11 +843,10 @@ public final class MediaBrowser {
         }
 
         @Override
-        public void onLoadThumbnail(final Uri uri, int width, int height, final Bitmap bitmap) {
+        public void onLoadThumbnail(final int seqNum, final Bitmap bitmap) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
-                ThumbnailRequest request = new ThumbnailRequest(uri, width, height);
-                mediaBrowser.onLoadThumbnail(this, request, bitmap);
+                mediaBrowser.onLoadThumbnail(this, seqNum, bitmap);
             }
         }
     }
index 2d4bb78..ffbaedd 100644 (file)
@@ -266,7 +266,7 @@ public abstract class MediaBrowserService extends Service {
         }
 
         @Override
-        public void loadThumbnail(final Uri uri, final int width, final int height,
+        public void loadThumbnail(final int seq, final Uri uri, final int width, final int height,
                 final IMediaBrowserServiceCallbacks callbacks) {
             if (uri == null) {
                 throw new IllegalStateException("loadThumbnail sent null list for uri " + uri);
@@ -299,7 +299,7 @@ public abstract class MediaBrowserService extends Service {
                             }
 
                             try {
-                                callbacks.onLoadThumbnail(uri, width, height, bitmap);
+                                callbacks.onLoadThumbnail(seq, bitmap);
                             } catch (RemoteException e) {
                                 // The other side is in the process of crashing.
                                 Log.w(TAG, "RemoteException in calling onLoadThumbnail", e);