Merge "Refactor audio device type in audio frameworks."

This commit is contained in:
Treehugger Robot
2019-12-06 17:26:20 +00:00
committed by Gerrit Code Review
3 changed files with 279 additions and 176 deletions

View File

@@ -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.
@@ -541,51 +543,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
@@ -633,37 +659,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
@@ -1222,6 +1258,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) |

View File

@@ -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

View File

@@ -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;
@@ -863,13 +866,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();
}
@@ -1126,7 +1130,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,
@@ -1757,8 +1761,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;
}
@@ -1779,14 +1783,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();
@@ -1856,7 +1860,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
@@ -1885,9 +1889,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);
@@ -1896,7 +1900,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()) {
@@ -1918,7 +1922,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:
@@ -2286,13 +2290,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));
@@ -2319,8 +2327,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
@@ -2352,7 +2360,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
@@ -2361,7 +2369,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);
@@ -2374,13 +2382,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();
@@ -2563,7 +2571,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;
}
}
@@ -2609,7 +2617,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];
@@ -2726,8 +2734,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++;
@@ -2736,8 +2744,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;
}
}
@@ -2822,7 +2830,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;
@@ -3680,7 +3688,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,
@@ -4221,6 +4229,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) {
@@ -4230,7 +4240,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;
@@ -4363,12 +4377,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
@@ -4384,7 +4402,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) {
@@ -4513,14 +4531,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
@@ -4580,11 +4591,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;
@@ -4602,12 +4614,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;
@@ -4668,7 +4680,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);
}
}
@@ -4806,8 +4818,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);
@@ -4978,7 +4990,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);
}
@@ -5307,7 +5319,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,
@@ -5753,9 +5765,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.
@@ -5765,7 +5777,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) {
@@ -5800,14 +5812,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);
@@ -5819,16 +5826,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;
@@ -5869,14 +5875,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,
@@ -6097,6 +6103,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;
@@ -6133,7 +6152,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);