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

Commit f7f27b01 authored by Winni Chang's avatar Winni Chang
Browse files

Rollback and refine compatibility issues for ARC devices

Roll back the commit in onHotplug() due to numerous compatibility issues. Some ARC devices needs to restart initiate flow to output audio.

Additionally, some ARC devices require additional command, <System Audio Mode Request> [Active Source], to output sound.

Bug: 360768278
Flag: EXEMPT bugfix
Change-Id: I785208f206127d859b4f3e5e451562d3a2d5d542
parent 31c24639
Loading
Loading
Loading
Loading
+9 −16
Original line number Diff line number Diff line
@@ -1418,23 +1418,16 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
            mService.getHdmiCecNetwork().removeCecSwitches(portId);
        }

        if (!mService.isEarcEnabled() || !mService.isEarcSupported()) {
            HdmiDeviceInfo avr = getAvrDeviceInfo();
            if (avr != null
                    && portId == avr.getPortId()
                    && isConnectedToArcPort(avr.getPhysicalAddress())) {
        // Turning System Audio Mode off when the AVR is unlugged or standby.
        // When the device is not unplugged but reawaken from standby, we check if the System
        // Audio Control Feature is enabled or not then decide if turning SAM on/off accordingly.
        if (getAvrDeviceInfo() != null && portId == getAvrDeviceInfo().getPortId()) {
            HdmiLogger.debug("Port ID:%d, 5v=%b", portId, connected);
                if (connected) {
                    if (mArcEstablished) {
                        enableAudioReturnChannel(true);
            if (!connected) {
                setSystemAudioMode(false);
            } else {
                        HdmiLogger.debug("Restart ARC again");
                onNewAvrAdded(getAvrDeviceInfo());
            }
                } else {
                    enableAudioReturnChannel(false);
                }
            }
        }

        // Tv device will have permanent HotplugDetectionAction.
+2 −13
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
    @Override
    boolean start() {
        mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
        tv().removeAction(RequestArcTerminationAction.class);

        addTimer(mState, HdmiConfig.TIMEOUT_MS);
        sendGiveSystemAudioModeStatus();
@@ -91,21 +92,9 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {

        // If System Audio Control feature is enabled, turn on system audio mode when new AVR is
        // detected. Otherwise, turn off system audio mode.
        // If AVR reports SAM on and it is in standby, the action SystemAudioActionFromTv
        // triggers a <SAM Request> that will wake-up the AVR.
        boolean targetSystemAudioMode = tv().isSystemAudioControlFeatureEnabled();
        if (currentSystemAudioMode != targetSystemAudioMode
                || (currentSystemAudioMode && tv().getAvrDeviceInfo() != null
                && tv().getAvrDeviceInfo().getDevicePowerStatus()
                == HdmiControlManager.POWER_STATUS_STANDBY)) {
            // Start System Audio Control feature actions only if necessary.
        addAndStartAction(
                    new SystemAudioActionFromTv(tv(), mAvrAddress, targetSystemAudioMode, null));
        } else {
            // If AVR already has correct system audio mode, update target system audio mode
            // immediately rather than starting feature action.
            tv().setSystemAudioMode(targetSystemAudioMode);
        }
        finish();
    }

+0 −78
Original line number Diff line number Diff line
@@ -1039,84 +1039,6 @@ public class HdmiCecLocalDeviceTvTest {
        assertThat(removedDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
    }

    @Test
    @Ignore("b/360768278")
    public void onHotplug_doNotSend_systemAudioModeRequestWithParameter(){
        // Add a device to the network and assert that this device is included in the list of
        // devices.
        HdmiDeviceInfo infoAudioSystem = HdmiDeviceInfo.cecDeviceBuilder()
            .setLogicalAddress(ADDR_AUDIO_SYSTEM)
            .setPhysicalAddress(0x2000)
            .setPortId(2)
            .setDeviceType(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM)
            .setVendorId(0x1000)
            .setDisplayName("Audio System")
            .build();
        mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoAudioSystem);
        mTestLooper.dispatchAll();
        assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
            .hasSize(1);
        mDeviceEventListeners.clear();
        assertThat(mDeviceEventListeners.size()).isEqualTo(0);

        // Connect port 2 (ARC port)
        mNativeWrapper.setPortConnectionStatus(2, true);

        // AVR connection
        HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc(
            ADDR_AUDIO_SYSTEM,
            ADDR_TV);

        mNativeWrapper.onCecMessage(initiateArc);
        mTestLooper.dispatchAll();

        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
            ADDR_TV,
            ADDR_AUDIO_SYSTEM);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        mNativeWrapper.clearResultMessages();

        // Audio System still acking polls. Allowing detection by HotplugDetectionAction
        mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.SUCCESS);
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        // Hotplug event
        mHdmiCecLocalDeviceTv.onHotplug(2, true);

        // Audio System replies to <Give System Audio Mode> with <System Audio Mode Status>[On]
        HdmiCecMessage reportSystemAudioModeOn =
            HdmiCecMessageBuilder.buildReportSystemAudioMode(
                ADDR_AUDIO_SYSTEM,
                mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(),
                true);
        mHdmiControlService.handleCecCommand(reportSystemAudioModeOn);
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        // Hotplug event when turn off the audio system
        mHdmiCecLocalDeviceTv.onHotplug(2, false);
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        // Some audio systems (eg. Sony) might trigger 5V status from false to true when the
        // devices are off
        mHdmiCecLocalDeviceTv.onHotplug(2, true);

        // Audio System replies to <Give System Audio Mode> with <System Audio Mode Status>
        HdmiCecMessage reportSystemAudioMode =
            HdmiCecMessageBuilder.buildReportSystemAudioMode(
                ADDR_AUDIO_SYSTEM,
                mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(),
                true);
        mHdmiControlService.handleCecCommand(reportSystemAudioMode);
        mTestLooper.dispatchAll();

        HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
            mTvLogicalAddress, ADDR_AUDIO_SYSTEM, mTvPhysicalAddress, true);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest);
    }

    @Test
    public void listenerInvokedIfPhysicalAddressReported() {
        mHdmiControlService.getHdmiCecNetwork().clearDeviceList();