From db1b56d9edb5b98b3ea015a5e98462cc56764da7 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 11 Feb 2020 15:49:15 -0800 Subject: [PATCH] AudioSystem: add owner UID to setPhoneState API. Communicate current audio mode owner UID to native service when changing audio mode via setPhoneState. This will be used by call audio capture restriction rules. Bug: 148368476 Test: manual phone call tests Change-Id: Ieb1ff01f20d4b70a4f52b6a0e320d8275d90dbfb --- core/jni/android_media_AudioSystem.cpp | 10 ++-- media/java/android/media/AudioSystem.java | 13 ++++- .../android/server/audio/AudioService.java | 56 ++++++++++++++----- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 87be5f63c4990..d8f30e94d6674 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -566,10 +566,10 @@ android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, ji return (jint) status; } -static jint -android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state) -{ - return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state)); +static jint android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state, + jint uid) { + return (jint)check_AudioSystem_Command( + AudioSystem::setPhoneState((audio_mode_t)state, (uid_t)uid)); } static jint @@ -2434,7 +2434,7 @@ static const JNINativeMethod gMethods[] = (void *)android_media_AudioSystem_getDeviceConnectionState}, {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange}, - {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState}, + {"setPhoneState", "(II)I", (void *)android_media_AudioSystem_setPhoneState}, {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse}, {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse}, {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume}, diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 0a0f7f643ac9c..53379b8761c42 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -1024,7 +1024,18 @@ public class AudioSystem String device_name, int codecFormat); @UnsupportedAppUsage - public static native int setPhoneState(int state); + public static int setPhoneState(int state) { + Log.w(TAG, "Do not use this method! Use AudioManager.setMode() instead."); + return 0; + } + /** + * @hide + * Send the current audio mode to audio policy manager and audio HAL. + * @param state the audio mode + * @param uid the UID of the app owning the audio mode + * @return command completion status. + */ + public static native int setPhoneState(int state, int uid); @UnsupportedAppUsage public static native int setForceUse(int usage, int config); @UnsupportedAppUsage diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 67d7530fa11e5..f41eeeb11d5a2 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1001,11 +1001,14 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.onAudioServerDied(); // Restore call state - if (AudioSystem.setPhoneState(mMode) == AudioSystem.AUDIO_STATUS_OK) { - mModeLogger.log(new AudioEventLogger.StringEvent( - "onAudioServerDied causes setPhoneState(" + AudioSystem.modeToString(mMode) + ")")); + synchronized (mDeviceBroker.mSetModeLock) { + if (AudioSystem.setPhoneState(mMode, getModeOwnerUid()) + == AudioSystem.AUDIO_STATUS_OK) { + mModeLogger.log(new AudioEventLogger.StringEvent( + "onAudioServerDied causes setPhoneState(" + AudioSystem.modeToString(mMode) + + ", uid=" + getModeOwnerUid() + ")")); + } } - final int forSys; synchronized (mSettingsLock) { forSys = mCameraSoundForced ? @@ -3425,14 +3428,30 @@ public class AudioService extends IAudioService.Stub return modeOwnerPid; } + /** + * Return the uid of the current audio mode owner + * @return 0 if nobody owns the mode + */ + /*package*/ int getModeOwnerUid() { + int modeOwnerUid = 0; + try { + modeOwnerUid = mSetModeDeathHandlers.get(0).getUid(); + } catch (Exception e) { + // nothing to do, modeOwnerUid is not modified + } + return modeOwnerUid; + } + private class SetModeDeathHandler implements IBinder.DeathRecipient { - private IBinder mCb; // To be notified of client's death - private int mPid; + private final IBinder mCb; // To be notified of client's death + private final int mPid; + private final int mUid; private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client - SetModeDeathHandler(IBinder cb, int pid) { + SetModeDeathHandler(IBinder cb, int pid, int uid) { mCb = cb; mPid = pid; + mUid = uid; } public void binderDied() { @@ -3445,7 +3464,7 @@ public class AudioService extends IAudioService.Stub if (index < 0) { Log.w(TAG, "unregistered setMode() client died"); } else { - newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG); + newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, mUid, TAG); } } // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all @@ -3470,6 +3489,10 @@ public class AudioService extends IAudioService.Stub public IBinder getBinder() { return mCb; } + + public int getUid() { + return mUid; + } } /** @see AudioManager#setMode(int) */ @@ -3518,7 +3541,8 @@ public class AudioService extends IAudioService.Stub + " without permission or being mode owner"); return; } - newModeOwnerPid = setModeInt(mode, cb, callingPid, callingPackage); + newModeOwnerPid = setModeInt( + mode, cb, callingPid, Binder.getCallingUid(), callingPackage); } // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all // SCO connections not started by the application changing the mode when pid changes @@ -3530,9 +3554,11 @@ public class AudioService extends IAudioService.Stub // setModeInt() returns a valid PID if the audio mode was successfully set to // any mode other than NORMAL. @GuardedBy("mDeviceBroker.mSetModeLock") - private int setModeInt(int mode, IBinder cb, int pid, String caller) { - if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller=" - + caller + ")"); } + private int setModeInt(int mode, IBinder cb, int pid, int uid, String caller) { + if (DEBUG_MODE) { + Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + + ", uid=" + uid + ", caller=" + caller + ")"); + } int newModeOwnerPid = 0; if (cb == null) { Log.e(TAG, "setModeInt() called with null binder"); @@ -3569,7 +3595,7 @@ public class AudioService extends IAudioService.Stub } } else { if (hdlr == null) { - hdlr = new SetModeDeathHandler(cb, pid); + hdlr = new SetModeDeathHandler(cb, pid, uid); } // Register for client death notification try { @@ -3587,7 +3613,7 @@ public class AudioService extends IAudioService.Stub if (actualMode != mMode) { final long identity = Binder.clearCallingIdentity(); - status = AudioSystem.setPhoneState(actualMode); + status = AudioSystem.setPhoneState(actualMode, getModeOwnerUid()); Binder.restoreCallingIdentity(identity); if (status == AudioSystem.AUDIO_STATUS_OK) { if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + actualMode); } @@ -6634,7 +6660,7 @@ public class AudioService extends IAudioService.Stub static final int LOG_NB_EVENTS_DYN_POLICY = 10; final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE, - "phone state (logged after successfull call to AudioSystem.setPhoneState(int))"); + "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); // logs for wired + A2DP device connections: // - wired: logged before onSetWiredDeviceConnectionState() is executed