Merge "Fix signedness of DisplayAddress.Physical ports"
diff --git a/core/java/android/hardware/display/DisplayViewport.java b/core/java/android/hardware/display/DisplayViewport.java
index f2c50b5..5adf948 100644
--- a/core/java/android/hardware/display/DisplayViewport.java
+++ b/core/java/android/hardware/display/DisplayViewport.java
@@ -134,7 +134,9 @@
result += prime * result + deviceWidth;
result += prime * result + deviceHeight;
result += prime * result + uniqueId.hashCode();
- result += prime * result + physicalPort;
+ if (physicalPort != null) {
+ result += prime * result + physicalPort.hashCode();
+ }
result += prime * result + type;
return result;
}
@@ -142,11 +144,12 @@
// For debugging purposes.
@Override
public String toString() {
+ final Integer port = physicalPort == null ? null : Byte.toUnsignedInt(physicalPort);
return "DisplayViewport{type=" + typeToString(type)
+ ", valid=" + valid
+ ", displayId=" + displayId
+ ", uniqueId='" + uniqueId + "'"
- + ", physicalPort=" + physicalPort
+ + ", physicalPort=" + port
+ ", orientation=" + orientation
+ ", logicalFrame=" + logicalFrame
+ ", physicalFrame=" + physicalFrame
diff --git a/core/java/android/view/DisplayAddress.java b/core/java/android/view/DisplayAddress.java
index c8b7e25e..e0d9a4d 100644
--- a/core/java/android/view/DisplayAddress.java
+++ b/core/java/android/view/DisplayAddress.java
@@ -41,6 +41,18 @@
}
/**
+ * Creates an address for a physical display given its port and model.
+ *
+ * @param port A port in the range [0, 255] interpreted as signed.
+ * @param model A positive integer, or {@code null} if the model cannot be identified.
+ * @return The {@link Physical} address.
+ */
+ @NonNull
+ public static Physical fromPortAndModel(byte port, Long model) {
+ return new Physical(port, model);
+ }
+
+ /**
* Creates an address for a network display given its MAC address.
*
* @param macAddress A MAC address in colon notation.
@@ -64,12 +76,23 @@
public static final class Physical extends DisplayAddress {
private static final long UNKNOWN_MODEL = 0;
private static final int MODEL_SHIFT = 8;
- private static final int PORT_MASK = 0xFF;
private final long mPhysicalDisplayId;
/**
+ * Stable display ID combining port and model.
+ *
+ * @return An ID in the range [0, 2^64) interpreted as signed.
+ * @see SurfaceControl#getPhysicalDisplayIds
+ */
+ public long getPhysicalDisplayId() {
+ return mPhysicalDisplayId;
+ }
+
+ /**
* Physical port to which the display is connected.
+ *
+ * @return A port in the range [0, 255] interpreted as signed.
*/
public byte getPort() {
return (byte) mPhysicalDisplayId;
@@ -78,7 +101,7 @@
/**
* Model identifier unique across manufacturers.
*
- * @return The model ID, or {@code null} if the model cannot be identified.
+ * @return A positive integer, or {@code null} if the model cannot be identified.
*/
@Nullable
public Long getModel() {
@@ -95,7 +118,7 @@
@Override
public String toString() {
final StringBuilder builder = new StringBuilder("{")
- .append("port=").append(getPort() & PORT_MASK);
+ .append("port=").append(Byte.toUnsignedInt(getPort()));
final Long model = getModel();
if (model != null) {
@@ -119,6 +142,11 @@
mPhysicalDisplayId = physicalDisplayId;
}
+ private Physical(byte port, Long model) {
+ mPhysicalDisplayId = Byte.toUnsignedLong(port)
+ | (model == null ? UNKNOWN_MODEL : (model << MODEL_SHIFT));
+ }
+
public static final @NonNull Parcelable.Creator<Physical> CREATOR =
new Parcelable.Creator<Physical>() {
@Override
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index c4ea81a..1d7c942 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -848,7 +848,7 @@
int[] ports = res.getIntArray(
com.android.internal.R.array.config_localPrivateDisplayPorts);
if (ports != null) {
- int port = physicalAddress.getPort();
+ int port = Byte.toUnsignedInt(physicalAddress.getPort());
for (int p : ports) {
if (p == port) {
return true;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index df7c070..470a02e 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -642,7 +642,8 @@
if (mIdentifier == IDENTIFIER_PORT && displayInfo.address != null) {
// Config suggests using port as identifier for physical displays.
if (displayInfo.address instanceof DisplayAddress.Physical) {
- return "port:" + ((DisplayAddress.Physical) displayInfo.address).getPort();
+ byte port = ((DisplayAddress.Physical) displayInfo.address).getPort();
+ return "port:" + Byte.toUnsignedInt(port);
}
}
return displayInfo.uniqueId;
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 9e255fe..3518dc5 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -53,9 +53,12 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class LocalDisplayAdapterTest {
- private static final long HANDLER_WAIT_MS = 100;
+ private static final Long DISPLAY_MODEL = Long.valueOf(0xAAAAAAAAL);
+ private static final int PORT_A = 0;
+ private static final int PORT_B = 0x80;
+ private static final int PORT_C = 0xFF;
- private static final int PHYSICAL_DISPLAY_ID_MODEL_SHIFT = 8;
+ private static final long HANDLER_WAIT_MS = 100;
private StaticMockitoSession mMockitoSession;
@@ -74,7 +77,7 @@
private TestListener mListener = new TestListener();
- private LinkedList<Long> mDisplayIds = new LinkedList<>();
+ private LinkedList<DisplayAddress.Physical> mAddresses = new LinkedList<>();
@Before
public void setUp() throws Exception {
@@ -106,30 +109,22 @@
*/
@Test
public void testPrivateDisplay() throws Exception {
- // needs default one always
- final long displayId0 = 0;
- setUpDisplay(new DisplayConfig(displayId0, createDummyDisplayInfo()));
- final long displayId1 = 1;
- setUpDisplay(new DisplayConfig(displayId1, createDummyDisplayInfo()));
- final long displayId2 = 2;
- setUpDisplay(new DisplayConfig(displayId2, createDummyDisplayInfo()));
+ setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_A), createDummyDisplayInfo()));
+ setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_B), createDummyDisplayInfo()));
+ setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_C), createDummyDisplayInfo()));
updateAvailableDisplays();
- // display 1 should be marked as private while display 2 is not.
- doReturn(new int[]{(int) displayId1}).when(mMockedResources)
+ doReturn(new int[]{ PORT_B }).when(mMockedResources)
.getIntArray(com.android.internal.R.array.config_localPrivateDisplayPorts);
mAdapter.registerLocked();
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
// This should be public
- assertDisplay(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), displayId0,
- false);
+ assertDisplay(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false);
// This should be private
- assertDisplay(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), displayId1,
- true);
+ assertDisplay(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_B, true);
// This should be public
- assertDisplay(mListener.addedDisplays.get(2).getDisplayDeviceInfoLocked(), displayId2,
- false);
+ assertDisplay(mListener.addedDisplays.get(2).getDisplayDeviceInfoLocked(), PORT_C, false);
}
/**
@@ -137,11 +132,8 @@
*/
@Test
public void testPublicDisplaysForNoConfigLocalPrivateDisplayPorts() throws Exception {
- // needs default one always
- final long displayId0 = 0;
- setUpDisplay(new DisplayConfig(displayId0, createDummyDisplayInfo()));
- final long displayId1 = 1;
- setUpDisplay(new DisplayConfig(displayId1, createDummyDisplayInfo()));
+ setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_A), createDummyDisplayInfo()));
+ setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_C), createDummyDisplayInfo()));
updateAvailableDisplays();
// config_localPrivateDisplayPorts is null
mAdapter.registerLocked();
@@ -149,35 +141,36 @@
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
// This should be public
- assertDisplay(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), displayId0,
- false);
+ assertDisplay(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, false);
// This should be public
- assertDisplay(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), displayId1,
- false);
+ assertDisplay(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_C, false);
}
- private void assertDisplay(DisplayDeviceInfo info, long expectedPort, boolean shouldBePrivate) {
- DisplayAddress.Physical physical = (DisplayAddress.Physical) info.address;
- assertNotNull(physical);
- assertEquals(expectedPort, physical.getPort());
+ private static void assertDisplay(
+ DisplayDeviceInfo info, int expectedPort, boolean shouldBePrivate) {
+ final DisplayAddress.Physical address = (DisplayAddress.Physical) info.address;
+ assertNotNull(address);
+ assertEquals((byte) expectedPort, address.getPort());
+ assertEquals(DISPLAY_MODEL, address.getModel());
assertEquals(shouldBePrivate, (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0);
}
private class DisplayConfig {
- public final long displayId;
+ public final DisplayAddress.Physical address;
public final IBinder displayToken = new Binder();
public final SurfaceControl.PhysicalDisplayInfo displayInfo;
- private DisplayConfig(long displayId, SurfaceControl.PhysicalDisplayInfo displayInfo) {
- this.displayId = displayId | (0x1 << PHYSICAL_DISPLAY_ID_MODEL_SHIFT);
+ private DisplayConfig(
+ DisplayAddress.Physical address, SurfaceControl.PhysicalDisplayInfo displayInfo) {
+ this.address = address;
this.displayInfo = displayInfo;
}
}
private void setUpDisplay(DisplayConfig config) {
- mDisplayIds.add(config.displayId);
- doReturn(config.displayToken).when(
- () -> SurfaceControl.getPhysicalDisplayToken(config.displayId));
+ mAddresses.add(config.address);
+ doReturn(config.displayToken).when(() ->
+ SurfaceControl.getPhysicalDisplayToken(config.address.getPhysicalDisplayId()));
doReturn(new SurfaceControl.PhysicalDisplayInfo[]{
config.displayInfo
}).when(() -> SurfaceControl.getDisplayConfigs(config.displayToken));
@@ -192,16 +185,20 @@
}
private void updateAvailableDisplays() {
- long[] ids = new long[mDisplayIds.size()];
+ long[] ids = new long[mAddresses.size()];
int i = 0;
- for (long id : mDisplayIds) {
- ids[i] = id;
+ for (DisplayAddress.Physical address : mAddresses) {
+ ids[i] = address.getPhysicalDisplayId();
i++;
}
doReturn(ids).when(() -> SurfaceControl.getPhysicalDisplayIds());
}
- private SurfaceControl.PhysicalDisplayInfo createDummyDisplayInfo() {
+ private static DisplayAddress.Physical createDisplayAddress(int port) {
+ return DisplayAddress.fromPortAndModel((byte) port, DISPLAY_MODEL);
+ }
+
+ private static SurfaceControl.PhysicalDisplayInfo createDummyDisplayInfo() {
SurfaceControl.PhysicalDisplayInfo info = new SurfaceControl.PhysicalDisplayInfo();
info.density = 100;
info.xDpi = 100;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 4d2183b..8566412 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -80,6 +80,9 @@
@RunWith(WindowTestRunner.class)
public class DisplayWindowSettingsTests extends WindowTestsBase {
+ private static final byte DISPLAY_PORT = (byte) 0xFF;
+ private static final long DISPLAY_MODEL = 0xEEEEEEEEL;
+
private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
private DisplayWindowSettings mTarget;
@@ -479,10 +482,11 @@
@Test
public void testReadingDisplaySettingsFromStorage_UsePortAsId() {
- final DisplayAddress.Physical displayAddress = DisplayAddress.fromPhysicalDisplayId(123456);
+ final DisplayAddress.Physical displayAddress =
+ DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
mPrimaryDisplay.getDisplayInfo().address = displayAddress;
- final String displayIdentifier = "port:" + displayAddress.getPort();
+ final String displayIdentifier = "port:" + Byte.toUnsignedInt(DISPLAY_PORT);
prepareDisplaySettings(displayIdentifier, true /* usePortAsId */);
readAndAssertDisplaySettings(mPrimaryDisplay);
@@ -521,7 +525,8 @@
@Test
public void testWritingDisplaySettingsToStorage_UsePortAsId() throws Exception {
// Store config to use port as identifier.
- final DisplayAddress.Physical displayAddress = DisplayAddress.fromPhysicalDisplayId(123456);
+ final DisplayAddress.Physical displayAddress =
+ DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL);
mSecondaryDisplay.getDisplayInfo().address = displayAddress;
prepareDisplaySettings(null /* displayIdentifier */, true /* usePortAsId */);
@@ -532,7 +537,7 @@
assertTrue(mStorage.wasWriteSuccessful());
// Verify that settings were stored correctly.
- assertEquals("Attribute value must be stored", "port:" + displayAddress.getPort(),
+ assertEquals("Attribute value must be stored", "port:" + Byte.toUnsignedInt(DISPLAY_PORT),
getStoredDisplayAttributeValue("name"));
assertEquals("Attribute value must be stored", "true",
getStoredDisplayAttributeValue("shouldShowSystemDecors"));