Loading services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +40 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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() { Loading Loading @@ -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); Loading @@ -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; } } Loading services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java +52 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading
services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +40 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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() { Loading Loading @@ -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); Loading @@ -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; } } Loading
services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java +52 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading