Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +75 −8 Original line number Diff line number Diff line Loading @@ -442,16 +442,83 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); List<Integer> deviceTypes = HdmiProperties.device_type(); 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( 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; mSettingsObserver = new SettingsObserver(mHandler); mHdmiCecConfig = new HdmiCecConfig(context); 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) { Loading services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +69 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } } Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +75 −8 Original line number Diff line number Diff line Loading @@ -442,16 +442,83 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); List<Integer> deviceTypes = HdmiProperties.device_type(); 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( 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; mSettingsObserver = new SettingsObserver(mHandler); mHdmiCecConfig = new HdmiCecConfig(context); 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) { Loading
services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +69 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } }