diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-09-24 05:38:34 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-09-24 05:38:34 +0000 |
commit | 4d49c4ee8eda1a766abe078cb5cfeb59a91b7d58 (patch) | |
tree | 0a402e6536cbee6100f37b377aedc9a433aafc74 | |
parent | 18b3d041032786e6ae392d3f613377c1b9387952 (diff) | |
parent | 1f22876d650a2e8c00553b9440fdce2287f085ca (diff) | |
download | Bluetooth-4d49c4ee8eda1a766abe078cb5cfeb59a91b7d58.tar.gz |
Merge "Add timeout handler for browser subscription callback function" into sc-qpr1-dev
3 files changed, 57 insertions, 5 deletions
diff --git a/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java b/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java index 49c46e160..5100b5823 100644 --- a/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java +++ b/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java @@ -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; } - Log.e(TAG, "Timeout while waiting for playback to begin on " + mPackageName); - mPlaybackCallback.run(STATUS_PLAYBACK_TIMEOUT_ERROR); + 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(); } diff --git a/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java b/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java index 7443e4e91..6dc617af6 100644 --- a/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java +++ b/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java @@ -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() diff --git a/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java b/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java index 5cb6782bf..fee2c4e47 100644 --- a/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java +++ b/tests/unit/src/com/android/bluetooth/audio_util/BrowserPlayerWrapperTest.java @@ -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(); + } } |