summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author jiabin <jiabin@google.com> 2019-11-15 10:05:59 -0800
committer jiabin <jiabin@google.com> 2019-11-21 13:46:11 -0800
commite1573108fe027edae946511f761439f191315eb8 (patch)
tree95e6aace2075e890817667aa87aef7f371224e3d
parentbe3930b7d57711ab5bc51f32ec36f6c24c3b0df8 (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
-rw-r--r--media/java/android/media/AudioSystem.java214
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java50
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java191
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);