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

Commit 7c3f6d91 authored by Yan Han's avatar Yan Han
Browse files

Make TV query devices with unknown physical address

Currently, TVs only send <Give Physical Address> to devices detected in
a HotplugDetectionAction if they do not have a HdmiDeviceInfo in
HdmiCecNetwork.

This change ensures that the TV sends <Give Physical
Address> if the device has a HdmiDeviceInfo with a missing physical
address. This situation occurs because an empty HdmiDeviceInfo is
created when a message is received from an undiscovered device.

Test: atest HdmiCecLocalDeviceTvTest#hotplugDetectionAction_discoversDeviceAfterMessageReceived
Bug: 199027082
Change-Id: I584a78dde9ec28988447b8a15a2ccadbf1af9b19
parent 56244e07
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ import java.util.List;
final class HotplugDetectionAction extends HdmiCecFeatureAction {
    private static final String TAG = "HotPlugDetectionAction";

    private static final int POLLING_INTERVAL_MS_FOR_TV = 5000;
    public static final int POLLING_INTERVAL_MS_FOR_TV = 5000;
    public static final int POLLING_INTERVAL_MS_FOR_PLAYBACK = 60000;
    private static final int TIMEOUT_COUNT = 3;
    public static final int TIMEOUT_COUNT = 3;
    private static final int AVR_COUNT_MAX = 3;

    // State in which waits for next polling
@@ -155,8 +155,9 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction {
    }

    private void checkHotplug(List<Integer> ackedAddress, boolean audioOnly) {
        BitSet currentInfos = infoListToBitSet(
                localDevice().mService.getHdmiCecNetwork().getDeviceInfoList(false), audioOnly);
        List<HdmiDeviceInfo> deviceInfoList =
                localDevice().mService.getHdmiCecNetwork().getDeviceInfoList(false);
        BitSet currentInfos = infoListToBitSet(deviceInfoList, audioOnly, false);
        BitSet polledResult = addressListToBitSet(ackedAddress);

        // At first, check removed devices.
@@ -183,7 +184,8 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction {
        }

        // Next, check added devices.
        BitSet added = complement(polledResult, currentInfos);
        BitSet currentInfosWithPhysicalAddress = infoListToBitSet(deviceInfoList, audioOnly, true);
        BitSet added = complement(polledResult, currentInfosWithPhysicalAddress);
        index = -1;
        while ((index = added.nextSetBit(index + 1)) != -1) {
            Slog.v(TAG, "Add device by hot-plug detection:" + index);
@@ -191,14 +193,15 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction {
        }
    }

    private static BitSet infoListToBitSet(List<HdmiDeviceInfo> infoList, boolean audioOnly) {
    private static BitSet infoListToBitSet(
            List<HdmiDeviceInfo> infoList, boolean audioOnly, boolean requirePhysicalAddress) {
        BitSet set = new BitSet(NUM_OF_ADDRESS);
        for (HdmiDeviceInfo info : infoList) {
            if (audioOnly) {
                if (info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
                    set.set(info.getLogicalAddress());
                }
            } else {
            boolean audioOnlyConditionMet = !audioOnly
                    || (info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
            boolean requirePhysicalAddressConditionMet = !requirePhysicalAddress
                    || (info.getPhysicalAddress() != HdmiDeviceInfo.PATH_INVALID);
            if (audioOnlyConditionMet && requirePhysicalAddressConditionMet) {
                set.set(info.getLogicalAddress());
            }
        }
+28 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

@SmallTest
@RunWith(JUnit4.class)
@@ -522,4 +523,31 @@ public class HdmiCecLocalDeviceTvTest {

        verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
    }

    /**
     * Tests that receiving a message from a device does not prevent it from being discovered
     * by HotplugDetectionAction.
     */
    @Test
    public void hotplugDetectionAction_discoversDeviceAfterMessageReceived() {
        // Playback 1 sends a message before ACKing a poll
        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.NACK);
        HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildActiveSource(
                ADDR_PLAYBACK_1, ADDR_TV);
        mNativeWrapper.onCecMessage(hdmiCecMessage);
        mTestLooper.dispatchAll();

        // Playback 1 begins ACKing polls, allowing detection by HotplugDetectionAction
        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
        for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
            mTestLooper.moveTimeForward(
                    TimeUnit.SECONDS.toMillis(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV));
            mTestLooper.dispatchAll();
        }

        // Device sends <Give Physical Address> to Playback 1 after detecting it
        HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(
                ADDR_TV, ADDR_PLAYBACK_1);
        assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress);
    }
}