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

Commit 17c51c7b authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Track CEC version of CEC devices

Update tracked devices CEC version based on messages received by remote
devices.
Messages that can indicate CEC version are: <CEC Version>, <Report
Features>, <Report Power Status> (broadcast).

Bug: 169121287
Test: atest HdmiCecNetworkTest

Change-Id: I944dc1cdb93b32fb28fef4b2c111a08b232543c4
parent 6f69264f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -282,6 +282,8 @@ abstract class HdmiCecLocalDevice {
                return handleGiveOsdName(message);
            case Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID:
                return handleGiveDeviceVendorId(null);
            case Constants.MESSAGE_CEC_VERSION:
                return handleCecVersion();
            case Constants.MESSAGE_GET_CEC_VERSION:
                return handleGetCecVersion(message);
            case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS:
@@ -405,6 +407,14 @@ abstract class HdmiCecLocalDevice {
        return true;
    }

    @ServiceThreadOnly
    private boolean handleCecVersion() {
        assertRunOnServiceThread();

        // Return true to avoid <Feature Abort> responses. Cec Version is tracked in HdmiCecNetwork.
        return true;
    }

    @ServiceThreadOnly
    protected boolean handleActiveSource(HdmiCecMessage message) {
        return false;
+47 −2
Original line number Diff line number Diff line
@@ -166,7 +166,6 @@ public class HdmiCecNetwork {
        }
        return false;
    }

    /**
     * Clear all logical addresses registered in the device.
     *
@@ -523,8 +522,29 @@ public class HdmiCecNetwork {
            case Constants.MESSAGE_DEVICE_VENDOR_ID:
                handleDeviceVendorId(message);
                break;
            case Constants.MESSAGE_CEC_VERSION:
                handleCecVersion(message);
                break;
            case Constants.MESSAGE_REPORT_FEATURES:
                handleReportFeatures(message);
                break;
        }
    }

    @ServiceThreadOnly
    private void handleReportFeatures(HdmiCecMessage message) {
        assertRunOnServiceThread();

        int version = Byte.toUnsignedInt(message.getParams()[0]);
        updateDeviceCecVersion(message.getSource(), version);
    }

    @ServiceThreadOnly
    private void handleCecVersion(HdmiCecMessage message) {
        assertRunOnServiceThread();

        int version = Byte.toUnsignedInt(message.getParams()[0]);
        updateDeviceCecVersion(message.getSource(), version);
    }

    @ServiceThreadOnly
@@ -555,6 +575,31 @@ public class HdmiCecNetwork {
        // Update power status of device
        int newStatus = message.getParams()[0] & 0xFF;
        updateDevicePowerStatus(message.getSource(), newStatus);

        if (message.getDestination() == Constants.ADDR_BROADCAST) {
            updateDeviceCecVersion(message.getSource(), HdmiControlManager.HDMI_CEC_VERSION_2_0);
        }
    }

    @ServiceThreadOnly
    private void updateDeviceCecVersion(int logicalAddress, int hdmiCecVersion) {
        assertRunOnServiceThread();
        HdmiDeviceInfo deviceInfo = getCecDeviceInfo(logicalAddress);
        if (deviceInfo == null) {
            Slog.w(TAG, "Can not update CEC version of non-existing device:" + logicalAddress);
            return;
        }

        if (deviceInfo.getCecVersion() == hdmiCecVersion) {
            return;
        }

        HdmiDeviceInfo updatedDeviceInfo = new HdmiDeviceInfo(deviceInfo.getLogicalAddress(),
                deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(), deviceInfo.getDeviceType(),
                deviceInfo.getVendorId(),
                deviceInfo.getDisplayName(), deviceInfo.getDevicePowerStatus(),
                hdmiCecVersion);
        updateCecDevice(updatedDeviceInfo);
    }

    @ServiceThreadOnly
+12 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID;
import static com.android.server.hdmi.Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -264,4 +266,14 @@ public class HdmiCecLocalDeviceTest {

        assertFalse(result);
    }

    @Test
    public void handleCecVersion_isHandled() {
        boolean result = mHdmiLocalDevice.onMessage(
                HdmiCecMessageBuilder.buildCecVersion(ADDR_PLAYBACK_1, mHdmiLocalDevice.mAddress,
                        HdmiControlManager.HDMI_CEC_VERSION_1_4_b));

        assertThat(result).isTrue();
    }

}
+98 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
@@ -313,6 +314,7 @@ public class HdmiCecNetworkTest {
        int powerStatus = HdmiControlManager.POWER_STATUS_ON;
        String osdName = "Test Device";
        int vendorId = 1234;
        int cecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;

        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(logicalAddress,
@@ -325,6 +327,8 @@ public class HdmiCecNetworkTest {
                        Constants.ADDR_BROADCAST, osdName));
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildDeviceVendorIdCommand(logicalAddress, vendorId));
        mHdmiCecNetwork.handleCecMessage(HdmiCecMessageBuilder.buildCecVersion(logicalAddress,
                Constants.ADDR_BROADCAST, cecVersion));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

@@ -335,6 +339,7 @@ public class HdmiCecNetworkTest {
        assertThat(cecDeviceInfo.getDisplayName()).isEqualTo(osdName);
        assertThat(cecDeviceInfo.getVendorId()).isEqualTo(vendorId);
        assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(powerStatus);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(cecVersion);
    }

    @Test
@@ -374,16 +379,18 @@ public class HdmiCecNetworkTest {

        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportPowerStatus(logicalAddress,
                        Constants.ADDR_BROADCAST, powerStatus));
                        Constants.ADDR_TV, powerStatus));
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportPowerStatus(logicalAddress,
                        Constants.ADDR_BROADCAST, updatedPowerStatus));
                        Constants.ADDR_TV, updatedPowerStatus));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(updatedPowerStatus);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(
                HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
    }

    @Test
@@ -428,6 +435,8 @@ public class HdmiCecNetworkTest {
        assertThat(cecDeviceInfo.getVendorId()).isEqualTo(updatedVendorId);
        assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(
                HdmiControlManager.POWER_STATUS_UNKNOWN);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(
                HdmiControlManager.HDMI_CEC_VERSION_1_4_b);
    }

    @Test
@@ -446,4 +455,91 @@ public class HdmiCecNetworkTest {
                HdmiControlManager.DEVICE_EVENT_ADD_DEVICE,
                HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
    }

    @Test
    public void cecDevices_tracking_reportPowerStatus_broadcast_infersCec2() {
        int logicalAddress = Constants.ADDR_PLAYBACK_1;
        int powerStatus = HdmiControlManager.POWER_STATUS_ON;
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportPowerStatus(logicalAddress,
                        Constants.ADDR_BROADCAST, powerStatus));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getPhysicalAddress()).isEqualTo(
                Constants.INVALID_PHYSICAL_ADDRESS);
        assertThat(cecDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_RESERVED);
        assertThat(cecDeviceInfo.getVendorId()).isEqualTo(Constants.UNKNOWN_VENDOR_ID);
        assertThat(cecDeviceInfo.getDisplayName()).isEqualTo(
                HdmiUtils.getDefaultDeviceName(logicalAddress));
        assertThat(cecDeviceInfo.getDevicePowerStatus()).isEqualTo(powerStatus);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(
                HdmiControlManager.HDMI_CEC_VERSION_2_0);
    }

    @Test
    public void cecDevices_tracking_reportCecVersion_tracksCecVersion_cec14() {
        int logicalAddress = Constants.ADDR_PLAYBACK_1;
        int cecVersion = HdmiControlManager.HDMI_CEC_VERSION_1_4_b;
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildCecVersion(logicalAddress, Constants.ADDR_BROADCAST,
                        cecVersion));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(cecVersion);
    }

    @Test
    public void cecDevices_tracking_reportCecVersion_tracksCecVersion_cec20() {
        int logicalAddress = Constants.ADDR_PLAYBACK_1;
        int cecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildCecVersion(logicalAddress, Constants.ADDR_BROADCAST,
                        cecVersion));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(cecVersion);
    }

    @Test
    public void cecDevices_tracking_reportFeatures_tracksCecVersion_cec14() {
        int logicalAddress = Constants.ADDR_PLAYBACK_1;
        int cecVersion = HdmiControlManager.HDMI_CEC_VERSION_1_4_b;
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportFeatures(logicalAddress,
                        cecVersion, Collections.emptyList(),
                        Constants.RC_PROFILE_SOURCE, Collections.emptyList(),
                        Collections.emptyList()));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(cecVersion);
    }

    @Test
    public void cecDevices_tracking_reportFeatures_tracksCecVersion_cec20() {
        int logicalAddress = Constants.ADDR_PLAYBACK_1;
        int cecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
        mHdmiCecNetwork.handleCecMessage(
                HdmiCecMessageBuilder.buildReportFeatures(logicalAddress,
                        cecVersion, Collections.emptyList(),
                        Constants.RC_PROFILE_SOURCE, Collections.emptyList(),
                        Collections.emptyList()));

        assertThat(mHdmiCecNetwork.getSafeCecDevicesLocked()).hasSize(1);

        HdmiDeviceInfo cecDeviceInfo = mHdmiCecNetwork.getCecDeviceInfo(logicalAddress);
        assertThat(cecDeviceInfo.getLogicalAddress()).isEqualTo(logicalAddress);
        assertThat(cecDeviceInfo.getCecVersion()).isEqualTo(cecVersion);
    }
}