From 78dfa03b6f1a4cba6d95c1e200edf136633c1c2b Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Mon, 28 Sep 2020 12:12:48 +0200 Subject: [PATCH] Update Active Source on Routing Change and Set Stream Path messages This change handles the case of the input being switched to our physical address without us becoming the active source. Bug: 166760714 Test: atest HdmiCecLocalDevicePlaybackTest Change-Id: I4b2b78251759fce330bdb2bb72f384b3e1f6c475 --- .../hdmi/HdmiCecLocalDevicePlayback.java | 6 + .../server/hdmi/HdmiCecLocalDeviceSource.java | 13 ++- .../hdmi/HdmiCecLocalDevicePlaybackTest.java | 106 +++++++++++++++++- 3 files changed, 119 insertions(+), 6 deletions(-) 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(); }