Support rotation on secondary displays (3/N)

Move major operations of rotation/orientation from
PhoneWindowManager to DisplayRotation.

Create DisplayPolicy and move partial fields which
have dependency with rotation.

Bug: 111361251
Test: go/wm-smoke
Test: atest FrameworksServicesTests:AppWindowTokenTests
Test: atest FrameworksServicesTests:PhoneWindowManagerLayoutTest
Test: atest CtsActivityManagerDeviceTestCases:ActivityManagerMultiDisplayTests
Change-Id: I2dfd15ffcc41e10a9074087e6aa15975c92b4979
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 605705e..ec2584b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -235,7 +235,8 @@
     private final DisplayInfo mDisplayInfo = new DisplayInfo();
     private final Display mDisplay;
     private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
-    final DisplayRotation mDisplayRotation;
+    private final DisplayPolicy mDisplayPolicy;
+    private DisplayRotation mDisplayRotation;
     DisplayFrames mDisplayFrames;
 
     /**
@@ -306,8 +307,11 @@
     private boolean mLayoutNeeded;
     int pendingLayoutChanges;
     int mDeferredRotationPauseCount;
+
     // TODO(multi-display): remove some of the usages.
+    @VisibleForTesting
     boolean isDefaultDisplay;
+
     /**
      * Flag indicating whether WindowManager should override info for this display in
      * DisplayManager.
@@ -764,7 +768,13 @@
         mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
                 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
         initializeDisplayBaseInfo();
-        mDisplayRotation = new DisplayRotation(this, mService.mPolicy, mService.mContext);
+        mDisplayPolicy = new DisplayPolicy(service);
+        mDisplayRotation = new DisplayRotation(service, this);
+        if (isDefaultDisplay) {
+            // The policy may be invoked right after here, so it requires the necessary default
+            // fields of this display content.
+            mService.mPolicy.setDefaultDisplay(this);
+        }
         mDividerControllerLocked = new DockedStackDividerController(service, this);
         mPinnedStackControllerLocked = new PinnedStackController(service, this);
 
@@ -921,11 +931,20 @@
         return mDisplayMetrics;
     }
 
+    DisplayPolicy getDisplayPolicy() {
+        return mDisplayPolicy;
+    }
+
     @Override
     public DisplayRotation getDisplayRotation() {
         return mDisplayRotation;
     }
 
+    @VisibleForTesting
+    void setDisplayRotation(DisplayRotation displayRotation) {
+        mDisplayRotation = displayRotation;
+    }
+
     int getRotation() {
         return mRotation;
     }
@@ -979,10 +998,7 @@
 
         mDeferredRotationPauseCount--;
         if (mDeferredRotationPauseCount == 0) {
-            final boolean changed = updateRotationUnchecked();
-            if (changed) {
-                mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
-            }
+            updateRotationAndSendNewConfigIfNeeded();
         }
     }
 
@@ -998,8 +1014,7 @@
         final int oldRotation = getRotation();
         final boolean oldAltOrientation = getAltOrientation();
 
-        final int rotation = mService.mPolicy.rotationForOrientationLw(
-                mDisplayRotation, lastOrientation, oldRotation);
+        final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
         final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
                 lastOrientation, rotation);
         if (oldRotation == rotation && oldAltOrientation == altOrientation) {
@@ -1009,6 +1024,19 @@
     }
 
     /**
+     * Update rotation of the display and send configuration if the rotation is changed.
+     *
+     * @return {@code true} if the rotation has been changed and the new config is sent.
+     */
+    boolean updateRotationAndSendNewConfigIfNeeded() {
+        final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
+        if (changed) {
+            mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
+        }
+        return changed;
+    }
+
+    /**
      * Update rotation of the display.
      *
      * @return {@code true} if the rotation has been changed.  In this case YOU MUST CALL
@@ -1066,8 +1094,7 @@
         final int oldRotation = mRotation;
         final int lastOrientation = mLastOrientation;
         final boolean oldAltOrientation = mAltOrientation;
-        final int rotation = mService.mPolicy.rotationForOrientationLw(mDisplayRotation,
-                lastOrientation, oldRotation);
+        final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
         if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
                 + mDisplayId + " based on lastOrientation=" + lastOrientation
                 + " and oldRotation=" + oldRotation);
@@ -1220,7 +1247,24 @@
     }
 
     void configureDisplayPolicy() {
-        mDisplayRotation.configure();
+        final int width = mBaseDisplayWidth;
+        final int height = mBaseDisplayHeight;
+        final int shortSize;
+        final int longSize;
+        if (width > height) {
+            shortSize = height;
+            longSize = width;
+        } else {
+            shortSize = width;
+            longSize = height;
+        }
+
+        final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+        final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+
+        mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
+        mDisplayPolicy.configure(width, height, shortSizeDp);
+
         mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
                 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
     }
@@ -2394,6 +2438,8 @@
         pw.println();
         mDisplayFrames.dump(prefix, pw);
         pw.println();
+        mDisplayPolicy.dump(prefix, pw);
+        pw.println();
         mDisplayRotation.dump(prefix, pw);
         pw.println();
         mInputMonitor.dump(pw, "  ");