Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27466147 authored by Yan Han's avatar Yan Han
Browse files

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
parent 9420094f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+102 −0
Original line number Diff line number Diff line
@@ -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());
    }
}