diff options
| author | 2020-08-05 15:19:59 +0200 | |
|---|---|---|
| committer | 2020-08-06 16:52:01 +0200 | |
| commit | 4574a8dc3a90c508585e8a2cd79dce8398469577 (patch) | |
| tree | f92b1233c51a8054529f5058c9312d1b1a7941a2 | |
| parent | 9547241ba12a2b89609484217ec8ea7d276c7601 (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
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(); + } } |