Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0f14bb7 authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge "Add setStreamPath handler and change isPhysicalAddressMeOrBelow logic."

parents 8c4d24f0 6a6d6182
Loading
Loading
Loading
Loading
+69 −16
Original line number Diff line number Diff line
@@ -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.
     * 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;
            }
        return false;
        }
        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;
    }
}
+33 −15
Original line number Diff line number Diff line
@@ -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);
    }
}