diff options
| author | 2019-11-15 10:05:59 -0800 | |
|---|---|---|
| committer | 2019-11-21 13:46:11 -0800 | |
| commit | e1573108fe027edae946511f761439f191315eb8 (patch) | |
| tree | 95e6aace2075e890817667aa87aef7f371224e3d | |
| parent | be3930b7d57711ab5bc51f32ec36f6c24c3b0df8 (diff) | |
Refactor audio device type in audio frameworks.
As audio device type can not be used as bit mask any more, refactoring
the code to use a set for a combination of audio device type instead.
Bug: 135621476
Test: atest AudioDeviceBrokerTest
Test: audio smoke test
Change-Id: I2c6fabfafcc6eaf607975076d9ee1a78887a2c85
3 files changed, 279 insertions, 176 deletions
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index a3a87774483b..d64e4ef00164 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -30,7 +30,9 @@ import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java. @@ -543,51 +545,75 @@ public class AudioSystem public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT; - public static final int DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | - DEVICE_OUT_SPEAKER | - DEVICE_OUT_WIRED_HEADSET | - DEVICE_OUT_WIRED_HEADPHONE | - DEVICE_OUT_BLUETOOTH_SCO | - DEVICE_OUT_BLUETOOTH_SCO_HEADSET | - DEVICE_OUT_BLUETOOTH_SCO_CARKIT | - DEVICE_OUT_BLUETOOTH_A2DP | - DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | - DEVICE_OUT_HDMI | - DEVICE_OUT_ANLG_DOCK_HEADSET | - DEVICE_OUT_DGTL_DOCK_HEADSET | - DEVICE_OUT_USB_ACCESSORY | - DEVICE_OUT_USB_DEVICE | - DEVICE_OUT_REMOTE_SUBMIX | - DEVICE_OUT_TELEPHONY_TX | - DEVICE_OUT_LINE | - DEVICE_OUT_HDMI_ARC | - DEVICE_OUT_SPDIF | - DEVICE_OUT_FM | - DEVICE_OUT_AUX_LINE | - DEVICE_OUT_SPEAKER_SAFE | - DEVICE_OUT_IP | - DEVICE_OUT_BUS | - DEVICE_OUT_PROXY | - DEVICE_OUT_USB_HEADSET | - DEVICE_OUT_HEARING_AID | - DEVICE_OUT_DEFAULT); - public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | - DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); - public static final int DEVICE_OUT_ALL_SCO = (DEVICE_OUT_BLUETOOTH_SCO | - DEVICE_OUT_BLUETOOTH_SCO_HEADSET | - DEVICE_OUT_BLUETOOTH_SCO_CARKIT); + // Deprecated in R because multiple device types are no longer accessed as a bit mask. + // Removing this will get lint warning about changing hidden apis. @UnsupportedAppUsage public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY | DEVICE_OUT_USB_DEVICE | DEVICE_OUT_USB_HEADSET); - public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE | - DEVICE_OUT_HDMI_ARC | - DEVICE_OUT_SPDIF); - public static final int DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER = - (DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO | - DEVICE_OUT_SPEAKER); + + public static final Set<Integer> DEVICE_OUT_ALL_SET; + public static final Set<Integer> DEVICE_OUT_ALL_A2DP_SET; + public static final Set<Integer> DEVICE_OUT_ALL_SCO_SET; + public static final Set<Integer> DEVICE_OUT_ALL_USB_SET; + public static final Set<Integer> DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET; + public static final Set<Integer> DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET; + static { + DEVICE_OUT_ALL_SET = new HashSet<>(); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_EARPIECE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPEAKER); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_WIRED_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_WIRED_HEADPHONE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO_CARKIT); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_ANLG_DOCK_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DGTL_DOCK_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_ACCESSORY); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_DEVICE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_REMOTE_SUBMIX); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_TELEPHONY_TX); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_LINE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI_ARC); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPDIF); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_FM); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_AUX_LINE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPEAKER_SAFE); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_IP); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BUS); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_PROXY); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HEARING_AID); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DEFAULT); + + DEVICE_OUT_ALL_A2DP_SET = new HashSet<>(); + DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP); + DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES); + DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + + DEVICE_OUT_ALL_SCO_SET = new HashSet<>(); + DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO); + DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO_HEADSET); + DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO_CARKIT); + + DEVICE_OUT_ALL_USB_SET = new HashSet<>(); + DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_ACCESSORY); + DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_DEVICE); + DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_HEADSET); + + DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET = new HashSet<>(); + DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_AUX_LINE); + DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_HDMI_ARC); + DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_SPDIF); + + DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET = new HashSet<>(); + DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.addAll(DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET); + DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.add(DEVICE_OUT_SPEAKER); + } // input devices @UnsupportedAppUsage @@ -635,37 +661,47 @@ public class AudioSystem @UnsupportedAppUsage public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT; - public static final int DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | - DEVICE_IN_AMBIENT | - DEVICE_IN_BUILTIN_MIC | - DEVICE_IN_BLUETOOTH_SCO_HEADSET | - DEVICE_IN_WIRED_HEADSET | - DEVICE_IN_HDMI | - DEVICE_IN_TELEPHONY_RX | - DEVICE_IN_BACK_MIC | - DEVICE_IN_REMOTE_SUBMIX | - DEVICE_IN_ANLG_DOCK_HEADSET | - DEVICE_IN_DGTL_DOCK_HEADSET | - DEVICE_IN_USB_ACCESSORY | - DEVICE_IN_USB_DEVICE | - DEVICE_IN_FM_TUNER | - DEVICE_IN_TV_TUNER | - DEVICE_IN_LINE | - DEVICE_IN_SPDIF | - DEVICE_IN_BLUETOOTH_A2DP | - DEVICE_IN_LOOPBACK | - DEVICE_IN_IP | - DEVICE_IN_BUS | - DEVICE_IN_PROXY | - DEVICE_IN_USB_HEADSET | - DEVICE_IN_BLUETOOTH_BLE | - DEVICE_IN_HDMI_ARC | - DEVICE_IN_ECHO_REFERENCE | - DEVICE_IN_DEFAULT); - public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET; - public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY | - DEVICE_IN_USB_DEVICE | - DEVICE_IN_USB_HEADSET); + public static final Set<Integer> DEVICE_IN_ALL_SET; + public static final Set<Integer> DEVICE_IN_ALL_SCO_SET; + public static final Set<Integer> DEVICE_IN_ALL_USB_SET; + static { + DEVICE_IN_ALL_SET = new HashSet<>(); + DEVICE_IN_ALL_SET.add(DEVICE_IN_COMMUNICATION); + DEVICE_IN_ALL_SET.add(DEVICE_IN_AMBIENT); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BUILTIN_MIC); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_SCO_HEADSET); + DEVICE_IN_ALL_SET.add(DEVICE_IN_WIRED_HEADSET); + DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI); + DEVICE_IN_ALL_SET.add(DEVICE_IN_TELEPHONY_RX); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BACK_MIC); + DEVICE_IN_ALL_SET.add(DEVICE_IN_REMOTE_SUBMIX); + DEVICE_IN_ALL_SET.add(DEVICE_IN_ANLG_DOCK_HEADSET); + DEVICE_IN_ALL_SET.add(DEVICE_IN_DGTL_DOCK_HEADSET); + DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_ACCESSORY); + DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_DEVICE); + DEVICE_IN_ALL_SET.add(DEVICE_IN_FM_TUNER); + DEVICE_IN_ALL_SET.add(DEVICE_IN_TV_TUNER); + DEVICE_IN_ALL_SET.add(DEVICE_IN_LINE); + DEVICE_IN_ALL_SET.add(DEVICE_IN_SPDIF); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_A2DP); + DEVICE_IN_ALL_SET.add(DEVICE_IN_LOOPBACK); + DEVICE_IN_ALL_SET.add(DEVICE_IN_IP); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BUS); + DEVICE_IN_ALL_SET.add(DEVICE_IN_PROXY); + DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_HEADSET); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_BLE); + DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_ARC); + DEVICE_IN_ALL_SET.add(DEVICE_IN_ECHO_REFERENCE); + DEVICE_IN_ALL_SET.add(DEVICE_IN_DEFAULT); + + DEVICE_IN_ALL_SCO_SET = new HashSet<>(); + DEVICE_IN_ALL_SCO_SET.add(DEVICE_IN_BLUETOOTH_SCO_HEADSET); + + DEVICE_IN_ALL_USB_SET = new HashSet<>(); + DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_ACCESSORY); + DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_DEVICE); + DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_HEADSET); + } // device states, must match AudioSystem::device_connection_state @UnsupportedAppUsage @@ -1229,6 +1265,40 @@ public class AudioSystem return getPlatformType(context) == PLATFORM_TELEVISION || forceSingleVolume; } + /** + * Return a set of audio device types from a bit mask audio device type, which may + * represent multiple audio device types. + * FIXME: Remove this when getting ride of bit mask usage of audio device types. + */ + public static Set<Integer> generateAudioDeviceTypesSet(int types) { + Set<Integer> deviceTypes = new HashSet<>(); + Set<Integer> allDeviceTypes = + (types & DEVICE_BIT_IN) == 0 ? DEVICE_OUT_ALL_SET : DEVICE_IN_ALL_SET; + for (int deviceType : allDeviceTypes) { + if ((types & deviceType) == deviceType) { + deviceTypes.add(deviceType); + } + } + return deviceTypes; + } + + /** + * Return the intersection of two audio device types collections. + */ + public static Set<Integer> intersectionAudioDeviceTypes( + @NonNull Set<Integer> a, @NonNull Set<Integer> b) { + Set<Integer> intersection = new HashSet<>(a); + intersection.retainAll(b); + return intersection; + } + + /** + * Return true if the audio device types collection only contains the given device type. + */ + public static boolean isSingleAudioDeviceType(@NonNull Set<Integer> types, int type) { + return types.size() == 1 && types.contains(type); + } + public static final int DEFAULT_MUTE_STREAMS_AFFECTED = (1 << STREAM_MUSIC) | (1 << STREAM_RING) | diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index 90973a888a9d..a2b3574880c4 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -44,6 +44,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; /** * Class to manage the inventory of all connected devices. @@ -372,9 +374,14 @@ public class AudioDeviceInventory { mDeviceBroker.postObserveDevicesForAllStreams(); } - private static final int DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG = - AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE - | AudioSystem.DEVICE_OUT_LINE | AudioSystem.DEVICE_OUT_ALL_USB; + private static final Set<Integer> DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET; + static { + DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET = new HashSet<>(); + DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); + DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); + DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); + DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); + } /*package*/ void onSetWiredDeviceConnectionState( AudioDeviceInventory.WiredDeviceConnectionState wdcs) { @@ -382,7 +389,7 @@ public class AudioDeviceInventory { synchronized (mConnectedDevices) { if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED) - && ((wdcs.mType & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0)) { + && DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) { mDeviceBroker.setBluetoothA2dpOnInt(true, "onSetWiredDeviceConnectionState state DISCONNECTED"); } @@ -393,7 +400,7 @@ public class AudioDeviceInventory { return; } if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) { - if ((wdcs.mType & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0) { + if (DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) { mDeviceBroker.setBluetoothA2dpOnInt(false, "onSetWiredDeviceConnectionState state not DISCONNECTED"); } @@ -764,13 +771,19 @@ public class AudioDeviceInventory { // - none of these devices are connected anymore after one is disconnected AND // - the device being disconnected is actually used for music. // Access synchronized on mConnectedDevices - private int mBecomingNoisyIntentDevices = - AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE - | AudioSystem.DEVICE_OUT_ALL_A2DP | AudioSystem.DEVICE_OUT_HDMI - | AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET - | AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET - | AudioSystem.DEVICE_OUT_ALL_USB | AudioSystem.DEVICE_OUT_LINE - | AudioSystem.DEVICE_OUT_HEARING_AID; + private static final Set<Integer> BECOMING_NOISY_INTENT_DEVICES_SET; + static { + BECOMING_NOISY_INTENT_DEVICES_SET = new HashSet<>(); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_HDMI); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_LINE); + BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID); + BECOMING_NOISY_INTENT_DEVICES_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); + BECOMING_NOISY_INTENT_DEVICES_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); + } // must be called before removing the device from mConnectedDevices // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying @@ -781,16 +794,16 @@ public class AudioDeviceInventory { if (state != AudioService.CONNECTION_STATE_DISCONNECTED) { return 0; } - if ((device & mBecomingNoisyIntentDevices) == 0) { + if (!BECOMING_NOISY_INTENT_DEVICES_SET.contains(device)) { return 0; } int delay = 0; - int devices = 0; + Set<Integer> devices = new HashSet<>(); for (int i = 0; i < mConnectedDevices.size(); i++) { int dev = mConnectedDevices.valueAt(i).mDeviceType; if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) - && ((dev & mBecomingNoisyIntentDevices) != 0)) { - devices |= dev; + && BECOMING_NOISY_INTENT_DEVICES_SET.contains(dev)) { + devices.add(dev); } } if (musicDevice == AudioSystem.DEVICE_NONE) { @@ -801,8 +814,9 @@ public class AudioDeviceInventory { // because music routing is altered in this case. // also checks whether media routing if affected by a dynamic policy or mirroring if (((device == musicDevice) || mDeviceBroker.isInCommunication()) - && (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy() - && ((musicDevice & AudioSystem.DEVICE_OUT_REMOTE_SUBMIX) == 0)) { + && AudioSystem.isSingleAudioDeviceType(devices, device) + && !mDeviceBroker.hasMediaDynamicPolicy() + && (musicDevice != AudioSystem.DEVICE_OUT_REMOTE_SUBMIX)) { if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/) && !mDeviceBroker.hasAudioFocusUsers()) { // no media playback, not a "becoming noisy" situation, otherwise it could cause diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 9fa572f9fe9a..148d28f12313 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -147,6 +147,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -501,18 +502,20 @@ public class AudioService extends IAudioService.Stub private volatile IRingtonePlayer mRingtonePlayer; // Devices for which the volume is fixed (volume is either max or muted) - int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI | - AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | - AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | - AudioSystem.DEVICE_OUT_HDMI_ARC | - AudioSystem.DEVICE_OUT_SPDIF | - AudioSystem.DEVICE_OUT_AUX_LINE; + Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( + AudioSystem.DEVICE_OUT_HDMI, + AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, + AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, + AudioSystem.DEVICE_OUT_HDMI_ARC, + AudioSystem.DEVICE_OUT_SPDIF, + AudioSystem.DEVICE_OUT_AUX_LINE)); // Devices for which the volume is always max, no volume panel - int mFullVolumeDevices = 0; + Set<Integer> mFullVolumeDevices = new HashSet<>(); // Devices for the which use the "absolute volume" concept (framework sends audio signal // full scale, and volume control separately) and can be used for multiple use cases reflected // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). - int mAbsVolumeMultiModeCaseDevices = AudioSystem.DEVICE_OUT_HEARING_AID; + Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( + Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID)); private final boolean mMonitorRotation; @@ -866,13 +869,14 @@ public class AudioService extends IAudioService.Stub } mHdmiTvClient = mHdmiManager.getTvClient(); if (mHdmiTvClient != null) { - mFixedVolumeDevices &= ~AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER; + mFixedVolumeDevices.removeAll( + AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); } mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); if (mHdmiPlaybackClient != null) { // not a television: HDMI output will be always at max - mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_HDMI; - mFullVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI; + mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI); + mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI); } mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); } @@ -1131,7 +1135,7 @@ public class AudioService extends IAudioService.Stub @AudioService.ConnectionState int state, String caller) { if (state == AudioService.CONNECTION_STATE_CONNECTED) { // DEVICE_OUT_HDMI is now connected - if ((AudioSystem.DEVICE_OUT_HDMI & mSafeMediaVolumeDevices) != 0) { + if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) { sendMsg(mAudioHandler, MSG_CHECK_MUSIC_ACTIVE, SENDMSG_REPLACE, @@ -1762,8 +1766,8 @@ public class AudioService extends IAudioService.Stub // skip a2dp absolute volume control request when the device // is not an a2dp device - if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && - (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { + if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { return; } @@ -1784,14 +1788,14 @@ public class AudioService extends IAudioService.Stub flags &= ~AudioManager.FLAG_FIXED_VOLUME; if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && - ((device & mFixedVolumeDevices) != 0)) { + mFixedVolumeDevices.contains(device)) { flags |= AudioManager.FLAG_FIXED_VOLUME; // Always toggle between max safe volume and 0 for fixed volume devices where safe // volume is enforced, and max and 0 for the others. // This is simulated by stepping by the full allowed volume range if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && - (device & mSafeMediaVolumeDevices) != 0) { + mSafeMediaVolumeDevices.contains(device)) { step = safeMediaVolumeIndex(device); } else { step = streamState.getMaxIndex(); @@ -1861,7 +1865,7 @@ public class AudioService extends IAudioService.Stub !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); mVolumeController.postDisplaySafeVolumeWarning(flags); - } else if (((device & mFullVolumeDevices) == 0) + } else if (!mFullVolumeDevices.contains(device) && (streamState.adjustIndex(direction * step, device, caller) || streamState.mIsMuted)) { // Post message to set system volume (it in turn will post a @@ -1890,9 +1894,9 @@ public class AudioService extends IAudioService.Stub int newIndex = mStreamStates[streamType].getIndex(device); // Check if volume update should be send to AVRCP - if (streamTypeAlias == AudioSystem.STREAM_MUSIC && - (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && - (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { + if (streamTypeAlias == AudioSystem.STREAM_MUSIC + && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" + newIndex + "stream=" + streamType); @@ -1901,7 +1905,7 @@ public class AudioService extends IAudioService.Stub } // Check if volume update should be send to Hearing Aid - if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) { + if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { // only modify the hearing aid attenuation when the stream to modify matches // the one expected by the hearing aid if (streamType == getHearingAidStreamType()) { @@ -1923,7 +1927,7 @@ public class AudioService extends IAudioService.Stub if (mHdmiCecSink && streamTypeAlias == AudioSystem.STREAM_MUSIC // vol change on a full volume device - && ((device & mFullVolumeDevices) != 0)) { + && mFullVolumeDevices.contains(device)) { int keyCode = KeyEvent.KEYCODE_UNKNOWN; switch (direction) { case AudioManager.ADJUST_RAISE: @@ -2291,13 +2295,17 @@ public class AudioService extends IAudioService.Stub int streamType = getHearingAidStreamType(newMode); - final int device = AudioSystem.getDevicesForStream(streamType); - if ((device & mAbsVolumeMultiModeCaseDevices) == 0) { + final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet( + AudioSystem.getDevicesForStream(streamType)); + final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes( + mAbsVolumeMultiModeCaseDevices, deviceTypes); + if (absVolumeMultiModeCaseDevices.isEmpty()) { return; } // handling of specific interfaces goes here: - if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) { + if (AudioSystem.isSingleAudioDeviceType( + absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) { final int index = getStreamVolume(streamType); sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID, newMode, streamType, index)); @@ -2324,8 +2332,8 @@ public class AudioService extends IAudioService.Stub // skip a2dp absolute volume control request when the device // is not an a2dp device - if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && - (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { + if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { return; } // If we are being called by the system (e.g. hardware keys) check for current user @@ -2357,7 +2365,7 @@ public class AudioService extends IAudioService.Stub index = rescaleIndex(index * 10, streamType, streamTypeAlias); if (streamTypeAlias == AudioSystem.STREAM_MUSIC - && (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 + && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index @@ -2366,7 +2374,7 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); } - if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0 + if (device == AudioSystem.DEVICE_OUT_HEARING_AID && streamType == getHearingAidStreamType()) { Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index + " stream=" + streamType); @@ -2379,13 +2387,13 @@ public class AudioService extends IAudioService.Stub flags &= ~AudioManager.FLAG_FIXED_VOLUME; if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && - ((device & mFixedVolumeDevices) != 0)) { + mFixedVolumeDevices.contains(device)) { flags |= AudioManager.FLAG_FIXED_VOLUME; // volume is either 0 or max allowed for fixed volume devices if (index != 0) { if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && - (device & mSafeMediaVolumeDevices) != 0) { + mSafeMediaVolumeDevices.contains(device)) { index = safeMediaVolumeIndex(device); } else { index = streamState.getMaxIndex(); @@ -2568,7 +2576,7 @@ public class AudioService extends IAudioService.Stub if (streamType == AudioSystem.STREAM_MUSIC) { flags = updateFlagsForTvPlatform(flags); - if ((device & mFullVolumeDevices) != 0) { + if (mFullVolumeDevices.contains(device)) { flags &= ~AudioManager.FLAG_SHOW_UI; } } @@ -2614,7 +2622,7 @@ public class AudioService extends IAudioService.Stub int device, boolean force, String caller) { - if ((device & mFullVolumeDevices) != 0) { + if (mFullVolumeDevices.contains(device)) { return; } VolumeStreamState streamState = mStreamStates[streamType]; @@ -2731,8 +2739,8 @@ public class AudioService extends IAudioService.Stub if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); if (mRmtSbmxFullVolRefCount == 0) { - mFullVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; - mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; + mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); + mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); applyRequired = true; } mRmtSbmxFullVolRefCount++; @@ -2741,8 +2749,8 @@ public class AudioService extends IAudioService.Stub if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { mRmtSbmxFullVolRefCount--; if (mRmtSbmxFullVolRefCount == 0) { - mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; - mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; + mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); + mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); applyRequired = true; } } @@ -2828,7 +2836,7 @@ public class AudioService extends IAudioService.Stub index = 0; } if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && - (device & mFixedVolumeDevices) != 0) { + mFixedVolumeDevices.contains(device)) { index = mStreamStates[streamType].getMaxIndex(); } return (index + 5) / 10; @@ -3700,7 +3708,7 @@ public class AudioService extends IAudioService.Stub if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) { int device = getDeviceForStream(AudioSystem.STREAM_MUSIC); - if ((device & mSafeMediaVolumeDevices) != 0) { + if (mSafeMediaVolumeDevices.contains(device)) { sendMsg(mAudioHandler, MSG_CHECK_MUSIC_ACTIVE, SENDMSG_REPLACE, @@ -4252,6 +4260,8 @@ public class AudioService extends IAudioService.Stub // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. // - HDMI-CEC system audio mode only output: give priority to available item in order. + // FIXME: Haven't applied audio device type refactor to this API + // as it is going to be deprecated. if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { device = AudioSystem.DEVICE_OUT_SPEAKER; } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) { @@ -4261,7 +4271,11 @@ public class AudioService extends IAudioService.Stub } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) { device = AudioSystem.DEVICE_OUT_AUX_LINE; } else { - device &= AudioSystem.DEVICE_OUT_ALL_A2DP; + for (int deviceType : AudioSystem.DEVICE_OUT_ALL_A2DP_SET) { + if ((deviceType & device) == deviceType) { + return deviceType; + } + } } } return device; @@ -4394,12 +4408,16 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.postBluetoothA2dpDeviceConfigChange(device); } - private static final int DEVICE_MEDIA_UNMUTED_ON_PLUG = - AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE | - AudioSystem.DEVICE_OUT_LINE | - AudioSystem.DEVICE_OUT_ALL_A2DP | - AudioSystem.DEVICE_OUT_ALL_USB | - AudioSystem.DEVICE_OUT_HDMI; + private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; + static { + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); + DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI); + } /** only public for mocking/spying, do not call outside of AudioService */ @VisibleForTesting @@ -4415,7 +4433,7 @@ public class AudioService extends IAudioService.Stub } if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS - && (newDevice & DEVICE_MEDIA_UNMUTED_ON_PLUG) != 0 + && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0 && (newDevice & AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC)) != 0) { @@ -4544,14 +4562,7 @@ public class AudioService extends IAudioService.Stub } } synchronized (VolumeStreamState.class) { - int remainingDevices = AudioSystem.DEVICE_OUT_ALL; - - for (int i = 0; remainingDevices != 0; i++) { - int device = (1 << i); - if ((device & remainingDevices) == 0) { - continue; - } - remainingDevices &= ~device; + for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { // retrieve current volume for device // if no volume stored for current stream and device, use default volume if default @@ -4611,11 +4622,12 @@ public class AudioService extends IAudioService.Stub int index; if (mIsMuted) { index = 0; - } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && isAvrcpAbsVolSupported) { + } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && isAvrcpAbsVolSupported) { index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); - } else if ((device & mFullVolumeDevices) != 0) { + } else if (mFullVolumeDevices.contains(device)) { index = (mIndexMax + 5)/10; - } else if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) { + } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { index = (mIndexMax + 5)/10; } else { index = (getIndex(device) + 5)/10; @@ -4633,12 +4645,12 @@ public class AudioService extends IAudioService.Stub if (device != AudioSystem.DEVICE_OUT_DEFAULT) { if (mIsMuted) { index = 0; - } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && - isAvrcpAbsVolSupported) { + } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && isAvrcpAbsVolSupported) { index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); - } else if ((device & mFullVolumeDevices) != 0) { + } else if (mFullVolumeDevices.contains(device)) { index = (mIndexMax + 5)/10; - } else if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) { + } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { index = (mIndexMax + 5)/10; } else { index = (mIndexMap.valueAt(i) + 5)/10; @@ -4699,7 +4711,7 @@ public class AudioService extends IAudioService.Stub && device == AudioSystem.DEVICE_OUT_SPEAKER) { for (int i = 0; i < mIndexMap.size(); i++) { int otherDevice = mIndexMap.keyAt(i); - if ((otherDevice & AudioSystem.DEVICE_OUT_ALL_SCO) != 0) { + if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { mIndexMap.put(otherDevice, index); } } @@ -4837,8 +4849,8 @@ public class AudioService extends IAudioService.Stub for (int i = 0; i < mIndexMap.size(); i++) { int device = mIndexMap.keyAt(i); int index = mIndexMap.valueAt(i); - if (((device & mFullVolumeDevices) != 0) - || (((device & mFixedVolumeDevices) != 0) && index != 0)) { + if (mFullVolumeDevices.contains(device) + || (mFixedVolumeDevices.contains(device) && index != 0)) { mIndexMap.put(device, mIndexMax); } applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported); @@ -5009,7 +5021,7 @@ public class AudioService extends IAudioService.Stub // that may have a different device selected int streamDevice = getDeviceForStream(streamType); if ((device != streamDevice) && isAvrcpAbsVolSupported - && ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) { + && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) { mStreamStates[streamType].applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported); } @@ -5338,7 +5350,7 @@ public class AudioService extends IAudioService.Stub } /*package*/ void checkMusicActive(int deviceType, String caller) { - if ((deviceType & mSafeMediaVolumeDevices) != 0) { + if (mSafeMediaVolumeDevices.contains(deviceType)) { sendMsg(mAudioHandler, MSG_CHECK_MUSIC_ACTIVE, SENDMSG_REPLACE, @@ -5784,9 +5796,9 @@ public class AudioService extends IAudioService.Stub // the headset is compliant to EN 60950 with a max loudness of 100dB SPL. private int mSafeUsbMediaVolumeIndex; // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced, - /*package*/ final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET - | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE - | AudioSystem.DEVICE_OUT_USB_HEADSET; + /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>( + Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET, + AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET)); // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled. // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS. @@ -5796,7 +5808,7 @@ public class AudioService extends IAudioService.Stub private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed private int safeMediaVolumeIndex(int device) { - if ((device & mSafeMediaVolumeDevices) == 0) { + if (!mSafeMediaVolumeDevices.contains(device)) { return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]; } if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) { @@ -5831,14 +5843,9 @@ public class AudioService extends IAudioService.Stub private void enforceSafeMediaVolume(String caller) { VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; - int devices = mSafeMediaVolumeDevices; - int i = 0; + Set<Integer> devices = mSafeMediaVolumeDevices; - while (devices != 0) { - int device = 1 << i++; - if ((device & devices) == 0) { - continue; - } + for (int device : devices) { int index = streamState.getIndex(device); if (index > safeMediaVolumeIndex(device)) { streamState.setIndex(safeMediaVolumeIndex(device), device, caller); @@ -5850,16 +5857,15 @@ public class AudioService extends IAudioService.Stub streamState, 0); } - devices &= ~device; } } private boolean checkSafeMediaVolume(int streamType, int index, int device) { synchronized (mSafeMediaVolumeStateLock) { - if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) && - (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && - ((device & mSafeMediaVolumeDevices) != 0) && - (index > safeMediaVolumeIndex(device))) { + if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) + && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) + && (mSafeMediaVolumeDevices.contains(device)) + && (index > safeMediaVolumeIndex(device))) { return false; } return true; @@ -5900,14 +5906,14 @@ public class AudioService extends IAudioService.Stub if (DEBUG_VOL) { Log.d(TAG, "CEC sink: setting HDMI as full vol device"); } - mFullVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI; + mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI); } else { if (DEBUG_VOL) { Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); } // Android TV devices without CEC service apply software volume on // HDMI output - mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_HDMI; + mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI); } checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, @@ -6128,6 +6134,19 @@ public class AudioService extends IAudioService.Stub pw.println(); } + private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { + Iterator<Integer> it = deviceTypes.iterator(); + if (!it.hasNext()) { + return ""; + } + final StringBuilder sb = new StringBuilder(); + sb.append("0x" + Integer.toHexString(it.next())); + while (it.hasNext()) { + sb.append("," + "0x" + Integer.toHexString(it.next())); + } + return sb.toString(); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; @@ -6164,7 +6183,7 @@ public class AudioService extends IAudioService.Stub pw.println(mDeviceBroker.isAvrcpAbsoluteVolumeSupported()); pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); - pw.print(" mFixedVolumeDevices=0x"); pw.println(Integer.toHexString(mFixedVolumeDevices)); + pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); pw.print(" mHdmiCecSink="); pw.println(mHdmiCecSink); pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); |