Merge "Guard against missing device info" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
abc4de09cc
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -988,6 +988,7 @@ public class HdmiControlService extends SystemService {
|
||||
return mCecController.getVendorId();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ServiceThreadOnly
|
||||
HdmiDeviceInfo getDeviceInfo(int logicalAddress) {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user