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

Commit 1f22876d authored by Patty's avatar Patty
Browse files

Add timeout handler for browser subscription callback function

This patch is to add a timeout handler to avoid the BrowserSubscriptionCallback doesn't be called on time

Tag: #stability
Bug: 196683375
Test: atest BluetoothInstrumentationTests
Change-Id: I9f285115ea2851078843192349705a382e5c5613
Merged-In: I9f285115ea2851078843192349705a382e5c5613
parent b4d7d319
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ class BrowsedPlayerWrapper {

    // Internal function to call once the Browser is connected
    private boolean getFolderItemsInternal(String mediaId, BrowseCallback cb) {
        mWrappedBrowser.subscribe(mediaId, new BrowserSubscriptionCallback(cb));
        mWrappedBrowser.subscribe(mediaId, new BrowserSubscriptionCallback(cb, mLooper, mediaId));
        return true;
    }

@@ -302,14 +302,23 @@ class BrowsedPlayerWrapper {
    class TimeoutHandler extends Handler {
        static final int MSG_TIMEOUT = 0;
        static final long CALLBACK_TIMEOUT_MS = 5000;
        static final long SUBSCRIPTION_TIMEOUT_MS = 3000;

        private PlaybackCallback mPlaybackCallback = null;
        private BrowseCallback mBrowseCallback = null;
        private String mId = "";

        TimeoutHandler(Looper looper, PlaybackCallback cb) {
            super(looper);
            mPlaybackCallback = cb;
        }

        TimeoutHandler(Looper looper, BrowseCallback cb, String mediaId) {
            super(looper);
            mBrowseCallback = cb;
            mId = mediaId;
        }

        @Override
        public void handleMessage(Message msg) {
            if (msg.what != MSG_TIMEOUT) {
@@ -317,8 +326,14 @@ class BrowsedPlayerWrapper {
                return;
            }

            if (mPlaybackCallback != null) {
                Log.e(TAG, "Timeout while waiting for playback to begin on " + mPackageName);
                mPlaybackCallback.run(STATUS_PLAYBACK_TIMEOUT_ERROR);
            } else {
                Log.e(TAG, "Timeout while waiting subscription result for " + mPackageName);
                mBrowseCallback.run(STATUS_LOOKUP_ERROR, mId, new ArrayList<ListItem>());
                disconnect();
            }
        }
    }

@@ -391,9 +406,20 @@ class BrowsedPlayerWrapper {
     */
    private class BrowserSubscriptionCallback extends MediaBrowser.SubscriptionCallback {
        BrowseCallback mBrowseCallback = null;
        private Looper mLooper = null;
        private TimeoutHandler mTimeoutHandler = null;

        BrowserSubscriptionCallback(BrowseCallback cb) {
        BrowserSubscriptionCallback(BrowseCallback cb, Looper looper, String mediaId) {
            mBrowseCallback = cb;
            mLooper = looper;
            mTimeoutHandler = new TimeoutHandler(mLooper, cb, mediaId);
            mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT,
                    TimeoutHandler.SUBSCRIPTION_TIMEOUT_MS);
        }

        @Override
        public Handler getTimeoutHandler() {
            return mTimeoutHandler;
        }

        @Override
@@ -439,6 +465,7 @@ class BrowsedPlayerWrapper {
            }

            mCachedFolders.put(parentId, return_list);
            mTimeoutHandler.removeMessages(TimeoutHandler.MSG_TIMEOUT);

            // Clone the list so that the callee can mutate it without affecting the cached data
            mBrowseCallback.run(STATUS_SUCCESS, parentId, Util.cloneList(return_list));
@@ -450,6 +477,7 @@ class BrowsedPlayerWrapper {
        @Override
        public void onError(String id) {
            Log.e(TAG, "BrowserSubscriptionCallback: Could not get folder items");
            mTimeoutHandler.removeMessages(TimeoutHandler.MSG_TIMEOUT);
            mBrowseCallback.run(STATUS_LOOKUP_ERROR, id, new ArrayList<ListItem>());
            disconnect();
        }
+7 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
@@ -65,7 +66,12 @@ public class MediaBrowser {
     * Wrapper for MediaBrowser.SubscriptionCallback
     */
    public abstract static class SubscriptionCallback extends
            android.media.browse.MediaBrowser.SubscriptionCallback {}
            android.media.browse.MediaBrowser.SubscriptionCallback {
        /**
         * Wrapper for MediaBrowser.SubscriptionCallback.getTimeoutHandler()
         */
        public abstract Handler getTimeoutHandler();
    }

    /**
     * Wrapper for MediaBrowser.connect()
+18 −0
Original line number Diff line number Diff line
@@ -410,4 +410,22 @@ public class BrowserPlayerWrapperTest {

        verify(mMockBrowser).disconnect();
    }

    @Test
    public void testGetFolderItems_Timeout() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();

        wrapper.getFolderItems("test_folder", mBrowseCb);

        browserConnCb.onConnected();
        verify(mMockBrowser).subscribe(any(), mSubscriptionCb.capture());
        MediaBrowser.SubscriptionCallback subscriptionCb = mSubscriptionCb.getValue();
        Handler timeoutHandler = subscriptionCb.getTimeoutHandler();

        timeoutHandler.sendEmptyMessage(BrowsedPlayerWrapper.TimeoutHandler.MSG_TIMEOUT);
        verify(mMockBrowser, timeout(2000).times(1)).disconnect();
    }
}