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();
+ }
}