summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michal Olech <molech@google.com> 2020-08-05 15:19:59 +0200
committer Michal Olech <molech@google.com> 2020-08-06 16:52:01 +0200
commit4574a8dc3a90c508585e8a2cd79dce8398469577 (patch)
treef92b1233c51a8054529f5058c9312d1b1a7941a2
parent9547241ba12a2b89609484217ec8ea7d276c7601 (diff)
Handle losing Active Source to non-CEC device
When <Routing Change>, <Routing Information> or <Set Stream Path> messages pointing to a different device are received Active Source should be invalidated. Bug: 162565747 Test: atest HdmiCecLocalDevicePlaybackTest Change-Id: Ic62ce400a7c4faee35b2595abecbcbb1813ea562
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java20
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java145
3 files changed, 186 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 596c1eccfabe..d675b81629a4 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -232,11 +232,12 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
mAutoTvOff = enabled;
}
+ @Override
@ServiceThreadOnly
@VisibleForTesting
void setIsActiveSource(boolean on) {
assertRunOnServiceThread();
- mIsActiveSource = on;
+ super.setIsActiveSource(on);
if (on) {
getWakeLock().acquire();
} else {
@@ -274,19 +275,15 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
@Override
@ServiceThreadOnly
- protected boolean handleActiveSource(HdmiCecMessage message) {
- super.handleActiveSource(message);
- if (mIsActiveSource) {
- return true;
- }
+ protected void onActiveSourceLost() {
+ assertRunOnServiceThread();
switch (mPowerStateChangeOnActiveSourceLost) {
case STANDBY_NOW:
mService.standby();
- return true;
+ return;
case NONE:
- return true;
+ return;
}
- return true;
}
@ServiceThreadOnly
@@ -398,9 +395,12 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
}
@Override
+ @ServiceThreadOnly
protected void handleRoutingChangeAndInformation(int physicalAddress, HdmiCecMessage message) {
+ assertRunOnServiceThread();
if (physicalAddress != mService.getPhysicalAddress()) {
- return; // Do nothing.
+ setActiveSource(physicalAddress);
+ return;
}
switch (mPlaybackDeviceActionOnRoutingControl) {
case WAKE_UP_AND_SEND_ACTIVE_SOURCE:
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index 1c677184b9d2..44ad8eea65ca 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -114,6 +114,19 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
}
@ServiceThreadOnly
+ protected void onActiveSourceLost() {
+ // Nothing to do.
+ }
+
+ @ServiceThreadOnly
+ protected void setActiveSource(int physicalAddress) {
+ assertRunOnServiceThread();
+ // Invalidate the internal active source record. This will also update mIsActiveSource.
+ ActiveSource activeSource = ActiveSource.of(Constants.ADDR_INVALID, physicalAddress);
+ setActiveSource(activeSource);
+ }
+
+ @ServiceThreadOnly
protected boolean handleActiveSource(HdmiCecMessage message) {
assertRunOnServiceThread();
int logicalAddress = message.getSource();
@@ -148,6 +161,9 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
if (physicalAddress == mService.getPhysicalAddress() && mService.isPlaybackDevice()) {
setAndBroadcastActiveSource(message, physicalAddress);
}
+ if (physicalAddress != mService.getPhysicalAddress()) {
+ setActiveSource(physicalAddress);
+ }
switchInputOnReceivingNewActivePath(physicalAddress);
return true;
}
@@ -156,18 +172,21 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
@ServiceThreadOnly
protected boolean handleRoutingChange(HdmiCecMessage message) {
assertRunOnServiceThread();
+ int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2);
+ if (physicalAddress != mService.getPhysicalAddress()) {
+ setActiveSource(physicalAddress);
+ }
if (!isRoutingControlFeatureEnabled()) {
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
return true;
}
- int newPath = HdmiUtils.twoBytesToInt(message.getParams(), 2);
// if the current device is a pure playback device
if (!mIsSwitchDevice
- && newPath == mService.getPhysicalAddress()
+ && physicalAddress == mService.getPhysicalAddress()
&& mService.isPlaybackDevice()) {
- setAndBroadcastActiveSource(message, newPath);
+ setAndBroadcastActiveSource(message, physicalAddress);
}
- handleRoutingChangeAndInformation(newPath, message);
+ handleRoutingChangeAndInformation(physicalAddress, message);
return true;
}
@@ -175,11 +194,14 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
@ServiceThreadOnly
protected boolean handleRoutingInformation(HdmiCecMessage message) {
assertRunOnServiceThread();
+ int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+ if (physicalAddress != mService.getPhysicalAddress()) {
+ setActiveSource(physicalAddress);
+ }
if (!isRoutingControlFeatureEnabled()) {
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
return true;
}
- int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
// if the current device is a pure playback device
if (!mIsSwitchDevice
&& physicalAddress == mService.getPhysicalAddress()
@@ -222,7 +244,11 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
@ServiceThreadOnly
void setIsActiveSource(boolean on) {
assertRunOnServiceThread();
+ boolean wasActiveSource = mIsActiveSource;
mIsActiveSource = on;
+ if (wasActiveSource && !mIsActiveSource) {
+ onActiveSourceLost();
+ }
}
protected void wakeUpIfActiveSource() {
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 960a7ab52c22..d8c03dbd850a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -262,6 +262,112 @@ public class HdmiCecLocalDevicePlaybackTest {
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
+ @Test
+ public void handleRoutingChange_otherDevice_None() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleRoutingChange_otherDevice_StandbyNow() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isTrue();
+ }
+
+ @Test
+ public void handleRoutingChange_otherDevice_StandbyNow_InactiveSource() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleRoutingChange_sameDevice_StandbyNow_ActiveSource() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+ mPlaybackPhysicalAddress);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleRoutingInformation_otherDevice_None() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleRoutingInformation_otherDevice_StandbyNow() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isTrue();
+ }
+
+ @Test
+ public void handleRoutingInformation_otherDevice_StandbyNow_InactiveSource() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleRoutingInformation_sameDevice_StandbyNow_ActiveSource() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+ mPlaybackPhysicalAddress);
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
+ assertThat(mStandby).isFalse();
+ }
+
// Playback device does not handle routing control related feature right now
@Ignore("b/120845532")
@Test
@@ -629,4 +735,43 @@ public class HdmiCecLocalDevicePlaybackTest {
mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress());
assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isTrue();
}
+
+ @Test
+ public void handleSetStreamPath_otherDevice_None() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.NONE;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
+
+ @Test
+ public void handleSetStreamPath_otherDevice_StandbyNow() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isTrue();
+ }
+
+ @Test
+ public void handleSetStreamPath_otherDevice_StandbyNow_InactiveSource() {
+ mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost =
+ HdmiProperties.power_state_change_on_active_source_lost_values.STANDBY_NOW;
+ mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
+ mStandby = false;
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mIsActiveSource).isFalse();
+ assertThat(mStandby).isFalse();
+ }
}