Merge "Check if getSystemSessionInfo requested by a Proxy Router" into main
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 7727078..63cb945 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -50,7 +50,7 @@
// MediaRouterService.java for readability.
// Methods for MediaRouter2
- List<MediaRoute2Info> getSystemRoutes();
+ List<MediaRoute2Info> getSystemRoutes(String callerPackageName, boolean isProxyRouter);
RoutingSessionInfo getSystemSessionInfo();
void registerRouter2(IMediaRouter2 router, String packageName);
@@ -75,7 +75,8 @@
// Methods for MediaRouter2Manager
List<RoutingSessionInfo> getRemoteSessions(IMediaRouter2Manager manager);
- RoutingSessionInfo getSystemSessionInfoForPackage(String packageName);
+ RoutingSessionInfo getSystemSessionInfoForPackage(String callerPackageName,
+ String targetPackageName);
void registerManager(IMediaRouter2Manager manager, String packageName);
void registerProxyRouter(IMediaRouter2Manager manager, String callingPackageName, String targetPackageName, in UserHandle targetUser);
void unregisterManager(IMediaRouter2Manager manager);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index e0258ba..3f9440b 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -613,7 +613,7 @@
mImpl = new LocalMediaRouter2Impl(mContext.getPackageName());
mHandler = new Handler(Looper.getMainLooper());
- loadSystemRoutes();
+ loadSystemRoutes(/* isProxyRouter */ false);
RoutingSessionInfo currentSystemSessionInfo = mImpl.getSystemSessionInfo();
if (currentSystemSessionInfo == null) {
@@ -631,21 +631,22 @@
IMediaRouterService.Stub.asInterface(
ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
- loadSystemRoutes();
+ loadSystemRoutes(/* isProxyRouter */ true);
mSystemController =
new SystemRoutingController(
ProxyMediaRouter2Impl.getSystemSessionInfoImpl(
- mMediaRouterService, clientPackageName));
+ mMediaRouterService, mContext.getPackageName(), clientPackageName));
mImpl = new ProxyMediaRouter2Impl(context, clientPackageName, user);
}
@GuardedBy("mLock")
- private void loadSystemRoutes() {
+ private void loadSystemRoutes(boolean isProxyRouter) {
List<MediaRoute2Info> currentSystemRoutes = null;
try {
- currentSystemRoutes = mMediaRouterService.getSystemRoutes();
+ currentSystemRoutes = mMediaRouterService.getSystemRoutes(mContext.getPackageName(),
+ isProxyRouter);
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
@@ -2644,7 +2645,8 @@
@Override
public RoutingSessionInfo getSystemSessionInfo() {
- return getSystemSessionInfoImpl(mMediaRouterService, mClientPackageName);
+ return getSystemSessionInfoImpl(
+ mMediaRouterService, mContext.getPackageName(), mClientPackageName);
}
/**
@@ -3049,9 +3051,11 @@
* <p>Extracted into a static method to allow calling this from the constructor.
*/
/* package */ static RoutingSessionInfo getSystemSessionInfoImpl(
- @NonNull IMediaRouterService service, @NonNull String clientPackageName) {
+ @NonNull IMediaRouterService service,
+ @NonNull String callerPackageName,
+ @NonNull String clientPackageName) {
try {
- return service.getSystemSessionInfoForPackage(clientPackageName);
+ return service.getSystemSessionInfoForPackage(callerPackageName, clientPackageName);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 7756d93..e62d112 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -81,6 +81,7 @@
@GuardedBy("sLock")
private static MediaRouter2Manager sInstance;
+ private final Context mContext;
private final MediaSessionManager mMediaSessionManager;
private final Client mClient;
private final IMediaRouterService mMediaRouterService;
@@ -120,6 +121,7 @@
}
private MediaRouter2Manager(Context context) {
+ mContext = context.getApplicationContext();
mMediaRouterService = IMediaRouterService.Stub.asInterface(
ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
mMediaSessionManager = (MediaSessionManager) context
@@ -374,16 +376,17 @@
}
/**
- * Gets the system routing session for the given {@code packageName}.
- * Apps can select a route that is not the global route. (e.g. an app can select the device
- * route while BT route is available.)
+ * Gets the system routing session for the given {@code targetPackageName}. Apps can select a
+ * route that is not the global route. (e.g. an app can select the device route while BT route
+ * is available.)
*
- * @param packageName the package name of the application.
+ * @param targetPackageName the package name of the application.
*/
@Nullable
- public RoutingSessionInfo getSystemRoutingSession(@Nullable String packageName) {
+ public RoutingSessionInfo getSystemRoutingSession(@Nullable String targetPackageName) {
try {
- return mMediaRouterService.getSystemSessionInfoForPackage(packageName);
+ return mMediaRouterService.getSystemSessionInfoForPackage(
+ mContext.getPackageName(), targetPackageName);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index ae6a7e9..ec15ff3 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -221,18 +221,27 @@
// Start of methods that implement MediaRouter2 operations.
@NonNull
- public List<MediaRoute2Info> getSystemRoutes() {
+ public List<MediaRoute2Info> getSystemRoutes(@NonNull String callerPackageName,
+ boolean isProxyRouter) {
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
- final boolean hasSystemRoutingPermission = checkCallerHasSystemRoutingPermissions(pid, uid);
+
+ boolean hasSystemRoutingPermissions;
+ if (!isProxyRouter) {
+ hasSystemRoutingPermissions = checkCallerHasSystemRoutingPermissions(pid, uid);
+ } else {
+ // Request from ProxyRouter.
+ hasSystemRoutingPermissions =
+ checkCallerHasPrivilegedRoutingPermissions(pid, uid, callerPackageName);
+ }
final long token = Binder.clearCallingIdentity();
try {
Collection<MediaRoute2Info> systemRoutes;
synchronized (mLock) {
UserRecord userRecord = getOrCreateUserRecordLocked(userId);
- if (hasSystemRoutingPermission) {
+ if (hasSystemRoutingPermissions) {
MediaRoute2ProviderInfo providerInfo =
userRecord.mHandler.mSystemProvider.getProviderInfo();
if (providerInfo != null) {
@@ -795,12 +804,21 @@
@Nullable
public RoutingSessionInfo getSystemSessionInfo(
- @Nullable String packageName, boolean setDeviceRouteSelected) {
+ @NonNull String callerPackageName,
+ @Nullable String targetPackageName,
+ boolean setDeviceRouteSelected) {
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
- final boolean hasSystemRoutingPermissions =
- checkCallerHasSystemRoutingPermissions(pid, uid);
+
+ boolean hasSystemRoutingPermissions;
+ if (targetPackageName == null) {
+ hasSystemRoutingPermissions = checkCallerHasSystemRoutingPermissions(pid, uid);
+ } else {
+ // Request from ProxyRouter.
+ hasSystemRoutingPermissions =
+ checkCallerHasPrivilegedRoutingPermissions(pid, uid, callerPackageName);
+ }
final long token = Binder.clearCallingIdentity();
try {
@@ -812,14 +830,14 @@
// Return a fake system session that shows the device route as selected and
// available bluetooth routes as transferable.
return userRecord.mHandler.mSystemProvider
- .generateDeviceRouteSelectedSessionInfo(packageName);
+ .generateDeviceRouteSelectedSessionInfo(targetPackageName);
} else {
sessionInfos = userRecord.mHandler.mSystemProvider.getSessionInfos();
if (!sessionInfos.isEmpty()) {
// Return a copy of the current system session with no modification,
// except setting the client package name.
return new RoutingSessionInfo.Builder(sessionInfos.get(0))
- .setClientPackageName(packageName)
+ .setClientPackageName(targetPackageName)
.build();
} else {
Slog.w(TAG, "System provider does not have any session info.");
@@ -828,7 +846,7 @@
} else {
return new RoutingSessionInfo.Builder(
userRecord.mHandler.mSystemProvider.getDefaultSessionInfo())
- .setClientPackageName(packageName)
+ .setClientPackageName(targetPackageName)
.build();
}
}
@@ -843,6 +861,12 @@
|| checkCallerHasBluetoothPermissions(pid, uid);
}
+ private boolean checkCallerHasPrivilegedRoutingPermissions(
+ int pid, int uid, @NonNull String callerPackageName) {
+ return checkMediaContentControlPermission(uid, pid)
+ || checkMediaRoutingControlPermission(uid, pid, callerPackageName);
+ }
+
private boolean checkCallerHasModifyAudioRoutingPermission(int pid, int uid) {
return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
== PackageManager.PERMISSION_GRANTED;
@@ -864,30 +888,29 @@
Manifest.permission.MEDIA_CONTENT_CONTROL
})
private void enforcePrivilegedRoutingPermissions(
- int callerUid, int callerPid, @Nullable String callerPackageName) {
- if (hasMediaContentControlPermission(callerUid, callerPid)) {
+ int callerUid, int callerPid, @NonNull String callerPackageName) {
+ if (checkMediaContentControlPermission(callerUid, callerPid)) {
return;
}
- if (!Flags.enablePrivilegedRoutingForMediaRoutingControl()) {
- throw new SecurityException("Must hold MEDIA_CONTENT_CONTROL");
- }
-
if (!checkMediaRoutingControlPermission(callerUid, callerPid, callerPackageName)) {
throw new SecurityException(
"Must hold MEDIA_CONTENT_CONTROL or MEDIA_ROUTING_CONTROL permissions.");
}
}
- @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
- private boolean hasMediaContentControlPermission(int callerUid, int callerPid) {
+ private boolean checkMediaContentControlPermission(int callerUid, int callerPid) {
return mContext.checkPermission(
Manifest.permission.MEDIA_CONTENT_CONTROL, callerPid, callerUid)
== PackageManager.PERMISSION_GRANTED;
}
private boolean checkMediaRoutingControlPermission(
- int callerUid, int callerPid, @Nullable String callerPackageName) {
+ int callerUid, int callerPid, @NonNull String callerPackageName) {
+ if (!Flags.enablePrivilegedRoutingForMediaRoutingControl()) {
+ return false;
+ }
+
return PermissionChecker.checkPermissionForDataDelivery(
mContext,
Manifest.permission.MEDIA_ROUTING_CONTROL,
@@ -1520,7 +1543,7 @@
boolean hasMediaRoutingControl =
checkMediaRoutingControlPermission(callerUid, callerPid, callerPackageName);
- boolean hasMediaContentControl = hasMediaContentControlPermission(callerUid, callerPid);
+ boolean hasMediaContentControl = checkMediaContentControlPermission(callerUid, callerPid);
Slog.i(
TAG,
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 6af3480..76b8db6 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -411,15 +411,21 @@
// Binder call
@Override
- public List<MediaRoute2Info> getSystemRoutes() {
- return mService2.getSystemRoutes();
+ public List<MediaRoute2Info> getSystemRoutes(@NonNull String callerPackageName,
+ boolean isProxyRouter) {
+ if (!validatePackageName(Binder.getCallingUid(), callerPackageName)) {
+ throw new SecurityException("callerPackageName does not match calling uid.");
+ }
+ return mService2.getSystemRoutes(callerPackageName, isProxyRouter);
}
// Binder call
@Override
public RoutingSessionInfo getSystemSessionInfo() {
return mService2.getSystemSessionInfo(
- null /* packageName */, false /* setDeviceRouteSelected */);
+ /* callerPackageName */ null,
+ /* targetPackageName */ null, /* setDeviceRouteSelected */
+ false);
}
// Binder call
@@ -530,16 +536,22 @@
// Binder call
@Override
- public RoutingSessionInfo getSystemSessionInfoForPackage(@Nullable String packageName) {
+ public RoutingSessionInfo getSystemSessionInfoForPackage(
+ @NonNull String callerPackageName, @Nullable String targetPackageName) {
final int uid = Binder.getCallingUid();
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
+
+ if (!validatePackageName(uid, callerPackageName)) {
+ throw new SecurityException("callerPackageName does not match calling uid.");
+ }
+
boolean setDeviceRouteSelected = false;
synchronized (mLock) {
UserRecord userRecord = mUserRecords.get(userId);
List<ClientRecord> userClientRecords =
userRecord != null ? userRecord.mClientRecords : Collections.emptyList();
for (ClientRecord clientRecord : userClientRecords) {
- if (TextUtils.equals(clientRecord.mPackageName, packageName)) {
+ if (TextUtils.equals(clientRecord.mPackageName, targetPackageName)) {
if (mDefaultAudioRouteId.equals(clientRecord.mSelectedRouteId)) {
setDeviceRouteSelected = true;
break;
@@ -547,7 +559,8 @@
}
}
}
- return mService2.getSystemSessionInfo(packageName, setDeviceRouteSelected);
+ return mService2.getSystemSessionInfo(
+ callerPackageName, targetPackageName, setDeviceRouteSelected);
}
// Binder call