summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kyunglyul Hyun <klhyun@google.com> 2020-01-29 19:59:33 +0900
committer Kyunglyul Hyun <klhyun@google.com> 2020-01-31 17:11:27 +0900
commit96d36cee930f67a644f6f98408541082224e413a (patch)
treed9d9a1fdc985e06d4a94373a82996cf8f73b5c5e
parent1605af297d4ab67439b2e751c55b33f7ad5515c1 (diff)
MediaRouter: Add MediaRoute2Info#isSystemRoute
MediaRoute2Info#isSystemRoute returns true only if it is generated by SystemMediaRoute2Provider. In addition, MediaRouter2 and MediaRouter2Manager always include system routes when getRoutes or getAvailableRoutes is called. This CL will change the behavior of MediaRouter2#getRoutes(), however, without this change, there doesn't seem to be a good way to get system routes. (e.g. how can we support multiple bt routes in xMR?) Bug: 145632124 Test: atest android.media.cts.MediaRoute2InfoTest && atest android.media.cts.MediaRouter2Test && atest android.media.cts.RouteDiscoveryPreferenceTest && atest android.media.cts.RoutingSessionInfoTest && atest mediaroutertest Change-Id: I18ea188b68e6e1335cb0e25c3cc3674910d4d645
-rw-r--r--api/current.txt1
-rw-r--r--media/java/android/media/MediaRoute2Info.java30
-rw-r--r--media/java/android/media/MediaRoute2ProviderInfo.java17
-rw-r--r--media/java/android/media/MediaRouter2.java13
-rw-r--r--media/java/android/media/MediaRouter2Manager.java7
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java9
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2Provider.java2
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java2
8 files changed, 75 insertions, 6 deletions
diff --git a/api/current.txt b/api/current.txt
index 1306bfa7fb05..a91768331dd5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26729,6 +26729,7 @@ package android.media {
method public int getVolume();
method public int getVolumeHandling();
method public int getVolumeMax();
+ method public boolean isSystemRoute();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index dd01243629c3..4ff70c665012 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -197,6 +197,7 @@ public final class MediaRoute2Info implements Parcelable {
final List<String> mFeatures;
@DeviceType
final int mDeviceType;
+ final boolean mIsSystem;
final Uri mIconUri;
final CharSequence mDescription;
@ConnectionState
@@ -213,6 +214,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = builder.mName;
mFeatures = builder.mFeatures;
mDeviceType = builder.mDeviceType;
+ mIsSystem = builder.mIsSystem;
mIconUri = builder.mIconUri;
mDescription = builder.mDescription;
mConnectionState = builder.mConnectionState;
@@ -229,6 +231,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mFeatures = in.createStringArrayList();
mDeviceType = in.readInt();
+ mIsSystem = in.readBoolean();
mIconUri = in.readParcelable(null);
mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mConnectionState = in.readInt();
@@ -287,6 +290,17 @@ public final class MediaRoute2Info implements Parcelable {
}
/**
+ * Returns whether the route is a system route or not.
+ * <p>
+ * System routes are media routes directly controlled by the system
+ * such as phone speaker, wired headset, and Bluetooth devices.
+ * </p>
+ */
+ public boolean isSystemRoute() {
+ return mIsSystem;
+ }
+
+ /**
* Gets the URI of the icon representing this route.
* <p>
* This icon will be used in picker UIs if available.
@@ -423,6 +437,7 @@ public final class MediaRoute2Info implements Parcelable {
&& Objects.equals(mName, other.mName)
&& Objects.equals(mFeatures, other.mFeatures)
&& (mDeviceType == other.mDeviceType)
+ && (mIsSystem == other.mIsSystem)
&& Objects.equals(mIconUri, other.mIconUri)
&& Objects.equals(mDescription, other.mDescription)
&& (mConnectionState == other.mConnectionState)
@@ -436,7 +451,7 @@ public final class MediaRoute2Info implements Parcelable {
@Override
public int hashCode() {
// Note: mExtras is not included.
- return Objects.hash(mId, mName, mFeatures, mDeviceType, mIconUri, mDescription,
+ return Objects.hash(mId, mName, mFeatures, mDeviceType, mIsSystem, mIconUri, mDescription,
mConnectionState, mClientPackageName, mVolumeHandling, mVolumeMax, mVolume,
mProviderId);
}
@@ -473,6 +488,7 @@ public final class MediaRoute2Info implements Parcelable {
TextUtils.writeToParcel(mName, dest, flags);
dest.writeStringList(mFeatures);
dest.writeInt(mDeviceType);
+ dest.writeBoolean(mIsSystem);
dest.writeParcelable(mIconUri, flags);
TextUtils.writeToParcel(mDescription, dest, flags);
dest.writeInt(mConnectionState);
@@ -494,6 +510,7 @@ public final class MediaRoute2Info implements Parcelable {
@DeviceType
int mDeviceType = DEVICE_TYPE_UNKNOWN;
+ boolean mIsSystem;
Uri mIconUri;
CharSequence mDescription;
@ConnectionState
@@ -540,6 +557,7 @@ public final class MediaRoute2Info implements Parcelable {
mName = routeInfo.mName;
mFeatures = new ArrayList<>(routeInfo.mFeatures);
mDeviceType = routeInfo.mDeviceType;
+ mIsSystem = routeInfo.mIsSystem;
mIconUri = routeInfo.mIconUri;
mDescription = routeInfo.mDescription;
mConnectionState = routeInfo.mConnectionState;
@@ -608,6 +626,16 @@ public final class MediaRoute2Info implements Parcelable {
}
/**
+ * Sets whether the route is a system route or not.
+ * @hide
+ */
+ @NonNull
+ public Builder setSystemRoute(boolean isSystem) {
+ mIsSystem = isSystem;
+ return this;
+ }
+
+ /**
* Sets the URI of the icon representing this route.
* <p>
* This icon will be used in picker UIs if available.
diff --git a/media/java/android/media/MediaRoute2ProviderInfo.java b/media/java/android/media/MediaRoute2ProviderInfo.java
index c9a2ec7ed095..afe002edfbcd 100644
--- a/media/java/android/media/MediaRoute2ProviderInfo.java
+++ b/media/java/android/media/MediaRoute2ProviderInfo.java
@@ -180,6 +180,23 @@ public final class MediaRoute2ProviderInfo implements Parcelable {
}
/**
+ * Sets whether the provider provides system routes or not
+ */
+ @NonNull
+ public Builder setSystemRouteProvider(boolean isSystem) {
+ int count = mRoutes.size();
+ for (int i = 0; i < count; i++) {
+ MediaRoute2Info route = mRoutes.valueAt(i);
+ if (route.isSystemRoute() != isSystem) {
+ mRoutes.setValueAt(i, new MediaRoute2Info.Builder(route)
+ .setSystemRoute(isSystem)
+ .build());
+ }
+ }
+ return this;
+ }
+
+ /**
* Adds a route to the provider
*/
@NonNull
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 7b9a44f71473..f751a22c4900 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -230,7 +230,11 @@ public class MediaRouter2 {
/**
* Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
* known to the media router.
+ * <p>
+ * {@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.
+ * </p>
*
* @return the list of routes that contains at least one of the route features in discovery
* preferences registered by the application
@@ -243,7 +247,8 @@ public class MediaRouter2 {
List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
filteredRoutes.add(route);
}
}
@@ -307,12 +312,18 @@ public class MediaRouter2 {
* with the given route.
*
* @param route the route you want to create a controller with.
+ * @throws IllegalArgumentException if the given route is
+ * {@link MediaRoute2Info#isSystemRoute() system route}
*
* @see RoutingControllerCallback#onControllerCreated
* @see RoutingControllerCallback#onControllerCreationFailed
*/
public void requestCreateController(@NonNull MediaRoute2Info route) {
Objects.requireNonNull(route, "route must not be null");
+ if (route.isSystemRoute()) {
+ throw new IllegalArgumentException("Can't create a route controller with "
+ + "a system route. Use getSystemController().");
+ }
// TODO: Check the given route exists
final int requestId;
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 61e2f77b7d2e..662eeb1418f1 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -161,14 +161,15 @@ public class MediaRouter2Manager {
public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
Objects.requireNonNull(packageName, "packageName must not be null");
+ List<MediaRoute2Info> routes = new ArrayList<>();
+
List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
if (preferredFeatures == null) {
- return Collections.emptyList();
+ preferredFeatures = Collections.emptyList();
}
- List<MediaRoute2Info> routes = new ArrayList<>();
synchronized (mRoutesLock) {
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.hasAnyFeatures(preferredFeatures)) {
+ if (route.isSystemRoute() || route.hasAnyFeatures(preferredFeatures)) {
routes.add(route);
}
}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 4a2044af0431..16259ab45792 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -196,7 +196,14 @@ public class MediaRouterManagerTest {
public void testRouteFeatures() throws Exception {
Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_SPECIAL);
- assertEquals(1, routes.size());
+ int routeCount = 0;
+ for (MediaRoute2Info route : routes.values()) {
+ if (!route.isSystemRoute()) {
+ routeCount++;
+ }
+ }
+
+ assertEquals(1, routeCount);
assertNotNull(routes.get(ROUTE_ID_SPECIAL_FEATURE));
}
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 1cd8aad3f0c5..5123362d84ba 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -36,6 +36,7 @@ abstract class MediaRoute2Provider {
final Object mLock = new Object();
Callback mCallback;
+ boolean mIsSystemRouteProvider;
private volatile MediaRoute2ProviderInfo mProviderInfo;
@GuardedBy("mLock")
@@ -85,6 +86,7 @@ abstract class MediaRoute2Provider {
} else {
mProviderInfo = new MediaRoute2ProviderInfo.Builder(providerInfo)
.setUniqueId(mUniqueId)
+ .setSystemRouteProvider(mIsSystemRouteProvider)
.build();
}
}
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 558eb8d05783..924a9b71c8ec 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -83,6 +83,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
super(sComponentName);
setCallback(callback);
+ mIsSystemRouteProvider = true;
+
mContext = context;
mHandler = new Handler(Looper.getMainLooper());