From d0df8698c40381b953528a0a53434fa03719dc59 Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Mon, 14 Dec 2020 10:08:23 +0100 Subject: [PATCH] Determine if CEC stack should handle KEYCODE_TV_POWER Bug: 157402294 Test: atest HdmiCecLocalDevicePlaybackTest and atest HdmiCecLocalDeviceTvTest Change-Id: I1ffc246ff25354d3d61548d10756f1088850d367 --- .../hardware/hdmi/HdmiControlManager.java | 14 ++++++++++ .../hdmi/HdmiControlServiceWrapper.java | 10 +++++++ .../hardware/hdmi/IHdmiControlService.aidl | 1 + .../hdmi/HdmiAudioSystemClientTest.java | 5 ++++ .../server/hdmi/HdmiControlService.java | 24 +++++++++++++++++ .../server/hdmi/FakeHdmiCecConfig.java | 9 +++++++ .../hdmi/HdmiCecLocalDevicePlaybackTest.java | 27 +++++++++++++++++++ .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 11 ++++++++ 8 files changed, 101 insertions(+) diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index ae10f4006ce5c..b867e6e1457ae 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -847,6 +847,20 @@ public final class HdmiControlManager { } } + /** + * Determines whether the HDMI CEC stack should handle KEYCODE_TV_POWER. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.HDMI_CEC) + public boolean shouldHandleTvPowerKey() { + try { + return mService.shouldHandleTvPowerKey(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Controls whether volume control commands via HDMI CEC are enabled. * diff --git a/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java b/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java index 202e0907f8030..3b61911fcde5b 100644 --- a/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java +++ b/core/java/android/hardware/hdmi/HdmiControlServiceWrapper.java @@ -71,6 +71,11 @@ public final class HdmiControlServiceWrapper { HdmiControlServiceWrapper.this.toggleAndFollowTvPower(); } + @Override + public boolean shouldHandleTvPowerKey() { + return HdmiControlServiceWrapper.this.shouldHandleTvPowerKey(); + } + @Override public void queryDisplayStatus(IHdmiControlCallback callback) { HdmiControlServiceWrapper.this.queryDisplayStatus(callback); @@ -367,6 +372,11 @@ public final class HdmiControlServiceWrapper { /** @hide */ public void toggleAndFollowTvPower() {} + /** @hide */ + public boolean shouldHandleTvPowerKey() { + return true; + } + /** @hide */ public void queryDisplayStatus(IHdmiControlCallback callback) {} diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index 6d0c688f701e3..65bd8565c8641 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -43,6 +43,7 @@ interface IHdmiControlService { HdmiDeviceInfo getActiveSource(); void oneTouchPlay(IHdmiControlCallback callback); void toggleAndFollowTvPower(); + boolean shouldHandleTvPowerKey(); void queryDisplayStatus(IHdmiControlCallback callback); void addHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener); void removeHdmiControlStatusChangeListener(IHdmiControlStatusChangeListener listener); diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java index 306388f30e20a..9531181d3d292 100644 --- a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java +++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java @@ -194,6 +194,11 @@ public class HdmiAudioSystemClientTest { public void toggleAndFollowTvPower() { } + @Override + public boolean shouldHandleTvPowerKey() { + return false; + } + @Override public void queryDisplayStatus(final IHdmiControlCallback callback) { } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index c943fbcdee2e7..13daf37550678 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1652,6 +1652,12 @@ public class HdmiControlService extends SystemService { }); } + @Override + public boolean shouldHandleTvPowerKey() { + enforceAccessPermission(); + return HdmiControlService.this.shouldHandleTvPowerKey(); + } + @Override public void queryDisplayStatus(final IHdmiControlCallback callback) { enforceAccessPermission(); @@ -2334,6 +2340,24 @@ public class HdmiControlService extends SystemService { source.toggleAndFollowTvPower(); } + @VisibleForTesting + protected boolean shouldHandleTvPowerKey() { + if (isTvDevice()) { + return false; + } + String powerControlMode = getHdmiCecConfig().getStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE); + if (powerControlMode.equals(HdmiControlManager.POWER_CONTROL_MODE_NONE)) { + return false; + } + int hdmiCecEnabled = getHdmiCecConfig().getIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED); + if (hdmiCecEnabled != HdmiControlManager.HDMI_CEC_CONTROL_ENABLED) { + return false; + } + return true; + } + @ServiceThreadOnly protected void queryDisplayStatus(final IHdmiControlCallback callback) { assertRunOnServiceThread(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java index 227e8c76987f8..e5bcedb555ac2 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java @@ -77,6 +77,15 @@ final class FakeHdmiCecConfig extends HdmiCecConfig { + " " + " " + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + ""; FakeHdmiCecConfig(@NonNull Context context) { 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 f7d52b6e8b8cb..7aea4ffe1b038 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -1334,4 +1334,31 @@ public class HdmiCecLocalDevicePlaybackTest { assertThat(mNativeWrapper.getResultMessages()).contains(userControlReleased); assertThat(mStandby).isFalse(); } + + @Test + public void shouldHandleTvPowerKey_CecDisabled() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HdmiControlManager.HDMI_CEC_CONTROL_DISABLED); + assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse(); + } + + @Test + public void shouldHandleTvPowerKey_PowerControlModeNone() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, + HdmiControlManager.POWER_CONTROL_MODE_NONE); + assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse(); + } + + @Test + public void shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv() { + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, + HdmiControlManager.POWER_CONTROL_MODE_TV); + assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isTrue(); + } } 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 d24b376793cd1..81f55d80762b6 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -192,4 +192,15 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mHdmiControlService.getActiveSource().getPhysicalAddress()).isEqualTo( externalDevice.getPhysicalAddress()); } + + @Test + public void shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv() { + mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, + HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); + mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setStringValue( + HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, + HdmiControlManager.POWER_CONTROL_MODE_TV); + assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse(); + } }