Merge "Add setStreamPath handler and change isPhysicalAddressMeOrBelow logic."

This commit is contained in:
Shubang Lu
2019-01-09 01:26:01 +00:00
committed by Android (Google) Code Review
2 changed files with 103 additions and 32 deletions

View File

@@ -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;
@@ -147,6 +158,20 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
return true;
}
@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() {
@@ -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.
*
* <p>Return true if it does or if the two devices share the same physical address.
*
* <p>This check assumes both device physical address and target address are valid.
* Method to parse target physical address to the port number on the current device.
*
* <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>If the target device has the same physical address as the current device, return
* {@link #TARGET_SAME_PHYSICAL_ADDRESS}.
*
* <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;
}
return false;
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 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;
}
}

View File

@@ -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);
}
}