Read device types from ro.hdmi.cec_device_types.

Test: atest HdmiControlServiceTest
Bug: 185198967
Change-Id: Ic76b45e429159c29108f7694b6bcd57893cffd54
This commit is contained in:
Yan Han
2021-05-03 13:18:46 +02:00
parent d45c3c8ddc
commit e1a9dd9ea2
2 changed files with 144 additions and 8 deletions

View File

@@ -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(',');

View File

@@ -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;
@@ -826,4 +828,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);
}
}