OSDN Git Service

Pipe caller's identity through volume methods
authorRoboErik <epastern@google.com>
Tue, 12 Aug 2014 22:48:49 +0000 (15:48 -0700)
committerRoboErik <epastern@google.com>
Thu, 14 Aug 2014 17:21:26 +0000 (10:21 -0700)
setStreamVolume and adjustStreamVolume were always being called
from the session service's uid/package. This adds the plumbing to
allow the original app's info to be passed in to the audio service
when volume is changed.

Change-Id: Ib36639dab1e518b435161dc453c8ba9351df3e9b

media/java/android/media/AudioManagerInternal.java [new file with mode: 0644]
media/java/android/media/AudioService.java
media/java/android/media/session/ISessionController.aidl
media/java/android/media/session/MediaController.java
services/core/java/com/android/server/media/MediaSessionRecord.java
services/core/java/com/android/server/media/MediaSessionService.java

diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
new file mode 100644 (file)
index 0000000..6f1bdef
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media;
+
+import com.android.server.LocalServices;
+
+/**
+ * Class for system services to access extra AudioManager functionality. The
+ * AudioService is responsible for registering an implementation with
+ * {@link LocalServices}.
+ *
+ * @hide
+ */
+public abstract class AudioManagerInternal {
+
+    public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+            String callingPackage, int uid);
+
+    public abstract void setStreamVolumeForUid(int streamType, int direction, int flags,
+            String callingPackage, int uid);
+}
index c6489a6..48059a1 100644 (file)
@@ -79,6 +79,7 @@ import android.view.WindowManager;
 
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.util.XmlUtils;
+import com.android.server.LocalServices;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -635,6 +636,7 @@ public class AudioService extends IAudioService.Stub {
         mMasterVolumeRamp = context.getResources().getIntArray(
                 com.android.internal.R.array.config_masterVolumeRamp);
 
+        LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
     }
 
     public void systemReady() {
@@ -956,6 +958,11 @@ public class AudioService extends IAudioService.Stub {
     /** @see AudioManager#adjustStreamVolume(int, int, int) */
     public void adjustStreamVolume(int streamType, int direction, int flags,
             String callingPackage) {
+        adjustStreamVolume(streamType, direction, flags, callingPackage, Binder.getCallingUid());
+    }
+
+    private void adjustStreamVolume(int streamType, int direction, int flags,
+            String callingPackage, int uid) {
         if (mUseFixedVolume) {
             return;
         }
@@ -984,8 +991,8 @@ public class AudioService extends IAudioService.Stub {
             return;
         }
 
-        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
+                != AppOpsManager.MODE_ALLOWED) {
             return;
         }
 
@@ -1161,6 +1168,11 @@ public class AudioService extends IAudioService.Stub {
 
     /** @see AudioManager#setStreamVolume(int, int, int) */
     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
+        setStreamVolume(streamType, index, flags, callingPackage, Binder.getCallingUid());
+    }
+
+    private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
+            int uid) {
         if (mUseFixedVolume) {
             return;
         }
@@ -1179,8 +1191,8 @@ public class AudioService extends IAudioService.Stub {
             return;
         }
 
-        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
+                != AppOpsManager.MODE_ALLOWED) {
             return;
         }
 
@@ -5347,6 +5359,24 @@ public class AudioService extends IAudioService.Stub {
         }
     }
 
+    /**
+     * Interface for system components to get some extra functionality through
+     * LocalServices.
+     */
+    final class AudioServiceInternal extends AudioManagerInternal {
+        @Override
+        public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+                String callingPackage, int uid) {
+            adjustStreamVolume(streamType, direction, flags, callingPackage, uid);
+        }
+
+        @Override
+        public void setStreamVolumeForUid(int streamType, int direction, int flags,
+                String callingPackage, int uid) {
+            setStreamVolume(streamType, direction, flags, callingPackage, uid);
+        }
+    }
+
     //==========================================================================================
     // Audio policy management
     //==========================================================================================
index 3518458..5764bd1 100644 (file)
@@ -48,8 +48,8 @@ interface ISessionController {
     PendingIntent getLaunchPendingIntent();
     long getFlags();
     ParcelableVolumeInfo getVolumeAttributes();
-    void adjustVolume(int direction, int flags);
-    void setVolumeTo(int value, int flags);
+    void adjustVolume(int direction, int flags, String packageName);
+    void setVolumeTo(int value, int flags, String packageName);
 
     IMediaRouterDelegate createMediaRouterDelegate(IMediaRouterStateCallback callback);
 
index f6e189a..d649dbd 100644 (file)
@@ -310,7 +310,7 @@ public final class MediaController {
      */
     public void setVolumeTo(int value, int flags) {
         try {
-            mSessionBinder.setVolumeTo(value, flags);
+            mSessionBinder.setVolumeTo(value, flags, mContext.getPackageName());
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling setVolumeTo.", e);
         }
@@ -331,7 +331,7 @@ public final class MediaController {
      */
     public void adjustVolume(int direction, int flags) {
         try {
-            mSessionBinder.adjustVolume(direction, flags);
+            mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName());
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
         }
index e549ead..bb434c8 100644 (file)
@@ -22,6 +22,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
 import android.media.AudioManager;
+import android.media.AudioManagerInternal;
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
@@ -52,6 +53,8 @@ import android.util.Log;
 import android.util.Slog;
 import android.view.KeyEvent;
 
+import com.android.server.LocalServices;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.UUID;
@@ -111,6 +114,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
     // Volume handling fields
     private AudioAttributes mAudioAttrs;
     private AudioManager mAudioManager;
+    private AudioManagerInternal mAudioManagerInternal;
     private int mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL;
     private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
     private int mMaxVolume = 0;
@@ -134,6 +138,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         mService = service;
         mHandler = new MessageHandler(handler.getLooper());
         mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
+        mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
     }
 
@@ -227,7 +232,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
      *
      * @param direction The direction to adjust volume in.
      */
-    public void adjustVolume(int direction, int flags) {
+    public void adjustVolume(int direction, int flags, String packageName, int uid) {
         if (isPlaybackActive(false)) {
             flags &= ~AudioManager.FLAG_PLAY_SOUND;
         }
@@ -238,7 +243,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         }
         if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
             int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
-            mAudioManager.adjustStreamVolume(stream, direction, flags);
+            mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, packageName,
+                    uid);
         } else {
             if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
                 // Nothing to do, the volume cannot be changed
@@ -262,10 +268,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         }
     }
 
-    public void setVolumeTo(int value, int flags) {
+    public void setVolumeTo(int value, int flags, String packageName, int uid) {
         if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
             int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
-            mAudioManager.setStreamVolume(stream, value, flags);
+            mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid);
         } else {
             if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
                 // Nothing to do. The volume can't be set directly.
@@ -984,20 +990,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         }
 
         @Override
-        public void adjustVolume(int direction, int flags) {
+        public void adjustVolume(int direction, int flags, String packageName) {
+            int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                MediaSessionRecord.this.adjustVolume(direction, flags);
+                MediaSessionRecord.this.adjustVolume(direction, flags, packageName, uid);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
-        public void setVolumeTo(int value, int flags) {
+        public void setVolumeTo(int value, int flags, String packageName) {
+            int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                MediaSessionRecord.this.setVolumeTo(value, flags);
+                MediaSessionRecord.this.setVolumeTo(value, flags, packageName, uid);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
index 0514f48..1221aa4 100644 (file)
@@ -812,7 +812,8 @@ public class MediaSessionService extends SystemService implements Monitor {
                     Log.e(TAG, "Error adjusting default volume.", e);
                 }
             } else {
-                session.adjustVolume(direction, flags);
+                session.adjustVolume(direction, flags, getContext().getPackageName(),
+                        UserHandle.myUserId());
                 if (session.getPlaybackType() == MediaSession.PLAYBACK_TYPE_REMOTE
                         && mRvc != null) {
                     try {