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

Commit 1c900231 authored by Yan Han's avatar Yan Han
Browse files

Add method to compute the relationship between two paths.

This is a helper function used to implement the initial set of Westworld
atoms.

Test: atest HdmiUtilsTest
Bug: 159796477

Change-Id: Ic21fa1a9b7bd93e0ae7e125601e532468fae7928
parent 56a78405
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -329,6 +329,30 @@ final class Constants {
    static final int INVALID_PHYSICAL_ADDRESS = HdmiDeviceInfo.PATH_INVALID;
    static final int PATH_INTERNAL = HdmiDeviceInfo.PATH_INTERNAL;

    // The relationship from one path (physical address) to another.
    @IntDef({
            PATH_RELATIONSHIP_UNKNOWN,
            PATH_RELATIONSHIP_DIFFERENT_BRANCH,
            PATH_RELATIONSHIP_ANCESTOR,
            PATH_RELATIONSHIP_DESCENDANT,
            PATH_RELATIONSHIP_SIBLING,
            PATH_RELATIONSHIP_SAME
    })
    @interface PathRelationship {}

    // One or both of the paths is invalid
    static final int PATH_RELATIONSHIP_UNKNOWN = 0;
    // None of the relationships below holds
    static final int PATH_RELATIONSHIP_DIFFERENT_BRANCH = 1;
    // A path is either the TV, or between the TV and another path
    static final int PATH_RELATIONSHIP_ANCESTOR = 2;
    // A path is located somewhere below another path
    static final int PATH_RELATIONSHIP_DESCENDANT = 3;
    // A path has the same parent as another path
    static final int PATH_RELATIONSHIP_SIBLING = 4;
    // A path is equal to another path
    static final int PATH_RELATIONSHIP_SAME = 5;

    // Strategy for device polling.
    // Should use "OR(|) operation of POLL_STRATEGY_XXX and POLL_ITERATION_XXX.
    static final int POLL_STRATEGY_MASK = 0x3; // first and second bit.
+37 −19
Original line number Diff line number Diff line
@@ -24,10 +24,11 @@ import android.util.Xml;

import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;

import com.android.server.hdmi.Constants.AbortReason;
import com.android.server.hdmi.Constants.AudioCodec;
import com.android.server.hdmi.Constants.FeatureOpcode;
import com.android.server.hdmi.Constants.PathRelationship;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

@@ -311,26 +312,43 @@ final class HdmiUtils {
     * @return true if the new path in the active routing path
     */
    static boolean isInActiveRoutingPath(int activePath, int newPath) {
        // Check each nibble of the currently active path and the new path till the position
        // where the active nibble is not zero. For (activePath, newPath),
        // (1.1.0.0, 1.0.0.0) -> true, new path is a parent
        // (1.2.1.0, 1.2.1.2) -> true, new path is a descendant
        // (1.1.0.0, 1.2.0.0) -> false, new path is a sibling
        // (1.0.0.0, 2.0.0.0) -> false, in a completely different path
        for (int i = 12; i >= 0; i -= 4) {
            int nibbleActive = (activePath >> i) & 0xF;
            if (nibbleActive == 0) {
                break;
        @PathRelationship int pathRelationship = pathRelationship(newPath, activePath);
        return (pathRelationship == Constants.PATH_RELATIONSHIP_ANCESTOR
                || pathRelationship == Constants.PATH_RELATIONSHIP_DESCENDANT
                || pathRelationship == Constants.PATH_RELATIONSHIP_SAME);
    }
            int nibbleNew = (newPath >> i) & 0xF;
            if (nibbleNew == 0) {
                break;

    /**
     * Computes the relationship from the first path to the second path.
     */
    static @PathRelationship int pathRelationship(int firstPath, int secondPath) {
        if (firstPath == Constants.INVALID_PHYSICAL_ADDRESS
                || secondPath == Constants.INVALID_PHYSICAL_ADDRESS) {
            return Constants.PATH_RELATIONSHIP_UNKNOWN;
        }
        // Loop forwards through both paths, looking for the first nibble where the paths differ.
        // Checking this nibble and the next one distinguishes between most possible relationships.
        for (int nibbleIndex = 0; nibbleIndex <= 3; nibbleIndex++) {
            int shift = 12 - nibbleIndex * 4;
            int firstPathNibble = (firstPath >> shift) & 0xF;
            int secondPathNibble = (secondPath >> shift) & 0xF;
            // Found the first nibble where the paths differ.
            if (firstPathNibble != secondPathNibble) {
                int firstPathNextNibble = (firstPath >> (shift - 4)) & 0xF;
                int secondPathNextNibble = (secondPath >> (shift - 4)) & 0xF;
                if (firstPathNibble == 0) {
                    return Constants.PATH_RELATIONSHIP_ANCESTOR;
                } else if (secondPathNibble == 0) {
                    return Constants.PATH_RELATIONSHIP_DESCENDANT;
                } else if (nibbleIndex == 3
                        || (firstPathNextNibble == 0 && secondPathNextNibble == 0)) {
                    return Constants.PATH_RELATIONSHIP_SIBLING;
                } else {
                    return Constants.PATH_RELATIONSHIP_DIFFERENT_BRANCH;
                }
            if (nibbleActive != nibbleNew) {
                return false;
            }
        }
        return true;
        return Constants.PATH_RELATIONSHIP_SAME;
    }

    /**
+90 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ package com.android.server.hdmi;

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

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.platform.test.annotations.Presubmit;
import android.util.Slog;

@@ -145,4 +148,91 @@ public class HdmiUtilsTest {

        assertThat(config).isEqualTo(expectedConfig);
    }

    @Test
    public void isAffectingActiveRoutingPath() {
        // New path alters the parent
        assertTrue(HdmiUtils.isAffectingActiveRoutingPath(0x1100, 0x2000));
        // New path is a sibling
        assertTrue(HdmiUtils.isAffectingActiveRoutingPath(0x1100, 0x1200));
        // New path is the descendant of a sibling
        assertFalse(HdmiUtils.isAffectingActiveRoutingPath(0x1100, 0x1210));
        // In a completely different path
        assertFalse(HdmiUtils.isAffectingActiveRoutingPath(0x1000, 0x3200));
    }

    @Test
    public void isInActiveRoutingPath() {
        // New path is a parent
        assertTrue(HdmiUtils.isInActiveRoutingPath(0x1100, 0x1000));
        // New path is a descendant
        assertTrue(HdmiUtils.isInActiveRoutingPath(0x1210, 0x1212));
        // New path is a sibling
        assertFalse(HdmiUtils.isInActiveRoutingPath(0x1100, 0x1200));
        // In a completely different path
        assertFalse(HdmiUtils.isInActiveRoutingPath(0x1000, 0x2000));
    }

    @Test
    public void pathRelationship_unknown() {
        assertThat(HdmiUtils.pathRelationship(0x1234, Constants.INVALID_PHYSICAL_ADDRESS))
                .isEqualTo(Constants.PATH_RELATIONSHIP_UNKNOWN);
        assertThat(HdmiUtils.pathRelationship(Constants.INVALID_PHYSICAL_ADDRESS, 0x1234))
                .isEqualTo(Constants.PATH_RELATIONSHIP_UNKNOWN);
        assertThat(HdmiUtils.pathRelationship(Constants.INVALID_PHYSICAL_ADDRESS,
                Constants.INVALID_PHYSICAL_ADDRESS))
                .isEqualTo(Constants.PATH_RELATIONSHIP_UNKNOWN);
    }

    @Test
    public void pathRelationship_differentBranch() {
        assertThat(HdmiUtils.pathRelationship(0x1200, 0x2000))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DIFFERENT_BRANCH);
        assertThat(HdmiUtils.pathRelationship(0x1234, 0x1224))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DIFFERENT_BRANCH);
        assertThat(HdmiUtils.pathRelationship(0x1234, 0x1134))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DIFFERENT_BRANCH);
        assertThat(HdmiUtils.pathRelationship(0x1234, 0x2234))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DIFFERENT_BRANCH);
    }

    @Test
    public void pathRelationship_ancestor() {
        assertThat(HdmiUtils.pathRelationship(0x0000, 0x1230))
                .isEqualTo(Constants.PATH_RELATIONSHIP_ANCESTOR);
        assertThat(HdmiUtils.pathRelationship(0x1000, 0x1230))
                .isEqualTo(Constants.PATH_RELATIONSHIP_ANCESTOR);
        assertThat(HdmiUtils.pathRelationship(0x1200, 0x1230))
                .isEqualTo(Constants.PATH_RELATIONSHIP_ANCESTOR);
    }

    @Test
    public void pathRelationship_descendant() {
        assertThat(HdmiUtils.pathRelationship(0x1230, 0x0000))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DESCENDANT);
        assertThat(HdmiUtils.pathRelationship(0x1230, 0x1000))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DESCENDANT);
        assertThat(HdmiUtils.pathRelationship(0x1230, 0x1200))
                .isEqualTo(Constants.PATH_RELATIONSHIP_DESCENDANT);
    }

    @Test
    public void pathRelationship_sibling() {
        assertThat(HdmiUtils.pathRelationship(0x1000, 0x2000))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SIBLING);
        assertThat(HdmiUtils.pathRelationship(0x1200, 0x1100))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SIBLING);
        assertThat(HdmiUtils.pathRelationship(0x1230, 0x1220))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SIBLING);
        assertThat(HdmiUtils.pathRelationship(0x1234, 0x1233))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SIBLING);
    }

    @Test
    public void pathRelationship_same() {
        assertThat(HdmiUtils.pathRelationship(0x0000, 0x0000))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SAME);
        assertThat(HdmiUtils.pathRelationship(0x1234, 0x1234))
                .isEqualTo(Constants.PATH_RELATIONSHIP_SAME);
    }
}