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

Commit 6a6d6182 authored by Amy's avatar Amy Committed by shubang
Browse files

Add setStreamPath handler and change isPhysicalAddressMeOrBelow logic.

cherry-pick ag/4824661

Test: com.android.server.hdmi
Change-Id: I2af5cc35d15b2d304f76786d4b1114a81ea90b9c
parent 9a66ff3c
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);
    }
}