From c036350122226b86130773cc6b472f0a2bbe756d Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Fri, 19 Jun 2020 13:33:16 +0900 Subject: [PATCH] System routes are not automatically exposed From this CL, even for system routes (phone speaker, bt routes), features are required to get notified of events on routes or to get them as "available" routes. By adding this, apps can disable cast -> phone feature. Bug: 159090706 Test: cts test && atest mediaroutertest && manually using support v7 demos such that with LIVE_AUDIO : nothing changed w/o LIVE_AUDIO : cast -> phone feature is disabled unregistering callback : cast -> cast (media transfer) and phone -> phone is only enabled <- this is the expected behavior for apps that updates AndroidX library Change-Id: I4bd27eb1d4776b9cedb59b10e1bac5868d56d305 --- media/java/android/media/MediaRoute2Info.java | 17 +++++++---- media/java/android/media/MediaRouter2.java | 28 ++++++------------- .../android/media/MediaRouter2Manager.java | 20 +++---------- .../MediaRouter2ManagerTest.java | 3 -- .../server/media/BluetoothRouteProvider.java | 1 + .../media/SystemMediaRoute2Provider.java | 2 ++ 6 files changed, 28 insertions(+), 43 deletions(-) diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java index 54c0bc94c2d09..fad25e071f90b 100644 --- a/media/java/android/media/MediaRoute2Info.java +++ b/media/java/android/media/MediaRoute2Info.java @@ -226,7 +226,7 @@ public final class MediaRoute2Info implements Parcelable { public static final int TYPE_GROUP = 2000; /** - * Media feature: Live audio. + * Route feature: Live audio. *

* A route that supports live audio routing will allow the media audio stream * to be sent to supported destinations. This can include internal speakers or @@ -241,7 +241,7 @@ public final class MediaRoute2Info implements Parcelable { public static final String FEATURE_LIVE_AUDIO = "android.media.route.feature.LIVE_AUDIO"; /** - * Media feature: Live video. + * Route feature: Live video. *

* A route that supports live video routing will allow a mirrored version * of the device's primary display or a customized @@ -262,7 +262,14 @@ public final class MediaRoute2Info implements Parcelable { public static final String FEATURE_LIVE_VIDEO = "android.media.route.feature.LIVE_VIDEO"; /** - * Media feature: Remote playback. + * Route feature: Local playback. + * @hide + */ + public static final String FEATURE_LOCAL_PLAYBACK = + "android.media.route.feature.LOCAL_PLAYBACK"; + + /** + * Route feature: Remote playback. *

* A route that supports remote playback routing will allow an application to send * requests to play content remotely to supported destinations. @@ -283,7 +290,7 @@ public final class MediaRoute2Info implements Parcelable { "android.media.route.feature.REMOTE_PLAYBACK"; /** - * Media feature: Remote audio playback. + * Route feature: Remote audio playback. *

* A route that supports remote audio playback routing will allow an application to send * requests to play audio content remotely to supported destinations. @@ -295,7 +302,7 @@ public final class MediaRoute2Info implements Parcelable { "android.media.route.feature.REMOTE_AUDIO_PLAYBACK"; /** - * Media feature: Remote video playback. + * Route feature: Remote video playback. *

* A route that supports remote video playback routing will allow an application to send * requests to play video content remotely to supported destinations. diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 6fe48a4ef7e06..8e95239a73f89 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -151,7 +151,7 @@ public final class MediaRouter2 { * * @hide */ - public static boolean checkRouteListContainsRouteId(@NonNull List routeList, + static boolean checkRouteListContainsRouteId(@NonNull List routeList, @NonNull String routeId) { for (MediaRoute2Info info : routeList) { if (TextUtils.equals(routeId, info.getId())) { @@ -258,8 +258,6 @@ public final class MediaRouter2 { * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently * known to the media router. *

- * {@link MediaRoute2Info#isSystemRoute() System routes} such as phone speaker, - * Bluetooth devices are always included in the list. * Please note that the list can be changed before callbacks are invoked. *

* @@ -274,8 +272,7 @@ public final class MediaRouter2 { List filteredRoutes = new ArrayList<>(); for (MediaRoute2Info route : mRoutes.values()) { - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { filteredRoutes.add(route); } } @@ -526,8 +523,7 @@ public final class MediaRouter2 { if (!currentRoutesIds.contains(routeId)) { // This route is removed while the callback is unregistered. MediaRoute2Info route = mRoutes.get(routeId); - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { removedRoutes.add(mRoutes.get(routeId)); } } @@ -537,16 +533,14 @@ public final class MediaRouter2 { if (mRoutes.containsKey(route.getId())) { if (!route.equals(mRoutes.get(route.getId()))) { // This route is changed while the callback is unregistered. - if (route.isSystemRoute() - || route.hasAnyFeatures( + if (route.hasAnyFeatures( mDiscoveryPreference.getPreferredFeatures())) { changedRoutes.add(route); } } } else { // This route is added while the callback is unregistered. - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { addedRoutes.add(route); } } @@ -582,8 +576,7 @@ public final class MediaRouter2 { synchronized (sRouterLock) { for (MediaRoute2Info route : routes) { mRoutes.put(route.getId(), route); - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { addedRoutes.add(route); } } @@ -599,8 +592,7 @@ public final class MediaRouter2 { synchronized (sRouterLock) { for (MediaRoute2Info route : routes) { mRoutes.remove(route.getId()); - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { removedRoutes.add(route); } } @@ -616,8 +608,7 @@ public final class MediaRouter2 { synchronized (sRouterLock) { for (MediaRoute2Info route : routes) { mRoutes.put(route.getId(), route); - if (route.isSystemRoute() - || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { + if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) { changedRoutes.add(route); } } @@ -799,8 +790,7 @@ public final class MediaRouter2 { private List filterRoutes(List routes, RouteDiscoveryPreference discoveryRequest) { return routes.stream() - .filter(route -> route.isSystemRoute() - || route.hasAnyFeatures(discoveryRequest.getPreferredFeatures())) + .filter(route -> route.hasAnyFeatures(discoveryRequest.getPreferredFeatures())) .collect(Collectors.toList()); } diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index 773263865135d..35aee7ebc7cee 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -165,20 +165,8 @@ public final class MediaRouter2Manager { public List getAvailableRoutes(@NonNull String packageName) { Objects.requireNonNull(packageName, "packageName must not be null"); - List routes = new ArrayList<>(); - - List preferredFeatures = mPreferredFeaturesMap.get(packageName); - if (preferredFeatures == null) { - preferredFeatures = Collections.emptyList(); - } - synchronized (mRoutesLock) { - for (MediaRoute2Info route : mRoutes.values()) { - if (route.isSystemRoute() || route.hasAnyFeatures(preferredFeatures)) { - routes.add(route); - } - } - } - return routes; + List sessions = getRoutingSessions(packageName); + return getAvailableRoutesForRoutingSession(sessions.get(sessions.size() - 1)); } /** @@ -202,7 +190,7 @@ public final class MediaRouter2Manager { } synchronized (mRoutesLock) { for (MediaRoute2Info route : mRoutes.values()) { - if (route.isSystemRoute() || route.hasAnyFeatures(preferredFeatures) + if (route.hasAnyFeatures(preferredFeatures) || sessionInfo.getSelectedRoutes().contains(route.getId()) || sessionInfo.getTransferableRoutes().contains(route.getId())) { routes.add(route); @@ -303,7 +291,7 @@ public final class MediaRouter2Manager { } /** - * Gets the list of all discovered routes + * Gets the list of all discovered routes. */ @NonNull public List getAllRoutes() { diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java index 638a842e4e5f1..0979627e5e8d7 100644 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java @@ -97,7 +97,6 @@ public class MediaRouter2ManagerTest { public static final List FEATURES_ALL = new ArrayList(); public static final List FEATURES_SPECIAL = new ArrayList(); - private static final List FEATURES_LIVE_AUDIO = new ArrayList<>(); static { FEATURES_ALL.add(FEATURE_SAMPLE); @@ -105,8 +104,6 @@ public class MediaRouter2ManagerTest { FEATURES_ALL.add(FEATURE_LIVE_AUDIO); FEATURES_SPECIAL.add(FEATURE_SPECIAL); - - FEATURES_LIVE_AUDIO.add(FEATURE_LIVE_AUDIO); } @Before diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index 4def7db76bc5f..47c1a50b742f2 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -266,6 +266,7 @@ class BluetoothRouteProvider { // Current volume will be set when connected. newBtRoute.route = new MediaRoute2Info.Builder(routeId, deviceName) .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO) + .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK) .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED) .setDescription(mContext.getResources().getText( R.string.bluetooth_a2dp_audio_route_name).toString()) diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index e01f36513c5cb..42d4c88959bd3 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -18,6 +18,7 @@ package com.android.server.media; import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO; import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO; +import static android.media.MediaRoute2Info.FEATURE_LOCAL_PLAYBACK; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_HDMI; @@ -262,6 +263,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .setType(type) .addFeature(FEATURE_LIVE_AUDIO) .addFeature(FEATURE_LIVE_VIDEO) + .addFeature(FEATURE_LOCAL_PLAYBACK) .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED) .build(); updateProviderState();