summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hyundo Moon <hdmoon@google.com> 2021-03-09 09:55:02 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-03-09 09:55:02 +0000
commit36ce69616d061ff04380cf4343b02b6df3ecf9b4 (patch)
tree670609bdc48a3fb2a7f9c551609f996ad4a21df4
parentc739060d183dd24bfae33e9f4b828f85620732f4 (diff)
parentdd4780eba1206848307863776bfbf1dab41aaadb (diff)
Merge "Add basic functionality of MR2Manager in MR2" into sc-dev
-rw-r--r--media/java/android/media/MediaRouter2.java98
-rw-r--r--media/java/android/media/RoutingSessionInfo.java1
2 files changed, 98 insertions, 1 deletions
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index ff52a1abc6f4..dc9c58ebf18c 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -67,6 +68,10 @@ public final class MediaRouter2 {
private static final long MANAGER_REQUEST_ID_NONE = MediaRoute2ProviderService.REQUEST_ID_NONE;
@GuardedBy("sRouterLock")
+ private static Map<String, MediaRouter2> sMediaRouter2Map = new ArrayMap<>();
+ private static MediaRouter2Manager sManager;
+
+ @GuardedBy("sRouterLock")
private static MediaRouter2 sInstance;
private final Context mContext;
@@ -82,7 +87,9 @@ public final class MediaRouter2 {
private final CopyOnWriteArrayList<ControllerCreationRequest> mControllerCreationRequests =
new CopyOnWriteArrayList<>();
+ private final String mClientPackageName;
private final String mPackageName;
+
@GuardedBy("sRouterLock")
final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
@@ -120,6 +127,42 @@ public final class MediaRouter2 {
}
}
+ /**
+ * Gets an instance of the media router which controls the app's media routing.
+ * Returns {@code null} if the given package name is invalid.
+ *
+ * @param clientPackageName the package name of the app to control
+ * @hide
+ */
+ //@SystemApi
+ @Nullable
+ public static MediaRouter2 getInstance(@NonNull Context context,
+ @NonNull String clientPackageName) {
+ Objects.requireNonNull(context, "context must not be null");
+ Objects.requireNonNull(clientPackageName, "clientPackageName must not be null");
+
+ PackageManager pm = context.getPackageManager();
+ try {
+ pm.getPackageInfo(clientPackageName, 0);
+ } catch (PackageManager.NameNotFoundException ex) {
+ Log.e(TAG, "Package " + clientPackageName + " not found. Ignoring.");
+ return null;
+ }
+
+ synchronized (sRouterLock) {
+ MediaRouter2 instance = sMediaRouter2Map.get(clientPackageName);
+ if (instance == null) {
+ // TODO: Add permission check here using MODIFY_AUDIO_ROUTING.
+ if (sManager == null) {
+ sManager = MediaRouter2Manager.getInstance(context.getApplicationContext());
+ }
+ instance = new MediaRouter2(context, clientPackageName);
+ sMediaRouter2Map.put(clientPackageName, instance);
+ }
+ return instance;
+ }
+ }
+
private MediaRouter2(Context appContext) {
mContext = appContext;
mMediaRouterService = IMediaRouterService.Stub.asInterface(
@@ -148,6 +191,17 @@ public final class MediaRouter2 {
mRoutes.put(route.getId(), route);
}
mSystemController = new SystemRoutingController(currentSystemSessionInfo);
+
+ mClientPackageName = null;
+ }
+
+ private MediaRouter2(Context context, String clientPackageName) {
+ mClientPackageName = clientPackageName;
+ mContext = context;
+ mMediaRouterService = null;
+ mPackageName = null;
+ mHandler = new Handler(Looper.getMainLooper());
+ mSystemController = null;
}
/**
@@ -166,6 +220,19 @@ public final class MediaRouter2 {
}
/**
+ * Gets the target package name of the app which this media router controls.
+ * This is only non-null when the router instance is created with the target package name.
+ *
+ * @see #getInstance(Context, String)
+ * @hide
+ */
+ //@SystemApi
+ @Nullable
+ public String getClientPackageName() {
+ return mClientPackageName;
+ }
+
+ /**
* Registers a callback to discover routes and to receive events when they change.
* <p>
* If the specified callback is already registered, its registration will be updated for the
@@ -270,6 +337,10 @@ public final class MediaRouter2 {
*/
@NonNull
public List<MediaRoute2Info> getRoutes() {
+ if (mClientPackageName != null) {
+ return sManager.getAvailableRoutes(mClientPackageName);
+ }
+
synchronized (sRouterLock) {
if (mShouldUpdateRoutes) {
mShouldUpdateRoutes = false;
@@ -378,6 +449,11 @@ public final class MediaRouter2 {
* @see TransferCallback#onTransferFailure
*/
public void transferTo(@NonNull MediaRoute2Info route) {
+ if (mClientPackageName != null) {
+ sManager.selectRoute(mClientPackageName, route);
+ return;
+ }
+
Objects.requireNonNull(route, "route must not be null");
Log.v(TAG, "Transferring to route: " + route);
transfer(getCurrentController(), route);
@@ -388,6 +464,12 @@ public final class MediaRouter2 {
* controls the media routing, this method is a no-op.
*/
public void stop() {
+ if (mClientPackageName != null) {
+ List<RoutingSessionInfo> sessionInfos = sManager.getRoutingSessions(mClientPackageName);
+ RoutingSessionInfo sessionToRelease = sessionInfos.get(sessionInfos.size() - 1);
+ sManager.releaseSession(sessionToRelease);
+ return;
+ }
getCurrentController().release();
}
@@ -397,7 +479,13 @@ public final class MediaRouter2 {
* @param route the route you want to transfer the media to.
* @hide
*/
- void transfer(@NonNull RoutingController controller, @NonNull MediaRoute2Info route) {
+ //@SystemApi
+ public void transfer(@NonNull RoutingController controller, @NonNull MediaRoute2Info route) {
+ if (mClientPackageName != null) {
+ sManager.transfer(controller.getRoutingSessionInfo(), route);
+ return;
+ }
+
Objects.requireNonNull(controller, "controller must not be null");
Objects.requireNonNull(route, "route must not be null");
@@ -486,6 +574,14 @@ public final class MediaRouter2 {
*/
@NonNull
public List<RoutingController> getControllers() {
+ // TODO: Do not create the controller instances every time,
+ // Instead, update the list using the sessions' ID and session related callbacks.
+ if (mClientPackageName != null) {
+ return sManager.getRoutingSessions(mClientPackageName).stream()
+ .map(info -> new RoutingController(info))
+ .collect(Collectors.toList());
+ }
+
List<RoutingController> result = new ArrayList<>();
result.add(0, mSystemController);
synchronized (sRouterLock) {
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index a5d25e0771fd..3bea73febc24 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -326,6 +326,7 @@ public final class RoutingSessionInfo implements Parcelable {
.append("RoutingSessionInfo{ ")
.append("sessionId=").append(getId())
.append(", name=").append(getName())
+ .append(", clientPackageName=").append(getClientPackageName())
.append(", selectedRoutes={")
.append(String.join(",", getSelectedRoutes()))
.append("}")