Loading services/core/java/com/android/server/hdmi/Constants.java +24 −0 Original line number Diff line number Diff line Loading @@ -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. Loading services/core/java/com/android/server/hdmi/HdmiUtils.java +37 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } /** Loading services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java +90 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading
services/core/java/com/android/server/hdmi/Constants.java +24 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
services/core/java/com/android/server/hdmi/HdmiUtils.java +37 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } /** Loading
services/tests/servicestests/src/com/android/server/hdmi/HdmiUtilsTest.java +90 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }