diff options
| author | 2024-04-29 14:35:06 -0700 | |
|---|---|---|
| committer | 2024-05-01 23:52:03 +0000 | |
| commit | e1469da87814c5609eb1774b4512cc1df83ab63b (patch) | |
| tree | 7a7898eddabdf55a5ed465bfd171753db0561574 | |
| parent | f0694c53eab5ab030d76dd66f2353396d4f6678e (diff) | |
HDMI: Support Feature Discovery feature
HDMI 2.1a page 468 specifies that when a device makes an update to one
or more of the operands of the <Report Feature> message change value, it
shall braodcast a <Report Features> message with the up-to-date operand
values.
Note: Due to build issue with main branch, manual testing and cts for tv
device are verified with udc-tv-dev branch.
Bug: 296356402
Test: manual testing on ADT-4 and gambit; atest com.android.server.hdmi.HdmiControlServiceTest#setRcProfile[menu_name]_reportFeatureBroadcast and atest com.android.server.hdmi.HdmiControlServiceTvTest#setRcProfileTV_reportFeatureBroadcast
Change-Id: Ib42ffccb64bb9c5a8c9dc703042b035496b89f5d
3 files changed, 149 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 54e1217013e6..d10e19200eb2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -867,6 +867,60 @@ public class HdmiControlService extends SystemService { } } }, mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_TV, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(true); + } + }, + mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(false); + } + }, + mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(false); + } + }, + mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(false); + } + }, + mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(false); + } + }, + mServiceThreadExecutor); + mHdmiCecConfig.registerChangeListener( + HdmiControlManager + .CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU, + new HdmiCecConfig.SettingChangeListener() { + @Override + public void onChange(String setting) { + reportFeatures(false); + } + }, + mServiceThreadExecutor); if (isTvDevice()) { mDeviceConfig.addOnPropertiesChangedListener(getContext().getMainExecutor(), @@ -968,6 +1022,21 @@ public class HdmiControlService extends SystemService { } } + /** Helper method for sending feature discovery command */ + private void reportFeatures(boolean isTvDeviceSetting) { + // check if tv device is enabled for tv device specific RC profile setting + if (isTvDeviceSetting) { + if (isTvDeviceEnabled()) { + tv().reportFeatures(); + } + } else { // check for source device setting + HdmiCecLocalDeviceSource source = isAudioSystemDevice() ? audioSystem() : playback(); + if (source != null) { + source.reportFeatures(); + } + } + } + /** * Returns the initial power status used when the HdmiControlService starts. */ diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index 1d3daccd0d90..9a92c704c247 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -408,6 +408,60 @@ public class HdmiControlServiceTest { } @Test + public void setRcProfileRootMenu_reportFeatureBroadcast() { + setRcProfileSourceDeviceTestHelper( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, + HdmiControlManager.RC_PROFILE_SOURCE_MENU_HANDLED); + } + + @Test + public void setRcProfileSetupMenu_reportFeatureBroadcast() { + setRcProfileSourceDeviceTestHelper( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU, + HdmiControlManager.RC_PROFILE_SOURCE_MENU_HANDLED); + } + + @Test + public void setRcProfileContentMenu_reportFeatureBroadcast() { + setRcProfileSourceDeviceTestHelper( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU, + HdmiControlManager.RC_PROFILE_SOURCE_MENU_HANDLED); + } + + @Test + public void setRcProfileTopMenu_reportFeatureBroadcast() { + setRcProfileSourceDeviceTestHelper( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU, + HdmiControlManager.RC_PROFILE_SOURCE_MENU_HANDLED); + } + + @Test + public void setRcProfileMediaSensitiveMenu_reportFeatureBroadcast() { + setRcProfileSourceDeviceTestHelper( + HdmiControlManager + .CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU, + HdmiControlManager.RC_PROFILE_SOURCE_MENU_HANDLED); + } + + /** Helper method to test if feature discovery message sent given RCProfile change */ + private void setRcProfileSourceDeviceTestHelper(final String setting, final int val) { + mNativeWrapper.clearResultMessages(); + + mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(setting, val); + mTestLooper.dispatchAll(); + + HdmiCecMessage reportFeatures = ReportFeaturesMessage.build(Constants.ADDR_PLAYBACK_1, + HdmiControlManager.HDMI_CEC_VERSION_2_0, + Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM), + mPlaybackDeviceSpy.getRcProfile(), mPlaybackDeviceSpy.getRcFeatures(), + mPlaybackDeviceSpy.getDeviceFeatures()); + assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures); + } + + @Test public void disableAndReenableCec_volumeControlReturnsToOriginalValue_enabled() { int volumeControlEnabled = HdmiControlManager.VOLUME_CONTROL_ENABLED; mHdmiControlServiceSpy.setHdmiCecVolumeControlEnabledInternal(volumeControlEnabled); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java index 920c376d5dfb..eed99756abb1 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java @@ -16,11 +16,14 @@ package com.android.server.hdmi; +import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV; + import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; import android.os.Looper; import android.os.test.TestLooper; @@ -35,6 +38,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.Collections; +import java.util.List; /** * TV specific tests for {@link HdmiControlService} class. @@ -47,6 +51,7 @@ public class HdmiControlServiceTvTest { private static final String TAG = "HdmiControlServiceTvTest"; private HdmiControlService mHdmiControlService; private HdmiCecController mHdmiCecController; + private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv; private FakeNativeWrapper mNativeWrapper; private HdmiEarcController mHdmiEarcController; private FakeEarcNativeWrapper mEarcNativeWrapper; @@ -90,6 +95,8 @@ public class HdmiControlServiceTvTest { mHdmiControlService.initService(); mTestLooper.dispatchAll(); + + mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); } @Test @@ -139,4 +146,23 @@ public class HdmiControlServiceTvTest { assertThat(mHdmiControlService .verifyPhysicalAddresses(HdmiUtils.buildMessage("4F:82:10"))).isFalse(); } + + @Test + public void setRcProfileTv_reportFeatureBroadcast() { + mNativeWrapper.clearResultMessages(); + + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, + HdmiControlManager.HDMI_CEC_VERSION_2_0); + mHdmiControlService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_RC_PROFILE_TV, + HdmiControlManager.RC_PROFILE_TV_NONE); + mTestLooper.dispatchAll(); + + HdmiCecMessage reportFeatures = ReportFeaturesMessage.build(Constants.ADDR_TV, + HdmiControlManager.HDMI_CEC_VERSION_2_0, List.of(DEVICE_TV), + mHdmiCecLocalDeviceTv.getRcProfile(), mHdmiCecLocalDeviceTv.getRcFeatures(), + mHdmiCecLocalDeviceTv.getDeviceFeatures()); + assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures); + } } |