summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/hdmi/DeviceSelectAction.java15
-rwxr-xr-xservices/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java3
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java3
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecNetwork.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java1
-rw-r--r--services/core/java/com/android/server/hdmi/OneTouchPlayAction.java37
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java46
7 files changed, 96 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
index c23e2e691b55..947ee24f8e02 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
@@ -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) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index d8914b389191..bdc4e66cf7f9 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -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));
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 7235a921254d..90d64339eac0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index b748ae026cfc..7ceaa959212e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -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) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 115cafedca93..e6e2f9631d45 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -988,6 +988,7 @@ public class HdmiControlService extends SystemService {
return mCecController.getVendorId();
}
+ @Nullable
@ServiceThreadOnly
HdmiDeviceInfo getDeviceInfo(int logicalAddress) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 73ecbe0432b7..9d2db94cac8e 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -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;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
index 907cf3eb1f70..c61635cbd4b6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -136,7 +136,6 @@ public class OneTouchPlayActionTest {
mPhysicalAddress = 0x2000;
mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
mTestLooper.dispatchAll();
- mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
}
private OneTouchPlayAction createOneTouchPlayAction(HdmiCecLocalDevicePlayback device,
@@ -147,7 +146,47 @@ public class OneTouchPlayActionTest {
}
@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();