diff options
4 files changed, 321 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index d0ad6fc0854f..b696c5481205 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -444,14 +444,62 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { new Runnable() { @Override public void run() { - if (!isActiveSource()) { + if (isActiveSource()) { + return; + } + + if (getActiveSource().logicalAddress != Constants.ADDR_TV) { startHdmiCecActiveSourceLostActivity(); mDelayedStandbyOnActiveSourceLostHandler .removeCallbacksAndMessages(null); mDelayedStandbyOnActiveSourceLostHandler.postDelayed( new DelayedStandbyOnActiveSourceLostRunnable(), STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + return; } + + // We observed specific TV panels (old models) that send faulty CEC + // source changing messages, especially during wake-up. + // This request helps to check if the TV correctly asserted active + // source or not. If the request times out, active source is + // asserted by the local device. + addAndStartAction(new RequestActiveSourceAction(mService.playback(), + new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + // If a device answers to <Request Active Source>, the + // pop-up should be triggered. + // During this action, the TV can switch to an HDMI input + // with a non-CEC capable device that won't be able to + // answer this request. + // In this case, the known active source would be + // represented by a valid physical address, but invalid + // logical address. The pop-up will be shown and the local + // device will not assert active source. + if (result == HdmiControlManager.RESULT_SUCCESS + || getActiveSource().logicalAddress + != Constants.ADDR_TV) { + startHdmiCecActiveSourceLostActivity(); + mDelayedStandbyOnActiveSourceLostHandler + .removeCallbacksAndMessages(null); + mDelayedStandbyOnActiveSourceLostHandler + .postDelayed( + new DelayedStandbyOnActiveSourceLostRunnable(), + STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + } else { + // The request times out and the local device is not + // active source, but the TV previously asserted active + // source. + if (getActiveSource().logicalAddress + == Constants.ADDR_TV) { + mService.setAndBroadcastActiveSource( + mService.getPhysicalAddress(), + getDeviceInfo().getDeviceType(), + Constants.ADDR_BROADCAST, + "RequestActiveSourceAction#RESULT_TIMEOUT"); + } + } + }})); } }, POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); return; @@ -698,6 +746,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { removeAction(HotplugDetectionAction.class); removeAction(NewDeviceAction.class); removeAction(PowerStatusMonitorActionFromPlayback.class); + removeAction(RequestActiveSourceAction.class); super.disableDevice(initiatedByCec, callback); clearDeviceInfoList(); checkIfPendingActionsCleared(); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 81be0baefd7a..cb0b4b08db8f 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -4344,6 +4344,7 @@ public class HdmiControlService extends SystemService { if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) { HdmiCecLocalDevicePlayback playback = playback(); playback.dismissUiOnActiveSourceStatusRecovered(); + playback.removeAction(RequestActiveSourceAction.class); playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress, caller); playback.wakeUpIfActiveSource(); diff --git a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java index a33d70a9b876..b0e93989d463 100644 --- a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java +++ b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java @@ -22,11 +22,11 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; /** - * Feature action that sends <Request Active Source> message and waits for <Active Source> on TV - * panels. - * This action has a delay before sending <Request Active Source>. This is because it should wait - * for a possible request from LauncherX and can be cancelled if an <Active Source> message was - * received or the TV switched to another input. + * Feature action that sends <Request Active Source> message and waits for <Active Source>. + * + * For TV panels, this action has a delay before sending <Request Active Source>. This is because it + * should wait for a possible request from LauncherX and can be cancelled if an <Active Source> + * message was received or the TV switched to another input. */ public class RequestActiveSourceAction extends HdmiCecFeatureAction { private static final String TAG = "RequestActiveSourceAction"; @@ -55,6 +55,13 @@ public class RequestActiveSourceAction extends HdmiCecFeatureAction { boolean start() { Slog.v(TAG, "RequestActiveSourceAction started."); + if (localDevice().mService.isPlaybackDevice()) { + mState = STATE_WAIT_FOR_ACTIVE_SOURCE; + sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress())); + addTimer(mState, HdmiConfig.TIMEOUT_MS); + return true; + } + mState = STATE_WAIT_FOR_LAUNCHERX_API_CALL; // We wait for default timeout to allow the message triggered by the LauncherX API call to diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index a0005d968e31..3360e1d08bda 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -413,7 +413,8 @@ public class HdmiCecLocalDevicePlaybackTest { .isEqualTo(Constants.HANDLED); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, false, + false); assertThat(mPowerManager.isInteractive()).isFalse(); } @@ -422,9 +423,8 @@ public class HdmiCecLocalDevicePlaybackTest { int newPlaybackPhysicalAddress = 0x2100; int switchPhysicalAddress = 0x2000; mNativeWrapper.setPhysicalAddress(newPlaybackPhysicalAddress); - mHdmiControlService.onHotplug(newPlaybackPhysicalAddress, true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); - + mHdmiControlService.onHotplug(newPlaybackPhysicalAddress, true); mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); @@ -457,7 +457,8 @@ public class HdmiCecLocalDevicePlaybackTest { .isEqualTo(Constants.HANDLED); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, false, + false); assertThat(mPowerManager.isInteractive()).isFalse(); } @@ -617,7 +618,8 @@ public class HdmiCecLocalDevicePlaybackTest { .isEqualTo(Constants.HANDLED); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, false, + false); assertThat(mPowerManager.isInteractive()).isFalse(); } @@ -722,7 +724,8 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( ADDR_INVALID); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS,true, + true); assertThat(mPowerManager.isInteractive()).isFalse(); } @@ -1265,14 +1268,35 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); - - // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + // After 30s of device inactivity, device would assert active source. + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, true, + true); assertThat(mPowerManager.isInteractive()).isFalse(); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); } @Test + public void handleActiveSourceFromTv_tvNotAnswerRequest_assertActiveSource() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, + HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); + mPowerManager.setInteractive(true); + HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)) + .isEqualTo(Constants.HANDLED); + message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)) + .isEqualTo(Constants.HANDLED); + mTestLooper.dispatchAll(); + // After 30s of device inactivity, device would assert active source. + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, true, + false); + assertThat(mPowerManager.isInteractive()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + } + + @Test public void handleActiveSource_otherDevice_ActiveSource_mediaSessionsPaused() { mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); @@ -1343,7 +1367,8 @@ public class HdmiCecLocalDevicePlaybackTest { .isEqualTo(Constants.HANDLED); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, true, + true); assertThat(mPowerManager.isInteractive()).isFalse(); mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); // 3. DUT becomes <AS> again. @@ -1704,9 +1729,9 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)) .isEqualTo(Constants.HANDLED); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); - // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, false, + false); assertThat(mPowerManager.isInteractive()).isFalse(); } @@ -2323,11 +2348,197 @@ public class HdmiCecLocalDevicePlaybackTest { mTestLooper.dispatchAll(); // After 30s of device inactivity, device would go to sleep. - skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS, true, + true); assertThat(mPowerManager.isInteractive()).isFalse(); } @Test + public void onActiveSourceLostToTv_requestActiveSourceAnsweredFromTv_showPopup() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, + HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); + + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mPowerManager.setInteractive(true); + mNativeWrapper.clearResultMessages(); + mTestLooper.dispatchAll(); + + HdmiCecMessage activeSourceFromTv = + HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + HdmiCecMessage requestActiveSource = + HdmiCecMessageBuilder.buildRequestActiveSource(mPlaybackLogicalAddress); + + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv)) + .isEqualTo(Constants.HANDLED); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + mTestLooper.dispatchAll(); + + // RequestActiveSourceAction is triggered. + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mNativeWrapper.onCecMessage(activeSourceFromTv); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV); + assertThat(mIsOnActiveSourceLostPopupActive).isTrue(); + } + + @Test + public void onActiveSourceLostToTv_requestActiveSourceNotAnswered_assertActiveSource() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, + HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); + + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mPowerManager.setInteractive(true); + mNativeWrapper.clearResultMessages(); + mTestLooper.dispatchAll(); + + HdmiCecMessage activeSourceFromTv = + HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + HdmiCecMessage requestActiveSource = + HdmiCecMessageBuilder.buildRequestActiveSource(mPlaybackLogicalAddress); + HdmiCecMessage activeSourceFromPlayback = + HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv)) + .isEqualTo(Constants.HANDLED); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + mTestLooper.dispatchAll(); + + // RequestActiveSourceAction is triggered. + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + // Pop-up is not shown, playback device asserts active source since TV doesn't answer the + // request. + assertThat(mIsOnActiveSourceLostPopupActive).isFalse(); + assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress) + .isEqualTo(mPlaybackLogicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress) + .isEqualTo(mPlaybackPhysicalAddress); + } + + @Test + public void onActiveSourceLost_requestActiveSourceNotAnswered_playbackIsAS_dontShowPopup() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, + HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); + + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mPowerManager.setInteractive(true); + mNativeWrapper.clearResultMessages(); + mTestLooper.dispatchAll(); + + HdmiCecMessage activeSourceFromTv = + HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + HdmiCecMessage requestActiveSource = + HdmiCecMessageBuilder.buildRequestActiveSource(mPlaybackLogicalAddress); + HdmiCecMessage setStreamPathToPlayback = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, + mPlaybackPhysicalAddress); + HdmiCecMessage activeSourceFromPlayback = + HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv)) + .isEqualTo(Constants.HANDLED); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + mTestLooper.dispatchAll(); + + // RequestActiveSourceAction is triggered. + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(setStreamPathToPlayback)) + .isEqualTo(Constants.HANDLED); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + // Pop-up is not shown since playback device is active source. + assertThat(mIsOnActiveSourceLostPopupActive).isFalse(); + assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress) + .isEqualTo(mPlaybackLogicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress) + .isEqualTo(mPlaybackPhysicalAddress); + } + + @Test + public void onActiveSourceLost_requestASNotAnswered_setStreamPathToNonCecInput_dontShowPopup() { + int otherPhysicalAddress = mPlaybackPhysicalAddress + 0x0100; + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, + HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); + + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mPowerManager.setInteractive(true); + mNativeWrapper.clearResultMessages(); + mTestLooper.dispatchAll(); + + HdmiCecMessage activeSourceFromTv = + HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + HdmiCecMessage requestActiveSource = + HdmiCecMessageBuilder.buildRequestActiveSource(mPlaybackLogicalAddress); + HdmiCecMessage setStreamPathToOtherInput = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, + otherPhysicalAddress); + HdmiCecMessage activeSourceFromPlayback = + HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv)) + .isEqualTo(Constants.HANDLED); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); + mTestLooper.dispatchAll(); + + // RequestActiveSourceAction is triggered. + assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(setStreamPathToOtherInput)) + .isEqualTo(Constants.HANDLED); + mTestLooper.dispatchAll(); + + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + + // Pop-up is shown, playback device doesn't assert active source since active path is + // switched to a non-CEC device. + assertThat(mIsOnActiveSourceLostPopupActive).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress) + .isEqualTo(ADDR_INVALID); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress) + .isEqualTo(otherPhysicalAddress); + } + + @Test public void onActiveSourceLost_interactionWithDut_noStandbyAfterTimeout() { mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, @@ -2350,7 +2561,7 @@ public class HdmiCecLocalDevicePlaybackTest { mTestLooper.dispatchAll(); // User interacted with the DUT, so the device will not go to standby. - skipActiveSourceLostUi(0); + skipActiveSourceLostUi(0, true, true); assertThat(mIsOnActiveSourceLostPopupActive).isFalse(); assertThat(mPowerManager.isInteractive()).isTrue(); assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue(); @@ -2387,6 +2598,10 @@ public class HdmiCecLocalDevicePlaybackTest { // Pop-up is triggered. mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); mTestLooper.dispatchAll(); + // RequestActiveSourceAction is triggered and TV confirms active source. + mNativeWrapper.onCecMessage(activeSourceFromTv); + mTestLooper.dispatchAll(); + assertThat(mIsOnActiveSourceLostPopupActive).isTrue(); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(setStreamPathToPlayback)) @@ -2407,6 +2622,8 @@ public class HdmiCecLocalDevicePlaybackTest { @Test public void onActiveSourceLost_incomingRoutingChangeToDut_noStandbyAfterTimeout() { + int otherPlaybackLogicalAddress = mPlaybackLogicalAddress == Constants.ADDR_PLAYBACK_2 + ? Constants.ADDR_PLAYBACK_1 : Constants.ADDR_PLAYBACK_2; mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW); @@ -2420,18 +2637,21 @@ public class HdmiCecLocalDevicePlaybackTest { mNativeWrapper.clearResultMessages(); mTestLooper.dispatchAll(); - HdmiCecMessage activeSourceFromTv = - HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); + HdmiCecMessage activeSourceFromOtherPlayback = + HdmiCecMessageBuilder.buildActiveSource(otherPlaybackLogicalAddress, + mPlaybackPhysicalAddress + 0x0100); HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress, mPlaybackPhysicalAddress); HdmiCecMessage routingChangeToPlayback = - HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, + HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, + mPlaybackPhysicalAddress + 0x0100, mPlaybackPhysicalAddress); - assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv)) + assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromOtherPlayback)) .isEqualTo(Constants.HANDLED); - assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + otherPlaybackLogicalAddress); mTestLooper.dispatchAll(); // Pop-up is triggered. @@ -2600,13 +2820,30 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mPowerManager.isInteractive()).isFalse(); } - private void skipActiveSourceLostUi(long idleDuration) { + private void skipActiveSourceLostUi(long idleDuration, boolean activeSourceLostToTv, + boolean tvAnswersRequest) { mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); mTestLooper.dispatchAll(); + if (activeSourceLostToTv) { + // RequestActiveSourceAction is triggered. + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + if (tvAnswersRequest) { + HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, + 0x0000); + mNativeWrapper.onCecMessage(activeSource); + mTestLooper.dispatchAll(); + } else { + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + assertThat(mIsOnActiveSourceLostPopupActive).isFalse(); + return; + } + } assertThat(mIsOnActiveSourceLostPopupActive).isTrue(); mPowerManagerInternal.setIdleDuration(idleDuration); mTestLooper.moveTimeForward(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS); mTestLooper.dispatchAll(); } -} +}
\ No newline at end of file |