From 89c3a9774820e481f0de84001ce1b323ae435542 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 16 Dec 2020 15:57:56 +0100 Subject: [PATCH] AudiomManager: route getDevicesForStream API through AudioService AudioSystem.getDevicesForStream() must only be called from system_server process so route calls from AudioManager through AudioService. Bug: 174989248 Test: make Change-Id: I5ce7b2298817adcc6a843718279b5383722850cf --- media/java/android/media/AudioManager.java | 16 +++++-- media/java/android/media/IAudioService.aidl | 4 +- .../android/server/audio/AudioService.java | 43 ++++++++++++++----- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 3bd68d893521e..d9cfb638d0689 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -2931,7 +2931,7 @@ public class AudioManager { public boolean isMusicActive() { final IAudioService service = getService(); try { - return service.isMusicActive(); + return service.isMusicActive(false /*remotely*/); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2945,7 +2945,12 @@ public class AudioManager { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isMusicActiveRemotely() { - return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); + final IAudioService service = getService(); + try { + return service.isMusicActive(true /*remotely*/); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -5108,7 +5113,12 @@ public class AudioManager { case STREAM_NOTIFICATION: case STREAM_DTMF: case STREAM_ACCESSIBILITY: - return AudioSystem.getDevicesForStream(streamType); + final IAudioService service = getService(); + try { + return service.getDevicesForStream(streamType); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } default: return 0; } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 2ac5b5088d988..a13add3a3a445 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -335,5 +335,7 @@ interface IAudioService { in String packageName, int uid, int pid, in UserHandle userHandle, int targetSdkVersion); - boolean isMusicActive(); + boolean isMusicActive(in boolean remotely); + + int getDevicesForStream(in int streamType); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 6bc927a5176fc..5ea00ef3ed4b2 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2108,10 +2108,22 @@ public class AudioService extends IAudioService.Stub return getDevicesForAttributesInt(attributes); } - /** @see AudioManager#isMusicActive() */ - public boolean isMusicActive() { + /** + * @see AudioManager#isMusicActive() + * @param remotely true if query is for remote playback (cast), false for local playback. + */ + public boolean isMusicActive(boolean remotely) { // no permission required - return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); + final long token = Binder.clearCallingIdentity(); + try { + if (remotely) { + return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); + } else { + return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); + } + } finally { + Binder.restoreCallingIdentity(token); + } } protected @NonNull ArrayList getDevicesForAttributesInt( @@ -5181,7 +5193,7 @@ public class AudioService extends IAudioService.Stub /** only public for mocking/spying, do not call outside of AudioService */ @VisibleForTesting public int getDeviceForStream(int stream) { - int device = getDevicesForStream(stream); + int device = getDevicesForStreamInt(stream); if ((device & (device - 1)) != 0) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. @@ -5210,14 +5222,23 @@ public class AudioService extends IAudioService.Stub return device; } - private int getDevicesForStream(int stream) { - return getDevicesForStream(stream, true /*checkOthers*/); + /** + * @see AudioManager#getDevicesForStream(int) + */ + public int getDevicesForStream(int streamType) { + ensureValidStreamType(streamType); + final long token = Binder.clearCallingIdentity(); + try { + return mAudioSystem.getDevicesForStream(streamType); + } finally { + Binder.restoreCallingIdentity(token); + } } - private int getDevicesForStream(int stream, boolean checkOthers) { + private int getDevicesForStreamInt(int stream) { ensureValidStreamType(stream); synchronized (VolumeStreamState.class) { - return mStreamStates[stream].observeDevicesForStream_syncVSS(checkOthers); + return mStreamStates[stream].observeDevicesForStream_syncVSS(true); } } @@ -6402,10 +6423,10 @@ public class AudioService extends IAudioService.Stub } pw.println(); pw.print(" Devices: "); - final int devices = getDevicesForStream(mStreamType); + final int devices = getDevicesForStreamInt(mStreamType); int device, i = 0, n = 0; // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive - // (the default device is not returned by getDevicesForStream) + // (the default device is not returned by getDevicesForStreamInt) while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) { if ((devices & device) != 0) { if (n++ > 0) { @@ -7637,7 +7658,7 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, "setHdmiSystemAudioSupported"); } - device = getDevicesForStream(AudioSystem.STREAM_MUSIC); + device = getDevicesForStreamInt(AudioSystem.STREAM_MUSIC); } } return device;