mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Use connection hints when connecting to MediaBrowserService
Minor improvement to allow an Media3 browser to pass extras when connecting the initial browser in `MediaControllerImplLegacy`. Before this change an empty bundle was sent. After this change the connection hints of the `Media3 browser is used as root hints of the initial browser that connects when the Media3 browser is built in `MediaBrowser.buildAsync`. #cherrypick PiperOrigin-RevId: 684372552
This commit is contained in:
parent
b6d0540059
commit
cbc0ee369f
@ -112,6 +112,10 @@
|
||||
* Fix bug where a Media3 controller was sometimes unable to let a session
|
||||
app start a foreground service after requesting `play()`.
|
||||
* Restrict `CommandButton.Builder.setIconUri` to only accept content Uris.
|
||||
* Pass connection hints of a Media3 browser to the initial
|
||||
`MediaBrowserCompat` when connecting to a legacy `MediaBrowserCompat`.
|
||||
The service can receive the connection hints passed in as root hints
|
||||
with the first call to `onGetRoot()`.
|
||||
* UI:
|
||||
* Make the stretched/cropped video in
|
||||
`PlayerView`-in-Compose-`AndroidView` workaround opt-in, due to issues
|
||||
|
@ -292,7 +292,7 @@ public final class MediaBrowser extends MediaController {
|
||||
if (token.isLegacySession()) {
|
||||
impl =
|
||||
new MediaBrowserImplLegacy(
|
||||
context, this, token, applicationLooper, checkNotNull(bitmapLoader));
|
||||
context, this, token, connectionHints, applicationLooper, checkNotNull(bitmapLoader));
|
||||
} else {
|
||||
impl = new MediaBrowserImplBase(context, this, token, connectionHints, applicationLooper);
|
||||
}
|
||||
|
@ -62,9 +62,10 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
Context context,
|
||||
@UnderInitialization MediaBrowser instance,
|
||||
SessionToken token,
|
||||
Bundle connectionHints,
|
||||
Looper applicationLooper,
|
||||
BitmapLoader bitmapLoader) {
|
||||
super(context, instance, token, applicationLooper, bitmapLoader);
|
||||
super(context, instance, token, connectionHints, applicationLooper, bitmapLoader);
|
||||
this.instance = instance;
|
||||
commandButtonsForMediaItems = ImmutableMap.of();
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ public class MediaController implements Player {
|
||||
@Nullable BitmapLoader bitmapLoader) {
|
||||
if (token.isLegacySession()) {
|
||||
return new MediaControllerImplLegacy(
|
||||
context, this, token, applicationLooper, checkNotNull(bitmapLoader));
|
||||
context, this, token, connectionHints, applicationLooper, checkNotNull(bitmapLoader));
|
||||
} else {
|
||||
return new MediaControllerImplBase(context, this, token, connectionHints, applicationLooper);
|
||||
}
|
||||
@ -2073,6 +2073,10 @@ public class MediaController implements Player {
|
||||
return impl.getBinder();
|
||||
}
|
||||
|
||||
/* package */ Bundle getConnectionHints() {
|
||||
return impl.getConnectionHints();
|
||||
}
|
||||
|
||||
private void verifyApplicationThread() {
|
||||
checkState(Looper.myLooper() == getApplicationLooper(), WRONG_THREAD_ERROR_MESSAGE);
|
||||
}
|
||||
@ -2081,6 +2085,8 @@ public class MediaController implements Player {
|
||||
|
||||
void connect(@UnderInitialization MediaControllerImpl this);
|
||||
|
||||
Bundle getConnectionHints();
|
||||
|
||||
void addListener(Player.Listener listener);
|
||||
|
||||
void removeListener(Player.Listener listener);
|
||||
|
@ -215,6 +215,11 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getConnectionHints() {
|
||||
return connectionHints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
|
@ -102,6 +102,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
private final ControllerCompatCallback controllerCompatCallback;
|
||||
private final BitmapLoader bitmapLoader;
|
||||
private final ImmutableList<CommandButton> commandButtonsForMediaItems;
|
||||
private final Bundle connectionHints;
|
||||
|
||||
@Nullable private MediaControllerCompat controllerCompat;
|
||||
@Nullable private MediaBrowserCompat browserCompat;
|
||||
@ -117,6 +118,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
Context context,
|
||||
@UnderInitialization MediaController instance,
|
||||
SessionToken token,
|
||||
Bundle connectionHints,
|
||||
Looper applicationLooper,
|
||||
BitmapLoader bitmapLoader) {
|
||||
// Initialize default values.
|
||||
@ -134,6 +136,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
this.instance = instance;
|
||||
controllerCompatCallback = new ControllerCompatCallback(applicationLooper);
|
||||
this.token = token;
|
||||
this.connectionHints = connectionHints;
|
||||
this.bitmapLoader = bitmapLoader;
|
||||
currentPositionMs = C.TIME_UNSET;
|
||||
lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET;
|
||||
@ -154,6 +157,11 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getConnectionHints() {
|
||||
return connectionHints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
@ -1410,7 +1418,10 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
// Create it on the application looper to respect that.
|
||||
browserCompat =
|
||||
new MediaBrowserCompat(
|
||||
context, token.getComponentName(), new ConnectionCallback(), null);
|
||||
context,
|
||||
token.getComponentName(),
|
||||
new ConnectionCallback(),
|
||||
instance.getConnectionHints());
|
||||
browserCompat.connect();
|
||||
});
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import static androidx.media3.session.LibraryResult.RESULT_SUCCESS;
|
||||
import static androidx.media3.session.MediaConstants.EXTRAS_KEY_COMPLETION_STATUS;
|
||||
import static androidx.media3.session.MediaConstants.EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED;
|
||||
import static androidx.media3.session.MediaConstants.EXTRA_KEY_ROOT_CHILDREN_BROWSABLE_ONLY;
|
||||
import static androidx.media3.session.MockMediaBrowserServiceCompat.EXTRAS_KEY_SEND_ROOT_HINTS_AS_SESSION_EXTRAS;
|
||||
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA_BROWSER_SERVICE_COMPAT;
|
||||
import static androidx.media3.test.session.common.MediaBrowserConstants.PARENT_ID;
|
||||
import static androidx.media3.test.session.common.MediaBrowserConstants.ROOT_EXTRAS_KEY;
|
||||
@ -136,6 +137,33 @@ public class MediaBrowserListenerWithMediaBrowserServiceCompatTest {
|
||||
assertThat(thrown).hasCauseThat().isInstanceOf(SecurityException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void connect_useConnectionHints_connectionHintsPassedToLegacyServerOnGetRootAsRootHints()
|
||||
throws Exception {
|
||||
Bundle connectionHints = new Bundle();
|
||||
connectionHints.putBoolean(EXTRAS_KEY_SEND_ROOT_HINTS_AS_SESSION_EXTRAS, true);
|
||||
CountDownLatch latch = new CountDownLatch(/* count= */ 1);
|
||||
AtomicReference<Bundle> extrasRef = new AtomicReference<>();
|
||||
createBrowser(
|
||||
connectionHints,
|
||||
/* maxCommandsForMediaItems= */ 0,
|
||||
/* listener= */ new MediaBrowser.Listener() {
|
||||
@Override
|
||||
public void onExtrasChanged(MediaController controller, Bundle extras) {
|
||||
extrasRef.set(extras);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||
assertThat(
|
||||
extrasRef
|
||||
.get()
|
||||
.getBoolean(
|
||||
EXTRAS_KEY_SEND_ROOT_HINTS_AS_SESSION_EXTRAS, /* defaultValue= */ false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLibraryRoot_browseActionsAvailable() throws Exception {
|
||||
remoteService.setProxyForTest(TEST_MEDIA_ITEMS_WITH_BROWSE_ACTIONS);
|
||||
|
@ -40,7 +40,9 @@ import static java.lang.Math.min;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.media.MediaBrowserCompat;
|
||||
import android.support.v4.media.MediaBrowserCompat.MediaItem;
|
||||
@ -68,6 +70,13 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat {
|
||||
*/
|
||||
public static final ImmutableList<MediaItem> MEDIA_ITEMS = createMediaItems();
|
||||
|
||||
/**
|
||||
* Key in the browser root hints to request a confirmation of the call to {@link
|
||||
* #onGetRoot(String, int, Bundle)}.
|
||||
*/
|
||||
public static final String EXTRAS_KEY_SEND_ROOT_HINTS_AS_SESSION_EXTRAS =
|
||||
"confirm_on_get_root_with_custom_action";
|
||||
|
||||
private static final String TAG = "MockMBSCompat";
|
||||
private static final Object lock = new Object();
|
||||
|
||||
@ -166,12 +175,18 @@ public class MockMediaBrowserServiceCompat extends MediaBrowserServiceCompat {
|
||||
// Test only -- reject any other request.
|
||||
return null;
|
||||
}
|
||||
if (rootHints.getBoolean(EXTRAS_KEY_SEND_ROOT_HINTS_AS_SESSION_EXTRAS, false)) {
|
||||
// Send delayed because the Media3 browser is in the process of connecting at this point and
|
||||
// won't receive listener callbacks before being connected.
|
||||
new Handler(Looper.myLooper())
|
||||
.postDelayed(() -> sessionCompat.setExtras(rootHints), /* delayMillis= */ 100L);
|
||||
}
|
||||
synchronized (lock) {
|
||||
if (isProxyOverridesMethod("onGetRoot")) {
|
||||
return serviceProxy.onGetRoot(clientPackageName, clientUid, rootHints);
|
||||
}
|
||||
}
|
||||
return new BrowserRoot("stub", null);
|
||||
return new BrowserRoot("stub", /* extras= */ rootHints);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user