Support rotation on secondary displays (1/N)

- Allow to apply rotation animation on non-default display.
- Separate by display:
    Rotation related timeout.
    Pause/resume rotation.
- Able to get/watch non-default display orientation/rotation.

Bug: 111361251
Test: atest FrameworksServicesTests:DisplayContentTests
Test: go/wm-smoke
Change-Id: I9533f1b90b9969d455b6dc235c5318e39f63ab12
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index ec068db..898ff4a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -35,6 +35,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -349,34 +351,36 @@
      */
     @Test
     public void testMaxUiWidth() throws Exception {
+        // Prevent base display metrics for test from being updated to the value of real display.
+        final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
         final int baseWidth = 1440;
         final int baseHeight = 2560;
         final int baseDensity = 300;
 
-        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+        displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
 
         final int maxWidth = 300;
         final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
         final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
 
-        mDisplayContent.setMaxUiWidth(maxWidth);
-        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+        displayContent.setMaxUiWidth(maxWidth);
+        verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
 
         // Assert setting values again does not change;
-        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
-        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+        displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+        verifySizes(displayContent, maxWidth, resultingHeight, resultingDensity);
 
         final int smallerWidth = 200;
         final int smallerHeight = 400;
         final int smallerDensity = 100;
 
         // Specify smaller dimension, verify that it is honored
-        mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
-        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+        displayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
+        verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
 
         // Verify that setting the max width to a greater value than the base width has no effect
-        mDisplayContent.setMaxUiWidth(maxWidth);
-        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+        displayContent.setMaxUiWidth(maxWidth);
+        verifySizes(displayContent, smallerWidth, smallerHeight, smallerDensity);
     }
 
     /**
@@ -463,22 +467,42 @@
     @Test
     public void testDisplayCutout_rot90() throws Exception {
         synchronized (sWm.getWindowManagerLock()) {
-            final DisplayContent dc = createNewDisplay();
-            dc.mInitialDisplayWidth = 200;
-            dc.mInitialDisplayHeight = 400;
-            Rect r1 = new Rect(80, 0, 120, 10);
+            // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
+            // if the device has no cutout).
+            final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
+            // Rotation may use real display info to compute bound, so here also uses the
+            // same width and height.
+            final int displayWidth = dc.mInitialDisplayWidth;
+            final int displayHeight = dc.mInitialDisplayHeight;
+            final int cutoutWidth = 40;
+            final int cutoutHeight = 10;
+            final int left = (displayWidth - cutoutWidth) / 2;
+            final int top = 0;
+            final int right = (displayWidth + cutoutWidth) / 2;
+            final int bottom = cutoutHeight;
+
+            final Rect r1 = new Rect(left, top, right, bottom);
             final DisplayCutout cutout = new WmDisplayCutout(
                     fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom), null)
-                    .computeSafeInsets(200, 400).getDisplayCutout();
+                    .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
 
             dc.mInitialDisplayCutout = cutout;
             dc.setRotation(Surface.ROTATION_90);
             dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
 
-            final Rect r = new Rect(0, 80, 10, 120);
+            // ----o----------      -------------
+            // |   |     |   |      |
+            // |   ------o   |      o---
+            // |             |      |  |
+            // |             |  ->  |  |
+            // |             |      ---o
+            // |             |      |
+            // |             |      -------------
+            final Rect r = new Rect(top, left, bottom, right);
             assertEquals(new WmDisplayCutout(
                     fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
-                    .computeSafeInsets(400, 200).getDisplayCutout(), dc.getDisplayInfo().displayCutout);
+                    .computeSafeInsets(displayHeight, displayWidth)
+                    .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
         }
     }
 
@@ -540,6 +564,16 @@
         assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
     }
 
+    /**
+     * Create DisplayContent that does not update display base/initial values from device to keep
+     * the values set by test.
+     */
+    private DisplayContent createDisplayNoUpdateDisplayInfo() {
+        final DisplayContent displayContent = spy(createNewDisplay());
+        doNothing().when(displayContent).updateDisplayInfo();
+        return displayContent;
+    }
+
     private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
         final LinkedList<WindowState> actualWindows = new LinkedList<>();