Make AudioManager device volume behavior APIs SystemApi
Allow privileged applications to control volume behavior of audio devices. Bug: 161878484 Test: atest AudioServiceHostTest Change-Id: Ic6206369a69b4103f715565f387f652626b832d4
This commit is contained in:
@@ -4201,6 +4201,7 @@ package android.media {
|
||||
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
|
||||
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
|
||||
@@ -4219,6 +4220,7 @@ package android.media {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
|
||||
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
|
||||
@@ -4229,6 +4231,11 @@ package android.media {
|
||||
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
|
||||
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
|
||||
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
|
||||
field public static final int SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
@@ -4600,36 +4600,41 @@ public class AudioManager {
|
||||
/**
|
||||
* @hide
|
||||
* Volume behavior for an audio device that has no particular volume behavior set. Invalid as
|
||||
* an argument to {@link #setDeviceVolumeBehavior(int, String, int)}.
|
||||
* an argument to {@link #setDeviceVolumeBehavior(AudioDeviceAttributes, int)} and should not
|
||||
* be returned by {@link #getDeviceVolumeBehavior(AudioDeviceAttributes)}.
|
||||
*/
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
|
||||
/**
|
||||
* @hide
|
||||
* Volume behavior for an audio device where a software attenuation is applied
|
||||
* @see #setDeviceVolumeBehavior(int, String, int)
|
||||
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
|
||||
/**
|
||||
* @hide
|
||||
* Volume behavior for an audio device where the volume is always set to provide no attenuation
|
||||
* nor gain (e.g. unit gain).
|
||||
* @see #setDeviceVolumeBehavior(int, String, int)
|
||||
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
|
||||
/**
|
||||
* @hide
|
||||
* Volume behavior for an audio device where the volume is either set to muted, or to provide
|
||||
* no attenuation nor gain (e.g. unit gain).
|
||||
* @see #setDeviceVolumeBehavior(int, String, int)
|
||||
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
|
||||
/**
|
||||
* @hide
|
||||
* Volume behavior for an audio device where no software attenuation is applied, and
|
||||
* the volume is kept synchronized between the host and the device itself through a
|
||||
* device-specific protocol such as BT AVRCP.
|
||||
* @see #setDeviceVolumeBehavior(int, String, int)
|
||||
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
|
||||
/**
|
||||
* @hide
|
||||
@@ -4638,8 +4643,9 @@ public class AudioManager {
|
||||
* device-specific protocol (such as for hearing aids), based on the audio mode (e.g.
|
||||
* normal vs in phone call).
|
||||
* @see #setMode(int)
|
||||
* @see #setDeviceVolumeBehavior(int, String, int)
|
||||
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
|
||||
|
||||
/** @hide */
|
||||
@@ -4686,27 +4692,15 @@ public class AudioManager {
|
||||
/**
|
||||
* @hide
|
||||
* Sets the volume behavior for an audio output device.
|
||||
* @param deviceType the type of audio device to be affected. Currently only supports
|
||||
* {@link AudioDeviceInfo#TYPE_HDMI}, {@link AudioDeviceInfo#TYPE_HDMI_ARC},
|
||||
* {@link AudioDeviceInfo#TYPE_LINE_DIGITAL} and {@link AudioDeviceInfo#TYPE_AUX_LINE}
|
||||
* @param deviceAddress the address of the device, if any
|
||||
* @param deviceVolumeBehavior one of the device behaviors
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public void setDeviceVolumeBehavior(int deviceType, @Nullable String deviceAddress,
|
||||
@DeviceVolumeBehavior int deviceVolumeBehavior) {
|
||||
setDeviceVolumeBehavior(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
|
||||
deviceType, deviceAddress), deviceVolumeBehavior);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Sets the volume behavior for an audio output device.
|
||||
* @param device the device to be affected. Currently only supports devices of type
|
||||
* {@link AudioDeviceInfo#TYPE_HDMI}, {@link AudioDeviceInfo#TYPE_HDMI_ARC},
|
||||
* {@link AudioDeviceInfo#TYPE_LINE_DIGITAL} and {@link AudioDeviceInfo#TYPE_AUX_LINE}
|
||||
* @see #DEVICE_VOLUME_BEHAVIOR_VARIABLE
|
||||
* @see #DEVICE_VOLUME_BEHAVIOR_FULL
|
||||
* @see #DEVICE_VOLUME_BEHAVIOR_FIXED
|
||||
* @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
|
||||
* @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
|
||||
* @param device the device to be affected
|
||||
* @param deviceVolumeBehavior one of the device behaviors
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
|
||||
@DeviceVolumeBehavior int deviceVolumeBehavior) {
|
||||
@@ -4723,31 +4717,16 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns the volume device behavior for the given device type and address
|
||||
* @param deviceType an audio output device type, as defined in {@link AudioDeviceInfo}
|
||||
* @param deviceAddress the address of the audio device, if any.
|
||||
* @return the volume behavior for the device
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(int deviceType,
|
||||
@Nullable String deviceAddress) {
|
||||
// verify arguments
|
||||
AudioDeviceInfo.enforceValidAudioDeviceTypeOut(deviceType);
|
||||
return getDeviceVolumeBehavior(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
|
||||
deviceType, deviceAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns the volume device behavior for the given audio device
|
||||
* @param device the audio device
|
||||
* @return the volume behavior for the device
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public @DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
|
||||
@NonNull AudioDeviceAttributes device) {
|
||||
public @DeviceVolumeBehavior
|
||||
int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
|
||||
// verify arguments (validity of device type is enforced in server)
|
||||
Objects.requireNonNull(device);
|
||||
// communicate with service
|
||||
|
||||
@@ -4141,6 +4141,7 @@ package android.media {
|
||||
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
|
||||
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
|
||||
@@ -4159,6 +4160,7 @@ package android.media {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
|
||||
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
|
||||
@@ -4169,6 +4171,11 @@ package android.media {
|
||||
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
|
||||
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
|
||||
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
|
||||
field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
|
||||
field public static final int SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
@@ -414,13 +414,6 @@ public class AudioService extends IAudioService.Stub
|
||||
AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT
|
||||
};
|
||||
|
||||
private static Set<Integer> sDeviceVolumeBehaviorSupportedDeviceOutSet = new HashSet<>(
|
||||
Arrays.asList(
|
||||
AudioSystem.DEVICE_OUT_HDMI,
|
||||
AudioSystem.DEVICE_OUT_HDMI_ARC,
|
||||
AudioSystem.DEVICE_OUT_SPDIF,
|
||||
AudioSystem.DEVICE_OUT_LINE));
|
||||
|
||||
private final boolean mUseFixedVolume;
|
||||
|
||||
// If absolute volume is supported in AVRCP device
|
||||
@@ -4952,11 +4945,6 @@ public class AudioService extends IAudioService.Stub
|
||||
|
||||
private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut,
|
||||
@AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
|
||||
if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)) {
|
||||
// unsupported for now
|
||||
throw new IllegalArgumentException("Unsupported device type " + audioSystemDeviceOut);
|
||||
}
|
||||
|
||||
// update device masks based on volume behavior
|
||||
switch (deviceVolumeBehavior) {
|
||||
case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
|
||||
@@ -4990,20 +4978,14 @@ public class AudioService extends IAudioService.Stub
|
||||
* @param device the audio output device type
|
||||
* @return the volume behavior for the device
|
||||
*/
|
||||
public @AudioManager.DeviceVolumeBehaviorState int getDeviceVolumeBehavior(
|
||||
@NonNull AudioDeviceAttributes device) {
|
||||
public @AudioManager.DeviceVolumeBehavior
|
||||
int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
|
||||
// verify permissions
|
||||
enforceModifyAudioRoutingPermission();
|
||||
|
||||
// translate Java device type to native device type (for the devices masks for full / fixed)
|
||||
final int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
|
||||
device.getType());
|
||||
if (!sDeviceVolumeBehaviorSupportedDeviceOutSet.contains(audioSystemDeviceOut)
|
||||
&& audioSystemDeviceOut != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
|
||||
&& audioSystemDeviceOut != AudioSystem.DEVICE_OUT_HEARING_AID) {
|
||||
throw new IllegalArgumentException("Unsupported volume behavior "
|
||||
+ audioSystemDeviceOut);
|
||||
}
|
||||
|
||||
int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
|
||||
if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
|
||||
@@ -9078,7 +9060,7 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
private void restoreDeviceVolumeBehavior() {
|
||||
for (int deviceType : sDeviceVolumeBehaviorSupportedDeviceOutSet) {
|
||||
for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user