Introduce fixed rotation transform

It allows activity to be shown in an orientation different
from the current display. This initial change only handles
the case when transiting to another activity with different
orientation.

The opening activity and its process will be updated with
rotated configuration. The rotated display frames and insets
are also associated to the activity, then the activity can
be layouted in the rotated bounds. The surface of activity
is rotated to fit current display. And the display will be
rotated seamlessly until the transition is done.

The function is disabled by default. It can be enabled by:
adb shell settings put global fixed_rotation_transform 1

Bug: 143053092
Bug: 146415879
Bug: 147469351
Test: atest DisplayContentTests#testApplyTopFixedRotationTransform

Change-Id: Iea15c6fc68133728e5fcda87ba4efd1850fdf5d4
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 3b6816a..1a8f2a6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -995,6 +995,35 @@
     }
 
     @Test
+    public void testApplyTopFixedRotationTransform() {
+        mWm.mIsFixedRotationTransformEnabled = true;
+        final Configuration config90 = new Configuration();
+        mDisplayContent.getDisplayRotation().setRotation(ROTATION_90);
+        mDisplayContent.computeScreenConfiguration(config90);
+        mDisplayContent.onRequestedOverrideConfigurationChanged(config90);
+
+        final Configuration config = new Configuration();
+        mDisplayContent.getDisplayRotation().setRotation(Surface.ROTATION_0);
+        mDisplayContent.computeScreenConfiguration(config);
+        mDisplayContent.onRequestedOverrideConfigurationChanged(config);
+
+        final ActivityRecord app = mAppWindow.mActivityRecord;
+        mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
+                false /* alwaysKeepCurrent */);
+        mDisplayContent.mOpeningApps.add(app);
+        app.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertTrue(app.isFixedRotationTransforming());
+        assertEquals(config.orientation, mDisplayContent.getConfiguration().orientation);
+        assertEquals(config90.orientation, app.getConfiguration().orientation);
+
+        mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token);
+
+        assertFalse(app.hasFixedRotationTransform());
+        assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation);
+    }
+
+    @Test
     public void testRemoteRotation() {
         DisplayContent dc = createNewDisplay();