Change the HDMI_ARC audio output device to full volume.
Much of our logic for volume handling using ARC relies on incorrect assumptions. Alongside the switch to full volume, this CL makes the following changes to align our logic with the current capabilities of HDMI CEC. 1. We no longer attempt to track the Audio System's volume/mute state. 2. We no longer support setting the Audio System's volume to a precise level, or setting its absolute mute state. 3. When adjusting stream volume, depending on the adjustment, we send a single CEC UI command out of "Volume Up", "Volume Down", and "Mute" (which toggles mute). Bug: 191230338 Test: Manual with TV connected to Audio System Change-Id: If4d5e2042bbadcec1903152c29de7c55bb0ace22
This commit is contained in:
@@ -64,6 +64,7 @@ import android.database.ContentObserver;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.SensorPrivacyManagerInternal;
|
||||
import android.hardware.hdmi.HdmiAudioSystemClient;
|
||||
import android.hardware.hdmi.HdmiClient;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiPlaybackClient;
|
||||
import android.hardware.hdmi.HdmiTvClient;
|
||||
@@ -588,11 +589,12 @@ public class AudioService extends IAudioService.Stub
|
||||
Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
|
||||
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
|
||||
AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
|
||||
AudioSystem.DEVICE_OUT_HDMI_ARC,
|
||||
AudioSystem.DEVICE_OUT_HDMI_EARC,
|
||||
AudioSystem.DEVICE_OUT_AUX_LINE));
|
||||
// Devices for which the volume is always max, no volume panel
|
||||
Set<Integer> mFullVolumeDevices = new HashSet<>();
|
||||
Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
|
||||
AudioSystem.DEVICE_OUT_HDMI_ARC,
|
||||
AudioSystem.DEVICE_OUT_HDMI_EARC
|
||||
));
|
||||
// Devices for the which use the "absolute volume" concept (framework sends audio signal
|
||||
// full scale, and volume control separately) and can be used for multiple use cases reflected
|
||||
// by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
|
||||
@@ -2283,7 +2285,6 @@ public class AudioService extends IAudioService.Stub
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
|
||||
}
|
||||
setSystemAudioMute(masterMute);
|
||||
AudioSystem.setMasterMute(masterMute);
|
||||
broadcastMasterMuteStatus(masterMute);
|
||||
|
||||
@@ -2865,9 +2866,6 @@ public class AudioService extends IAudioService.Stub
|
||||
} else {
|
||||
state = direction == AudioManager.ADJUST_MUTE;
|
||||
}
|
||||
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
|
||||
setSystemAudioMute(state);
|
||||
}
|
||||
for (int stream = 0; stream < mStreamStates.length; stream++) {
|
||||
if (streamTypeAlias == mStreamVolumeAlias[stream]) {
|
||||
if (!(readCameraSoundForced()
|
||||
@@ -2933,11 +2931,6 @@ public class AudioService extends IAudioService.Stub
|
||||
mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if volume update should be sent to Hdmi system audio.
|
||||
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
|
||||
setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
|
||||
}
|
||||
}
|
||||
|
||||
final int newIndex = mStreamStates[streamType].getIndex(device);
|
||||
@@ -2945,7 +2938,13 @@ public class AudioService extends IAudioService.Stub
|
||||
if (adjustVolume) {
|
||||
synchronized (mHdmiClientLock) {
|
||||
if (mHdmiManager != null) {
|
||||
if (mHdmiPlaybackClient != null
|
||||
// At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
|
||||
HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient;
|
||||
if (mHdmiTvClient != null) {
|
||||
fullVolumeHdmiClient = mHdmiTvClient;
|
||||
}
|
||||
|
||||
if (fullVolumeHdmiClient != null
|
||||
&& mHdmiCecVolumeControlEnabled
|
||||
&& streamTypeAlias == AudioSystem.STREAM_MUSIC
|
||||
// vol change on a full volume device
|
||||
@@ -2959,6 +2958,10 @@ public class AudioService extends IAudioService.Stub
|
||||
keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
|
||||
break;
|
||||
case AudioManager.ADJUST_TOGGLE_MUTE:
|
||||
case AudioManager.ADJUST_MUTE:
|
||||
case AudioManager.ADJUST_UNMUTE:
|
||||
// Many CEC devices only support toggle mute. Therefore, we send the
|
||||
// same keycode for all three mute options.
|
||||
keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
|
||||
break;
|
||||
default:
|
||||
@@ -2967,17 +2970,16 @@ public class AudioService extends IAudioService.Stub
|
||||
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final long time = java.lang.System.currentTimeMillis();
|
||||
switch (keyEventMode) {
|
||||
case VOL_ADJUST_NORMAL:
|
||||
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
|
||||
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
|
||||
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
|
||||
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
|
||||
break;
|
||||
case VOL_ADJUST_START:
|
||||
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
|
||||
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
|
||||
break;
|
||||
case VOL_ADJUST_END:
|
||||
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
|
||||
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
|
||||
@@ -3032,27 +3034,6 @@ public class AudioService extends IAudioService.Stub
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) {
|
||||
// Sets the audio volume of AVR when we are in system audio mode. The new volume info
|
||||
// is tranformed to HDMI-CEC commands and passed through CEC bus.
|
||||
synchronized (mHdmiClientLock) {
|
||||
if (mHdmiManager == null
|
||||
|| mHdmiTvClient == null
|
||||
|| oldVolume == newVolume
|
||||
|| (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0
|
||||
|| !mHdmiSystemAudioSupported
|
||||
|| !mHdmiCecVolumeControlEnabled) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StreamVolumeCommand contains the information needed to defer the process of
|
||||
// setStreamVolume() in case the user has to acknowledge the safe volume warning message.
|
||||
static class StreamVolumeCommand {
|
||||
@@ -3556,10 +3537,6 @@ public class AudioService extends IAudioService.Stub
|
||||
mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
|
||||
}
|
||||
|
||||
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
|
||||
setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
|
||||
}
|
||||
|
||||
flags &= ~AudioManager.FLAG_FIXED_VOLUME;
|
||||
if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
|
||||
flags |= AudioManager.FLAG_FIXED_VOLUME;
|
||||
@@ -3821,18 +3798,6 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void setSystemAudioMute(boolean state) {
|
||||
synchronized (mHdmiClientLock) {
|
||||
if (mHdmiManager == null || mHdmiTvClient == null || !mHdmiSystemAudioSupported) return;
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mHdmiTvClient.setSystemAudioMute(state);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** get stream mute state. */
|
||||
public boolean isStreamMute(int streamType) {
|
||||
if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
|
||||
@@ -3983,7 +3948,6 @@ public class AudioService extends IAudioService.Stub
|
||||
if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
|
||||
|| (getCurrentUserId() == userId)) {
|
||||
if (mute != AudioSystem.getMasterMute()) {
|
||||
setSystemAudioMute(mute);
|
||||
AudioSystem.setMasterMute(mute);
|
||||
sendMasterMuteUpdate(mute, flags);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import android.hardware.hdmi.HdmiRecordSources;
|
||||
import android.hardware.hdmi.HdmiTimerRecordSources;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.tv.TvInputInfo;
|
||||
import android.media.tv.TvInputManager.TvInputCallback;
|
||||
@@ -409,6 +408,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
return Constants.ADDR_INVALID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int findAudioReceiverAddress() {
|
||||
return Constants.ADDR_AUDIO_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ServiceThreadOnly
|
||||
@Constants.HandleMessageResult
|
||||
@@ -925,10 +929,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
synchronized (mLock) {
|
||||
mSystemAudioMute = mute;
|
||||
mSystemAudioVolume = volume;
|
||||
int maxVolume = mService.getAudioManager().getStreamMaxVolume(
|
||||
AudioManager.STREAM_MUSIC);
|
||||
mService.setAudioStatus(mute,
|
||||
VolumeControlAction.scaleToCustomVolume(volume, maxVolume));
|
||||
displayOsd(HdmiControlManager.OSD_MESSAGE_AVR_VOLUME_CHANGED,
|
||||
mute ? HdmiControlManager.AVR_VOLUME_MUTED : volume);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user