Merge "Add method to compute the relationship between two paths."

This commit is contained in:
Yan Han
2020-09-14 08:56:43 +00:00
committed by Android (Google) Code Review
3 changed files with 151 additions and 19 deletions

View File

@@ -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.

View File

@@ -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;
}
int nibbleNew = (newPath >> i) & 0xF;
if (nibbleNew == 0) {
break;
}
if (nibbleActive != nibbleNew) {
return false;
@PathRelationship int pathRelationship = pathRelationship(newPath, activePath);
return (pathRelationship == Constants.PATH_RELATIONSHIP_ANCESTOR
|| pathRelationship == Constants.PATH_RELATIONSHIP_DESCENDANT
|| pathRelationship == Constants.PATH_RELATIONSHIP_SAME);
}
/**
* 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;
}
}
}
return true;
return Constants.PATH_RELATIONSHIP_SAME;
}
/**

View File

@@ -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);
}
}