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

Commit 57e26739 authored by Paul Colta's avatar Paul Colta
Browse files

HDMI: TV should ignore <Standby> from non-AS devices

Source devices can send the TV to sleep by sending <Standby> even when they are not the active source.
This patch avoids this issue by ignoring <Standby> messages from non-active source devices.

It is possible that the active source known by the TV panel is
not the true active source, but the chances are much lower than OTT
knowing a wrong active source. Otherwise, many other bugs would've
occured on ATV CEC implementation about TV panels knowing a wrong AS.

Bug: 322298325
Bug: 308832215
Test: atest HdmiCecLocalDeviceTvTest
Change-Id: I4dc00ebd99ddb8f9393424749d9117a9e76b32bf
parent 62e873cd
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -479,6 +479,22 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        return Constants.HANDLED;
    }

    @Override
    @ServiceThreadOnly
    @Constants.HandleMessageResult
    protected int handleStandby(HdmiCecMessage message) {
        assertRunOnServiceThread();

        // Ignore <Standby> from non-active source device.
        if (getActiveSource().logicalAddress != message.getSource()) {
            Slog.d(TAG, "<Standby> was not sent by the current active source, ignoring."
                    + " Current active source has logical address "
                    + getActiveSource().logicalAddress);
            return Constants.HANDLED;
        }
        return super.handleStandby(message);
    }

    @Override
    @ServiceThreadOnly
    @Constants.HandleMessageResult
+39 −0
Original line number Diff line number Diff line
@@ -169,6 +169,11 @@ public class HdmiCecLocalDeviceTvTest {
                        return false;
                    }

                    @Override
                    boolean isPowerOnOrTransient() {
                        return true;
                    }

                    @Override
                    void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
                        mDeviceEventListeners.add(new DeviceEventListener(device, status));
@@ -1839,4 +1844,38 @@ public class HdmiCecLocalDeviceTvTest {

        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSourceFromTv);
    }

    @Test
    public void handleStandby_fromActiveSource_standby() {
        mPowerManager.setInteractive(true);
        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
        mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000,
                "HdmiCecLocalDeviceTvTest");
        mTestLooper.dispatchAll();

        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
                ADDR_TV);
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                .isEqualTo(Constants.HANDLED);
        mTestLooper.dispatchAll();

        assertThat(mPowerManager.isInteractive()).isFalse();
    }

    @Test
    public void handleStandby_fromNonActiveSource_noStandby() {
        mPowerManager.setInteractive(true);
        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
        mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000,
                "HdmiCecLocalDeviceTvTest");
        mTestLooper.dispatchAll();

        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
                ADDR_TV);
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                .isEqualTo(Constants.HANDLED);
        mTestLooper.dispatchAll();

        assertThat(mPowerManager.isInteractive()).isTrue();
    }
}