Compatible behavior for non-resizable activity (1/N)

Introduce a fixed screen mode for non-resizable activity. If the
activity has fixed of orientation or aspect ratio, it can keep the
original configuration when the size of container is changed.

The original bounds and screen related attributes are set to the
override configuration. So when the activity meet:
 - Move to another display
 - Display size changed
The activity won't be relaunch or receive unexpected config changes.

The next CL will utilize this information to scale and offset the
windows of the non-resizable activity into the corresponding place
according to different use cases.

Bug: 112288258
Test: atest ActivityRecordTests
Change-Id: I5050f180e5d6c6c05514f0dc79102c0668c75c23
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 69f0012..fe42de1 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -1288,22 +1288,7 @@
                 || top == null) {
             return getRequestedOverrideConfiguration().orientation;
         }
-        int screenOrientation = top.getOrientation();
-        if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
-            // NOSENSOR means the display's "natural" orientation, so return that.
-            ActivityDisplay display = mStack != null ? mStack.getDisplay() : null;
-            if (display != null && display.mDisplayContent != null) {
-                return mStack.getDisplay().mDisplayContent.getNaturalOrientation();
-            }
-        } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
-            // LOCKED means the activity's orientation remains unchanged, so return existing value.
-            return top.getConfiguration().orientation;
-        } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation)) {
-            return ORIENTATION_LANDSCAPE;
-        } else if (ActivityInfo.isFixedOrientationPortrait(screenOrientation)) {
-            return ORIENTATION_PORTRAIT;
-        }
-        return ORIENTATION_UNDEFINED;
+        return top.getRequestedConfigurationOrientation();
     }
 
     /**
@@ -2084,6 +2069,11 @@
         return Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
     }
 
+    void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
+            @NonNull Configuration parentConfig) {
+        computeConfigResourceOverrides(inOutConfig, parentConfig, true /* insideParentBounds */);
+    }
+
     /**
      * Calculates configuration values used by the client to get resources. This should be run
      * using app-facing bounds (bounds unmodified by animations or transient interactions).
@@ -2093,7 +2083,7 @@
      * just be inherited from the parent configuration.
      **/
     void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
-            @NonNull Configuration parentConfig) {
+            @NonNull Configuration parentConfig, boolean insideParentBounds) {
         int windowingMode = inOutConfig.windowConfiguration.getWindowingMode();
         if (windowingMode == WINDOWING_MODE_UNDEFINED) {
             windowingMode = parentConfig.windowConfiguration.getWindowingMode();
@@ -2111,7 +2101,7 @@
             inOutConfig.windowConfiguration.setAppBounds(bounds);
             outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
         }
-        if (windowingMode != WINDOWING_MODE_FREEFORM) {
+        if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
             final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
             if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
                 outAppBounds.intersect(parentAppBounds);
@@ -2120,7 +2110,7 @@
 
         if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
                 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-            if (mStack != null) {
+            if (insideParentBounds && mStack != null) {
                 final DisplayInfo di = new DisplayInfo();
                 mStack.getDisplay().mDisplay.getDisplayInfo(di);
 
@@ -2135,12 +2125,16 @@
             }
 
             if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
-                inOutConfig.screenWidthDp = Math.min((int) (mTmpStableBounds.width() / density),
-                        parentConfig.screenWidthDp);
+                final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
+                inOutConfig.screenWidthDp = insideParentBounds
+                        ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
+                        : overrideScreenWidthDp;
             }
             if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-                inOutConfig.screenHeightDp = Math.min((int) (mTmpStableBounds.height() / density),
-                        parentConfig.screenHeightDp);
+                final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
+                inOutConfig.screenHeightDp = insideParentBounds
+                        ? Math.min(overrideScreenHeightDp, parentConfig.screenWidthDp)
+                        : overrideScreenHeightDp;
             }
 
             if (inOutConfig.smallestScreenWidthDp
@@ -2162,7 +2156,7 @@
 
         if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
             inOutConfig.orientation = (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
-                    ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
+                    ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
         }
         if (inOutConfig.screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
             // For calculating screen layout, we need to use the non-decor inset screen area for the