Merge "HDMI: Source asserts <AS> if TV doesn't answer to <Request AS>" into main
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index d0ad6fc..b696c54 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 @@
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 @@
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 81be0ba..cb0b4b0 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 @@
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 a33d70a..b0e9398 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 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 @@
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 a0005d9..3360e1d 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 @@
.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 @@
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 @@
.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 @@
.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 @@
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 @@
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 @@
.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 @@
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 @@
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 @@
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 @@
// 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 @@
@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 @@
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 @@
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