Volume prototypes: Allow delegate volume UI to set remote controller.

Allow the blessed component (stored in secure settings) to replace
the remote volume controller (for media sessions) in addition
to the volume controller - needed in order to properly support
cast etc.

Bug: 19260237
Change-Id: I7ecc79cb4249744e8d4ffedcab737a35331e220f
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 1a0f81d..06c154e 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.media.AudioManager;
+import android.media.AudioManagerInternal;
 import android.media.AudioSystem;
 import android.media.IAudioService;
 import android.media.IRemoteVolumeController;
@@ -59,6 +60,7 @@
 import android.util.SparseArray;
 import android.view.KeyEvent;
 
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.Watchdog;
 import com.android.server.Watchdog.Monitor;
@@ -94,6 +96,7 @@
     private KeyguardManager mKeyguardManager;
     private IAudioService mAudioService;
     private AudioManager mAudioManager;
+    private AudioManagerInternal mAudioManagerInternal;
     private ContentResolver mContentResolver;
     private SettingsObserver mSettingsObserver;
 
@@ -121,6 +124,7 @@
                 (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
         mAudioService = getAudioService();
         mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+        mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
         mSettingsObserver.observe();
@@ -343,7 +347,13 @@
         }
     }
 
-    private void enforceStatusBarPermission(String action, int pid, int uid) {
+    private void enforceSystemUiPermission(String action, int pid, int uid) {
+        if (mAudioManagerInternal != null) {
+            final int vcuid = mAudioManagerInternal.getVolumeControllerUid();
+            if (vcuid > 0 && uid == vcuid) {
+                return;
+            }
+        }
         if (getContext().checkPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
                 pid, uid) != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Only system ui may " + action);
@@ -789,7 +799,7 @@
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                enforceStatusBarPermission("listen for volume changes", pid, uid);
+                enforceSystemUiPermission("listen for volume changes", pid, uid);
                 mRvc = rvc;
             } finally {
                 Binder.restoreCallingIdentity(token);