diff options
| -rw-r--r-- | media/java/android/media/AudioManager.java | 28 | ||||
| -rw-r--r-- | services/core/java/com/android/server/EventLogTags.logtags | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 53 |
3 files changed, 79 insertions, 3 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 28941b9..cb70e8b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -134,6 +134,22 @@ public class AudioManager { public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION"; /** + * @hide Broadcast intent when the devices for a particular stream type changes. + * Includes the stream, the new devices and previous devices. + * Notes: + * - for internal platform use only, do not make public, + * - never used for "remote" volume changes + * + * @see #EXTRA_VOLUME_STREAM_TYPE + * @see #EXTRA_VOLUME_STREAM_DEVICES + * @see #EXTRA_PREV_VOLUME_STREAM_DEVICES + * @see #getDevicesForStream + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String STREAM_DEVICES_CHANGED_ACTION = + "android.media.STREAM_DEVICES_CHANGED_ACTION"; + + /** * @hide Broadcast intent when a stream mute state changes. * Includes the stream that changed and the new mute state * @@ -196,6 +212,18 @@ public class AudioManager { "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE"; /** + * @hide The devices associated with the stream for the stream devices changed intent. + */ + public static final String EXTRA_VOLUME_STREAM_DEVICES = + "android.media.EXTRA_VOLUME_STREAM_DEVICES"; + + /** + * @hide The previous devices associated with the stream for the stream devices changed intent. + */ + public static final String EXTRA_PREV_VOLUME_STREAM_DEVICES = + "android.media.EXTRA_PREV_VOLUME_STREAM_DEVICES"; + + /** * @hide The new master volume mute state for the master mute changed intent. * Value is boolean */ diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 983d83a..694e851 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -221,3 +221,4 @@ option java_package com.android.server # AudioService.java # --------------------------- 40000 volume_changed (stream|1), (prev_level|1), (level|1), (max_level|1), (caller|3) +40001 stream_devices_changed (stream|1), (prev_devices|1), (devices|1) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 65b2ae2..a913a51 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3305,7 +3305,7 @@ public class AudioService extends IAudioService.Stub { } private int getDeviceForStream(int stream) { - int device = AudioSystem.getDevicesForStream(stream); + int device = getDevicesForStream(stream); if ((device & (device - 1)) != 0) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. @@ -3328,6 +3328,27 @@ public class AudioService extends IAudioService.Stub { return device; } + private int getDevicesForStream(int stream) { + return getDevicesForStream(stream, true /*checkOthers*/); + } + + private int getDevicesForStream(int stream, boolean checkOthers) { + ensureValidStreamType(stream); + synchronized (VolumeStreamState.class) { + return mStreamStates[stream].observeDevicesForStream_syncVSS(checkOthers); + } + } + + private void observeDevicesForStreams(int skipStream) { + synchronized (VolumeStreamState.class) { + for (int stream = 0; stream < mStreamStates.length; stream++) { + if (stream != skipStream) { + mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/); + } + } + } + } + /* * A class just for packaging up a set of connection parameters. */ @@ -3406,9 +3427,11 @@ public class AudioService extends IAudioService.Stub { private boolean mIsMuted; private String mVolumeIndexSettingName; + private int mObservedDevices; private final SparseIntArray mIndexMap = new SparseIntArray(8); private final Intent mVolumeChanged; + private final Intent mStreamDevicesChanged; private VolumeStreamState(String settingName, int streamType) { @@ -3422,6 +3445,29 @@ public class AudioService extends IAudioService.Stub { readSettings(); mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); + mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); + mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); + } + + public int observeDevicesForStream_syncVSS(boolean checkOthers) { + final int devices = AudioSystem.getDevicesForStream(mStreamType); + if (devices == mObservedDevices) { + return devices; + } + final int prevDevices = mObservedDevices; + mObservedDevices = devices; + if (checkOthers) { + // one stream's devices have changed, check the others + observeDevicesForStreams(mStreamType); + } + // log base stream changes to the event log + if (mStreamVolumeAlias[mStreamType] == mStreamType) { + EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); + } + sendBroadcastToAll(mStreamDevicesChanged + .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, prevDevices) + .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, devices)); + return devices; } public String getSettingNameForDevice(int device) { @@ -3716,7 +3762,7 @@ public class AudioService extends IAudioService.Stub { } pw.println(); pw.print(" Devices: "); - final int devices = AudioSystem.getDevicesForStream(mStreamType); + final int devices = getDevicesForStream(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) @@ -4250,6 +4296,7 @@ public class AudioService extends IAudioService.Stub { } } mRoutesObservers.finishBroadcast(); + observeDevicesForStreams(-1); break; } @@ -5348,7 +5395,7 @@ public class AudioService extends IAudioService.Stub { on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : AudioSystem.FORCE_NONE); } - device = AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC); + device = getDevicesForStream(AudioSystem.STREAM_MUSIC); } } } |
