Don't update volume in AudioService when SAM is on and ARC is off

This prevents volume from changing on TV panels when a connected
amplifier sends <Report Audio Status>.

Test: manual with Isto and Atom
atest com.android.server.hdmi.HdmiCecLocalDeviceTvTest#handleReportAudioStatus_SamOnArcOff_noVolumeChange
Bug: 182369742

Change-Id: I412ee9d5b1ba7aab382e73deab8ac19546175842
This commit is contained in:
Yan Han
2021-04-06 14:55:00 +02:00
parent 9420094fba
commit 274661478c
2 changed files with 103 additions and 0 deletions

View File

@@ -1253,6 +1253,7 @@ public class HdmiControlService extends SystemService {
void setAudioStatus(boolean mute, int volume) {
if (!isTvDeviceEnabled()
|| !tv().isSystemAudioActivated()
|| !tv().isArcEstablished() // Don't update TV volume when SAM is on and ARC is off
|| getHdmiCecVolumeControl()
== HdmiControlManager.VOLUME_CONTROL_DISABLED) {
return;

View File

@@ -25,6 +25,13 @@ import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
@@ -494,4 +501,99 @@ public class HdmiCecLocalDeviceTvTest {
ABORT_UNRECOGNIZED_OPCODE);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
}
@Test
public void handleReportAudioStatus_SamOnArcOff_setStreamVolumeNotCalled() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecFeatureAction systemAudioAutoInitiationAction =
new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM);
mHdmiCecLocalDeviceTv.addAndStartAction(systemAudioAutoInitiationAction);
HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
mHdmiControlService.handleCecCommand(reportSystemAudioMode);
mTestLooper.dispatchAll();
// SAM must be on; ARC must be off
assertTrue(mHdmiCecLocalDeviceTv.isSystemAudioActivated());
assertFalse(mHdmiCecLocalDeviceTv.isArcEstablished());
HdmiCecMessage reportAudioStatus = HdmiCecMessageBuilder.buildReportAudioStatus(
ADDR_AUDIO_SYSTEM,
ADDR_TV,
50, // Volume of incoming message does not affect HDMI-CEC logic
false);
mNativeWrapper.onCecMessage(reportAudioStatus);
mTestLooper.dispatchAll();
verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
}
@Test
public void handleReportAudioStatus_SamOnArcOn_setStreamVolumeCalled() {
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecFeatureAction systemAudioAutoInitiationAction =
new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM);
mHdmiCecLocalDeviceTv.addAndStartAction(systemAudioAutoInitiationAction);
HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
mHdmiControlService.handleCecCommand(reportSystemAudioMode);
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(requestArcInitiation);
mTestLooper.dispatchAll();
// SAM and ARC must be on
assertTrue(mHdmiCecLocalDeviceTv.isSystemAudioActivated());
assertTrue(mHdmiCecLocalDeviceTv.isArcEstablished());
HdmiCecMessage reportAudioStatus = HdmiCecMessageBuilder.buildReportAudioStatus(
ADDR_AUDIO_SYSTEM,
ADDR_TV,
50, // Volume of incoming message does not affect HDMI-CEC logic
false);
mNativeWrapper.onCecMessage(reportAudioStatus);
mTestLooper.dispatchAll();
verify(mAudioManager, times(1)).setStreamVolume(anyInt(), anyInt(), anyInt());
}
@Test
public void handleReportAudioStatus_SamOff_setStreamVolumeNotCalled() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
mTestLooper.dispatchAll();
assertFalse(mHdmiCecLocalDeviceTv.isSystemAudioActivated());
HdmiCecMessage reportAudioStatus = HdmiCecMessageBuilder.buildReportAudioStatus(
ADDR_AUDIO_SYSTEM,
ADDR_TV,
50, // Volume of incoming message does not affect HDMI-CEC logic
false);
mNativeWrapper.onCecMessage(reportAudioStatus);
mTestLooper.dispatchAll();
verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
}
}