From 658dc25dc0b771e2810fd414d31c54d603b25099 Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Wed, 10 Feb 2021 10:17:03 +0100 Subject: [PATCH] Use stored power state for 2.0 devices Power states should not be queried between devices supporting CEC 2.0. If the local device supports CEC 2.0, the target device supports CEC 2.0 and there's a valid power state stored, use the stored value. Bug: 179463842 Test: atest DevicePowerStatusActionTest Change-Id: I80bfec06c1aa11c9f95590d70399593c25160897 --- .../server/hdmi/DevicePowerStatusAction.java | 15 ++++ .../hdmi/DevicePowerStatusActionTest.java | 73 +++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java index 1a0a639c3c66c..7b646b36124b4 100644 --- a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java +++ b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; */ import android.hardware.hdmi.HdmiControlManager; +import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient.DisplayStatusCallback; import android.hardware.hdmi.IHdmiControlCallback; @@ -65,6 +66,20 @@ final class DevicePowerStatusAction extends HdmiCecFeatureAction { @Override boolean start() { + HdmiControlService service = localDevice().mService; + if (service.getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0) { + HdmiDeviceInfo deviceInfo = service.getHdmiCecNetwork().getCecDeviceInfo( + mTargetAddress); + if (deviceInfo != null + && deviceInfo.getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0) { + int powerStatus = deviceInfo.getDevicePowerStatus(); + if (powerStatus != HdmiControlManager.POWER_STATUS_UNKNOWN) { + invokeCallback(powerStatus); + finish(); + return true; + } + } + } queryDevicePowerStatus(); mState = STATE_WAITING_FOR_REPORT_POWER_STATUS; addTimer(mState, HdmiConfig.TIMEOUT_MS); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java index da9dcb79fb764..7cb72c414e526 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java @@ -16,6 +16,7 @@ package com.android.server.hdmi; +import static com.android.server.hdmi.Constants.ADDR_BROADCAST; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; @@ -28,6 +29,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.ContextWrapper; import android.hardware.hdmi.HdmiControlManager; +import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.tv.cec.V1_0.SendMessageResult; import android.media.AudioManager; @@ -214,4 +216,75 @@ public class DevicePowerStatusActionTest { verify(mCallbackMock).onComplete(HdmiControlManager.POWER_STATUS_UNKNOWN); } + + @Test + public void queryDisplayStatus_localDevice_2_0_targetDevice_1_4() throws Exception { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mPlaybackDevice.addAndStartAction(mDevicePowerStatusAction); + mTestLooper.dispatchAll(); + + HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus( + mPlaybackDevice.mAddress, ADDR_TV); + assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus); + + HdmiCecMessage response = HdmiCecMessageBuilder.buildReportPowerStatus( + ADDR_TV, mPlaybackDevice.mAddress, HdmiControlManager.POWER_STATUS_STANDBY); + mNativeWrapper.onCecMessage(response); + mTestLooper.dispatchAll(); + + verify(mCallbackMock).onComplete(HdmiControlManager.POWER_STATUS_STANDBY); + } + + @Test + public void queryDisplayStatus_localDevice_2_0_targetDevice_2_0() throws Exception { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + HdmiCecMessage reportPhysicalAddress = HdmiCecMessageBuilder + .buildReportPhysicalAddressCommand(ADDR_TV, 0x0000, HdmiDeviceInfo.DEVICE_TV); + mNativeWrapper.onCecMessage(reportPhysicalAddress); + mTestLooper.dispatchAll(); + HdmiCecMessage reportPowerStatusBroadcast = HdmiCecMessageBuilder.buildReportPowerStatus( + ADDR_TV, ADDR_BROADCAST, HdmiControlManager.POWER_STATUS_STANDBY); + mNativeWrapper.onCecMessage(reportPowerStatusBroadcast); + mTestLooper.dispatchAll(); + mPlaybackDevice.addAndStartAction(mDevicePowerStatusAction); + mTestLooper.dispatchAll(); + + HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus( + mPlaybackDevice.mAddress, ADDR_TV); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus); + + verify(mCallbackMock).onComplete(HdmiControlManager.POWER_STATUS_STANDBY); + } + + @Test + public void queryDisplayStatus_localDevice_2_0_targetDevice_2_0_unknown() throws Exception { + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + HdmiCecMessage reportPhysicalAddress = HdmiCecMessageBuilder + .buildReportPhysicalAddressCommand(ADDR_TV, 0x0000, HdmiDeviceInfo.DEVICE_TV); + mNativeWrapper.onCecMessage(reportPhysicalAddress); + mTestLooper.dispatchAll(); + HdmiCecMessage reportPowerStatusBroadcast = HdmiCecMessageBuilder.buildReportPowerStatus( + ADDR_TV, ADDR_BROADCAST, HdmiControlManager.POWER_STATUS_UNKNOWN); + mNativeWrapper.onCecMessage(reportPowerStatusBroadcast); + mTestLooper.dispatchAll(); + mPlaybackDevice.addAndStartAction(mDevicePowerStatusAction); + mTestLooper.dispatchAll(); + + HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus( + mPlaybackDevice.mAddress, ADDR_TV); + assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus); + + HdmiCecMessage response = HdmiCecMessageBuilder.buildReportPowerStatus( + ADDR_TV, mPlaybackDevice.mAddress, HdmiControlManager.POWER_STATUS_STANDBY); + mNativeWrapper.onCecMessage(response); + mTestLooper.dispatchAll(); + + verify(mCallbackMock).onComplete(HdmiControlManager.POWER_STATUS_STANDBY); + } }