Check camera-dictated aspect ratio on activities with desired orientation also.

Previously, camera aspect ratio was checked in orientation, so the apps that are already in portrait
windows would return early and camera compat aspect ratio would not be applied.

Flag: com.android.window.flags.enable_camera_compat_for_desktop_windowing
Test: atest WmTests:AppCompatAspectRatioPolicyTest
Test: atest WmTests:AppCompatCameraPolicyTest
Fixes: 376841066
Change-Id: If7e4f8037977241ff9473e799be3114f453692da
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java
index 548c0a3..fb7ce6b 100644
--- a/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioPolicy.java
@@ -70,15 +70,8 @@
         mAppCompatAspectRatioState.reset();
     }
 
-    float getDesiredAspectRatio(@NonNull Configuration newParentConfig,
+    private float getDesiredAspectRatio(@NonNull Configuration newParentConfig,
             @NonNull Rect parentBounds) {
-        // If in camera compat mode, aspect ratio from the camera compat policy has priority over
-        // default letterbox aspect ratio.
-        if (AppCompatCameraPolicy.shouldCameraCompatControlAspectRatio(
-                mActivityRecord)) {
-            return AppCompatCameraPolicy.getCameraCompatAspectRatio(mActivityRecord);
-        }
-
         final float letterboxAspectRatioOverride =
                 mAppCompatOverrides.getAppCompatAspectRatioOverrides()
                         .getFixedOrientationLetterboxAspectRatio(newParentConfig);
@@ -120,7 +113,16 @@
         if (mTransparentPolicy.isRunning()) {
             return mTransparentPolicy.getInheritedMinAspectRatio();
         }
+
         final ActivityInfo info = mActivityRecord.info;
+
+        // If in camera compat mode, aspect ratio from the camera compat policy has priority over
+        // the default aspect ratio.
+        if (AppCompatCameraPolicy.shouldCameraCompatControlAspectRatio(mActivityRecord)) {
+            return Math.max(AppCompatCameraPolicy.getCameraCompatMinAspectRatio(mActivityRecord),
+                    info.getMinAspectRatio());
+        }
+
         final AppCompatAspectRatioOverrides aspectRatioOverrides =
                 mAppCompatOverrides.getAppCompatAspectRatioOverrides();
         if (aspectRatioOverrides.shouldApplyUserMinAspectRatioOverride()) {
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
index 8c5689c1..8be66cc 100644
--- a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
@@ -234,7 +234,7 @@
     }
 
     // TODO(b/369070416): have policies implement the same interface.
-    static float getCameraCompatAspectRatio(@NonNull ActivityRecord activity) {
+    static float getCameraCompatMinAspectRatio(@NonNull ActivityRecord activity) {
         final AppCompatCameraPolicy cameraPolicy = getAppCompatCameraPolicy(activity);
         if (cameraPolicy == null) {
             return 1.0f;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 1c87802..a6c3fea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -87,6 +87,7 @@
 import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.times;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -4782,6 +4783,114 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+    public void testCameraCompatAspectRatioAppliedForFixedOrientationCameraActivities() {
+        // Needed to create camera compat policy in DisplayContent.
+        allowDesktopMode();
+        // Create display that has all stable insets and does not rotate.
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1080, 600)
+                .setSystemDecorations(true).setCanRotate(false).build();
+
+        final float cameraCompatAspectRatio = 4.0f;
+        setupCameraCompatAspectRatio(cameraCompatAspectRatio, display);
+
+        // Create task on test display.
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+
+        // Create fixed portrait activity.
+        final ActivityRecord fixedOrientationActivity = new ActivityBuilder(mAtm)
+                .setTask(task).setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT).build();
+        final Rect fixedOrientationAppBounds = new Rect(fixedOrientationActivity.getConfiguration()
+                .windowConfiguration.getAppBounds());
+
+        assertEquals(cameraCompatAspectRatio, computeAspectRatio(fixedOrientationAppBounds),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+    public void testCameraCompatAspectRatioForFixedOrientationCameraActivitiesPortraitWindow() {
+        // Needed to create camera compat policy in DisplayContent.
+        allowDesktopMode();
+        // Create portrait display that has all stable insets and does not rotate.
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1080, 1600)
+                .setSystemDecorations(true).setCanRotate(false).build();
+
+        final float cameraCompatAspectRatio = 4.0f;
+        setupCameraCompatAspectRatio(cameraCompatAspectRatio, display);
+
+        // Create task on test display.
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+
+        // Create fixed portrait activity.
+        final ActivityRecord fixedOrientationActivity = new ActivityBuilder(mAtm)
+                .setTask(task).setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT).build();
+        final Rect fixedOrientationAppBounds = new Rect(fixedOrientationActivity.getConfiguration()
+                .windowConfiguration.getAppBounds());
+
+        assertEquals(cameraCompatAspectRatio, computeAspectRatio(fixedOrientationAppBounds),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+    public void testCameraCompatAspectRatioAppliedInsteadOfDefaultAspectRatio() {
+        // Needed to create camera compat policy in DisplayContent.
+        allowDesktopMode();
+        // Create display that has all stable insets and does not rotate.
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1080, 600)
+                .setSystemDecorations(true).setCanRotate(false).build();
+
+        final float cameraCompatAspectRatio = 5.0f;
+        setupCameraCompatAspectRatio(cameraCompatAspectRatio, display);
+
+        // Create task on test display.
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+
+        // App's target min aspect ratio - this should not be used, as camera controls aspect ratio.
+        final float targetMinAspectRatio = 4.0f;
+
+        // Create fixed portrait activity with min aspect ratio greater than parent aspect ratio.
+        final ActivityRecord minAspectRatioActivity = new ActivityBuilder(mAtm)
+                .setTask(task).setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+                .setMinAspectRatio(targetMinAspectRatio).build();
+        final Rect minAspectRatioAppBounds = new Rect(minAspectRatioActivity.getConfiguration()
+                .windowConfiguration.getAppBounds());
+
+        assertEquals(cameraCompatAspectRatio, computeAspectRatio(minAspectRatioAppBounds),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+    public void testCameraCompatAspectRatio_defualtAspectRatioAppliedWhenGreater() {
+        // Needed to create camera compat policy in DisplayContent.
+        allowDesktopMode();
+        // Create display that has all stable insets and does not rotate.
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1080, 600)
+                .setSystemDecorations(true).setCanRotate(false).build();
+
+        final float cameraCompatAspectRatio = 5.0f;
+        setupCameraCompatAspectRatio(cameraCompatAspectRatio, display);
+
+        // Create task on test display.
+        final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
+
+        // App's target min aspect ratio bigger than camera compat aspect ratio - use that instead.
+        final float targetMinAspectRatio = 6.0f;
+
+        // Create fixed portrait activity with min aspect ratio greater than parent aspect ratio.
+        final ActivityRecord minAspectRatioActivity = new ActivityBuilder(mAtm)
+                .setTask(task).setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+                .setMinAspectRatio(targetMinAspectRatio).build();
+        final Rect minAspectRatioAppBounds = new Rect(minAspectRatioActivity.getConfiguration()
+                .windowConfiguration.getAppBounds());
+
+        assertEquals(targetMinAspectRatio, computeAspectRatio(minAspectRatioAppBounds),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+    }
+
+    @Test
     public void testUniversalResizeable() {
         mWm.mConstants.mIgnoreActivityOrientationRequest = true;
         setUpApp(mDisplayContent);
@@ -4851,6 +4960,25 @@
         assertEquals(newDensity, mActivity.getConfiguration().densityDpi);
     }
 
+    /**
+     * {@code canEnterDesktopMode} is called when {@link CameraCompatFreeformPolicy} is created in
+     * {@link AppCompatCameraPolicy}.
+     *
+     * <p>{@link #allowDesktopMode()} needs to be called before {@link DisplayContent} is created.
+     */
+    private void allowDesktopMode() {
+        doReturn(true).when(() -> DesktopModeHelper.canEnterDesktopMode(any()));
+    }
+
+    private void setupCameraCompatAspectRatio(float cameraCompatAspectRatio,
+            @NonNull DisplayContent display) {
+        CameraCompatFreeformPolicy cameraPolicy = display.mAppCompatCameraPolicy
+                .mCameraCompatFreeformPolicy;
+        spyOn(cameraPolicy);
+        doReturn(true).when(cameraPolicy).shouldCameraCompatControlAspectRatio(any());
+        doReturn(cameraCompatAspectRatio).when(cameraPolicy).getCameraCompatAspectRatio(any());
+    }
+
     private void setUpAllowThinLetterboxed(boolean thinLetterboxAllowed) {
         final AppCompatReachabilityOverrides reachabilityOverrides =
                 mActivity.mAppCompatController.getAppCompatReachabilityOverrides();