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

Commit 0e747da0 authored by Paul Colța's avatar Paul Colța Committed by Android (Google) Code Review
Browse files

Merge "HDMI: Delay OTP in case standby process started" into main

parents c415ebcd 0ed23ada
Loading
Loading
Loading
Loading
+40 −10
Original line number Diff line number Diff line
@@ -45,6 +45,13 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
    @VisibleForTesting
    static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;

    // State in which the action is delayed. If the action starts and
    // {@link PowerManager#isInteractive} returns false, it could indicate the beginning of a
    // standby process. In this scenario, the action will be removed when
    // {@link HdmiCecLocalDeviceSource#disableDevice} is called, therefore we delay the action.
    @VisibleForTesting
    static final int STATE_CHECK_STANDBY_PROCESS_STARTED = 2;

    // The maximum number of times we send <Give Device Power Status> before we give up.
    // We wait up to RESPONSE_TIMEOUT_MS * LOOP_COUNTER_MAX = 20 seconds.
    private static final int LOOP_COUNTER_MAX = 10;
@@ -87,6 +94,22 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
    boolean start() {
        // Because only source device can create this action, it's safe to cast.
        mSource = source();

        if (!mSource.mService.getPowerManager().isInteractive()) {
            Slog.d(TAG, "PowerManager is not interactive. Delay the action to check if standby"
                    + " started!");
            mState = STATE_CHECK_STANDBY_PROCESS_STARTED;
            addTimer(mState, HdmiConfig.TIMEOUT_MS);
        } else {
            startAction();
        }

        return true;
    }

    private void startAction() {
        Slog.i(TAG, "Start action.");

        sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));

        boolean is20TargetOnBefore = mIsCec20 && getTargetDevicePowerStatus(mSource, mTargetAddress,
@@ -116,12 +139,11 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
                    maySendActiveSource();
                }
                finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
                return true;
                return;
            }
        }
        mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
        addTimer(mState, HdmiConfig.TIMEOUT_MS);
        return true;
    }

    private void setAndBroadcastActiveSource() {
@@ -174,7 +196,8 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
        if (mState != state) {
            return;
        }
        if (state == STATE_WAITING_FOR_REPORT_POWER_STATUS) {
        switch (state) {
            case STATE_WAITING_FOR_REPORT_POWER_STATUS:
                if (mPowerStatusCounter++ < LOOP_COUNTER_MAX) {
                    queryDevicePowerStatus();
                    addTimer(mState, HdmiConfig.TIMEOUT_MS);
@@ -182,6 +205,13 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
                    // Couldn't wake up the TV for whatever reason. Report failure.
                    finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
                }
                return;
            case STATE_CHECK_STANDBY_PROCESS_STARTED:
                Slog.d(TAG, "Action was not removed, start the action.");
                startAction();
                return;
            default:
                return;
        }
    }

+52 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.hdmi;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
import static com.android.server.hdmi.OneTouchPlayAction.STATE_WAITING_FOR_REPORT_POWER_STATUS;

import static com.google.common.truth.Truth.assertThat;
@@ -46,6 +47,7 @@ import org.junit.runners.JUnit4;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/** Tests for {@link OneTouchPlayAction} */
@SmallTest
@@ -70,6 +72,7 @@ public class OneTouchPlayActionTest {

    private Context mContextSpy;
    private HdmiControlService mHdmiControlService;
    private HdmiCecController mHdmiCecController;
    private FakeNativeWrapper mNativeWrapper;
    private FakePowerManagerWrapper mPowerManager;
    private FakeHdmiCecConfig mHdmiCecConfig;
@@ -108,10 +111,10 @@ public class OneTouchPlayActionTest {
        mHdmiControlService.setHdmiCecConfig(mHdmiCecConfig);
        setHdmiControlEnabled(hdmiControlEnabled);
        mNativeWrapper = new FakeNativeWrapper();
        HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
        mHdmiCecController = HdmiCecController.createWithNativeWrapper(
                this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
        mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
        mHdmiControlService.setCecController(hdmiCecController);
        mHdmiControlService.setCecController(mHdmiCecController);
        mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
        mHdmiControlService.initService();
        mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
@@ -618,6 +621,53 @@ public class OneTouchPlayActionTest {
        assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
    }

    @Test
    public void onWakeUp_notInteractive_startOneTouchPlay() throws Exception {
        setUp(true);

        mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
        mPowerManager.setInteractive(false);
        mTestLooper.dispatchAll();

        assertThat(mPowerManager.isInteractive()).isFalse();
        mNativeWrapper.clearResultMessages();
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn =
                HdmiCecMessageBuilder.buildTextViewOn(
                        mHdmiControlService.playback().getDeviceInfo().getLogicalAddress(),
                        ADDR_TV);
        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
    }


    @Test
    public void onWakeUp_interruptedByOnStandby_notInteractive_OneTouchPlayNotStarted()
            throws Exception {
        setUp(true);
        long allocationDelay = TimeUnit.SECONDS.toMillis(1);
        mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
        mTestLooper.dispatchAll();

        mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
        mPowerManager.setInteractive(false);
        mTestLooper.dispatchAll();

        assertThat(mPowerManager.isInteractive()).isFalse();
        mNativeWrapper.clearResultMessages();
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn =
                HdmiCecMessageBuilder.buildTextViewOn(
                        mHdmiControlService.playback().getDeviceInfo().getLogicalAddress(),
                        ADDR_TV);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);

    }

    private static class TestActionTimer implements ActionTimer {
        private int mState;