AudioService: fix volume initialization on first ever boot

When HDMI is connected, it calls checkFixedVolumeDevices() that
  iterates over the devices in the volume index map to set them
  at max index. But since the map only contains DEVICE_OUT_DEFAULT
  after a factory reset, VolumeStreamState.checkFixedVolumeDevices()
  doesn't do anything for DEVICE_OUT_HDMI because it is not in the map.
The fix consists in adding the new device in the volume map for a
  connection, and initializing its volume with the default volume,
  VolumeStreamState.checkFixedVolumeDevices() will in turn update
  the volume to max if needed (reads mask or full/fix vol devices).

Bug: 130766100
Test: factory reset device and start playback, check HDMI volume with dumpsys audio
Change-Id: I4c338df6acc1e15af9606694cdbd485d1b991bb5
This commit is contained in:
Jean-Michel Trivi
2019-04-25 11:47:15 -07:00
parent 885109a484
commit 9c7d2b0a2a
3 changed files with 40 additions and 9 deletions

View File

@@ -416,8 +416,9 @@ import com.android.internal.annotations.GuardedBy;
mAudioService.checkMusicActive(deviceType, caller);
}
/*package*/ void checkVolumeCecOnHdmiConnection(int state, String caller) {
mAudioService.checkVolumeCecOnHdmiConnection(state, caller);
/*package*/ void checkVolumeCecOnHdmiConnection(
@AudioService.ConnectionState int state, String caller) {
mAudioService.postCheckVolumeCecOnHdmiConnection(state, caller);
}
/*package*/ boolean hasAudioFocusUsers() {

View File

@@ -363,8 +363,8 @@ public final class AudioDeviceInventory {
"onSetWiredDeviceConnectionState state DISCONNECTED");
}
if (!handleDeviceConnection(wdcs.mState == 1, wdcs.mType, wdcs.mAddress,
wdcs.mName)) {
if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
wdcs.mType, wdcs.mAddress, wdcs.mName)) {
// change of connection state failed, bailout
return;
}
@@ -375,7 +375,9 @@ public final class AudioDeviceInventory {
}
mDeviceBroker.checkMusicActive(wdcs.mType, wdcs.mCaller);
}
mDeviceBroker.checkVolumeCecOnHdmiConnection(wdcs.mState, wdcs.mCaller);
if (wdcs.mType == AudioSystem.DEVICE_OUT_HDMI) {
mDeviceBroker.checkVolumeCecOnHdmiConnection(wdcs.mState, wdcs.mCaller);
}
sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName);
updateAudioRoutes(wdcs.mType, wdcs.mState);
}

View File

@@ -260,6 +260,7 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_UPDATE_RINGER_MODE = 25;
private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
private static final int MSG_HDMI_VOLUME_CHECK = 28;
// start of messages handled under wakelock
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -1060,11 +1061,19 @@ public class AudioService extends IAudioService.Stub
}
}
/**
* Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
*/
/*package*/ void checkVolumeCecOnHdmiConnection(int state, String caller) {
if (state != 0) {
/*package*/ void postCheckVolumeCecOnHdmiConnection(
@AudioService.ConnectionState int state, String caller) {
sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
}
private void onCheckVolumeCecOnHdmiConnection(
@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) {
sendMsg(mAudioHandler,
@@ -1077,7 +1086,7 @@ public class AudioService extends IAudioService.Stub
}
if (isPlatformTelevision()) {
checkAllFixedVolumeDevices();
checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, caller);
synchronized (mHdmiClientLock) {
if (mHdmiManager != null && mHdmiPlaybackClient != null) {
mHdmiCecSink = false;
@@ -1098,6 +1107,21 @@ public class AudioService extends IAudioService.Stub
}
}
private void checkAddAllFixedVolumeDevices(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);
}
mStreamStates[streamType].checkFixedVolumeDevices();
}
}
private void checkAllFixedVolumeDevices()
{
int numStreamTypes = AudioSystem.getNumStreamTypes();
@@ -5329,6 +5353,9 @@ public class AudioService extends IAudioService.Stub
case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
onObserveDevicesForAllStreams();
break;
case MSG_HDMI_VOLUME_CHECK:
onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
}
}
}
@@ -6004,7 +6031,8 @@ public class AudioService extends IAudioService.Stub
// HDMI output
mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_HDMI;
}
checkAllFixedVolumeDevices();
checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
"HdmiPlaybackClient.DisplayStatusCallback");
}
}
}