summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt2
-rw-r--r--services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java38
-rw-r--r--services/core/java/com/android/server/wm/AppCompatRoundedCorners.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java60
6 files changed, 108 insertions, 13 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 9b850de6fede..c5ee3137e5ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -33,6 +33,7 @@ import android.util.Size
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
+import kotlin.math.ceil
val DESKTOP_MODE_INITIAL_BOUNDS_SCALE: Float =
SystemProperties.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
@@ -190,22 +191,22 @@ fun maximizeSizeGivenAspectRatio(
val finalWidth: Int
// Get orientation either through top activity or task's orientation
if (taskInfo.hasPortraitTopActivity()) {
- val tempWidth = (targetHeight / aspectRatio).toInt()
+ val tempWidth = ceil(targetHeight / aspectRatio).toInt()
if (tempWidth <= targetWidth) {
finalHeight = targetHeight
finalWidth = tempWidth
} else {
finalWidth = targetWidth
- finalHeight = (finalWidth * aspectRatio).toInt()
+ finalHeight = ceil(finalWidth * aspectRatio).toInt()
}
} else {
- val tempWidth = (targetHeight * aspectRatio).toInt()
+ val tempWidth = ceil(targetHeight * aspectRatio).toInt()
if (tempWidth <= targetWidth) {
finalHeight = targetHeight
finalWidth = tempWidth
} else {
finalWidth = targetWidth
- finalHeight = (finalWidth / aspectRatio).toInt()
+ finalHeight = ceil(finalWidth / aspectRatio).toInt()
}
}
return Size(finalWidth, finalHeight + captionInsets)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index edb9b2d2fede..fbfdb79eaaec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -279,7 +279,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
private val DEFAULT_PORTRAIT_BOUNDS = Rect(200, 165, 1400, 2085)
private val RESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 435, 1575, 1635)
private val RESIZABLE_PORTRAIT_BOUNDS = Rect(680, 75, 1880, 1275)
- private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 449, 1575, 1611)
+ private val UNRESIZABLE_LANDSCAPE_BOUNDS = Rect(25, 448, 1575, 1611)
private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 75, 1730, 1275)
private val wallpaperToken = MockToken().token()
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
index dff072e2dcf8..600216440090 100644
--- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -48,6 +49,8 @@ import java.io.PrintWriter;
*/
class AppCompatLetterboxPolicy {
+ private static final int DIFF_TOLERANCE_PX = 1;
+
@NonNull
private final ActivityRecord mActivityRecord;
@NonNull
@@ -56,6 +59,9 @@ class AppCompatLetterboxPolicy {
private final AppCompatRoundedCorners mAppCompatRoundedCorners;
@NonNull
private final AppCompatConfiguration mAppCompatConfiguration;
+ // Convenience temporary object to save allocation when calculating Rect.
+ @NonNull
+ private final Rect mTmpRect = new Rect();
private boolean mLastShouldShowLetterboxUi;
@@ -71,7 +77,7 @@ class AppCompatLetterboxPolicy {
: new LegacyLetterboxPolicyState();
// TODO (b/358334569) Improve cutout logic dependency on app compat.
mAppCompatRoundedCorners = new AppCompatRoundedCorners(mActivityRecord,
- this::isLetterboxedNotForDisplayCutout);
+ this::ieEligibleForRoundedCorners);
mAppCompatConfiguration = appCompatConfiguration;
}
@@ -84,7 +90,7 @@ class AppCompatLetterboxPolicy {
mLetterboxPolicyState.stop();
}
- /** @return {@value true} if the letterbox policy is running and the activity letterboxed. */
+ /** @return {@code true} if the letterbox policy is running and the activity letterboxed. */
boolean isRunning() {
return mLetterboxPolicyState.isRunning();
}
@@ -130,7 +136,7 @@ class AppCompatLetterboxPolicy {
* <li>The activity is in fullscreen.
* <li>The activity is portrait-only.
* <li>The activity doesn't have a starting window (education should only be displayed
- * once the starting window is removed in {@link #removeStartingWindow}).
+ * once the starting window is removed in {@link ActivityRecord#removeStartingWindow}).
* </ul>
*/
boolean isEligibleForLetterboxEducation() {
@@ -294,16 +300,40 @@ class AppCompatLetterboxPolicy {
}
}
+ private boolean ieEligibleForRoundedCorners(@NonNull WindowState mainWindow) {
+ return isLetterboxedNotForDisplayCutout(mainWindow)
+ && !isFreeformActivityMatchParentAppBoundsHeight();
+ }
+
private boolean isLetterboxedNotForDisplayCutout(@NonNull WindowState mainWindow) {
return shouldShowLetterboxUi(mainWindow)
&& !mainWindow.isLetterboxedForDisplayCutout();
}
+ private boolean isFreeformActivityMatchParentAppBoundsHeight() {
+ if (!Flags.excludeCaptionFromAppBounds()) {
+ return false;
+ }
+ final Task task = mActivityRecord.getTask();
+ if (task == null) {
+ return false;
+ }
+ final Rect parentAppBounds = task.getWindowConfiguration().getAppBounds();
+ if (parentAppBounds == null) {
+ return false;
+ }
+
+ mLetterboxPolicyState.getLetterboxInnerBounds(mTmpRect);
+ final int diff = parentAppBounds.height() - mTmpRect.height();
+ // Compare bounds with tolerance of 1 px to account for rounding error calculations.
+ return task.getWindowingMode() == WINDOWING_MODE_FREEFORM && diff <= DIFF_TOLERANCE_PX;
+ }
+
private static boolean shouldNotLayoutLetterbox(@Nullable WindowState w) {
if (w == null) {
return true;
}
- final int type = w.mAttrs.type;
+ final int type = w.getAttrs().type;
// Allow letterbox to be displayed early for base application or application starting
// windows even if it is not on the top z order to prevent flickering when the
// letterboxed window is brought to the top
diff --git a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
index 92d76e5616d8..8165638d4bda 100644
--- a/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
+++ b/services/core/java/com/android/server/wm/AppCompatRoundedCorners.java
@@ -35,12 +35,12 @@ class AppCompatRoundedCorners {
@NonNull
private final ActivityRecord mActivityRecord;
@NonNull
- private final Predicate<WindowState> mIsLetterboxedNotForDisplayCutout;
+ private final Predicate<WindowState> mRoundedCornersWindowCondition;
AppCompatRoundedCorners(@NonNull ActivityRecord activityRecord,
- @NonNull Predicate<WindowState> isLetterboxedNotForDisplayCutout) {
+ @NonNull Predicate<WindowState> roundedCornersWindowCondition) {
mActivityRecord = activityRecord;
- mIsLetterboxedNotForDisplayCutout = isLetterboxedNotForDisplayCutout;
+ mRoundedCornersWindowCondition = roundedCornersWindowCondition;
}
void updateRoundedCornersIfNeeded(@NonNull final WindowState mainWindow) {
@@ -136,7 +136,7 @@ class AppCompatRoundedCorners {
private boolean requiresRoundedCorners(@NonNull final WindowState mainWindow) {
final AppCompatLetterboxOverrides letterboxOverrides = mActivityRecord
.mAppCompatController.getLetterboxOverrides();
- return mIsLetterboxedNotForDisplayCutout.test(mainWindow)
+ return mRoundedCornersWindowCondition.test(mainWindow)
&& letterboxOverrides.isLetterboxActivityCornersRounded();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index 018ea58e7120..d016e735f0c7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -151,6 +151,10 @@ class AppCompatActivityRobot {
doReturn(taskBounds).when(mTaskStack.top()).getBounds();
}
+ void configureTaskAppBounds(@NonNull Rect appBounds) {
+ mTaskStack.top().getWindowConfiguration().setAppBounds(appBounds);
+ }
+
void configureTopActivityBounds(@NonNull Rect activityBounds) {
doReturn(activityBounds).when(mActivityStack.top()).getBounds();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
index 0c310324ce67..2603d787ae37 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxPolicyTest.java
@@ -16,7 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -27,6 +29,7 @@ import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import android.graphics.Rect;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -40,6 +43,7 @@ import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.window.flags.Flags;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -225,6 +229,53 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
});
}
+ @Test
+ @EnableFlags(Flags.FLAG_EXCLUDE_CAPTION_FROM_APP_BOUNDS)
+ public void testGetRoundedCornersRadius_letterboxBoundsMatchHeightInFreeform_notRounded() {
+ runTestScenario((robot) -> {
+ robot.conf().setLetterboxActivityCornersRadius(15);
+ robot.configureWindowState();
+ robot.activity().createActivityWithComponent();
+ robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
+ robot.activity().setTopActivityVisible(/* isVisible */ true);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
+ robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
+ robot.resources().configureGetDimensionPixelSize(R.dimen.taskbar_frame_height, 20);
+
+ robot.activity().setTaskWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Rect appBounds = new Rect(0, 0, 100, 500);
+ robot.configureWindowStateFrame(appBounds);
+ robot.activity().configureTaskAppBounds(appBounds);
+
+ robot.startLetterbox();
+
+ robot.checkWindowStateRoundedCornersRadius(/* expected */ 0);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_EXCLUDE_CAPTION_FROM_APP_BOUNDS)
+ public void testGetRoundedCornersRadius_letterboxBoundsNotMatchHeightInFreeform_rounded() {
+ runTestScenario((robot) -> {
+ robot.conf().setLetterboxActivityCornersRadius(15);
+ robot.configureWindowState();
+ robot.activity().createActivityWithComponent();
+ robot.setTopActivityInLetterboxAnimation(/* inLetterboxAnimation */ false);
+ robot.activity().setTopActivityVisible(/* isVisible */ true);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(/* inLetterbox */ true);
+ robot.conf().setLetterboxActivityCornersRounded(/* rounded */ true);
+ robot.resources().configureGetDimensionPixelSize(R.dimen.taskbar_frame_height, 20);
+
+ robot.activity().setTaskWindowingMode(WINDOWING_MODE_FREEFORM);
+ robot.configureWindowStateFrame(new Rect(0, 0, 500, 200));
+ robot.activity().configureTaskAppBounds(new Rect(0, 0, 500, 500));
+
+ robot.startLetterbox();
+
+ robot.checkWindowStateRoundedCornersRadius(/* expected */ 15);
+ });
+ }
+
/**
* Runs a test scenario providing a Robot.
*/
@@ -265,6 +316,10 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
spyOn(getTransparentPolicy());
}
+ void startLetterbox() {
+ getAppCompatLetterboxPolicy().start(mWindowState);
+ }
+
void configureWindowStateWithTaskBar(boolean hasInsetsRoundedCorners) {
configureWindowState(/* withTaskBar */ true, hasInsetsRoundedCorners);
}
@@ -273,6 +328,10 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
configureWindowState(/* withTaskBar */ false, /* hasInsetsRoundedCorners */ false);
}
+ void configureWindowStateFrame(@NonNull Rect frame) {
+ doReturn(frame).when(mWindowState).getFrame();
+ }
+
void configureInsetsRoundedCorners(@NonNull RoundedCorners roundedCorners) {
mInsetsState.setRoundedCorners(roundedCorners);
}
@@ -290,6 +349,7 @@ public class AppCompatLetterboxPolicyTest extends WindowTestsBase {
}
mWindowState.mInvGlobalScale = 1f;
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
+ attrs.type = TYPE_BASE_APPLICATION;
doReturn(mInsetsState).when(mWindowState).getInsetsState();
doReturn(attrs).when(mWindowState).getAttrs();
doReturn(true).when(mWindowState).isDrawn();