diff options
| -rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiControlService.java | 83 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java | 69 |
2 files changed, 144 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index ae069ddf235e..2ed160a33af4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -442,18 +442,85 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); - List<Integer> deviceTypes = HdmiProperties.device_type(); - if (deviceTypes.contains(null)) { - Slog.w(TAG, "Error parsing ro.hdmi.device.type: " + SystemProperties.get( - "ro.hdmi.device_type")); - deviceTypes = deviceTypes.stream().filter(Objects::nonNull).collect( - Collectors.toList()); - } - mLocalDevices = deviceTypes; + mLocalDevices = readDeviceTypes(); mSettingsObserver = new SettingsObserver(mHandler); mHdmiCecConfig = new HdmiCecConfig(context); } + @VisibleForTesting + protected List<HdmiProperties.cec_device_types_values> getCecDeviceTypes() { + return HdmiProperties.cec_device_types(); + } + + @VisibleForTesting + protected List<Integer> getDeviceTypes() { + return HdmiProperties.device_type(); + } + + /** + * Extracts a list of integer device types from the sysprop ro.hdmi.cec_device_types. + * If ro.hdmi.cec_device_types is not set, reads from ro.hdmi.device.type instead. + * @return the list of integer device types + */ + @VisibleForTesting + protected List<Integer> readDeviceTypes() { + List<HdmiProperties.cec_device_types_values> cecDeviceTypes = getCecDeviceTypes(); + if (!cecDeviceTypes.isEmpty()) { + if (cecDeviceTypes.contains(null)) { + Slog.w(TAG, "Error parsing ro.hdmi.cec_device_types: " + SystemProperties.get( + "ro.hdmi.cec_device_types")); + } + return cecDeviceTypes.stream() + .map(HdmiControlService::enumToIntDeviceType) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } else { + // If ro.hdmi.cec_device_types isn't set, fall back to reading ro.hdmi.device_type + List<Integer> deviceTypes = getDeviceTypes(); + if (deviceTypes.contains(null)) { + Slog.w(TAG, "Error parsing ro.hdmi.device_type: " + SystemProperties.get( + "ro.hdmi.device_type")); + } + return deviceTypes.stream() + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + } + + /** + * Converts an enum representing a value in ro.hdmi.cec_device_types to an integer device type. + * Returns null if the input is null or an unrecognized device type. + */ + @Nullable + private static Integer enumToIntDeviceType( + @Nullable HdmiProperties.cec_device_types_values cecDeviceType) { + if (cecDeviceType == null) { + return null; + } + switch (cecDeviceType) { + case TV: + return HdmiDeviceInfo.DEVICE_TV; + case RECORDING_DEVICE: + return HdmiDeviceInfo.DEVICE_RECORDER; + case RESERVED: + return HdmiDeviceInfo.DEVICE_RESERVED; + case TUNER: + return HdmiDeviceInfo.DEVICE_TUNER; + case PLAYBACK_DEVICE: + return HdmiDeviceInfo.DEVICE_PLAYBACK; + case AUDIO_SYSTEM: + return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; + case PURE_CEC_SWITCH: + return HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH; + case VIDEO_PROCESSOR: + return HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR; + default: + Slog.w(TAG, "Unrecognized device type in ro.hdmi.cec_device_types: " + + cecDeviceType.getPropValue()); + return null; + } + } + protected static List<Integer> getIntList(String string) { ArrayList<Integer> list = new ArrayList<>(); TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(','); 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 bcf30a255c20..0cf212c20c1e 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK; +import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV; import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; @@ -47,6 +48,7 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; +import android.sysprop.HdmiProperties; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -828,4 +830,71 @@ public class HdmiControlServiceTest { assertThat(mHdmiControlServiceSpy.dispatchMessageToLocalDevice(message)) .isEqualTo(Constants.ABORT_REFUSED); } + + @Test + public void readDeviceTypes_readsIntegerDeviceTypes() { + doReturn(Arrays.asList(new Integer[]{DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM})) + .when(mHdmiControlServiceSpy).getDeviceTypes(); + doReturn(Arrays.asList(new HdmiProperties.cec_device_types_values[]{})) + .when(mHdmiControlServiceSpy).getCecDeviceTypes(); + + assertThat(mHdmiControlServiceSpy.readDeviceTypes()) + .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); + } + + @Test + public void readDeviceTypes_readsEnumDeviceTypes() { + doReturn(Arrays.asList(new Integer[]{})).when(mHdmiControlServiceSpy).getDeviceTypes(); + doReturn(Arrays.asList( + new HdmiProperties.cec_device_types_values[]{ + HdmiProperties.cec_device_types_values.PLAYBACK_DEVICE, + HdmiProperties.cec_device_types_values.AUDIO_SYSTEM + })) + .when(mHdmiControlServiceSpy).getCecDeviceTypes(); + + assertThat(mHdmiControlServiceSpy.readDeviceTypes()) + .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); + } + + @Test + public void readDeviceTypes_readsEnumOverIntegerDeviceTypes() { + doReturn(Arrays.asList(new Integer[]{DEVICE_TV})) + .when(mHdmiControlServiceSpy).getDeviceTypes(); + doReturn(Arrays.asList( + new HdmiProperties.cec_device_types_values[]{ + HdmiProperties.cec_device_types_values.PLAYBACK_DEVICE, + HdmiProperties.cec_device_types_values.AUDIO_SYSTEM + })) + .when(mHdmiControlServiceSpy).getCecDeviceTypes(); + + assertThat(mHdmiControlServiceSpy.readDeviceTypes()) + .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); + } + + @Test + public void readDeviceTypes_doesNotReadNullEnumDeviceType() { + doReturn(Arrays.asList(new Integer[]{})).when(mHdmiControlServiceSpy).getDeviceTypes(); + doReturn(Arrays.asList( + new HdmiProperties.cec_device_types_values[]{ + HdmiProperties.cec_device_types_values.PLAYBACK_DEVICE, + HdmiProperties.cec_device_types_values.AUDIO_SYSTEM, + null + })) + .when(mHdmiControlServiceSpy).getCecDeviceTypes(); + + assertThat(mHdmiControlServiceSpy.readDeviceTypes()) + .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); + } + + @Test + public void readDeviceTypes_doesNotReadNullIntegerDeviceType() { + doReturn(Arrays.asList(new Integer[]{DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM, null})) + .when(mHdmiControlServiceSpy).getDeviceTypes(); + doReturn(Arrays.asList(new HdmiProperties.cec_device_types_values[]{})) + .when(mHdmiControlServiceSpy).getCecDeviceTypes(); + + assertThat(mHdmiControlServiceSpy.readDeviceTypes()) + .containsExactly(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM); + } + } |