[IMPR] AudioService: improve bijectivity between VSS / VGS am: 31bb5135cc
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21116552 Change-Id: I379edf92a53f9b35434bd2dfcd2bea134a2960cd Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1256,6 +1256,20 @@ public class AudioService extends IAudioService.Stub
|
|||||||
0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
|
0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initVolumeStreamStates() {
|
||||||
|
int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||||
|
synchronized (VolumeStreamState.class) {
|
||||||
|
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
||||||
|
VolumeStreamState streamState = mStreamStates[streamType];
|
||||||
|
int groupId = getVolumeGroupForStreamType(streamType);
|
||||||
|
if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
|
||||||
|
&& sVolumeGroupStates.indexOfKey(groupId) >= 0) {
|
||||||
|
streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Separating notification volume from ring is NOT of aliasing the corresponding streams
|
* Separating notification volume from ring is NOT of aliasing the corresponding streams
|
||||||
* @param properties
|
* @param properties
|
||||||
@@ -1285,6 +1299,8 @@ public class AudioService extends IAudioService.Stub
|
|||||||
// mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
|
// mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
|
||||||
// relies on audio policy having correct ranges for volume indexes.
|
// relies on audio policy having correct ranges for volume indexes.
|
||||||
mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
|
mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
|
||||||
|
// Link VGS on VSS
|
||||||
|
initVolumeStreamStates();
|
||||||
|
|
||||||
// Call setRingerModeInt() to apply correct mute
|
// Call setRingerModeInt() to apply correct mute
|
||||||
// state on streams affected by ringer mode.
|
// state on streams affected by ringer mode.
|
||||||
@@ -3857,6 +3873,23 @@ public class AudioService extends IAudioService.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||||
|
// For compatibility reason, use stream API if group linked to a valid stream
|
||||||
|
for (int stream : vgs.getLegacyStreamTypes()) {
|
||||||
|
try {
|
||||||
|
ensureValidStreamType(stream);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
|
||||||
|
+ "), do not change associated stream volume");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Call only for the first valid stream, legacy API will propagate to aliased streams.
|
||||||
|
// Note: Group and Stream does not share same convention, 0 is mute for stream,
|
||||||
|
// min index is acting as mute for Groups
|
||||||
|
if (vgs.isVssMuteBijective(stream)) {
|
||||||
|
adjustStreamVolume(stream, direction, flags, callingPackage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
|
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
|
||||||
direction, flags, callingPackage));
|
direction, flags, callingPackage));
|
||||||
vgs.adjustVolume(direction, flags);
|
vgs.adjustVolume(direction, flags);
|
||||||
@@ -7412,6 +7445,16 @@ public class AudioService extends IAudioService.Stub
|
|||||||
|| stream == AudioSystem.STREAM_BLUETOOTH_SCO;
|
|| stream == AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getVolumeGroupForStreamType(int stream) {
|
||||||
|
AudioAttributes attributes =
|
||||||
|
AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
|
||||||
|
if (attributes.equals(new AudioAttributes.Builder().build())) {
|
||||||
|
return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
|
||||||
|
}
|
||||||
|
return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
|
||||||
|
attributes, /* fallbackOnDefault= */ false);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Locking order for synchronized objects related to volume management:
|
// NOTE: Locking order for synchronized objects related to volume management:
|
||||||
// 1 mSettingsLock
|
// 1 mSettingsLock
|
||||||
// 2 VolumeStreamState.class
|
// 2 VolumeStreamState.class
|
||||||
@@ -7870,6 +7913,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
// 4 VolumeStreamState.class
|
// 4 VolumeStreamState.class
|
||||||
private class VolumeStreamState {
|
private class VolumeStreamState {
|
||||||
private final int mStreamType;
|
private final int mStreamType;
|
||||||
|
private VolumeGroupState mVolumeGroupState = null;
|
||||||
private int mIndexMin;
|
private int mIndexMin;
|
||||||
// min index when user doesn't have permission to change audio settings
|
// min index when user doesn't have permission to change audio settings
|
||||||
private int mIndexMinNoPerm;
|
private int mIndexMinNoPerm;
|
||||||
@@ -7933,6 +7977,15 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
|
mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
|
||||||
|
* <p> It helps to synchronize the index, mute attributes on the maching
|
||||||
|
* {@link volumeGroupState}
|
||||||
|
* @param volumeGroupState matching the {@link VolumeStreamState}
|
||||||
|
*/
|
||||||
|
public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
|
||||||
|
mVolumeGroupState = volumeGroupState;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
|
* Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
|
||||||
* @param index minimum index expressed in "UI units", i.e. no 10x factor
|
* @param index minimum index expressed in "UI units", i.e. no 10x factor
|
||||||
@@ -8191,6 +8244,9 @@ public class AudioService extends IAudioService.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
// If associated to volume group, update group cache
|
||||||
|
updateVolumeGroupIndex(device, /* forceMuteState= */ false);
|
||||||
|
|
||||||
oldIndex = (oldIndex + 5) / 10;
|
oldIndex = (oldIndex + 5) / 10;
|
||||||
index = (index + 5) / 10;
|
index = (index + 5) / 10;
|
||||||
// log base stream changes to the event log
|
// log base stream changes to the event log
|
||||||
@@ -8293,6 +8349,28 @@ public class AudioService extends IAudioService.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If associated to volume group, update group cache
|
||||||
|
private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
|
||||||
|
synchronized (VolumeStreamState.class) {
|
||||||
|
if (mVolumeGroupState != null) {
|
||||||
|
int groupIndex = (getIndex(device) + 5) / 10;
|
||||||
|
if (DEBUG_VOL) {
|
||||||
|
Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
|
||||||
|
+ ", muted=" + mIsMuted + ", device=" + device + ", index="
|
||||||
|
+ getIndex(device) + ", group " + mVolumeGroupState.name()
|
||||||
|
+ " Muted=" + mVolumeGroupState.isMuted() + ", Index=" + groupIndex
|
||||||
|
+ ", forceMuteState=" + forceMuteState);
|
||||||
|
}
|
||||||
|
mVolumeGroupState.updateVolumeIndex(groupIndex, device);
|
||||||
|
// Only propage mute of stream when applicable
|
||||||
|
if (mIndexMin == 0 || isCallStream(mStreamType)) {
|
||||||
|
// For call stream, align mute only when muted, not when index is set to 0
|
||||||
|
mVolumeGroupState.mute(forceMuteState ? mIsMuted : groupIndex == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mute/unmute the stream
|
* Mute/unmute the stream
|
||||||
* @param state the new mute state
|
* @param state the new mute state
|
||||||
@@ -8359,6 +8437,9 @@ public class AudioService extends IAudioService.Stub
|
|||||||
|
|
||||||
public void doMute() {
|
public void doMute() {
|
||||||
synchronized (VolumeStreamState.class) {
|
synchronized (VolumeStreamState.class) {
|
||||||
|
// If associated to volume group, update group cache
|
||||||
|
updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
|
||||||
|
|
||||||
// Set the new mute volume. This propagates the values to
|
// Set the new mute volume. This propagates the values to
|
||||||
// the audio system, otherwise the volume won't be changed
|
// the audio system, otherwise the volume won't be changed
|
||||||
// at the lower level.
|
// at the lower level.
|
||||||
@@ -8440,6 +8521,9 @@ public class AudioService extends IAudioService.Stub
|
|||||||
pw.println();
|
pw.println();
|
||||||
pw.print(" Devices: ");
|
pw.print(" Devices: ");
|
||||||
pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
|
pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
|
||||||
|
pw.println();
|
||||||
|
pw.print(" Volume Group: ");
|
||||||
|
pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user