Merge "Guard against missing device info" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-03-12 09:02:08 +00:00
committed by Android (Google) Code Review
7 changed files with 96 additions and 16 deletions

View File

@@ -97,11 +97,16 @@ final class DeviceSelectAction extends HdmiCecFeatureAction {
@Override
public boolean start() {
// Wake-up on <Set Stream Path> was not mandatory before CEC 2.0.
// The message is re-sent at the end of the action for devices that don't support 2.0.
sendSetStreamPath();
int targetPowerStatus = localDevice().mService.getHdmiCecNetwork()
.getCecDeviceInfo(getTargetAddress()).getDevicePowerStatus();
// Wake-up on <Set Stream Path> was not mandatory before CEC 2.0.
// The message is re-sent at the end of the action for devices that don't support 2.0.
sendSetStreamPath();
int targetPowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
HdmiDeviceInfo targetDevice = localDevice().mService.getHdmiCecNetwork().getCecDeviceInfo(
getTargetAddress());
if (targetDevice != null) {
targetPowerStatus = targetDevice.getDevicePowerStatus();
}
if (!mIsCec20 || targetPowerStatus == HdmiControlManager.POWER_STATUS_UNKNOWN) {
queryDevicePowerStatus();
} else if (targetPowerStatus == HdmiControlManager.POWER_STATUS_ON) {

View File

@@ -500,7 +500,8 @@ abstract class HdmiCecLocalDevice {
HdmiDeviceInfo cecDeviceInfo = mService.getHdmiCecNetwork().getCecDeviceInfo(address);
// If no non-default display name is available for the device, request the devices OSD name.
if (cecDeviceInfo.getDisplayName().equals(HdmiUtils.getDefaultDeviceName(address))) {
if (cecDeviceInfo != null && cecDeviceInfo.getDisplayName().equals(
HdmiUtils.getDefaultDeviceName(address))) {
mService.sendCecCommand(
HdmiCecMessageBuilder.buildGiveOsdNameCommand(mAddress, address));
}

View File

@@ -30,6 +30,7 @@ import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANAL
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
import android.annotation.Nullable;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
@@ -1147,6 +1148,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
&& getAvrDeviceInfo() != null;
}
@Nullable
@ServiceThreadOnly
HdmiDeviceInfo getAvrDeviceInfo() {
assertRunOnServiceThread();
@@ -1157,6 +1159,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return getSafeAvrDeviceInfo() != null;
}
@Nullable
HdmiDeviceInfo getSafeAvrDeviceInfo() {
return mService.getHdmiCecNetwork().getSafeCecDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
}

View File

@@ -185,6 +185,12 @@ public class HdmiCecNetwork {
mLocalDevices.clear();
}
/**
* Get the device info of a local device or a device in the CEC network by a device id.
* @param id id of the device to get
* @return the device with the given id, or {@code null}
*/
@Nullable
public HdmiDeviceInfo getDeviceInfo(int id) {
return mDeviceInfos.get(id);
}
@@ -717,6 +723,7 @@ public class HdmiCecNetwork {
* @return {@link HdmiDeviceInfo} matched with the given {@code logicalAddress}.
* Returns null if no logical address matched
*/
@Nullable
HdmiDeviceInfo getSafeCecDeviceInfo(int logicalAddress) {
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
if (info.isCecDevice() && info.getLogicalAddress() == logicalAddress) {

View File

@@ -988,6 +988,7 @@ public class HdmiControlService extends SystemService {
return mCecController.getVendorId();
}
@Nullable
@ServiceThreadOnly
HdmiDeviceInfo getDeviceInfo(int logicalAddress) {
assertRunOnServiceThread();

View File

@@ -16,6 +16,7 @@
package com.android.server.hdmi;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
import android.hardware.hdmi.IHdmiControlCallback;
import android.util.Slog;
@@ -62,8 +63,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
Slog.e(TAG, "Wrong arguments");
return null;
}
return new OneTouchPlayAction(source, targetAddress,
callback);
return new OneTouchPlayAction(source, targetAddress, callback);
}
private OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
@@ -71,8 +71,8 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
this(localDevice, targetAddress, callback,
localDevice.getDeviceInfo().getCecVersion()
>= HdmiControlManager.HDMI_CEC_VERSION_2_0
&& localDevice.mService.getHdmiCecNetwork().getCecDeviceInfo(
targetAddress).getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0);
&& getTargetCecVersion(localDevice, targetAddress)
>= HdmiControlManager.HDMI_CEC_VERSION_2_0);
}
@VisibleForTesting
@@ -88,9 +88,9 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
// Because only source device can create this action, it's safe to cast.
mSource = source();
sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
boolean targetOnBefore = localDevice().mService.getHdmiCecNetwork()
.getCecDeviceInfo(mTargetAddress).getDevicePowerStatus()
== HdmiControlManager.POWER_STATUS_ON;
boolean targetOnBefore = getTargetDevicePowerStatus(mSource, mTargetAddress,
HdmiControlManager.POWER_STATUS_UNKNOWN) == HdmiControlManager.POWER_STATUS_ON;
broadcastActiveSource();
// If the device is not an audio system itself, request the connected audio system to
// turn on.
@@ -98,8 +98,8 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
sendCommand(HdmiCecMessageBuilder.buildSystemAudioModeRequest(getSourceAddress(),
Constants.ADDR_AUDIO_SYSTEM, getSourcePath(), true));
}
int targetPowerStatus = localDevice().mService.getHdmiCecNetwork()
.getCecDeviceInfo(mTargetAddress).getDevicePowerStatus();
int targetPowerStatus = getTargetDevicePowerStatus(mSource, mTargetAddress,
HdmiControlManager.POWER_STATUS_UNKNOWN);
if (!mIsCec20 || targetPowerStatus == HdmiControlManager.POWER_STATUS_UNKNOWN) {
queryDevicePowerStatus();
} else if (targetPowerStatus == HdmiControlManager.POWER_STATUS_ON) {
@@ -179,4 +179,23 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
return sendStandbyOnSleep.equals(HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
}
private static int getTargetCecVersion(HdmiCecLocalDevice localDevice,
int targetLogicalAddress) {
HdmiDeviceInfo targetDevice = localDevice.mService.getHdmiCecNetwork().getCecDeviceInfo(
targetLogicalAddress);
if (targetDevice != null) {
return targetDevice.getCecVersion();
}
return HdmiControlManager.HDMI_CEC_VERSION_1_4_B;
}
private static int getTargetDevicePowerStatus(HdmiCecLocalDevice localDevice,
int targetLogicalAddress, int defaultPowerStatus) {
HdmiDeviceInfo targetDevice = localDevice.mService.getHdmiCecNetwork().getCecDeviceInfo(
targetLogicalAddress);
if (targetDevice != null) {
return targetDevice.getDevicePowerStatus();
}
return defaultPowerStatus;
}
}

View File

@@ -136,7 +136,6 @@ public class OneTouchPlayActionTest {
mPhysicalAddress = 0x2000;
mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
}
private OneTouchPlayAction createOneTouchPlayAction(HdmiCecLocalDevicePlayback device,
@@ -146,8 +145,48 @@ public class OneTouchPlayActionTest {
return action;
}
@Test
public void succeedWithUnknownTvDevice() {
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
mLocalDevices.add(playbackDevice);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
TestActionTimer actionTimer = new TestActionTimer();
TestCallback callback = new TestCallback();
OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
false);
playbackDevice.addAndStartAction(action);
mTestLooper.dispatchAll();
HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
playbackDevice.mAddress, mPhysicalAddress);
HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
ADDR_TV);
HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
.buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
mNativeWrapper.clearResultMessages();
assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
action.processCommand(reportPowerStatusOn);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
}
@Test
public void succeedAfterGettingPowerStatusOn_Cec14b() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
@@ -187,6 +226,7 @@ public class OneTouchPlayActionTest {
@Test
public void succeedAfterGettingTransientPowerStatus_Cec14b() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
@@ -236,6 +276,7 @@ public class OneTouchPlayActionTest {
@Test
public void timeOut_Cec14b() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
@@ -276,6 +317,7 @@ public class OneTouchPlayActionTest {
@Test
public void succeedIfPowerStatusOn_Cec20() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
@@ -307,6 +349,7 @@ public class OneTouchPlayActionTest {
@Test
public void succeedIfPowerStatusUnknown_Cec20() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();
@@ -348,6 +391,7 @@ public class OneTouchPlayActionTest {
@Test
public void succeedIfPowerStatusStandby_Cec20() {
mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
playbackDevice.init();