Letterbox: Display rounded corners behind navigation bar instead of above.

Also, scaling crop bounds when in SCM to avoid cropping more than necessary.

Fix: 201390999, 201573132
Test: atest WmTests:SizeCompatTests and manual
Change-Id: Ibf43bbdd444bb6df21cf42286fefd886558f236f
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index cf2afc9..c712c04 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -65,6 +65,10 @@
     private final LetterboxConfiguration mLetterboxConfiguration;
     private final ActivityRecord mActivityRecord;
 
+    // Taskbar expanded height. Used to determine whether to crop an app window to display rounded
+    // corners above the taskbar.
+    private float mExpandedTaskBarHeight;
+
     private boolean mShowWallpaperForLetterboxBackground;
 
     @Nullable
@@ -76,6 +80,8 @@
         // is created in its constructor. It shouldn't be used in this constructor but it's safe
         // to use it after since controller is only used in ActivityRecord.
         mActivityRecord = activityRecord;
+        mExpandedTaskBarHeight =
+                getResources().getDimensionPixelSize(R.dimen.taskbar_frame_height);
     }
 
     /** Cleans up {@link Letterbox} if it exists.*/
@@ -314,12 +320,27 @@
             final InsetsSource taskbarInsetsSource =
                     insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
 
-            Rect cropBounds = new Rect(mActivityRecord.getBounds());
-            // Activity bounds are in screen coordinates while (0,0) for activity's surface control
-            // is at the top left corner of an app window so offsetting bounds accordingly.
-            cropBounds.offsetTo(0, 0);
-            // Rounded cornerners should be displayed above the taskbar.
-            cropBounds.bottom = Math.min(cropBounds.bottom, taskbarInsetsSource.getFrame().top);
+            Rect cropBounds = null;
+
+            // Rounded corners should be displayed above the taskbar. When taskbar is hidden,
+            // an insets frame is equal to a navigation bar which shouldn't affect position of
+            // rounded corners since apps are expected to handle navigation bar inset.
+            // This condition checks whether the taskbar is visible.
+            if (taskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
+                cropBounds = new Rect(mActivityRecord.getBounds());
+                // Activity bounds are in screen coordinates while (0,0) for activity's surface
+                // control is at the top left corner of an app window so offsetting bounds
+                // accordingly.
+                cropBounds.offsetTo(0, 0);
+                // Rounded cornerners should be displayed above the taskbar.
+                cropBounds.bottom =
+                        Math.min(cropBounds.bottom, taskbarInsetsSource.getFrame().top);
+                if (mActivityRecord.inSizeCompatMode()
+                        && mActivityRecord.getSizeCompatScale() < 1.0f) {
+                    cropBounds.scale(1.0f / mActivityRecord.getSizeCompatScale());
+                }
+            }
+
             transaction
                     .setWindowCrop(windowSurface, cropBounds)
                     .setCornerRadius(windowSurface, getRoundedCorners(insetsState));