Merge "Add Android permissions for audioserver"
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 54bfca3..eca2c3b 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -144,6 +144,12 @@
     public static final int SHARED_RELRO_UID = 1037;
 
     /**
+     * Defines the UID/GID for the audioserver process.
+     * @hide
+     */
+    public static final int AUDIOSERVER_UID = 1041;
+
+    /**
      * Defines the start of a range of UIDs (and GIDs), going from this
      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
      * to applications.
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 51019cc..b4f88c33 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -106,6 +106,7 @@
     </permission>
 
     <permission name="android.permission.ACCESS_FM_RADIO" >
+        <!-- /dev/fm is gid media, not audio -->
         <group gid="media" />
     </permission>
 
@@ -128,6 +129,12 @@
     <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
     <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="media" />
 
+    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="audioserver" />
+    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="audioserver" />
+    <assign-permission name="android.permission.WAKE_LOCK" uid="audioserver" />
+    <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" />
+    <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" />
+
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
 
     <!-- This is a list of all the libraries available for application
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 7fcedc6..353b404 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -1176,6 +1176,9 @@
                             if ("media".equals(packageName)) {
                                 pkgUid = Process.MEDIA_UID;
                                 isPrivileged = false;
+                            } else if ("audioserver".equals(packageName)) {
+                                pkgUid = Process.AUDIOSERVER_UID;
+                                isPrivileged = false;
                             }
                         }
                     } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4f2f486..40d01e7 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -197,7 +197,7 @@
     private static final int MSG_SET_DEVICE_VOLUME = 0;
     private static final int MSG_PERSIST_VOLUME = 1;
     private static final int MSG_PERSIST_RINGER_MODE = 3;
-    private static final int MSG_MEDIA_SERVER_DIED = 4;
+    private static final int MSG_AUDIO_SERVER_DIED = 4;
     private static final int MSG_PLAY_SOUND_EFFECT = 5;
     private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
@@ -358,7 +358,7 @@
         public void onError(int error) {
             switch (error) {
             case AudioSystem.AUDIO_STATUS_SERVER_DIED:
-                sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED,
+                sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
                         SENDMSG_NOOP, 0, 0, null, 0);
                 break;
             default:
@@ -772,15 +772,15 @@
                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
     }
 
-    public void onMediaServerDied() {
+    public void onAudioServerDied() {
         if (!mSystemReady ||
                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
-            Log.e(TAG, "Media server died.");
-            sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
+            Log.e(TAG, "Audioserver died.");
+            sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
                     null, 500);
             return;
         }
-        Log.e(TAG, "Media server started.");
+        Log.e(TAG, "Audioserver started.");
 
         // indicate to audio HAL that we start the reconfiguration phase after a media
         // server crash
@@ -4406,8 +4406,8 @@
                     persistRingerMode(getRingerModeInternal());
                     break;
 
-                case MSG_MEDIA_SERVER_DIED:
-                    onMediaServerDied();
+                case MSG_AUDIO_SERVER_DIED:
+                    onAudioServerDied();
                     break;
 
                 case MSG_UNLOAD_SOUND_EFFECTS:
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index c0123bf..80faf473 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -40,12 +40,13 @@
     public int requestPriority(int pid, int tid, int prio) {
         //Log.i(TAG, "requestPriority(pid=" + pid + ", tid=" + tid + ", prio=" + prio + ")");
 
-        // Verify that caller is mediaserver, priority is in range, and that the
-        // callback thread specified by app belongs to the app that called mediaserver.
-        // Once we've verified that the caller is mediaserver, we can trust the pid but
+        // Verify that the caller uid is permitted, priority is in range,
+        // and that the callback thread specified by app belongs to the app that
+        // called mediaserver or audioserver.
+        // Once we've verified that the caller uid is permitted, we can trust the pid but
         // we can't trust the tid.  No need to explicitly check for pid == 0 || tid == 0,
         // since if not the case then the getThreadGroupLeader() test will also fail.
-        if (Binder.getCallingUid() != Process.MEDIA_UID || prio < PRIORITY_MIN ||
+        if (!isPermittedCallingUid() || prio < PRIORITY_MIN ||
                 prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
             return PackageManager.PERMISSION_DENIED;
         }
@@ -61,4 +62,14 @@
         return PackageManager.PERMISSION_GRANTED;
     }
 
+    private boolean isPermittedCallingUid() {
+        final int callingUid = Binder.getCallingUid();
+        switch (callingUid) {
+        case Process.AUDIOSERVER_UID: // fastcapture, fastmixer
+        case Process.MEDIA_UID: // camera
+            return true;
+        default:
+            return false;
+        }
+    }
 }