diff options
| author | 2021-03-24 00:12:01 +0900 | |
|---|---|---|
| committer | 2021-04-02 12:00:54 +0900 | |
| commit | cd83e77ea5c127b3e3c1560e5f6893ec6bb984c9 (patch) | |
| tree | f3500cf41ad640be09d9b07e4523fbb0d50eb7bf | |
| parent | 9587d2c459f610181905814db2e054a880865ba5 (diff) | |
System MR2: Check MODIFY_AUDIO_ROUTING permission
This CL adds a permission check for
MediaRouter2#getInstance(Context, String)
which creates the system MediaRouter2 instance.
Bug: 183428114
Test: CTS only passes with the right permission.
Change-Id: I38561dd6525d9e3c4514829662483d2c7a08dda1
5 files changed, 37 insertions, 4 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 696494b0248c..3f2aa79da3fc 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -5274,7 +5274,7 @@ package android.media { method @NonNull public java.util.List<android.media.MediaRoute2Info> getAllRoutes(); method @Nullable public String getClientPackageName(); method @Nullable public android.media.MediaRouter2.RoutingController getController(@NonNull String); - method @Nullable public static android.media.MediaRouter2 getInstance(@NonNull android.content.Context, @NonNull String); + method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static android.media.MediaRouter2 getInstance(@NonNull android.content.Context, @NonNull String); method public void setRouteVolume(@NonNull android.media.MediaRoute2Info, int); method public void startScan(); method public void stopScan(); diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl index 4b8a8adade1f..f817a3c3c353 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -48,6 +48,7 @@ interface IMediaRouterService { // MediaRouterService.java for readability. // Methods for MediaRouter2 + void checkModifyAudioRoutingPermission(); List<MediaRoute2Info> getSystemRoutes(); RoutingSessionInfo getSystemSessionInfo(); diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 1f6855a4ae8e..90fa9a52f5cf 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; @@ -159,9 +160,11 @@ public final class MediaRouter2 { * Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}. * * @param clientPackageName the package name of the app to control + * @throws SecurityException if the caller doesn't have MODIFY_AUDIO_ROUTING permission. * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) @Nullable public static MediaRouter2 getInstance(@NonNull Context context, @NonNull String clientPackageName) { @@ -179,13 +182,20 @@ public final class MediaRouter2 { synchronized (sSystemRouterLock) { MediaRouter2 instance = sSystemMediaRouter2Map.get(clientPackageName); if (instance == null) { - // TODO: Add permission check here using MODIFY_AUDIO_ROUTING. if (sManager == null) { + IMediaRouterService serviceBinder = IMediaRouterService.Stub.asInterface( + ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE)); + try { + // MediaRouterService will throw a SecurityException if the caller + // doesn't have MODIFY_AUDIO_ROUTING permission. + serviceBinder.checkModifyAudioRoutingPermission(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } sManager = MediaRouter2Manager.getInstance(context.getApplicationContext()); } instance = new MediaRouter2(context, clientPackageName); sSystemMediaRouter2Map.put(clientPackageName, instance); - // TODO: Remove router instance once it is not needed. instance.registerManagerCallbackForSystemRouter(); } return instance; @@ -281,9 +291,9 @@ public final class MediaRouter2 { mDiscoveryPreference = new RouteDiscoveryPreference.Builder( sManager.getPreferredFeatures(clientPackageName), true).build(); updateAllRoutesFromManager(); - mMediaRouterService = null; // TODO: Make this non-null and check permission. // Only used by non-system MediaRouter2. + mMediaRouterService = null; mPackageName = null; } diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 31edf43679e9..5286bce67b37 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -113,6 +113,22 @@ class MediaRouter2ServiceImpl { //////////////////////////////////////////////////////////////// @NonNull + public void checkModifyAudioRoutingPermission() { + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + + try { + if (mContext.checkPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Must hold the MODIFY_AUDIO_ROUTING permission."); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @NonNull public List<MediaRoute2Info> getSystemRoutes() { final int uid = Binder.getCallingUid(); final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier(); diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index b6d6cc48d0cd..b85cea7a637d 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -438,6 +438,12 @@ public final class MediaRouterService extends IMediaRouterService.Stub // Binder call @Override + public void checkModifyAudioRoutingPermission() { + mService2.checkModifyAudioRoutingPermission(); + } + + // Binder call + @Override public List<MediaRoute2Info> getSystemRoutes() { return mService2.getSystemRoutes(); } |