diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaLibraryServiceLegacyStub.java b/libraries/session/src/main/java/androidx/media3/session/MediaLibraryServiceLegacyStub.java index 9a90e9478a..eeb4f3674a 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaLibraryServiceLegacyStub.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaLibraryServiceLegacyStub.java @@ -17,6 +17,7 @@ package androidx.media3.session; import static android.support.v4.media.MediaBrowserCompat.EXTRA_PAGE; import static android.support.v4.media.MediaBrowserCompat.EXTRA_PAGE_SIZE; +import static androidx.media.utils.MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Util.castNonNull; @@ -108,7 +109,15 @@ import java.util.concurrent.atomic.AtomicReference; Log.e(TAG, "Couldn't get a result from onGetLibraryRoot", e); } if (result != null && result.resultCode == RESULT_SUCCESS && result.value != null) { - return new BrowserRoot(result.value.mediaId, MediaUtils.convertToRootHints(result.params)); + @Nullable + Bundle extras = + result.params != null ? MediaUtils.convertToRootHints(result.params) : new Bundle(); + boolean isSearchSessionCommandAvailable = + getConnectedControllersManager() + .isSessionCommandAvailable(controller, SessionCommand.COMMAND_CODE_LIBRARY_SEARCH); + checkNotNull(extras) + .putBoolean(BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, isSearchSessionCommandAvailable); + return new BrowserRoot(result.value.mediaId, extras); } // No library root, but keep browser compat connected to allow getting session. return MediaUtils.defaultBrowserRoot; diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java index b05e2dd455..d365a80edf 100644 --- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java +++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaBrowserCompatWithMediaLibraryServiceTest.java @@ -15,6 +15,7 @@ */ package androidx.media3.session; +import static androidx.media.utils.MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED; 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.MockMediaLibraryService.CONNECTION_HINTS_CUSTOM_LIBRARY_ROOT; @@ -583,4 +584,27 @@ public class MediaBrowserCompatWithMediaLibraryServiceTest assertThat(root).isEqualTo("myLibraryRoot"); } + + @Test + public void rootBrowserHints_searchSupported_reportsSearchSupported() throws Exception { + connectAndWait(/* connectionHints= */ Bundle.EMPTY); + + boolean isSearchSupported = + browserCompat.getExtras().getBoolean(BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED); + + assertThat(isSearchSupported).isTrue(); + } + + @Test + public void rootBrowserHints_searchNotSupported_reportsSearchNotSupported() throws Exception { + Bundle connectionHints = new Bundle(); + connectionHints.putBoolean( + MockMediaLibraryService.CONNECTION_HINTS_KEY_REMOVE_COMMAND_CODE_LIBRARY_SEARCH, true); + connectAndWait(connectionHints); + + boolean isSearchSupported = + browserCompat.getExtras().getBoolean(BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED); + + assertThat(isSearchSupported).isFalse(); + } } diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java index 995b162150..cfad2d7550 100644 --- a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java +++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java @@ -81,9 +81,16 @@ import java.util.concurrent.Executors; public class MockMediaLibraryService extends MediaLibraryService { /** ID of the session that this service will create. */ public static final String ID = "TestLibrary"; - + /** Key used in connection hints to instruct the mock service to use a given library root. */ public static final String CONNECTION_HINTS_CUSTOM_LIBRARY_ROOT = "CONNECTION_HINTS_CUSTOM_LIBRARY_ROOT"; + /** + * Key used in connection hints to instruct the mock service to remove {@link + * SessionCommand#COMMAND_CODE_LIBRARY_SEARCH} from the available commands in {@link + * MediaSession.Callback#onConnect(MediaSession, ControllerInfo)}. + */ + public static final String CONNECTION_HINTS_KEY_REMOVE_COMMAND_CODE_LIBRARY_SEARCH = + "CONNECTION_HINTS_KEY_REMOVE_SEARCH_SESSION_COMMAND"; public static final MediaItem ROOT_ITEM = new MediaItem.Builder() @@ -186,6 +193,12 @@ public class MockMediaLibraryService extends MediaLibraryService { SessionCommands.Builder builder = connectionResult.availableSessionCommands.buildUpon(); builder.add(new SessionCommand(CUSTOM_ACTION, /* extras= */ Bundle.EMPTY)); builder.add(new SessionCommand(CUSTOM_ACTION_ASSERT_PARAMS, /* extras= */ Bundle.EMPTY)); + if (controller + .getConnectionHints() + .getBoolean( + CONNECTION_HINTS_KEY_REMOVE_COMMAND_CODE_LIBRARY_SEARCH, /* defaultValue= */ false)) { + builder.remove(SessionCommand.COMMAND_CODE_LIBRARY_SEARCH); + } return MediaSession.ConnectionResult.accept( /* availableSessionCommands= */ builder.build(), connectionResult.availablePlayerCommands); @@ -196,7 +209,8 @@ public class MockMediaLibraryService extends MediaLibraryService { MediaLibrarySession session, ControllerInfo browser, @Nullable LibraryParams params) { assertLibraryParams(params); MediaItem rootItem = ROOT_ITEM; - // Use connection hints to select the library root. + // Use connection hints to select the library root to test whether the legacy browser root + // hints are propagated as connection hints. String customLibraryRoot = browser .getConnectionHints()