Letterbox: Add rounded corners above a taskbar.
Previously rounded corners were applied to the whole app window regardless of the taskbar insets which resulted in bottom rounded corners being hidden behind the taskbar. This change fixes that by cropping activity surface at the taskbar top. Also, starts to determine corner radius automatically based on the device corners radii but leaves an option to override it with a config overlay for flexibility. Fix: 197549955 Test: atest WmTests:SizeCompatTests and manual Change-Id: Id687858bca3277f9f680f78d19c4fbc86d192b41
This commit is contained in:
@@ -4849,8 +4849,8 @@
|
||||
<item name="config_fixedOrientationLetterboxAspectRatio" format="float" type="dimen">0.0</item>
|
||||
|
||||
<!-- Corners radius for activity presented the letterbox mode. Values < 0 will be ignored and
|
||||
corners of the activity won't be rounded. -->
|
||||
<integer name="config_letterboxActivityCornersRadius">0</integer>
|
||||
min between device bottom corner radii will be used instead. -->
|
||||
<integer name="config_letterboxActivityCornersRadius">-1</integer>
|
||||
|
||||
<!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
|
||||
ignored and 0 is used. -->
|
||||
|
||||
@@ -174,7 +174,7 @@ final class LetterboxConfiguration {
|
||||
* Whether corners of letterboxed activities are rounded.
|
||||
*/
|
||||
boolean isLetterboxActivityCornersRounded() {
|
||||
return getLetterboxActivityCornersRadius() > 0;
|
||||
return getLetterboxActivityCornersRadius() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,9 @@ import android.graphics.Color;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Slog;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.InsetsState;
|
||||
import android.view.RoundedCorner;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
import android.view.WindowManager;
|
||||
@@ -295,31 +298,66 @@ final class LetterboxUiController {
|
||||
}
|
||||
|
||||
private void updateRoundedCorners(WindowState mainWindow) {
|
||||
int cornersRadius =
|
||||
// Don't round corners if letterboxed only for display cutout.
|
||||
shouldShowLetterboxUi(mainWindow)
|
||||
&& !mainWindow.isLetterboxedForDisplayCutout()
|
||||
? Math.max(0, mLetterboxConfiguration.getLetterboxActivityCornersRadius())
|
||||
: 0;
|
||||
setCornersRadius(mainWindow, cornersRadius);
|
||||
}
|
||||
|
||||
private void setCornersRadius(WindowState mainWindow, int cornersRadius) {
|
||||
final SurfaceControl windowSurface = mainWindow.getClientViewRootSurface();
|
||||
if (windowSurface != null && windowSurface.isValid()) {
|
||||
Transaction transaction = mActivityRecord.getSyncTransaction();
|
||||
transaction.setCornerRadius(windowSurface, cornersRadius);
|
||||
|
||||
if (!isLetterboxedNotForDisplayCutout(mainWindow)
|
||||
|| !mLetterboxConfiguration.isLetterboxActivityCornersRounded()) {
|
||||
transaction
|
||||
.setWindowCrop(windowSurface, null)
|
||||
.setCornerRadius(windowSurface, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
final InsetsState insetsState = mainWindow.getInsetsState();
|
||||
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);
|
||||
transaction
|
||||
.setWindowCrop(windowSurface, cropBounds)
|
||||
.setCornerRadius(windowSurface, getRoundedCorners(insetsState));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns rounded corners radius based on override in
|
||||
// R.integer.config_letterboxActivityCornersRadius or min device bottom corner radii.
|
||||
// Device corners can be different on the right and left sides but we use the same radius
|
||||
// for all corners for consistency and pick a minimal bottom one for consistency with a
|
||||
// taskbar rounded corners.
|
||||
private int getRoundedCorners(InsetsState insetsState) {
|
||||
if (mLetterboxConfiguration.getLetterboxActivityCornersRadius() >= 0) {
|
||||
return mLetterboxConfiguration.getLetterboxActivityCornersRadius();
|
||||
}
|
||||
return Math.min(
|
||||
getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_LEFT),
|
||||
getInsetsStateCornerRadius(insetsState, RoundedCorner.POSITION_BOTTOM_RIGHT));
|
||||
}
|
||||
|
||||
private int getInsetsStateCornerRadius(
|
||||
InsetsState insetsState, @RoundedCorner.Position int position) {
|
||||
RoundedCorner corner = insetsState.getRoundedCorners().getRoundedCorner(position);
|
||||
return corner == null ? 0 : corner.getRadius();
|
||||
}
|
||||
|
||||
private boolean isLetterboxedNotForDisplayCutout(WindowState mainWindow) {
|
||||
return shouldShowLetterboxUi(mainWindow)
|
||||
&& !mainWindow.isLetterboxedForDisplayCutout();
|
||||
}
|
||||
|
||||
private void updateWallpaperForLetterbox(WindowState mainWindow) {
|
||||
@LetterboxBackgroundType int letterboxBackgroundType =
|
||||
mLetterboxConfiguration.getLetterboxBackgroundType();
|
||||
boolean wallpaperShouldBeShown =
|
||||
letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
|
||||
&& shouldShowLetterboxUi(mainWindow)
|
||||
// Don't use wallpaper as a background if letterboxed for display cutout.
|
||||
&& !mainWindow.isLetterboxedForDisplayCutout()
|
||||
&& isLetterboxedNotForDisplayCutout(mainWindow)
|
||||
// Check that dark scrim alpha or blur radius are provided
|
||||
&& (getLetterboxWallpaperBlurRadius() > 0
|
||||
|| getLetterboxWallpaperDarkScrimAlpha() > 0)
|
||||
@@ -375,6 +413,8 @@ final class LetterboxUiController {
|
||||
pw.println(prefix + " letterboxBackgroundType="
|
||||
+ letterboxBackgroundTypeToString(
|
||||
mLetterboxConfiguration.getLetterboxBackgroundType()));
|
||||
pw.println(prefix + " letterboxCornerRadius="
|
||||
+ getRoundedCorners(mainWin.getInsetsState()));
|
||||
if (mLetterboxConfiguration.getLetterboxBackgroundType()
|
||||
== LETTERBOX_BACKGROUND_WALLPAPER) {
|
||||
pw.println(prefix + " isLetterboxWallpaperBlurSupported="
|
||||
|
||||
Reference in New Issue
Block a user