Fix mute issue when changing audio routes
When audio device routing changes, verify that streams now routed via fixed/full volume properly update volume index and mute state to ensure the user does not get into a state where the stream is muted, but full volume behavior does not allow mute changes. AudioService#onObserveDevicesForAllStreams() is called as a result of AudioDeviceInventory#onReportNewRoutes(). Bug: 162480816 Test: manual Change-Id: Ia5298178338e70684176c5c8a6dc6a864bab6efe
This commit is contained in:
@@ -1282,7 +1282,6 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
if (isPlatformTelevision()) {
|
||||
checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, caller);
|
||||
synchronized (mHdmiClientLock) {
|
||||
if (mHdmiManager != null && mHdmiPlaybackClient != null) {
|
||||
updateHdmiCecSinkLocked(mHdmiCecSink | false);
|
||||
@@ -1302,22 +1301,54 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAddAllFixedVolumeDevices(int device, String caller) {
|
||||
/**
|
||||
* Update volume states for the given device.
|
||||
*
|
||||
* This will initialize the volume index if no volume index is available.
|
||||
* If the device is the currently routed device, fixed/full volume policies will be applied.
|
||||
*
|
||||
* @param device a single audio device, ensure that this is not a devices bitmask
|
||||
* @param caller caller of this method
|
||||
*/
|
||||
private void updateVolumeStatesForAudioDevice(int device, String caller) {
|
||||
final int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
|
||||
if (!mStreamStates[streamType].hasIndexForDevice(device)) {
|
||||
// set the default value, if device is affected by a full/fix/abs volume rule, it
|
||||
// will taken into account in checkFixedVolumeDevices()
|
||||
mStreamStates[streamType].setIndex(
|
||||
mStreamStates[mStreamVolumeAlias[streamType]]
|
||||
.getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
|
||||
device, caller, true /*hasModifyAudioSettings*/);
|
||||
}
|
||||
mStreamStates[streamType].checkFixedVolumeDevices();
|
||||
updateVolumeStates(device, streamType, caller);
|
||||
}
|
||||
}
|
||||
|
||||
// Unmute streams if device is full volume
|
||||
if (mFullVolumeDevices.contains(device)) {
|
||||
mStreamStates[streamType].mute(false);
|
||||
/**
|
||||
* Update volume states for the given device and given stream.
|
||||
*
|
||||
* This will initialize the volume index if no volume index is available.
|
||||
* If the device is the currently routed device, fixed/full volume policies will be applied.
|
||||
*
|
||||
* @param device a single audio device, ensure that this is not a devices bitmask
|
||||
* @param streamType streamType to be updated
|
||||
* @param caller caller of this method
|
||||
*/
|
||||
private void updateVolumeStates(int device, int streamType, String caller) {
|
||||
if (!mStreamStates[streamType].hasIndexForDevice(device)) {
|
||||
// set the default value, if device is affected by a full/fix/abs volume rule, it
|
||||
// will taken into account in checkFixedVolumeDevices()
|
||||
mStreamStates[streamType].setIndex(
|
||||
mStreamStates[mStreamVolumeAlias[streamType]]
|
||||
.getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
|
||||
device, caller, true /*hasModifyAudioSettings*/);
|
||||
}
|
||||
|
||||
// Check if device to be updated is routed for the given audio stream
|
||||
List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributes(
|
||||
new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
|
||||
for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
|
||||
if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
|
||||
device)) {
|
||||
mStreamStates[streamType].checkFixedVolumeDevices();
|
||||
|
||||
// Unmute streams if required if device is full volume
|
||||
if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
|
||||
mStreamStates[streamType].mute(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4901,7 +4932,15 @@ public class AudioService extends IAudioService.Stub
|
||||
synchronized (VolumeStreamState.class) {
|
||||
for (int stream = 0; stream < mStreamStates.length; stream++) {
|
||||
if (stream != skipStream) {
|
||||
mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/);
|
||||
int devices = mStreamStates[stream].observeDevicesForStream_syncVSS(
|
||||
false /*checkOthers*/);
|
||||
|
||||
Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices);
|
||||
for (Integer device : devicesSet) {
|
||||
// Update volume states for devices routed for the stream
|
||||
updateVolumeStates(device, stream,
|
||||
"AudioService#observeDevicesForStreams");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4970,7 +5009,7 @@ public class AudioService extends IAudioService.Stub
|
||||
+ Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
|
||||
// make sure we have a volume entry for this device, and that volume is updated according
|
||||
// to volume behavior
|
||||
checkAddAllFixedVolumeDevices(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
|
||||
updateVolumeStatesForAudioDevice(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7192,10 +7231,9 @@ public class AudioService extends IAudioService.Stub
|
||||
// HDMI output
|
||||
removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
|
||||
}
|
||||
updateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
|
||||
"HdmiPlaybackClient.DisplayStatusCallback");
|
||||
}
|
||||
|
||||
checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
|
||||
"HdmiPlaybackClient.DisplayStatusCallback");
|
||||
}
|
||||
|
||||
private class MyHdmiControlStatusChangeListenerCallback
|
||||
|
||||
Reference in New Issue
Block a user