summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michal Olech <molech@google.com> 2020-05-12 14:47:14 +0200
committer Michal Olech <molech@google.com> 2020-06-04 17:54:38 +0200
commit4fd720ad1b72240269a9891c0739239620199118 (patch)
treec50798a3fbcea4633aae31eee65a588c64424ab5
parent155d909a0811a383bd0f7d301d9cf28c5058cb4b (diff)
[CEC] <Active Source> on Routing Control
Wake up the playback device and optionally send <Active Source> on Routing Control messages Before the change: No response to <Routing Change> or <Routing Information> After the change: Device wakes up (and optionally sends <Active Source>) after receiving <Routing Change> or <Routing Information> with its physical address For better configurability, a "playback_device_action_on_routing_control" system property is introduced which controls what should be the behaviour of the device. Bug: 153950818 Test: flashed a playback device and inspected CEC messages Change-Id: I5ef3d624f5189dac91d3fd0211e16f00e7a6b77b
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java17
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java49
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java127
4 files changed, 195 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index ac3a65310d31..694f0d6fce40 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -483,6 +483,23 @@ final class Constants {
static final String PROPERTY_STRIP_AUDIO_TV_NO_SYSTEM_AUDIO =
"persist.sys.hdmi.property_strip_audio_tv_no_system_audio";
+ /**
+ * Determines playback device action upon receiving routing control messages.
+ * <ul>
+ * <li><b>none</b> No action taken.
+ * <li><b>wake_up_only</b> PowerManager.wakeUp() is called.
+ * <li><b>wake_up_and_send_active_source</b> Same as above and
+ * additionally <Active Source> is sent.
+ * </ul>
+ */
+ static final String PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL =
+ "ro.hdmi.cec.source.playback_device_action_on_routing_control";
+
+ static final String PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE = "none";
+ static final String PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_ONLY = "wake_up_only";
+ static final String PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_AND_SEND_ACTIVE_SOURCE =
+ "wake_up_and_send_active_source";
+
static final int RECORDING_TYPE_DIGITAL_RF = 1;
static final int RECORDING_TYPE_ANALOGUE_RF = 2;
static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 67861c28b37e..6f9ba182a711 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -63,6 +63,10 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
// TODO(amyjojo): adding system constants for input ports to TIF mapping.
private int mLocalActivePath = 0;
+ // Determines what action should be taken upon receiving Routing Control messages.
+ @VisibleForTesting
+ protected String mPlaybackDeviceActionOnRoutingControl;
+
HdmiCecLocalDevicePlayback(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);
@@ -71,6 +75,10 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
// The option is false by default. Update settings db as well to have the right
// initial setting on UI.
mService.writeBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, mAutoTvOff);
+
+ mPlaybackDeviceActionOnRoutingControl = SystemProperties.get(
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL,
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE);
}
@Override
@@ -334,6 +342,47 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
}
@Override
+ @ServiceThreadOnly
+ protected boolean handleRoutingChange(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams(), 2);
+ handleRoutingChangeAndInformation(physicalAddress, message);
+ return true;
+ }
+
+ @Override
+ @ServiceThreadOnly
+ protected boolean handleRoutingInformation(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+ handleRoutingChangeAndInformation(physicalAddress, message);
+ return true;
+ }
+
+ @Override
+ protected void handleRoutingChangeAndInformation(int physicalAddress, HdmiCecMessage message) {
+ if (physicalAddress != mService.getPhysicalAddress()) {
+ return; // Do nothing.
+ }
+ switch (mPlaybackDeviceActionOnRoutingControl) {
+ case Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_AND_SEND_ACTIVE_SOURCE:
+ setAndBroadcastActiveSource(message, physicalAddress);
+ break;
+ case Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_ONLY:
+ mService.wakeUp();
+ break;
+ case Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE:
+ break;
+ default:
+ Slog.w(TAG, "Invalid property '"
+ + Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL
+ + "' value: "
+ + mPlaybackDeviceActionOnRoutingControl);
+ break;
+ }
+ }
+
+ @Override
protected int findKeyReceiverAddress() {
return Constants.ADDR_TV;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index ae008b4bfa7a..5fe0be950974 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -199,7 +199,8 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
// do nothing
}
- // Source device with Switch functionality should implement this method.
+ // Only source devices that react to routing control messages should implement
+ // this method (e.g. a TV with built in switch).
// TODO(): decide which type will handle the routing when multi device type is supported
protected void handleRoutingChangeAndInformation(int physicalAddress, HdmiCecMessage message) {
// do nothing
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index b76211895ab0..f84284924008 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.hdmi;
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
@@ -109,6 +110,132 @@ public class HdmiCecLocalDevicePlaybackTest {
mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress);
}
+ @Test
+ public void handleRoutingChange_None() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isFalse();
+ assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
+ }
+
+ @Test
+ public void handleRoutingInformation_None() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_NONE;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isFalse();
+ assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
+ }
+
+ @Test
+ public void handleRoutingChange_WakeUpOnly() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_ONLY;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isTrue();
+ assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
+ }
+
+ @Test
+ public void handleRoutingInformation_WakeUpOnly() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_ONLY;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isTrue();
+ assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
+ }
+
+ @Test
+ public void handleRoutingChange_WakeUpAndSendActiveSource() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_AND_SEND_ACTIVE_SOURCE;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isTrue();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
+ @Test
+ public void handleRoutingInformation_WakeUpAndSendActiveSource() {
+ mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+ Constants.PLAYBACK_DEVICE_ACTION_ON_ROUTING_CONTROL_WAKE_UP_AND_SEND_ACTIVE_SOURCE;
+
+ mWokenUp = false;
+
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
+ mPlaybackPhysicalAddress);
+
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ mPlaybackPhysicalAddress);
+
+ assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message)).isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mWokenUp).isTrue();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
// Playback device does not handle routing control related feature right now
@Ignore("b/120845532")
@Test