Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +20 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ import java.util.stream.Collectors; /** * Represent a logical device of type TV residing in Android system. */ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDeviceTv"; // Whether ARC is available or not. "true" means that ARC is established between TV and Loading Loading @@ -113,6 +113,18 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // handle. private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this); private boolean mWasActiveSourceSetToConnectedDevice = false; @VisibleForTesting protected boolean getWasActiveSourceSetToConnectedDevice() { return mWasActiveSourceSetToConnectedDevice; } protected void setWasActiveSourceSetToConnectedDevice( boolean wasActiveSourceSetToConnectedDevice) { mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice; } // Defines the callback invoked when TV input framework is updated with input status. // We are interested in the notification for HDMI input addition event, in order to // process any CEC commands that arrived before the input is added. Loading Loading @@ -474,6 +486,7 @@ public final 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 { Loading @@ -489,13 +502,16 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { protected int handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); // Ignore <Standby> from non-active source device. if (getActiveSource().logicalAddress != message.getSource()) { // If a device has previously asserted the active source status, ignore <Standby> from // non-active source. if (getWasActiveSourceSetToConnectedDevice() && 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); return super.handleStandby(message); } Loading Loading @@ -1457,6 +1473,7 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { invokeStandbyCompletedCallback(callback); return; } setWasActiveSourceSetToConnectedDevice(false); boolean sendStandbyOnSleep = mService.getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP) Loading services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +63 −7 Original line number Diff line number Diff line Loading @@ -2012,38 +2012,94 @@ public class HdmiCecLocalDeviceTvTest { } @Test public void handleStandby_fromActiveSource_standby() { public void handleStandby_fromActiveSource_previousActiveSourceSet_standby() { mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback); mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000, "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isFalse(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); } @Test public void handleStandby_fromNonActiveSource_noStandby() { public void handleStandby_fromNonActiveSource_previousActiveSourceSet_noStandby() { HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_2, 0x2000); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback); mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000, "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isTrue(); } @Test public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() { HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isTrue(); assertThat(mPowerManager.isInteractive()).isFalse(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); } protected static class MockTvDevice extends HdmiCecLocalDeviceTv { MockTvDevice(HdmiControlService service) { super(service); } @Override protected int handleActiveSource(HdmiCecMessage message) { setWasActiveSourceSetToConnectedDevice(true); return super.handleActiveSource(message); } } } Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +20 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ import java.util.stream.Collectors; /** * Represent a logical device of type TV residing in Android system. */ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDeviceTv"; // Whether ARC is available or not. "true" means that ARC is established between TV and Loading Loading @@ -113,6 +113,18 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // handle. private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this); private boolean mWasActiveSourceSetToConnectedDevice = false; @VisibleForTesting protected boolean getWasActiveSourceSetToConnectedDevice() { return mWasActiveSourceSetToConnectedDevice; } protected void setWasActiveSourceSetToConnectedDevice( boolean wasActiveSourceSetToConnectedDevice) { mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice; } // Defines the callback invoked when TV input framework is updated with input status. // We are interested in the notification for HDMI input addition event, in order to // process any CEC commands that arrived before the input is added. Loading Loading @@ -474,6 +486,7 @@ public final 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 { Loading @@ -489,13 +502,16 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { protected int handleStandby(HdmiCecMessage message) { assertRunOnServiceThread(); // Ignore <Standby> from non-active source device. if (getActiveSource().logicalAddress != message.getSource()) { // If a device has previously asserted the active source status, ignore <Standby> from // non-active source. if (getWasActiveSourceSetToConnectedDevice() && 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); return super.handleStandby(message); } Loading Loading @@ -1457,6 +1473,7 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { invokeStandbyCompletedCallback(callback); return; } setWasActiveSourceSetToConnectedDevice(false); boolean sendStandbyOnSleep = mService.getHdmiCecConfig().getIntValue( HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP) Loading
services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +63 −7 Original line number Diff line number Diff line Loading @@ -2012,38 +2012,94 @@ public class HdmiCecLocalDeviceTvTest { } @Test public void handleStandby_fromActiveSource_standby() { public void handleStandby_fromActiveSource_previousActiveSourceSet_standby() { mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback); mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000, "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isFalse(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); } @Test public void handleStandby_fromNonActiveSource_noStandby() { public void handleStandby_fromNonActiveSource_previousActiveSourceSet_noStandby() { HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_2, 0x2000); HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback); mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000, "HdmiCecLocalDeviceTvTest"); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isTrue(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isTrue(); } @Test public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() { HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1, ADDR_TV); mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService); mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); mPowerManager.setInteractive(true); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage)) .isEqualTo(Constants.HANDLED); mTestLooper.dispatchAll(); assertThat(mPowerManager.isInteractive()).isTrue(); assertThat(mPowerManager.isInteractive()).isFalse(); assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice()) .isFalse(); } protected static class MockTvDevice extends HdmiCecLocalDeviceTv { MockTvDevice(HdmiControlService service) { super(service); } @Override protected int handleActiveSource(HdmiCecMessage message) { setWasActiveSourceSetToConnectedDevice(true); return super.handleActiveSource(message); } } }