summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java85
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java48
2 files changed, 102 insertions, 31 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 2ac04d1e2de0..6570493196f5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -60,6 +60,17 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
// AVR as audio receiver.
@ServiceThreadOnly private boolean mArcEstablished = false;
+ /**
+ * Return value of {@link #getLocalPortFromPhysicalAddress(int)}
+ */
+ private static final int TARGET_NOT_UNDER_LOCAL_DEVICE = -1;
+ private static final int TARGET_SAME_PHYSICAL_ADDRESS = 0;
+
+ // Local active port number used for Routing Control.
+ // Default 0 means HOME is the current active path. Temp solution only.
+ // TODO(amyjojo): adding system constants for Atom inputs port and TIF mapping.
+ private int mLocalActivePath = 0;
+
protected HdmiCecLocalDeviceAudioSystem(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mSystemAudioControlFeatureEnabled = true;
@@ -149,6 +160,20 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
@Override
@ServiceThreadOnly
+ protected boolean handleSetStreamPath(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+ // If current device is the target path, playback device should handle it.
+ // If the path is under the current device, should switch
+ int port = getLocalPortFromPhysicalAddress(physicalAddress);
+ if (port > 0) {
+ routeToPort(port);
+ }
+ return true;
+ }
+
+ @Override
+ @ServiceThreadOnly
protected int getPreferredAddress() {
assertRunOnServiceThread();
return SystemProperties.getInt(
@@ -396,7 +421,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
mService.wakeUp();
}
int targetPhysicalAddress = getActiveSource().physicalAddress;
- if (newSystemAudioMode && !isPhysicalAddressMeOrBelow(targetPhysicalAddress)) {
+ int port = getLocalPortFromPhysicalAddress(targetPhysicalAddress);
+ if (newSystemAudioMode && port >= 0) {
switchToAudioInput();
}
// TODO(b/80297700): Mute device when TV terminates the system audio control
@@ -411,27 +437,44 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
}
/**
- * Method to check if the target device belongs to the subtree of the current device or not.
+ * Method to parse target physical address to the port number on the current device.
*
- * <p>Return true if it does or if the two devices share the same physical address.
+ * <p>This check assumes target address is valid.
+ * @param targetPhysicalAddress is the physical address of the target device
+ * @return
+ * <p>If the target device is under the current device, return the port number of current device
+ * that the target device is connected to.
*
- * <p>This check assumes both device physical address and target address are valid.
+ * <p>If the target device has the same physical address as the current device, return
+ * {@link #TARGET_SAME_PHYSICAL_ADDRESS}.
*
- * @param targetPhysicalAddress is the physical address of the target device
+ * <p>If the target device is not under the current device, return
+ * {@link #TARGET_NOT_UNDER_LOCAL_DEVICE}.
*/
- protected boolean isPhysicalAddressMeOrBelow(int targetPhysicalAddress) {
+ protected int getLocalPortFromPhysicalAddress(int targetPhysicalAddress) {
int myPhysicalAddress = mService.getPhysicalAddress();
- int xor = targetPhysicalAddress ^ myPhysicalAddress;
- // Return true if two addresses are the same
- // or if they only differs for one byte, but not the first byte,
- // and myPhysicalAddress is 0 after that byte
- if (xor == 0
- || ((xor & 0x0f00) == xor && (myPhysicalAddress & 0x0fff) == 0)
- || ((xor & 0x00f0) == xor && (myPhysicalAddress & 0x00ff) == 0)
- || ((xor & 0x000f) == xor && (myPhysicalAddress & 0x000f) == 0)) {
- return true;
+ if (myPhysicalAddress == targetPhysicalAddress) {
+ return TARGET_SAME_PHYSICAL_ADDRESS;
+ }
+ int finalMask = 0xF000;
+ int mask;
+ int port = 0;
+ for (mask = 0x0F00; mask > 0x000F; mask >>= 4) {
+ if ((myPhysicalAddress & mask) == 0) {
+ port = mask & targetPhysicalAddress;
+ break;
+ } else {
+ finalMask |= mask;
+ }
+ }
+ if (finalMask != 0xFFFF && (finalMask & targetPhysicalAddress) == myPhysicalAddress) {
+ while (mask != 0x000F) {
+ mask >>= 4;
+ port >>= 4;
+ }
+ return port;
}
- return false;
+ return TARGET_NOT_UNDER_LOCAL_DEVICE;
}
protected void switchToAudioInput() {
@@ -529,4 +572,14 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
assertRunOnServiceThread();
mAutoDeviceOff = autoDeviceOff;
}
+
+ private void routeToPort(int portId) {
+ // TODO(AMYJOJO): route to specific input of the port
+ mLocalActivePath = portId;
+ }
+
+ @VisibleForTesting
+ protected int getLocalActivePath() {
+ return mLocalActivePath;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 5286104633e1..7e115f0028f7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -60,6 +60,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
private int mMusicVolume;
private int mMusicMaxVolume;
private boolean mMusicMute;
+ private int mAvrPhysicalAddress;
@Before
public void setUp() {
@@ -145,6 +146,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
mNativeWrapper.clearResultMessages();
+ mAvrPhysicalAddress = 0x2000;
+ mNativeWrapper.setPhysicalAddress(mAvrPhysicalAddress);
SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true");
}
@@ -386,42 +389,48 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
- public void isPhysicalAddressMeOrBelow_isMe() throws Exception {
+ public void pathToPort_isMe() throws Exception {
int targetPhysicalAddress = 0x1000;
mNativeWrapper.setPhysicalAddress(0x1000);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isTrue();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(0);
}
@Test
- public void isPhysicalAddressMeOrBelow_isBelow() throws Exception {
+ public void pathToPort_isBelow() throws Exception {
int targetPhysicalAddress = 0x1100;
mNativeWrapper.setPhysicalAddress(0x1000);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isTrue();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(1);
}
@Test
- public void isPhysicalAddressMeOrBelow_neitherMeNorBelow() throws Exception {
+ public void pathToPort_neitherMeNorBelow() throws Exception {
int targetPhysicalAddress = 0x3000;
mNativeWrapper.setPhysicalAddress(0x2000);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isFalse();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(-1);
targetPhysicalAddress = 0x2200;
mNativeWrapper.setPhysicalAddress(0x3300);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isFalse();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(-1);
targetPhysicalAddress = 0x2213;
mNativeWrapper.setPhysicalAddress(0x2212);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isFalse();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(-1);
targetPhysicalAddress = 0x2340;
mNativeWrapper.setPhysicalAddress(0x2310);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isFalse();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getLocalPortFromPhysicalAddress(targetPhysicalAddress))
+ .isEqualTo(-1);
}
@Test
@@ -513,4 +522,13 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
}
+
+ @Test
+ public void handleSetStreamPath_underCurrentDevice() {
+ assertThat(mHdmiCecLocalDeviceAudioSystem.getLocalActivePath()).isEqualTo(0);
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x2100);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetStreamPath(message)).isTrue();
+ assertThat(mHdmiCecLocalDeviceAudioSystem.getLocalActivePath()).isEqualTo(1);
+ }
}