diff options
| author | 2024-09-05 17:07:40 +0000 | |
|---|---|---|
| committer | 2024-09-05 17:07:40 +0000 | |
| commit | 761746054fa553d628f82679f21ef4e6b9974d62 (patch) | |
| tree | 937399dfa4627295d3c4fc28a37e22e0f9f03bb4 | |
| parent | feda343d2c39cf55f097390e3b66223fc54a2410 (diff) | |
| parent | ed479aa26817e1eaaa619ca05ae8737f7ad7fd31 (diff) | |
Merge "HDMI: Improve behavior of TVs ignoring standby from non-active source" into main
3 files changed, 59 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 81c30ddea4c0..4b85217c2136 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -116,11 +116,11 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private boolean mWasActiveSourceSetToConnectedDevice = false; @VisibleForTesting - protected boolean getWasActiveSourceSetToConnectedDevice() { + protected boolean getWasActivePathSetToConnectedDevice() { return mWasActiveSourceSetToConnectedDevice; } - protected void setWasActiveSourceSetToConnectedDevice( + protected void setWasActivePathSetToConnectedDevice( boolean wasActiveSourceSetToConnectedDevice) { mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice; } @@ -404,6 +404,15 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } } + @Override + void setActivePath(int path) { + super.setActivePath(path); + if (path != Constants.INVALID_PHYSICAL_ADDRESS + && path != Constants.TV_PHYSICAL_ADDRESS) { + setWasActivePathSetToConnectedDevice(true); + } + } + @ServiceThreadOnly void updateActiveInput(int path, boolean notifyInputChange) { assertRunOnServiceThread(); @@ -512,7 +521,6 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { || info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) { mService.getHdmiCecNetwork().updateDevicePowerStatus(logicalAddress, HdmiControlManager.POWER_STATUS_ON); - setWasActiveSourceSetToConnectedDevice(true); ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress); ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType()); } else { @@ -528,16 +536,16 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { protected int handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); - // If a device has previously asserted the active source status, ignore <Standby> from - // non-active source. - if (getWasActiveSourceSetToConnectedDevice() + // If the TV has previously changed the active path, ignore <Standby> from non-active + // source. + if (getWasActivePathSetToConnectedDevice() && getActiveSource().logicalAddress != message.getSource()) { Slog.d(TAG, "<Standby> was not sent by the current active source, ignoring." + " Current active source has logical address " + getActiveSource().logicalAddress); return Constants.HANDLED; } - setWasActiveSourceSetToConnectedDevice(false); + setWasActivePathSetToConnectedDevice(false); return super.handleStandby(message); } @@ -1509,7 +1517,7 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { invokeStandbyCompletedCallback(callback); return; } - setWasActiveSourceSetToConnectedDevice(false); + setWasActivePathSetToConnectedDevice(false); boolean sendStandbyOnSleep = mService.getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP) diff --git a/services/core/java/com/android/server/hdmi/RoutingControlAction.java b/services/core/java/com/android/server/hdmi/RoutingControlAction.java index 0c4fb26ce3b1..d48957b84d62 100644 --- a/services/core/java/com/android/server/hdmi/RoutingControlAction.java +++ b/services/core/java/com/android/server/hdmi/RoutingControlAction.java @@ -44,7 +44,8 @@ final class RoutingControlAction extends HdmiCecFeatureAction { static final int STATE_WAIT_FOR_ROUTING_INFORMATION = 1; // Time out in millseconds used for <Routing Information> - private static final int TIMEOUT_ROUTING_INFORMATION_MS = 1000; + @VisibleForTesting + static final int TIMEOUT_ROUTING_INFORMATION_MS = 1000; // If set to true, call {@link HdmiControlService#invokeInputChangeListener()} when // the routing control/active source change happens. The listener should be called if diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index a7e8a00921df..a5f1fcd01aa1 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -29,6 +29,7 @@ import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_ME import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON; import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS; +import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS; import static com.google.common.truth.Truth.assertThat; @@ -77,6 +78,7 @@ import java.util.concurrent.TimeUnit; public class HdmiCecLocalDeviceTvTest { private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1; private static final int PORT_1 = 1; + private static final int PORT_2 = 2; private static final String[] SADS_NOT_TO_QUERY = new String[]{ HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MPEG1, @@ -215,7 +217,7 @@ public class HdmiCecLocalDeviceTvTest { .setEarcSupported(false) .build(); hdmiPortInfos[1] = - new HdmiPortInfo.Builder(2, HdmiPortInfo.PORT_INPUT, 0x2000) + new HdmiPortInfo.Builder(PORT_2, HdmiPortInfo.PORT_INPUT, 0x2000) .setCecSupported(true) .setMhlSupported(false) .setArcSupported(true) @@ -2021,7 +2023,7 @@ public class HdmiCecLocalDeviceTvTest { ADDR_TV); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); mTestLooper.dispatchAll(); @@ -2031,14 +2033,14 @@ public class HdmiCecLocalDeviceTvTest { "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isFalse(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); } @@ -2051,7 +2053,7 @@ public class HdmiCecLocalDeviceTvTest { mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); @@ -2060,7 +2062,7 @@ public class HdmiCecLocalDeviceTvTest { "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); @@ -2076,22 +2078,51 @@ public class HdmiCecLocalDeviceTvTest { mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isFalse(); - assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) + assertThat(mHdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) .isFalse(); } @Test + public void handleStandby_fromNonActiveSource_previousActivePathSetToNonCecDevice_Standby() { + HdmiCecLocalDeviceTv hdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); + hdmiCecLocalDeviceTv.setDeviceInfo(mHdmiCecLocalDeviceTv.getDeviceInfo()); + mTestLooper.dispatchAll(); + + assertThat(hdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) + .isFalse(); + mPowerManager.setInteractive(true); + hdmiCecLocalDeviceTv.doManualPortSwitching(PORT_2, null); + mTestLooper.dispatchAll(); + + // Timeout the action RoutingControlAction such that the active path would be updated. + mTestLooper.moveTimeForward(TIMEOUT_ROUTING_INFORMATION_MS); + mTestLooper.dispatchAll(); + + assertThat(hdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) + .isTrue(); + HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby( + ADDR_PLAYBACK_1, ADDR_TV); + assertThat(hdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) + .isEqualTo(Constants.HANDLED); + mTestLooper.dispatchAll(); + + assertThat(mPowerManager.isInteractive()).isTrue(); + assertThat(hdmiCecLocalDeviceTv.getWasActivePathSetToConnectedDevice()) + .isTrue(); + } + + @Test public void handleReportPhysicalAddress_DeviceDiscoveryActionInProgress_noNewDeviceAction() { mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); @@ -2189,7 +2220,7 @@ public class HdmiCecLocalDeviceTvTest { @Override protected int handleActiveSource(HdmiCecMessage message) { - setWasActiveSourceSetToConnectedDevice(true); + setWasActivePathSetToConnectedDevice(true); return super.handleActiveSource(message); } } |