DisplayViewport should only have actual viewports (2/2)

Mapping actual logical displays to corresponding viewports.
The external viewport won't clone from internal if not exist.

Bug: 116850516
Test: atest DisplayManagerServiceTest
Change-Id: I9f1845f0389a463dd5d4c3fbcc09ad94cad6729b
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index cf8d21b..0a1a9a2 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1296,58 +1296,21 @@
             return;
         }
         display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
-
+        final int viewportType;
         // Update the corresponding viewport.
-        DisplayViewport internalViewport = getInternalViewportLocked();
         if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
-            populateViewportLocked(internalViewport, display, device);
-        }
-        DisplayViewport externalViewport = getExternalViewportLocked();
-        if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
-            populateViewportLocked(externalViewport, display, device);
-        } else if (!externalViewport.valid) {
-            // TODO (b/116850516) move this logic into InputReader
-            externalViewport.copyFrom(internalViewport);
-            externalViewport.type = DisplayViewport.VIEWPORT_EXTERNAL;
+            viewportType = VIEWPORT_INTERNAL;
+        } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
+            viewportType = VIEWPORT_EXTERNAL;
+        } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL
+                && !TextUtils.isEmpty(info.uniqueId)) {
+            viewportType = VIEWPORT_VIRTUAL;
+        } else {
+            Slog.wtf(TAG, "Unable to populate viewport for display device: " + info);
+            return;
         }
 
-        if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL && !TextUtils.isEmpty(info.uniqueId)) {
-            final DisplayViewport viewport = getVirtualViewportLocked(info.uniqueId);
-            populateViewportLocked(viewport, display, device);
-        }
-    }
-
-    /** Get the virtual device viewport that has the specified uniqueId.
-     * If such viewport does not exist, create it. */
-    private DisplayViewport getVirtualViewportLocked(@NonNull String uniqueId) {
-        DisplayViewport viewport;
-        final int count = mViewports.size();
-        for (int i = 0; i < count; i++) {
-            viewport = mViewports.get(i);
-            if (uniqueId.equals(viewport.uniqueId)) {
-                if (viewport.type != VIEWPORT_VIRTUAL) {
-                    Slog.wtf(TAG, "Found a viewport with uniqueId '"  + uniqueId
-                            + "' but it has type " + DisplayViewport.typeToString(viewport.type)
-                            + " (expected VIRTUAL)");
-                    continue;
-                }
-                return viewport;
-            }
-        }
-
-        viewport = new DisplayViewport();
-        viewport.uniqueId = uniqueId;
-        viewport.type = VIEWPORT_VIRTUAL;
-        mViewports.add(viewport);
-        return viewport;
-    }
-
-    private DisplayViewport getInternalViewportLocked() {
-        return getViewportByTypeLocked(VIEWPORT_INTERNAL);
-    }
-
-    private DisplayViewport getExternalViewportLocked() {
-        return getViewportByTypeLocked(VIEWPORT_EXTERNAL);
+        populateViewportLocked(viewportType, display.getDisplayIdLocked(), device, info.uniqueId);
     }
 
     /**
@@ -1355,35 +1318,44 @@
      * @param viewportType - either INTERNAL or EXTERNAL
      * @return the viewport with the requested type
      */
-    private DisplayViewport getViewportByTypeLocked(int viewportType) {
-        // Only allow a single INTERNAL or EXTERNAL viewport, which makes this function possible.
-        // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
-        // Creates the viewport if none exists.
-        if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL) {
+    private DisplayViewport getViewportLocked(int viewportType, String uniqueId) {
+        if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL
+                && viewportType != VIEWPORT_VIRTUAL) {
             Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type "
                     + DisplayViewport.typeToString(viewportType));
             return null;
         }
+
+        // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds
+        // to be identical (in particular, empty).
+        // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
+        if (viewportType != VIEWPORT_VIRTUAL) {
+            uniqueId = "";
+        }
+
         DisplayViewport viewport;
         final int count = mViewports.size();
         for (int i = 0; i < count; i++) {
             viewport = mViewports.get(i);
-            if (viewport.type == viewportType) {
+            if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) {
                 return viewport;
             }
         }
 
+        // Creates the viewport if none exists.
         viewport = new DisplayViewport();
         viewport.type = viewportType;
+        viewport.uniqueId = uniqueId;
         mViewports.add(viewport);
         return viewport;
     }
 
-    private static void populateViewportLocked(DisplayViewport viewport,
-            LogicalDisplay display, DisplayDevice device) {
-        viewport.valid = true;
-        viewport.displayId = display.getDisplayIdLocked();
+    private void populateViewportLocked(int viewportType,
+            int displayId, DisplayDevice device, String uniqueId) {
+        final DisplayViewport viewport = getViewportLocked(viewportType, uniqueId);
         device.populateViewportLocked(viewport);
+        viewport.valid = true;
+        viewport.displayId = displayId;
     }
 
     private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index e9bfa8f..abf9040 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -149,12 +149,11 @@
         verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
         List<DisplayViewport> viewports = viewportCaptor.getValue();
 
-        // Expect to receive 3 viewports: internal, external, and virtual
-        assertEquals(3, viewports.size());
+        // Expect to receive 2 viewports: internal, and virtual
+        assertEquals(2, viewports.size());
 
         DisplayViewport virtualViewport = null;
         DisplayViewport internalViewport = null;
-        DisplayViewport externalViewport = null;
         for (int i = 0; i < viewports.size(); i++) {
             DisplayViewport v = viewports.get(i);
             switch (v.type) {
@@ -163,7 +162,7 @@
                     break;
                 }
                 case DisplayViewport.VIEWPORT_EXTERNAL: {
-                    externalViewport = v;
+                    fail("EXTERNAL viewport should not exist.");
                     break;
                 }
                 case DisplayViewport.VIEWPORT_VIRTUAL: {
@@ -172,14 +171,12 @@
                 }
             }
         }
-        // INTERNAL and EXTERNAL viewports get created upon access
+        // INTERNAL viewport gets created upon access.
         assertNotNull(internalViewport);
-        assertNotNull(externalViewport);
         assertNotNull(virtualViewport);
 
-        // INTERNAL and EXTERNAL
+        // INTERNAL
         assertTrue(internalViewport.valid);
-        assertTrue(externalViewport.valid);
 
         // VIRTUAL
         assertEquals(height, virtualViewport.deviceHeight);
@@ -216,39 +213,16 @@
         verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
         List<DisplayViewport> viewports = viewportCaptor.getValue();
 
-        // Expect to receive 2 viewports: 1 internal, 1 external
-        assertEquals(2, viewports.size());
+        // Expect to receive actual viewports: 1 internal
+        assertEquals(1, viewports.size());
 
-        DisplayViewport internalViewport = null;
-        DisplayViewport externalViewport = null;
-        for (int i = 0; i < viewports.size(); i++) {
-            DisplayViewport v = viewports.get(i);
-            switch (v.type) {
-                case DisplayViewport.VIEWPORT_INTERNAL: {
-                    internalViewport = v;
-                    break;
-                }
-                case DisplayViewport.VIEWPORT_EXTERNAL: {
-                    externalViewport = v;
-                    break;
-                }
-                default: {
-                    fail("Unexpected viewport type: " + DisplayViewport.typeToString(v.type));
-                    break;
-                }
-            }
-        }
-        // INTERNAL and EXTERNAL viewports get created upon access
+        DisplayViewport internalViewport = viewports.get(0);
+
+        // INTERNAL is the only one actual display.
         assertNotNull(internalViewport);
-        assertNotNull(externalViewport);
+        assertEquals(DisplayViewport.VIEWPORT_INTERNAL, internalViewport.type);
         assertTrue(internalViewport.valid);
         assertEquals(displayId, internalViewport.displayId);
-
-        // To simplify comparison, override the type for external Viewport
-        // TODO (b/116850516) remove this
-        externalViewport.type = internalViewport.type;
-        assertEquals(internalViewport, externalViewport);
-        externalViewport.type = DisplayViewport.VIEWPORT_EXTERNAL; // undo the changes above
     }
 
     @Test