diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index f8d852a4d1add..af782767cd206 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -405,6 +405,12 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()"); return; } + if (!isActiveSource()) { + // If routing is changed to the device while Active Source, don't invalidate the + // Active Source + setActiveSource(physicalAddress, + "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()"); + } switch (mPlaybackDeviceActionOnRoutingControl) { case WAKE_UP_AND_SEND_ACTIVE_SOURCE: setAndBroadcastActiveSource(message, physicalAddress); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 60e2bf152c374..a148d82373dde 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -167,8 +167,9 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // If the path is under the current device, should switch if (physicalAddress == mService.getPhysicalAddress() && mService.isPlaybackDevice()) { setAndBroadcastActiveSource(message, physicalAddress); - } - if (physicalAddress != mService.getPhysicalAddress()) { + } else if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if stream path is set to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleSetStreamPath()"); } switchInputOnReceivingNewActivePath(physicalAddress); @@ -180,7 +181,9 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { protected boolean handleRoutingChange(HdmiCecMessage message) { assertRunOnServiceThread(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2); - if (physicalAddress != mService.getPhysicalAddress()) { + if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if routing is changed to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingChange()"); } if (!isRoutingControlFeatureEnabled()) { @@ -202,7 +205,9 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { protected boolean handleRoutingInformation(HdmiCecMessage message) { assertRunOnServiceThread(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); - if (physicalAddress != mService.getPhysicalAddress()) { + if (physicalAddress != mService.getPhysicalAddress() || !isActiveSource()) { + // Invalidate the active source if routing is changed to other physical address or + // our physical address while not active source setActiveSource(physicalAddress, "HdmiCecLocalDeviceSource#handleRoutingInformation()"); } if (!isRoutingControlFeatureEnabled()) { 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 2eee22086d8dd..323e6d77b740a 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_BROADCAST; +import static com.android.server.hdmi.Constants.ADDR_INVALID; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; @@ -275,6 +276,48 @@ public class HdmiCecLocalDevicePlaybackTest { HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingChange_sameDevice_None_ActiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingChange_sameDevice_None_InactiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); } @@ -328,10 +371,51 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); mStandby = false; - HdmiCecMessage message = - HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); + HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingInformation_sameDevice_None_ActiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress, + mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); + assertThat(mStandby).isFalse(); + } + + @Test + public void handleRoutingInformation_sameDevice_None_InactiveSource() { + mHdmiCecLocalDevicePlayback.mPowerStateChangeOnActiveSourceLost = + HdmiProperties.power_state_change_on_active_source_lost_values.NONE; + mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000, + "HdmiCecLocalDevicePlaybackTest"); + mStandby = false; + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); } @@ -569,6 +653,11 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + mPlaybackLogicalAddress); } @Test @@ -580,6 +669,11 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x0000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_TV); } @Test @@ -592,6 +686,7 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); } @Test @@ -603,6 +698,7 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message)).isTrue(); mTestLooper.dispatchAll(); assertThat(mStandby).isTrue(); + assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); } @Test @@ -825,6 +921,8 @@ public class HdmiCecLocalDevicePlaybackTest { mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath); mTestLooper.dispatchAll(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + mPlaybackPhysicalAddress); assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress()); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue(); @@ -841,6 +939,10 @@ public class HdmiCecLocalDevicePlaybackTest { HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000); assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message)).isTrue(); assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse(); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo( + 0x5000); + assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo( + ADDR_INVALID); assertThat(mStandby).isFalse(); }