[IMPR] AudioManager: add adjustAttributesVolume API

Bug: 237409207
Test: make

In order to manage mute / unmute from applications, it
is required to align volume per attributes on volume per stream
regarding the mute management.

Test: atest AudioManagerTest#testAdjustVolumeGroupVolume

Signed-off-by: Francois Gaffie <francois.gaffie@renault.com>
Change-Id: I3ad42802b8387ecbbb15a54774f4d2da0fed0988
This commit is contained in:
Francois Gaffie
2021-11-10 13:45:42 +01:00
committed by Eric Laurent
parent da1d1ff3d1
commit 32a2b5f661
6 changed files with 368 additions and 88 deletions

View File

@@ -20911,6 +20911,7 @@ package android.media {
method public void adjustStreamVolume(int, int, int);
method public void adjustSuggestedStreamVolume(int, int, int);
method public void adjustVolume(int, int);
method public void adjustVolumeGroupVolume(int, int, int);
method public void clearCommunicationDevice();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) public boolean clearPreferredMixerAttributes(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioDeviceInfo);
method public void dispatchMediaKeyEvent(android.view.KeyEvent);
@@ -20941,6 +20942,7 @@ package android.media {
method public float getStreamVolumeDb(int, int, int);
method @NonNull public java.util.List<android.media.AudioMixerAttributes> getSupportedMixerAttributes(@NonNull android.media.AudioDeviceInfo);
method @Deprecated public int getVibrateSetting(int);
method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes);
method @Deprecated public boolean isBluetoothA2dpOn();
method public boolean isBluetoothScoAvailableOffCall();
method @Deprecated public boolean isBluetoothScoOn();
@@ -20954,6 +20956,7 @@ package android.media {
method public boolean isStreamMute(int);
method public boolean isSurroundFormatEnabled(int);
method public boolean isVolumeFixed();
method public boolean isVolumeGroupMuted(int);
method @Deprecated public boolean isWiredHeadsetOn();
method public void loadSoundEffects();
method public void playSoundEffect(int);

View File

@@ -6672,6 +6672,7 @@ package android.media {
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleStreamVolume(int);
method @IntRange(from=0) @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleVolumeGroupVolume(int);
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);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -6681,6 +6682,9 @@ package android.media {
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMaxVolumeIndex(int);
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMinVolumeIndex(int);
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupVolumeIndex(int);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean isBluetoothVariableLatencyEnabled();
@@ -6714,6 +6718,7 @@ package android.media {
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 boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public void setVolumeGroupVolumeIndex(int, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean supportsBluetoothVariableLatency();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);

View File

@@ -1350,12 +1350,8 @@ public class AudioManager {
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
service.setVolumeIndexForAttributes(attr, index, flags,
getContext().getOpPackageName(), getContext().getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int groupId = getVolumeGroupIdForAttributes(attr);
setVolumeGroupVolumeIndex(groupId, index, flags);
}
/**
@@ -1374,11 +1370,8 @@ public class AudioManager {
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
return service.getVolumeIndexForAttributes(attr);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int groupId = getVolumeGroupIdForAttributes(attr);
return getVolumeGroupVolumeIndex(groupId);
}
/**
@@ -1395,11 +1388,8 @@ public class AudioManager {
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
return service.getMaxVolumeIndexForAttributes(attr);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int groupId = getVolumeGroupIdForAttributes(attr);
return getVolumeGroupMaxVolumeIndex(groupId);
}
/**
@@ -1415,9 +1405,183 @@ public class AudioManager {
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
int groupId = getVolumeGroupIdForAttributes(attr);
return getVolumeGroupMinVolumeIndex(groupId);
}
/**
* Returns the volume group id associated to the given {@link AudioAttributes}.
*
* @param attributes The {@link AudioAttributes} to consider.
* @return {@link android.media.audiopolicy.AudioVolumeGroup} id supporting the given
* {@link AudioAttributes} if found,
* {@code android.media.audiopolicy.AudioVolumeGroup.DEFAULT_VOLUME_GROUP} otherwise.
*/
public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
Preconditions.checkNotNull(attributes, "Audio Attributes must not be null");
return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes,
/* fallbackOnDefault= */ false);
}
/**
* Sets the volume index for a particular group associated to given id.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @param index The volume index to set. See
* {@link #getVolumeGroupMaxVolumeIndex(id)} for the largest valid value
* {@link #getVolumeGroupMinVolumeIndex(id)} for the lowest valid value.
* @param flags One or more flags.
* @hide
*/
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public void setVolumeGroupVolumeIndex(int groupId, int index, int flags) {
final IAudioService service = getService();
try {
return service.getMinVolumeIndexForAttributes(attr);
service.setVolumeGroupVolumeIndex(groupId, index, flags,
getContext().getOpPackageName(), getContext().getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the current volume index for a particular group associated to given id.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @return The current volume index for the stream.
* @hide
*/
@SystemApi
@IntRange(from = 0)
@RequiresPermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupVolumeIndex(int groupId) {
final IAudioService service = getService();
try {
return service.getVolumeGroupVolumeIndex(groupId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the maximum volume index for a particular group associated to given id.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @return The maximum valid volume index for the {@link AudioAttributes}.
* @hide
*/
@SystemApi
@IntRange(from = 0)
@RequiresPermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMaxVolumeIndex(int groupId) {
final IAudioService service = getService();
try {
return service.getVolumeGroupMaxVolumeIndex(groupId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the minimum volume index for a particular group associated to given id.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @return The minimum valid volume index for the {@link AudioAttributes}.
* @hide
*/
@SystemApi
@IntRange(from = 0)
@RequiresPermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMinVolumeIndex(int groupId) {
final IAudioService service = getService();
try {
return service.getVolumeGroupMinVolumeIndex(groupId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Adjusts the volume of a particular group associated to given id by one step in a direction.
* <p> If the volume group is associated to a stream type, it fallbacks on
* {@link #adjustStreamVolume(int, int, int)} for compatibility reason.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
* the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @param direction The direction to adjust the volume. One of
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
* {@link #ADJUST_SAME}.
* @param flags One or more flags.
* @throws SecurityException if the adjustment triggers a Do Not Disturb change and the caller
* is not granted notification policy access.
*/
public void adjustVolumeGroupVolume(int groupId, int direction, int flags) {
IAudioService service = getService();
try {
service.adjustVolumeGroupVolume(groupId, direction, flags,
getContext().getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Get last audible volume of the group associated to given id before it was muted.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
* the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @return current volume if not muted, volume before muted otherwise.
* @hide
*/
@SystemApi
@RequiresPermission("android.permission.QUERY_AUDIO_STATE")
@IntRange(from = 0)
public int getLastAudibleVolumeGroupVolume(int groupId) {
IAudioService service = getService();
try {
return service.getLastAudibleVolumeGroupVolume(groupId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the current mute state for a particular volume group associated to the given id.
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
* the volume group id supporting the given {@link AudioAttributes}.
*
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
* @return The mute state for the given {@link android.media.audiopolicy.AudioVolumeGroup} id.
* @see #adjustVolumeGroupVolume(int, int, int)
*/
public boolean isVolumeGroupMuted(int groupId) {
IAudioService service = getService();
try {
return service.isVolumeGroupMuted(groupId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -138,18 +138,25 @@ interface IAudioService {
@EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioVolumeGroup> getAudioVolumeGroups();
@EnforcePermission("MODIFY_AUDIO_ROUTING")
void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags,
String callingPackage, in String attributionTag);
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
void setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage,
in String attributionTag);
@EnforcePermission("MODIFY_AUDIO_ROUTING")
int getVolumeIndexForAttributes(in AudioAttributes aa);
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
int getVolumeGroupVolumeIndex(int groupId);
@EnforcePermission("MODIFY_AUDIO_ROUTING")
int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
int getVolumeGroupMaxVolumeIndex(int groupId);
@EnforcePermission("MODIFY_AUDIO_ROUTING")
int getMinVolumeIndexForAttributes(in AudioAttributes aa);
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
int getVolumeGroupMinVolumeIndex(int groupId);
@EnforcePermission("QUERY_AUDIO_STATE")
int getLastAudibleVolumeGroupVolume(int groupId);
boolean isVolumeGroupMuted(int groupId);
void adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage);
@EnforcePermission("QUERY_AUDIO_STATE")
int getLastAudibleStreamVolume(int streamType);

View File

@@ -2613,13 +2613,11 @@ public class AudioService extends IAudioService.Stub
}
if (!TextUtils.isEmpty(packageName)) {
PackageManager pm = mContext.getPackageManager();
ActivityManager am =
(ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
== PackageManager.PERMISSION_GRANTED) {
try {
assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG,
"updateAssistantUId() could not find UID for package: " + packageName);
@@ -3766,23 +3764,23 @@ public class AudioService extends IAudioService.Stub
}
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
@Override
@android.annotation.EnforcePermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
/** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
String callingPackage, String attributionTag) {
super.setVolumeIndexForAttributes_enforcePermission();
Objects.requireNonNull(attr, "attr must not be null");
int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
attr, /* fallbackOnDefault= */false);
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
Log.e(TAG, ": no volume group found for attributes " + attr.toString());
super.setVolumeGroupVolumeIndex_enforcePermission();
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return;
}
VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
index, flags, callingPackage + ", user " + ActivityManager.getCurrentUser()));
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
index, flags, callingPackage + ", user " + getCurrentUserId()));
vgs.setVolumeIndex(index, flags);
@@ -3791,7 +3789,7 @@ public class AudioService extends IAudioService.Stub
try {
ensureValidStreamType(groupedStream);
} catch (IllegalArgumentException e) {
Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream
Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
+ "), do not change associated stream volume");
continue;
}
@@ -3813,39 +3811,53 @@ public class AudioService extends IAudioService.Stub
return null;
}
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getVolumeIndexForAttributes(attr) */
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
super.getVolumeIndexForAttributes_enforcePermission();
Objects.requireNonNull(attr, "attr must not be null");
@Override
@android.annotation.EnforcePermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
/** @see AudioManager#getVolumeGroupVolumeIndex(int) */
public int getVolumeGroupVolumeIndex(int groupId) {
super.getVolumeGroupVolumeIndex_enforcePermission();
synchronized (VolumeStreamState.class) {
int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
attr, /* fallbackOnDefault= */false);
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
throw new IllegalArgumentException("No volume group for attributes " + attr);
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
throw new IllegalArgumentException("No volume group for id " + groupId);
}
VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
return vgs.isMuted() ? vgs.getMinIndex() : vgs.getVolumeIndex();
}
}
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
super.getMaxVolumeIndexForAttributes_enforcePermission();
Objects.requireNonNull(attr, "attr must not be null");
return AudioSystem.getMaxVolumeIndexForAttributes(attr);
/** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
@android.annotation.EnforcePermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMaxVolumeIndex(int groupId) {
super.getVolumeGroupMaxVolumeIndex_enforcePermission();
synchronized (VolumeStreamState.class) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
throw new IllegalArgumentException("No volume group for id " + groupId);
}
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
return vgs.getMaxIndex();
}
}
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
super.getMinVolumeIndexForAttributes_enforcePermission();
Objects.requireNonNull(attr, "attr must not be null");
return AudioSystem.getMinVolumeIndexForAttributes(attr);
/** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
@android.annotation.EnforcePermission(anyOf = {
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMinVolumeIndex(int groupId) {
super.getVolumeGroupMinVolumeIndex_enforcePermission();
synchronized (VolumeStreamState.class) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
throw new IllegalArgumentException("No volume group for id " + groupId);
}
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
return vgs.getMinIndex();
}
}
@Override
@@ -3914,6 +3926,46 @@ public class AudioService extends IAudioService.Stub
callingPackage, /*attributionTag*/ null);
}
/** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
String callingPackage) {
ensureValidDirection(direction);
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return;
}
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
direction, flags, callingPackage));
vgs.adjustVolume(direction, flags);
}
/** @see AudioManager#getLastAudibleVolumeGroupVolume(int) */
@android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
public int getLastAudibleVolumeGroupVolume(int groupId) {
super.getLastAudibleVolumeGroupVolume_enforcePermission();
synchronized (VolumeStreamState.class) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return 0;
}
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
return vgs.getVolumeIndex();
}
}
/** @see AudioManager#isVolumeGroupMuted(int) */
public boolean isVolumeGroupMuted(int groupId) {
synchronized (VolumeStreamState.class) {
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
Log.e(TAG, ": no volume group found for id " + groupId);
return false;
}
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
return vgs.isMuted();
}
}
/** @see AudioManager#setStreamVolume(int, int, int)
* Part of service interface, check permissions here */
public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
@@ -7489,14 +7541,56 @@ public class AudioService extends IAudioService.Stub
return mIsMuted;
}
public void adjustVolume(int direction, int flags) {
synchronized (AudioService.VolumeStreamState.class) {
int device = getDeviceForVolume();
int previousIndex = getIndex(device);
switch (direction) {
case AudioManager.ADJUST_TOGGLE_MUTE: {
// Note: If muted by volume 0, unmute will restore volume 0.
mute(!mIsMuted);
break;
}
case AudioManager.ADJUST_UNMUTE:
// Note: If muted by volume 0, unmute will restore volume 0.
mute(false);
break;
case AudioManager.ADJUST_MUTE:
// May be already muted by setvolume 0, prevent from setting same value
if (previousIndex != 0) {
// bypass persist
mute(true);
}
mIsMuted = true;
break;
case AudioManager.ADJUST_RAISE:
// As for stream, RAISE during mute will increment the index
setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags);
break;
case AudioManager.ADJUST_LOWER:
// For stream, ADJUST_LOWER on a muted VSS is a no-op
// If we decide to unmute on ADJUST_LOWER, cannot fallback on
// adjustStreamVolume for group associated to legacy stream type
if (isMuted() && previousIndex != 0) {
mute(false);
} else {
int newIndex = Math.max(previousIndex - 1, mIndexMin);
setVolumeIndex(newIndex, device, flags);
}
break;
}
}
}
public int getVolumeIndex() {
synchronized (VolumeStreamState.class) {
synchronized (AudioService.VolumeStreamState.class) {
return getIndex(getDeviceForVolume());
}
}
public void setVolumeIndex(int index, int flags) {
synchronized (VolumeStreamState.class) {
synchronized (AudioService.VolumeStreamState.class) {
if (mUseFixedVolume) {
return;
}
@@ -7581,7 +7675,7 @@ public class AudioService extends IAudioService.Stub
public void applyAllVolumes(boolean userSwitch) {
String caller = "from vgs";
synchronized (VolumeStreamState.class) {
synchronized (AudioService.VolumeStreamState.class) {
// apply device specific volumes first
for (int i = 0; i < mIndexMap.size(); i++) {
int device = mIndexMap.keyAt(i);
@@ -7681,7 +7775,7 @@ public class AudioService extends IAudioService.Stub
Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
+ mAudioVolumeGroup.name()
+ ", device " + AudioSystem.getOutputDeviceName(device)
+ " and User=" + ActivityManager.getCurrentUser());
+ " and User=" + getCurrentUserId());
}
boolean success = mSettings.putSystemIntForUser(mContentResolver,
getSettingNameForDevice(device),
@@ -7693,7 +7787,7 @@ public class AudioService extends IAudioService.Stub
}
public void readSettings() {
synchronized (VolumeStreamState.class) {
synchronized (AudioService.VolumeStreamState.class) {
// force maximum volume on all streams if fixed volume property is set
if (mUseFixedVolume) {
mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
@@ -7720,7 +7814,7 @@ public class AudioService extends IAudioService.Stub
if (DEBUG_VOL) {
Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
+ " for group " + mAudioVolumeGroup.name() + ", device: " + name
+ ", User=" + ActivityManager.getCurrentUser());
+ ", User=" + getCurrentUserId());
}
mIndexMap.put(device, getValidIndex(index));
}

View File

@@ -17,7 +17,6 @@
package com.android.server.audio;
import android.annotation.NonNull;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -197,6 +196,7 @@ public class AudioServiceEvents {
static final int VOL_SET_GROUP_VOL = 8;
static final int VOL_MUTE_STREAM_INT = 9;
static final int VOL_SET_LE_AUDIO_VOL = 10;
static final int VOL_ADJUST_GROUP_VOL = 11;
final int mOp;
final int mStream;
@@ -204,7 +204,6 @@ public class AudioServiceEvents {
final int mVal2;
final String mCaller;
final String mGroupName;
final AudioAttributes mAudioAttributes;
/** used for VOL_ADJUST_VOL_UID,
* VOL_ADJUST_SUGG_VOL,
@@ -217,7 +216,6 @@ public class AudioServiceEvents {
mVal2 = val2;
mCaller = caller;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
@@ -230,7 +228,6 @@ public class AudioServiceEvents {
mStream = -1;
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
@@ -243,7 +240,6 @@ public class AudioServiceEvents {
mStream = -1;
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
@@ -256,7 +252,6 @@ public class AudioServiceEvents {
// unused
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
@@ -269,19 +264,18 @@ public class AudioServiceEvents {
// unused
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
/** used for VOL_SET_GROUP_VOL */
VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller) {
/** used for VOL_SET_GROUP_VOL,
* VOL_ADJUST_GROUP_VOL */
VolumeEvent(int op, String group, int index, int flags, String caller) {
mOp = op;
mStream = -1;
mVal1 = index;
mVal2 = flags;
mCaller = caller;
mGroupName = group;
mAudioAttributes = aa;
logMetricEvent();
}
@@ -293,7 +287,6 @@ public class AudioServiceEvents {
mVal2 = 0;
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
@@ -335,6 +328,15 @@ public class AudioServiceEvents {
.record();
return;
}
case VOL_ADJUST_GROUP_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
.set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
.set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume")
.set(MediaMetrics.Property.FLAGS, mVal2)
.set(MediaMetrics.Property.GROUP, mGroupName)
.record();
return;
case VOL_SET_STREAM_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
@@ -386,7 +388,6 @@ public class AudioServiceEvents {
return;
case VOL_SET_GROUP_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString())
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
.set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
.set(MediaMetrics.Property.FLAGS, mVal2)
@@ -412,6 +413,13 @@ public class AudioServiceEvents {
.append(" flags:0x").append(Integer.toHexString(mVal2))
.append(") from ").append(mCaller)
.toString();
case VOL_ADJUST_GROUP_VOL:
return new StringBuilder("adjustVolumeGroupVolume(group:")
.append(mGroupName)
.append(" dir:").append(AudioManager.adjustToString(mVal1))
.append(" flags:0x").append(Integer.toHexString(mVal2))
.append(") from ").append(mCaller)
.toString();
case VOL_ADJUST_STREAM_VOL:
return new StringBuilder("adjustStreamVolume(stream:")
.append(AudioSystem.streamToString(mStream))
@@ -460,8 +468,7 @@ public class AudioServiceEvents {
.append(" stream:").append(AudioSystem.streamToString(mStream))
.toString();
case VOL_SET_GROUP_VOL:
return new StringBuilder("setVolumeIndexForAttributes(attr:")
.append(mAudioAttributes.toString())
return new StringBuilder("setVolumeIndexForAttributes(group:")
.append(" group: ").append(mGroupName)
.append(" index:").append(mVal1)
.append(" flags:0x").append(Integer.toHexString(mVal2))