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

Commit b2ea8ff7 authored by Paul Colta's avatar Paul Colta Committed by Android (Google) Code Review
Browse files

Merge "HDMI: If active source was set, ignore <Standby> from non active source" into main

parents 9552d1ee 7d7222df
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ import java.util.stream.Collectors;
/**
 * Represent a logical device of type TV residing in Android system.
 */
public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    private static final String TAG = "HdmiCecLocalDeviceTv";

    // Whether ARC is available or not. "true" means that ARC is established between TV and
@@ -113,6 +113,18 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    // handle.
    private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this);

    private boolean mWasActiveSourceSetToConnectedDevice = false;

    @VisibleForTesting
    protected boolean getWasActiveSourceSetToConnectedDevice() {
        return mWasActiveSourceSetToConnectedDevice;
    }

    protected void setWasActiveSourceSetToConnectedDevice(
            boolean wasActiveSourceSetToConnectedDevice) {
        mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice;
    }

    // Defines the callback invoked when TV input framework is updated with input status.
    // We are interested in the notification for HDMI input addition event, in order to
    // process any CEC commands that arrived before the input is added.
@@ -474,6 +486,7 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
                || info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
            mService.getHdmiCecNetwork().updateDevicePowerStatus(logicalAddress,
                    HdmiControlManager.POWER_STATUS_ON);
            setWasActiveSourceSetToConnectedDevice(true);
            ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
            ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
        } else {
@@ -489,13 +502,16 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    protected int handleStandby(HdmiCecMessage message) {
        assertRunOnServiceThread();

        // Ignore <Standby> from non-active source device.
        if (getActiveSource().logicalAddress != message.getSource()) {
        // If a device has previously asserted the active source status, ignore <Standby> from
        // non-active source.
        if (getWasActiveSourceSetToConnectedDevice()
                && 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;
        }
        setWasActiveSourceSetToConnectedDevice(false);
        return super.handleStandby(message);
    }

@@ -1457,6 +1473,7 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
            invokeStandbyCompletedCallback(callback);
            return;
        }
        setWasActiveSourceSetToConnectedDevice(false);
        boolean sendStandbyOnSleep =
                mService.getHdmiCecConfig().getIntValue(
                    HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP)
+63 −7
Original line number Diff line number Diff line
@@ -2012,38 +2012,94 @@ public class HdmiCecLocalDeviceTvTest {
    }

    @Test
    public void handleStandby_fromActiveSource_standby() {
    public void handleStandby_fromActiveSource_previousActiveSourceSet_standby() {
        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
        HdmiCecMessage activeSourceFromPlayback =
                HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000);
        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
                ADDR_TV);
        mTestLooper.dispatchAll();

        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isFalse();
        mPowerManager.setInteractive(true);
        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
        mTestLooper.dispatchAll();

        mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
        mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000,
                "HdmiCecLocalDeviceTvTest");
        mTestLooper.dispatchAll();

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

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

    @Test
    public void handleStandby_fromNonActiveSource_noStandby() {
    public void handleStandby_fromNonActiveSource_previousActiveSourceSet_noStandby() {
        HdmiCecMessage activeSourceFromPlayback =
                HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_2, 0x2000);
        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
                ADDR_TV);
        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
        mTestLooper.dispatchAll();

        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isFalse();
        mPowerManager.setInteractive(true);
        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);

        mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
        mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000,
                "HdmiCecLocalDeviceTvTest");
        mTestLooper.dispatchAll();

        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isTrue();
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                .isEqualTo(Constants.HANDLED);
        mTestLooper.dispatchAll();

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


    @Test
    public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() {
        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
                ADDR_TV);
        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
        mTestLooper.dispatchAll();

        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isFalse();
        mPowerManager.setInteractive(true);

        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isFalse();
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                .isEqualTo(Constants.HANDLED);
        mTestLooper.dispatchAll();

        assertThat(mPowerManager.isInteractive()).isTrue();
        assertThat(mPowerManager.isInteractive()).isFalse();
        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
                .isFalse();
    }

    protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
        MockTvDevice(HdmiControlService service) {
            super(service);
        }

        @Override
        protected int handleActiveSource(HdmiCecMessage message) {
            setWasActiveSourceSetToConnectedDevice(true);
            return super.handleActiveSource(message);
        }
    }
}