Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80bb169d authored by Yao Chen's avatar Yao Chen
Browse files

Use a sequence number for thumbnail callback.

Change-Id: I27888cd0437b4f654cb29371b7d86b9341d84ae9
parent 1aa5d2d7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+80 −60
Original line number Diff line number Diff line
@@ -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.
                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);
            }
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -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);