Merge "Refactor letterbox logic in separate classes." into sc-dev

This commit is contained in:
Mariia Sandrikova
2021-04-16 12:53:43 +00:00
committed by Android (Google) Code Review
8 changed files with 902 additions and 788 deletions

View File

@@ -189,6 +189,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
@@ -215,14 +216,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
import static com.android.server.wm.WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.letterboxBackgroundTypeToString;
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
@@ -268,7 +263,6 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -344,7 +338,6 @@ import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.Task.ActivityState;
import com.android.server.wm.WindowManagerService.H;
import com.android.server.wm.WindowManagerService.LetterboxBackgroundType;
import com.android.server.wm.utils.InsetUtils;
import com.google.android.collect.Sets;
@@ -645,7 +638,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
private boolean mWillCloseOrEnterPip;
private Letterbox mLetterbox;
@VisibleForTesting
final LetterboxUiController mLetterboxUiController;
/**
* The scale to fit at least one side of the activity to its parent. If the activity uses
@@ -674,8 +668,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Nullable
private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
private boolean mShowWallpaperForLetterboxBackground;
// activity is not displayed?
// TODO: rename to mNoDisplay
@VisibleForTesting
@@ -1103,61 +1095,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
pw.println(prefix + "lastParentTaskIdBeforePip=" + mLastParentBeforePip.mTaskId);
}
dumpLetterboxInfo(pw, prefix);
}
private void dumpLetterboxInfo(PrintWriter pw, String prefix) {
final WindowState mainWin = findMainWindow();
if (mainWin == null) {
return;
}
boolean areBoundsLetterboxed = mainWin.isLetterboxedAppWindow();
pw.println(prefix + "areBoundsLetterboxed=" + areBoundsLetterboxed);
if (!areBoundsLetterboxed) {
return;
}
pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
pw.println(prefix + " letterboxAspectRatio=" + computeAspectRatio(getBounds()));
boolean isLetterboxUiShown = isLetterboxed(mainWin);
pw.println(prefix + "isLetterboxUiShown=" + isLetterboxUiShown);
if (!isLetterboxUiShown) {
return;
}
pw.println(prefix + " letterboxBackgroundColor=" + Integer.toHexString(
getLetterboxBackgroundColor().toArgb()));
pw.println(prefix + " letterboxBackgroundType="
+ letterboxBackgroundTypeToString(mWmService.getLetterboxBackgroundType()));
if (mWmService.getLetterboxBackgroundType() == LETTERBOX_BACKGROUND_WALLPAPER) {
pw.println(prefix + " isLetterboxWallpaperBlurSupported="
+ isLetterboxWallpaperBlurSupported());
pw.println(prefix + " letterboxBackgroundWallpaperDarkScrimAlpha="
+ getLetterboxWallpaperDarkScrimAlpha());
pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
+ getLetterboxWallpaperBlurRadius());
}
pw.println(prefix + " letterboxHorizontalPositionMultiplier="
+ mWmService.getLetterboxHorizontalPositionMultiplier());
}
/**
* Returns a string representing the reason for letterboxing. This method assumes the activity
* is letterboxed.
*/
private String getLetterboxReasonString(WindowState mainWin) {
if (inSizeCompatMode()) {
return "SIZE_COMPAT_MODE";
}
if (isLetterboxedForFixedOrientationAndAspectRatio()) {
return "FIXED_ORIENTATION";
}
if (mainWin.isLetterboxedForDisplayCutout()) {
return "DISPLAY_CUTOUT";
}
return "UNKNOWN_REASON";
mLetterboxUiController.dump(pw, prefix);
}
void setAppTimeTracker(AppTimeTracker att) {
@@ -1446,183 +1384,29 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
if (mLetterbox != null) {
mLetterbox.onMovedToDisplay(mDisplayContent.getDisplayId());
}
mLetterboxUiController.onMovedToDisplay(mDisplayContent.getDisplayId());
}
// TODO(b/183754168): Move letterbox UI logic into a separate class.
void layoutLetterbox(WindowState winHint) {
final WindowState w = findMainWindow();
if (w == null || winHint != null && w != winHint) {
return;
}
final boolean surfaceReady = w.isDrawn() // Regular case
|| w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
updateRoundedCorners(w);
updateWallpaperForLetterbox(w);
if (needsLetterbox) {
if (mLetterbox == null) {
mLetterbox = new Letterbox(() -> makeChildSurface(null),
mWmService.mTransactionFactory,
mWmService::isLetterboxActivityCornersRounded,
this::getLetterboxBackgroundColor,
this::hasWallpaperBackgroudForLetterbox,
this::getLetterboxWallpaperBlurRadius,
this::getLetterboxWallpaperDarkScrimAlpha);
mLetterbox.attachInput(w);
}
getPosition(mTmpPoint);
// Get the bounds of the "space-to-fill". The transformed bounds have the highest
// priority because the activity is launched in a rotated environment. In multi-window
// mode, the task-level represents this. In fullscreen-mode, the task container does
// (since the orientation letterbox is also applied to the task).
final Rect transformedBounds = getFixedRotationTransformDisplayBounds();
final Rect spaceToFill = transformedBounds != null
? transformedBounds
: inMultiWindowMode()
? getRootTask().getBounds()
: getRootTask().getParent().getBounds();
mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
} else if (mLetterbox != null) {
mLetterbox.hide();
}
}
private Color getLetterboxBackgroundColor() {
final WindowState w = findMainWindow();
if (w == null || w.isLetterboxedForDisplayCutout()) {
return Color.valueOf(Color.BLACK);
}
@LetterboxBackgroundType int letterboxBackgroundType =
mWmService.getLetterboxBackgroundType();
switch (letterboxBackgroundType) {
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
return Color.valueOf(taskDescription.getBackgroundColorFloating());
}
break;
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
return Color.valueOf(taskDescription.getBackgroundColor());
}
break;
case LETTERBOX_BACKGROUND_WALLPAPER:
if (hasWallpaperBackgroudForLetterbox()) {
// Color is used for translucent scrim that dims wallpaper.
return Color.valueOf(Color.BLACK);
}
Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
+ "blur is not supported by a device or not supported in the current "
+ "window configuration or both alpha scrim and blur radius aren't "
+ "provided so using solid color background");
break;
case LETTERBOX_BACKGROUND_SOLID_COLOR:
return mWmService.getLetterboxBackgroundColor();
default:
throw new AssertionError(
"Unexpected letterbox background type: " + letterboxBackgroundType);
}
// If picked option configured incorrectly or not supported then default to a solid color
// background.
return mWmService.getLetterboxBackgroundColor();
}
/**
* @return {@code true} when the main window is letterboxed, this activity isn't transparent
* and doesn't show a wallpaper.
*/
@VisibleForTesting
boolean isLetterboxed(WindowState mainWindow) {
return mainWindow.isLetterboxedAppWindow() && fillsParent()
// Check for FLAG_SHOW_WALLPAPER explicitly instead of using
// WindowContainer#showWallpaper because the later will return true when this
// activity is using blurred wallpaper for letterbox backgroud.
&& (mainWindow.mAttrs.flags & FLAG_SHOW_WALLPAPER) == 0;
}
private void updateRoundedCorners(WindowState mainWindow) {
int cornersRadius =
// Don't round corners if letterboxed only for display cutout.
isLetterboxed(mainWindow) && !mainWindow.isLetterboxedForDisplayCutout()
? Math.max(0, mWmService.getLetterboxActivityCornersRadius()) : 0;
setCornersRadius(mainWindow, cornersRadius);
}
private void setCornersRadius(WindowState mainWindow, int cornersRadius) {
final SurfaceControl windowSurface = mainWindow.getClientViewRootSurface();
if (windowSurface != null && windowSurface.isValid()) {
Transaction transaction = getSyncTransaction();
transaction.setCornerRadius(windowSurface, cornersRadius);
}
mLetterboxUiController.layoutLetterbox(winHint);
}
boolean hasWallpaperBackgroudForLetterbox() {
return mShowWallpaperForLetterboxBackground;
}
private void updateWallpaperForLetterbox(WindowState mainWindow) {
@LetterboxBackgroundType int letterboxBackgroundType =
mWmService.getLetterboxBackgroundType();
boolean wallpaperShouldBeShown =
letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
&& isLetterboxed(mainWindow)
// Don't use wallpaper as a background if letterboxed for display cutout.
&& !mainWindow.isLetterboxedForDisplayCutout()
// Check that dark scrim alpha or blur radius are provided
&& (getLetterboxWallpaperBlurRadius() > 0
|| getLetterboxWallpaperDarkScrimAlpha() > 0)
// Check that blur is supported by a device if blur radius is provided.
&& (getLetterboxWallpaperBlurRadius() <= 0
|| isLetterboxWallpaperBlurSupported());
if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
requestUpdateWallpaperIfNeeded();
}
}
private int getLetterboxWallpaperBlurRadius() {
int blurRadius = mWmService.getLetterboxBackgroundWallpaperBlurRadius();
return blurRadius < 0 ? 0 : blurRadius;
}
private float getLetterboxWallpaperDarkScrimAlpha() {
float alpha = mWmService.getLetterboxBackgroundWallpaperDarkScrimAlpha();
// No scrim by default.
return (alpha < 0 || alpha >= 1) ? 0.0f : alpha;
}
private boolean isLetterboxWallpaperBlurSupported() {
return mWmService.mContext.getSystemService(WindowManager.class).isCrossWindowBlurEnabled();
return mLetterboxUiController.hasWallpaperBackgroudForLetterbox();
}
void updateLetterboxSurface(WindowState winHint) {
final WindowState w = findMainWindow();
if (w != winHint && winHint != null && w != null) {
return;
}
layoutLetterbox(winHint);
if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
mLetterbox.applySurfaceChanges(getSyncTransaction());
}
mLetterboxUiController.updateLetterboxSurface(winHint);
}
/** Gets the letterbox insets. The insets will be empty if there is no letterbox. */
Rect getLetterboxInsets() {
if (mLetterbox != null) {
return mLetterbox.getInsets();
} else {
return new Rect();
}
return mLetterboxUiController.getLetterboxInsets();
}
/** Gets the inner bounds of letterbox. The bounds will be empty if there is no letterbox. */
void getLetterboxInnerBounds(Rect outBounds) {
if (mLetterbox != null) {
outBounds.set(mLetterbox.getInnerFrame());
} else {
outBounds.setEmpty();
}
mLetterboxUiController.getLetterboxInnerBounds(outBounds);
}
/**
@@ -1630,7 +1414,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* when the current activity is displayed.
*/
boolean isFullyTransparentBarAllowed(Rect rect) {
return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
return mLetterboxUiController.isFullyTransparentBarAllowed(rect);
}
/**
@@ -1638,7 +1422,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* the given {@code rect}.
*/
boolean isLetterboxOverlappingWith(Rect rect) {
return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
return mLetterboxUiController.isLetterboxOverlappingWith(rect);
}
static class Token extends IApplicationToken.Stub {
@@ -1887,6 +1671,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mPersistentState = persistentState;
taskDescription = _taskDescription;
mLetterboxUiController = new LetterboxUiController(mWmService, this);
if (_createTime > 0) {
createTime = _createTime;
}
@@ -3718,10 +3505,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
dc.setFocusedApp(null);
mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
}
if (mLetterbox != null) {
mLetterbox.destroy();
mLetterbox = null;
}
mLetterboxUiController.destroy();
if (!delayed) {
updateReportedVisibilityLocked();
@@ -7149,7 +6934,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
offsetX = getHorizontalCenterOffset(
parentAppBounds.width(), screenResolvedBounds.width());
} else {
float positionMultiplier = mWmService.getLetterboxHorizontalPositionMultiplier();
float positionMultiplier =
mWmService.mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
positionMultiplier =
(positionMultiplier < 0.0f || positionMultiplier > 1.0f)
// Default to central position if invalid value is provided.
@@ -7222,7 +7008,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Override from config_fixedOrientationLetterboxAspectRatio or via ADB with
// set-fixed-orientation-letterbox-aspect-ratio.
final float letterboxAspectRatioOverride =
mWmService.getFixedOrientationLetterboxAspectRatio();
mWmService.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
aspect = letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
? letterboxAspectRatioOverride : aspect;
@@ -7740,7 +7526,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/**
* Returns the aspect ratio of the given {@code rect}.
*/
private static float computeAspectRatio(Rect rect) {
static float computeAspectRatio(Rect rect) {
final int width = rect.width();
final int height = rect.height();
if (width == 0 || height == 0) {

View File

@@ -0,0 +1,328 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Color;
import com.android.internal.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** Reads letterbox configs from resources and controls their overrides at runtime. */
final class LetterboxConfiguration {
/**
* Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
* set-fixed-orientation-letterbox-aspect-ratio or via {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
* if it is <= this value.
*/
static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
/** Enum for Letterbox background type. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
@interface LetterboxBackgroundType {};
/** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
/** Color specified in R.attr.colorBackground for the letterboxed application. */
static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND = 1;
/** Color specified in R.attr.colorBackgroundFloating for the letterboxed application. */
static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING = 2;
/** Using wallpaper as a background which can be blurred or dimmed with dark scrim. */
static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
final Context mContext;
// Aspect ratio of letterbox for fixed orientation, values <=
// MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
private float mFixedOrientationLetterboxAspectRatio;
// Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
private int mLetterboxActivityCornersRadius;
// Color for {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} letterbox background type.
private Color mLetterboxBackgroundColor;
@LetterboxBackgroundType
private int mLetterboxBackgroundType;
// Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
// Values <= 0 are ignored and 0 is used instead.
private int mLetterboxBackgroundWallpaperBlurRadius;
// Alpha of a black scrim shown over wallpaper letterbox background when
// LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
// Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
// Horizontal position of a center of the letterboxed app window. 0 corresponds to the left
// side of the screen and 1.0 to the right side.
private float mLetterboxHorizontalPositionMultiplier;
LetterboxConfiguration(Context context) {
mContext = context;
mFixedOrientationLetterboxAspectRatio = context.getResources().getFloat(
R.dimen.config_fixedOrientationLetterboxAspectRatio);
mLetterboxActivityCornersRadius = context.getResources().getInteger(
R.integer.config_letterboxActivityCornersRadius);
mLetterboxBackgroundColor = Color.valueOf(context.getResources().getColor(
R.color.config_letterboxBackgroundColor));
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(context);
mLetterboxBackgroundWallpaperBlurRadius = context.getResources().getDimensionPixelSize(
R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
mLetterboxBackgroundWallpaperDarkScrimAlpha = context.getResources().getFloat(
R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
mLetterboxHorizontalPositionMultiplier = context.getResources().getFloat(
R.dimen.config_letterboxHorizontalPositionMultiplier);
}
/**
* Overrides the aspect ratio of letterbox for fixed orientation. If given value is <= {@link
* #MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
* the framework implementation will be used to determine the aspect ratio.
*/
void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
mFixedOrientationLetterboxAspectRatio = aspectRatio;
}
/**
* Resets the aspect ratio of letterbox for fixed orientation to {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
*/
void resetFixedOrientationLetterboxAspectRatio() {
mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
}
/**
* Gets the aspect ratio of letterbox for fixed orientation.
*/
float getFixedOrientationLetterboxAspectRatio() {
return mFixedOrientationLetterboxAspectRatio;
}
/**
* Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
* both it and a value of {@link
* com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
* and corners of the activity won't be rounded.
*/
void setLetterboxActivityCornersRadius(int cornersRadius) {
mLetterboxActivityCornersRadius = cornersRadius;
}
/**
* Resets corners raidus for activities presented in the letterbox mode to {@link
* com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
*/
void resetLetterboxActivityCornersRadius() {
mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
com.android.internal.R.integer.config_letterboxActivityCornersRadius);
}
/**
* Whether corners of letterboxed activities are rounded.
*/
boolean isLetterboxActivityCornersRounded() {
return getLetterboxActivityCornersRadius() > 0;
}
/**
* Gets corners raidus for activities presented in the letterbox mode.
*/
int getLetterboxActivityCornersRadius() {
return mLetterboxActivityCornersRadius;
}
/**
* Gets color of letterbox background which is used when {@link
* #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
* fallback for other backfround types.
*/
Color getLetterboxBackgroundColor() {
return mLetterboxBackgroundColor;
}
/**
* Sets color of letterbox background which is used when {@link
* #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
* fallback for other backfround types.
*/
void setLetterboxBackgroundColor(Color color) {
mLetterboxBackgroundColor = color;
}
/**
* Resets color of letterbox background to {@link
* com.android.internal.R.color.config_letterboxBackgroundColor}.
*/
void resetLetterboxBackgroundColor() {
mLetterboxBackgroundColor = Color.valueOf(mContext.getResources().getColor(
com.android.internal.R.color.config_letterboxBackgroundColor));
}
/**
* Gets {@link LetterboxBackgroundType} specified in {@link
* com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
*/
@LetterboxBackgroundType
int getLetterboxBackgroundType() {
return mLetterboxBackgroundType;
}
/** Sets letterbox background type. */
void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
mLetterboxBackgroundType = backgroundType;
}
/**
* Resets cletterbox background type to {@link
* com.android.internal.R.integer.config_letterboxBackgroundType}.
*/
void resetLetterboxBackgroundType() {
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
}
/** Returns a string representing the given {@link LetterboxBackgroundType}. */
static String letterboxBackgroundTypeToString(
@LetterboxBackgroundType int backgroundType) {
switch (backgroundType) {
case LETTERBOX_BACKGROUND_SOLID_COLOR:
return "LETTERBOX_BACKGROUND_SOLID_COLOR";
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND";
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING";
case LETTERBOX_BACKGROUND_WALLPAPER:
return "LETTERBOX_BACKGROUND_WALLPAPER";
default:
return "unknown=" + backgroundType;
}
}
@LetterboxBackgroundType
private static int readLetterboxBackgroundTypeFromConfig(Context context) {
int backgroundType = context.getResources().getInteger(
com.android.internal.R.integer.config_letterboxBackgroundType);
return backgroundType == LETTERBOX_BACKGROUND_SOLID_COLOR
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING
|| backgroundType == LETTERBOX_BACKGROUND_WALLPAPER
? backgroundType : LETTERBOX_BACKGROUND_SOLID_COLOR;
}
/**
* Overrides alpha of a black scrim shown over wallpaper for {@link
* #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
*
* <p>If given value is < 0 or >= 1, both it and a value of {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
* and 0.0 (transparent) is instead.
*/
void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
}
/**
* Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
*/
void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
}
/**
* Gets alpha of a black scrim shown over wallpaper letterbox background.
*/
float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
return mLetterboxBackgroundWallpaperDarkScrimAlpha;
}
/**
* Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
* {@link mLetterboxBackgroundType}.
*
* <p> If given value <= 0, both it and a value of {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
* and 0 is used instead.
*/
void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
mLetterboxBackgroundWallpaperBlurRadius = radius;
}
/**
* Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
* mLetterboxBackgroundType} to {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
*/
void resetLetterboxBackgroundWallpaperBlurRadius() {
mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
}
/**
* Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
* mLetterboxBackgroundType}.
*/
int getLetterboxBackgroundWallpaperBlurRadius() {
return mLetterboxBackgroundWallpaperBlurRadius;
}
/*
* Gets horizontal position of a center of the letterboxed app window specified
* in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}
* or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
* right side.
*
* <p>This value can be outside of [0, 1] range so clients need to check and default to the
* central position (0.5).
*/
float getLetterboxHorizontalPositionMultiplier() {
return mLetterboxHorizontalPositionMultiplier;
}
/**
* Overrides horizontal position of a center of the letterboxed app window. If given value < 0
* or > 1, then it and a value of {@link
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
* central position (0.5) is used.
*/
void setLetterboxHorizontalPositionMultiplier(float multiplier) {
mLetterboxHorizontalPositionMultiplier = multiplier;
}
/**
* Resets horizontal position of a center of the letterboxed app window to {@link
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
*/
void resetLetterboxHorizontalPositionMultiplier() {
mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
}
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTypeToString;
import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Slog;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import java.io.PrintWriter;
/** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
// TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
// SizeCompatTests and LetterboxTests but not all.
// TODO(b/185264020): Consider making LetterboxUiController applicable to any level of the
// hierarchy in addition to ActivityRecord (Task, DisplayArea, ...).
final class LetterboxUiController {
private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
private final Point mTmpPoint = new Point();
private final LetterboxConfiguration mLetterboxConfiguration;
private final ActivityRecord mActivityRecord;
private boolean mShowWallpaperForLetterboxBackground;
@Nullable
private Letterbox mLetterbox;
LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
mLetterboxConfiguration = wmService.mLetterboxConfiguration;
// Given activityRecord may not be fully constructed since LetterboxUiController
// 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;
}
/** Cleans up {@link Letterbox} if it exists.*/
void destroy() {
if (mLetterbox != null) {
mLetterbox.destroy();
mLetterbox = null;
}
}
void onMovedToDisplay(int displayId) {
if (mLetterbox != null) {
mLetterbox.onMovedToDisplay(displayId);
}
}
boolean hasWallpaperBackgroudForLetterbox() {
return mShowWallpaperForLetterboxBackground;
}
/** Gets the letterbox insets. The insets will be empty if there is no letterbox. */
Rect getLetterboxInsets() {
if (mLetterbox != null) {
return mLetterbox.getInsets();
} else {
return new Rect();
}
}
/** Gets the inner bounds of letterbox. The bounds will be empty if there is no letterbox. */
void getLetterboxInnerBounds(Rect outBounds) {
if (mLetterbox != null) {
outBounds.set(mLetterbox.getInnerFrame());
} else {
outBounds.setEmpty();
}
}
/**
* @return {@code true} if bar shown within a given rectangle is allowed to be fully transparent
* when the current activity is displayed.
*/
boolean isFullyTransparentBarAllowed(Rect rect) {
return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
}
/**
* @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
* the given {@code rect}.
*/
boolean isLetterboxOverlappingWith(Rect rect) {
return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
}
void updateLetterboxSurface(WindowState winHint) {
final WindowState w = mActivityRecord.findMainWindow();
if (w != winHint && winHint != null && w != null) {
return;
}
layoutLetterbox(winHint);
if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
mLetterbox.applySurfaceChanges(mActivityRecord.getSyncTransaction());
}
}
void layoutLetterbox(WindowState winHint) {
final WindowState w = mActivityRecord.findMainWindow();
if (w == null || winHint != null && w != winHint) {
return;
}
final boolean surfaceReady = w.isDrawn() // Regular case
|| w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
updateRoundedCorners(w);
updateWallpaperForLetterbox(w);
if (needsLetterbox) {
if (mLetterbox == null) {
mLetterbox = new Letterbox(() -> mActivityRecord.makeChildSurface(null),
mActivityRecord.mWmService.mTransactionFactory,
mLetterboxConfiguration::isLetterboxActivityCornersRounded,
this::getLetterboxBackgroundColor,
this::hasWallpaperBackgroudForLetterbox,
this::getLetterboxWallpaperBlurRadius,
this::getLetterboxWallpaperDarkScrimAlpha);
mLetterbox.attachInput(w);
}
mActivityRecord.getPosition(mTmpPoint);
// Get the bounds of the "space-to-fill". The transformed bounds have the highest
// priority because the activity is launched in a rotated environment. In multi-window
// mode, the task-level represents this. In fullscreen-mode, the task container does
// (since the orientation letterbox is also applied to the task).
final Rect transformedBounds = mActivityRecord.getFixedRotationTransformDisplayBounds();
final Rect spaceToFill = transformedBounds != null
? transformedBounds
: mActivityRecord.inMultiWindowMode()
? mActivityRecord.getRootTask().getBounds()
: mActivityRecord.getRootTask().getParent().getBounds();
mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
} else if (mLetterbox != null) {
mLetterbox.hide();
}
}
/**
* @return {@code true} when the main window is letterboxed, this activity isn't transparent
* and doesn't show a wallpaper.
*/
@VisibleForTesting
boolean isLetterboxed(WindowState mainWindow) {
return mainWindow.isLetterboxedAppWindow() && mActivityRecord.fillsParent()
// Check for FLAG_SHOW_WALLPAPER explicitly instead of using
// WindowContainer#showWallpaper because the later will return true when this
// activity is using blurred wallpaper for letterbox backgroud.
&& (mainWindow.mAttrs.flags & FLAG_SHOW_WALLPAPER) == 0;
}
private Color getLetterboxBackgroundColor() {
final WindowState w = mActivityRecord.findMainWindow();
if (w == null || w.isLetterboxedForDisplayCutout()) {
return Color.valueOf(Color.BLACK);
}
@LetterboxBackgroundType int letterboxBackgroundType =
mLetterboxConfiguration.getLetterboxBackgroundType();
TaskDescription taskDescription = mActivityRecord.taskDescription;
switch (letterboxBackgroundType) {
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
return Color.valueOf(taskDescription.getBackgroundColorFloating());
}
break;
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
return Color.valueOf(taskDescription.getBackgroundColor());
}
break;
case LETTERBOX_BACKGROUND_WALLPAPER:
if (hasWallpaperBackgroudForLetterbox()) {
// Color is used for translucent scrim that dims wallpaper.
return Color.valueOf(Color.BLACK);
}
Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
+ "blur is not supported by a device or not supported in the current "
+ "window configuration or both alpha scrim and blur radius aren't "
+ "provided so using solid color background");
break;
case LETTERBOX_BACKGROUND_SOLID_COLOR:
return mLetterboxConfiguration.getLetterboxBackgroundColor();
default:
throw new AssertionError(
"Unexpected letterbox background type: " + letterboxBackgroundType);
}
// If picked option configured incorrectly or not supported then default to a solid color
// background.
return mLetterboxConfiguration.getLetterboxBackgroundColor();
}
private void updateRoundedCorners(WindowState mainWindow) {
int cornersRadius =
// Don't round corners if letterboxed only for display cutout.
isLetterboxed(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);
}
}
private void updateWallpaperForLetterbox(WindowState mainWindow) {
@LetterboxBackgroundType int letterboxBackgroundType =
mLetterboxConfiguration.getLetterboxBackgroundType();
boolean wallpaperShouldBeShown =
letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
&& isLetterboxed(mainWindow)
// Don't use wallpaper as a background if letterboxed for display cutout.
&& !mainWindow.isLetterboxedForDisplayCutout()
// Check that dark scrim alpha or blur radius are provided
&& (getLetterboxWallpaperBlurRadius() > 0
|| getLetterboxWallpaperDarkScrimAlpha() > 0)
// Check that blur is supported by a device if blur radius is provided.
&& (getLetterboxWallpaperBlurRadius() <= 0
|| isLetterboxWallpaperBlurSupported());
if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
mActivityRecord.requestUpdateWallpaperIfNeeded();
}
}
private int getLetterboxWallpaperBlurRadius() {
int blurRadius = mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius();
return blurRadius < 0 ? 0 : blurRadius;
}
private float getLetterboxWallpaperDarkScrimAlpha() {
float alpha = mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha();
// No scrim by default.
return (alpha < 0 || alpha >= 1) ? 0.0f : alpha;
}
private boolean isLetterboxWallpaperBlurSupported() {
return mLetterboxConfiguration.mContext.getSystemService(WindowManager.class)
.isCrossWindowBlurEnabled();
}
void dump(PrintWriter pw, String prefix) {
final WindowState mainWin = mActivityRecord.findMainWindow();
if (mainWin == null) {
return;
}
boolean areBoundsLetterboxed = mainWin.isLetterboxedAppWindow();
pw.println(prefix + "areBoundsLetterboxed=" + areBoundsLetterboxed);
if (!areBoundsLetterboxed) {
return;
}
pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
pw.println(prefix + " letterboxAspectRatio="
+ mActivityRecord.computeAspectRatio(mActivityRecord.getBounds()));
boolean isLetterboxUiShown = isLetterboxed(mainWin);
pw.println(prefix + "isLetterboxUiShown=" + isLetterboxUiShown);
if (!isLetterboxUiShown) {
return;
}
pw.println(prefix + " letterboxBackgroundColor=" + Integer.toHexString(
getLetterboxBackgroundColor().toArgb()));
pw.println(prefix + " letterboxBackgroundType="
+ letterboxBackgroundTypeToString(
mLetterboxConfiguration.getLetterboxBackgroundType()));
if (mLetterboxConfiguration.getLetterboxBackgroundType()
== LETTERBOX_BACKGROUND_WALLPAPER) {
pw.println(prefix + " isLetterboxWallpaperBlurSupported="
+ isLetterboxWallpaperBlurSupported());
pw.println(prefix + " letterboxBackgroundWallpaperDarkScrimAlpha="
+ getLetterboxWallpaperDarkScrimAlpha());
pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
+ getLetterboxWallpaperBlurRadius());
}
pw.println(prefix + " letterboxHorizontalPositionMultiplier="
+ mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
}
/**
* Returns a string representing the reason for letterboxing. This method assumes the activity
* is letterboxed.
*/
private String getLetterboxReasonString(WindowState mainWin) {
if (mActivityRecord.inSizeCompatMode()) {
return "SIZE_COMPAT_MODE";
}
if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) {
return "FIXED_ORIENTATION";
}
if (mainWin.isLetterboxedForDisplayCutout()) {
return "DISPLAY_CUTOUT";
}
return "UNKNOWN_REASON";
}
}

View File

@@ -159,7 +159,6 @@ import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
@@ -977,56 +976,7 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean mAnimationsDisabled = false;
boolean mPointerLocationEnabled = false;
/**
* Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
* set-fixed-orientation-letterbox-aspect-ratio or via {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
* if it is <= this value.
*/
static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
/** Enum for Letterbox background type. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
@interface LetterboxBackgroundType {};
/** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
/** Color specified in R.attr.colorBackground for the letterboxed application. */
static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND = 1;
/** Color specified in R.attr.colorBackgroundFloating for the letterboxed application. */
static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING = 2;
/** Using wallpaper as a background which can be blurred or dimmed with dark scrim. */
static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
// Aspect ratio of letterbox for fixed orientation, values <=
// MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
private float mFixedOrientationLetterboxAspectRatio;
// Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
private int mLetterboxActivityCornersRadius;
// Color for {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} letterbox background type.
private Color mLetterboxBackgroundColor;
@LetterboxBackgroundType
private int mLetterboxBackgroundType;
// Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
// Values <= 0 are ignored and 0 is used instead.
private int mLetterboxBackgroundWallpaperBlurRadius;
// Alpha of a black scrim shown over wallpaper letterbox background when
// LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
// Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
// horizontal position of a center of the letterboxed app window. 0 corresponds to the left
// side of the screen and 1.0 to the right side.
private float mLetterboxHorizontalPositionMultiplier;
final LetterboxConfiguration mLetterboxConfiguration;
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
@@ -1258,19 +1208,7 @@ public class WindowManagerService extends IWindowManager.Stub
mAssistantOnTopOfDream = context.getResources().getBoolean(
com.android.internal.R.bool.config_assistantOnTopOfDream);
mFixedOrientationLetterboxAspectRatio = context.getResources().getFloat(
com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
mLetterboxActivityCornersRadius = context.getResources().getInteger(
com.android.internal.R.integer.config_letterboxActivityCornersRadius);
mLetterboxBackgroundColor = Color.valueOf(context.getResources().getColor(
com.android.internal.R.color.config_letterboxBackgroundColor));
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(context);
mLetterboxBackgroundWallpaperBlurRadius = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
mLetterboxBackgroundWallpaperDarkScrimAlpha = context.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
mLetterboxHorizontalPositionMultiplier = context.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
mLetterboxConfiguration = new LetterboxConfiguration(context);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
@@ -3869,233 +3807,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
/**
* Overrides the aspect ratio of letterbox for fixed orientation. If given value is <= {@link
* #MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
* the framework implementation will be used to determine the aspect ratio.
*/
void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
mFixedOrientationLetterboxAspectRatio = aspectRatio;
}
/**
* Resets the aspect ratio of letterbox for fixed orientation to {@link
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
*/
void resetFixedOrientationLetterboxAspectRatio() {
mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
}
/**
* Gets the aspect ratio of letterbox for fixed orientation.
*/
float getFixedOrientationLetterboxAspectRatio() {
return mFixedOrientationLetterboxAspectRatio;
}
/**
* Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
* both it and a value of {@link
* com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
* and corners of the activity won't be rounded.
*/
void setLetterboxActivityCornersRadius(int cornersRadius) {
mLetterboxActivityCornersRadius = cornersRadius;
}
/**
* Resets corners raidus for activities presented in the letterbox mode to {@link
* com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
*/
void resetLetterboxActivityCornersRadius() {
mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
com.android.internal.R.integer.config_letterboxActivityCornersRadius);
}
/**
* Whether corners of letterboxed activities are rounded.
*/
boolean isLetterboxActivityCornersRounded() {
return getLetterboxActivityCornersRadius() > 0;
}
/**
* Gets corners raidus for activities presented in the letterbox mode.
*/
int getLetterboxActivityCornersRadius() {
return mLetterboxActivityCornersRadius;
}
/**
* Gets color of letterbox background which is used when {@link
* #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
* fallback for other backfround types.
*/
Color getLetterboxBackgroundColor() {
return mLetterboxBackgroundColor;
}
/**
* Sets color of letterbox background which is used when {@link
* #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
* fallback for other backfround types.
*/
void setLetterboxBackgroundColor(Color color) {
mLetterboxBackgroundColor = color;
}
/**
* Resets color of letterbox background to {@link
* com.android.internal.R.color.config_letterboxBackgroundColor}.
*/
void resetLetterboxBackgroundColor() {
mLetterboxBackgroundColor = Color.valueOf(mContext.getResources().getColor(
com.android.internal.R.color.config_letterboxBackgroundColor));
}
/**
* Gets {@link LetterboxBackgroundType} specified in {@link
* com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
*/
@LetterboxBackgroundType
int getLetterboxBackgroundType() {
return mLetterboxBackgroundType;
}
/** Sets letterbox background type. */
void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
mLetterboxBackgroundType = backgroundType;
}
/**
* Resets cletterbox background type to {@link
* com.android.internal.R.integer.config_letterboxBackgroundType}.
*/
void resetLetterboxBackgroundType() {
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
}
@LetterboxBackgroundType
private static int readLetterboxBackgroundTypeFromConfig(Context context) {
int backgroundType = context.getResources().getInteger(
com.android.internal.R.integer.config_letterboxBackgroundType);
return backgroundType == LETTERBOX_BACKGROUND_SOLID_COLOR
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING
|| backgroundType == LETTERBOX_BACKGROUND_WALLPAPER
? backgroundType : LETTERBOX_BACKGROUND_SOLID_COLOR;
}
/** Returns a string representing the given {@link LetterboxBackgroundType}. */
static String letterboxBackgroundTypeToString(
@LetterboxBackgroundType int backgroundType) {
switch (backgroundType) {
case LETTERBOX_BACKGROUND_SOLID_COLOR:
return "LETTERBOX_BACKGROUND_SOLID_COLOR";
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND";
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING";
case LETTERBOX_BACKGROUND_WALLPAPER:
return "LETTERBOX_BACKGROUND_WALLPAPER";
default:
return "unknown=" + backgroundType;
}
}
/**
* Overrides alpha of a black scrim shown over wallpaper for {@link
* #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
*
* <p>If given value is < 0 or >= 1, both it and a value of {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
* and 0.0 (transparent) is instead.
*/
void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
}
/**
* Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
*/
void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
}
/**
* Gets alpha of a black scrim shown over wallpaper letterbox background.
*/
float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
return mLetterboxBackgroundWallpaperDarkScrimAlpha;
}
/**
* Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
* {@link mLetterboxBackgroundType}.
*
* <p> If given value <= 0, both it and a value of {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
* and 0 is used instead.
*/
void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
mLetterboxBackgroundWallpaperBlurRadius = radius;
}
/**
* Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
* mLetterboxBackgroundType} to {@link
* com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
*/
void resetLetterboxBackgroundWallpaperBlurRadius() {
mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
}
/**
* Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
* mLetterboxBackgroundType}.
*/
int getLetterboxBackgroundWallpaperBlurRadius() {
return mLetterboxBackgroundWallpaperBlurRadius;
}
/*
* Gets horizontal position of a center of the letterboxed app window specified
* in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}
* or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
* right side.
*
* <p>This value can be outside of [0, 1] range so clients need to check and default to the
* central position (0.5).
*/
float getLetterboxHorizontalPositionMultiplier() {
return mLetterboxHorizontalPositionMultiplier;
}
/**
* Overrides horizontal position of a center of the letterboxed app window. If given value < 0
* or > 1, then it and a value of {@link
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
* central position (0.5) is used.
*/
void setLetterboxHorizontalPositionMultiplier(float multiplier) {
mLetterboxHorizontalPositionMultiplier = multiplier;
}
/**
* Resets horizontal position of a center of the letterboxed app window to {@link
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
*/
void resetLetterboxHorizontalPositionMultiplier() {
mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
}
@Override
public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
if (!checkCallingPermission(

View File

@@ -19,10 +19,10 @@ package com.android.server.wm;
import static android.os.Build.IS_USER;
import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
import android.graphics.Color;
import android.graphics.Point;
@@ -41,7 +41,7 @@ import com.android.internal.os.ByteTransferPipe;
import com.android.internal.protolog.ProtoLogImpl;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerService.LetterboxBackgroundType;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import java.io.IOException;
import java.io.PrintWriter;
@@ -64,10 +64,12 @@ public class WindowManagerShellCommand extends ShellCommand {
// Internal service impl -- must perform security checks before touching.
private final WindowManagerService mInternal;
private final LetterboxConfiguration mLetterboxConfiguration;
public WindowManagerShellCommand(WindowManagerService service) {
mInterface = service;
mInternal = service;
mLetterboxConfiguration = service.mLetterboxConfiguration;
}
@Override
@@ -119,34 +121,12 @@ public class WindowManagerShellCommand extends ShellCommand {
return runGetIgnoreOrientationRequest(pw);
case "dump-visible-window-views":
return runDumpVisibleWindowViews(pw);
case "set-fixed-orientation-letterbox-aspect-ratio":
return runSetFixedOrientationLetterboxAspectRatio(pw);
case "get-fixed-orientation-letterbox-aspect-ratio":
return runGetFixedOrientationLetterboxAspectRatio(pw);
case "set-letterbox-activity-corners-radius":
return runSetLetterboxActivityCornersRadius(pw);
case "get-letterbox-activity-corners-radius":
return runGetLetterboxActivityCornersRadius(pw);
case "set-letterbox-background-type":
return runSetLetterboxBackgroundType(pw);
case "get-letterbox-background-type":
return runGetLetterboxBackgroundType(pw);
case "set-letterbox-background-color":
return runSetLetterboxBackgroundColor(pw);
case "get-letterbox-background-color":
return runGetLetterboxBackgroundColor(pw);
case "set-letterbox-background-wallpaper-blur-radius":
return runSetLetterboxBackgroundWallpaperBlurRadius(pw);
case "get-letterbox-background-wallpaper-blur-radius":
return runGetLetterboxBackgroundWallpaperBlurRadius(pw);
case "set-letterbox-background-wallpaper-dark-scrim-alpha":
return runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
case "get-letterbox-background-wallpaper-dark-scrim-alpha":
return runGetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
case "set-letterbox-horizontal-position-multiplier":
return runSeLetterboxHorizontalPositionMultiplier(pw);
case "get-letterbox-horizontal-position-multiplier":
return runGetLetterboxHorizontalPositionMultiplier(pw);
case "set-letterbox-style":
return runSetLetterboxStyle(pw);
case "get-letterbox-style":
return runGetLetterboxStyle(pw);
case "reset-letterbox-style":
return runResetLetterboxStyle(pw);
case "set-sandbox-display-apis":
return runSandboxDisplayApis(pw);
case "reset":
@@ -611,12 +591,6 @@ public class WindowManagerShellCommand extends ShellCommand {
final float aspectRatio;
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetFixedOrientationLetterboxAspectRatio();
}
return 0;
}
aspectRatio = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad aspect ratio format " + e);
@@ -627,19 +601,7 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setFixedOrientationLetterboxAspectRatio(aspectRatio);
}
return 0;
}
private int runGetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final float aspectRatio = mInternal.getFixedOrientationLetterboxAspectRatio();
if (aspectRatio <= WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
pw.println("Letterbox aspect ratio is not set");
} else {
pw.println("Letterbox aspect ratio is " + aspectRatio);
}
mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio);
}
return 0;
}
@@ -648,12 +610,6 @@ public class WindowManagerShellCommand extends ShellCommand {
final int cornersRadius;
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxActivityCornersRadius();
}
return 0;
}
cornersRadius = Integer.parseInt(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad corners radius format " + e);
@@ -664,110 +620,59 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxActivityCornersRadius(cornersRadius);
}
return 0;
}
private int runGetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final int cornersRadius = mInternal.getLetterboxActivityCornersRadius();
if (cornersRadius < 0) {
pw.println("Letterbox corners radius is not set");
} else {
pw.println("Letterbox corners radius is " + cornersRadius);
}
mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius);
}
return 0;
}
private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
@LetterboxBackgroundType final int backgroundType;
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxBackgroundType();
}
return 0;
}
switch (arg) {
case "solid_color":
backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
break;
case "app_color_background":
backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
break;
case "app_color_background_floating":
backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
break;
case "wallpaper":
backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
break;
default:
getErrPrintWriter().println(
"Error: 'reset', 'solid_color', 'app_color_background' or "
+ "'wallpaper' should be provided as an argument");
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxBackgroundType(backgroundType);
}
return 0;
}
private int runGetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
@LetterboxBackgroundType final int backgroundType =
mInternal.getLetterboxBackgroundType();
switch (backgroundType) {
case LETTERBOX_BACKGROUND_SOLID_COLOR:
pw.println("Letterbox background type is 'solid_color'");
try {
String arg = getNextArgRequired();
switch (arg) {
case "solid_color":
backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
break;
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
pw.println("Letterbox background type is 'app_color_background'");
case "app_color_background":
backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
break;
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
pw.println("Letterbox background type is 'app_color_background_floating'");
case "app_color_background_floating":
backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
break;
case LETTERBOX_BACKGROUND_WALLPAPER:
pw.println("Letterbox background type is 'wallpaper'");
case "wallpaper":
backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
break;
default:
throw new AssertionError(
"Unexpected letterbox background type: " + backgroundType);
getErrPrintWriter().println(
"Error: 'reset', 'solid_color', 'app_color_background' or "
+ "'wallpaper' should be provided as an argument");
return -1;
}
} catch (IllegalArgumentException e) {
getErrPrintWriter().println(
"Error: 'reset', 'solid_color', 'app_color_background' or "
+ "'wallpaper' should be provided as an argument" + e);
return -1;
}
synchronized (mInternal.mGlobalLock) {
mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType);
}
return 0;
}
private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
final Color color;
String arg = getNextArgRequired();
try {
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxBackgroundColor();
}
return 0;
}
String arg = getNextArgRequired();
color = Color.valueOf(Color.parseColor(arg));
} catch (IllegalArgumentException e) {
getErrPrintWriter().println(
"Error: 'reset' or color in #RRGGBB format should be provided as "
+ "an argument " + e + " but got " + arg);
+ "an argument " + e);
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxBackgroundColor(color);
}
return 0;
}
private int runGetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final Color color = mInternal.getLetterboxBackgroundColor();
pw.println("Letterbox background color is " + Integer.toHexString(color.toArgb()));
mLetterboxConfiguration.setLetterboxBackgroundColor(color);
}
return 0;
}
@@ -777,12 +682,6 @@ public class WindowManagerShellCommand extends ShellCommand {
final int radius;
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
}
return 0;
}
radius = Integer.parseInt(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: blur radius format " + e);
@@ -793,20 +692,7 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxBackgroundWallpaperBlurRadius(radius);
}
return 0;
}
private int runGetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final int radius = mInternal.getLetterboxBackgroundWallpaperBlurRadius();
if (radius <= 0) {
pw.println("Letterbox background wallpaper blur radius is not set");
} else {
pw.println("Letterbox background wallpaper blur radius is " + radius);
}
mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius);
}
return 0;
}
@@ -816,12 +702,6 @@ public class WindowManagerShellCommand extends ShellCommand {
final float alpha;
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
}
return 0;
}
alpha = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad alpha format " + e);
@@ -832,20 +712,7 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
}
return 0;
}
private int runGetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final float alpha = mInternal.getLetterboxBackgroundWallpaperDarkScrimAlpha();
if (alpha < 0 || alpha >= 1) {
pw.println("Letterbox dark scrim alpha is not set");
} else {
pw.println("Letterbox dark scrim alpha is " + alpha);
}
mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
}
return 0;
}
@@ -854,12 +721,6 @@ public class WindowManagerShellCommand extends ShellCommand {
final float multiplier;
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
synchronized (mInternal.mGlobalLock) {
mInternal.resetLetterboxHorizontalPositionMultiplier();
}
return 0;
}
multiplier = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad multiplier format " + e);
@@ -870,23 +731,121 @@ public class WindowManagerShellCommand extends ShellCommand {
return -1;
}
synchronized (mInternal.mGlobalLock) {
mInternal.setLetterboxHorizontalPositionMultiplier(multiplier);
mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier);
}
return 0;
}
private int runGetLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
final float multiplier = mInternal.getLetterboxHorizontalPositionMultiplier();
if (multiplier < 0) {
pw.println("Letterbox horizontal position multiplier is not set");
} else {
pw.println("Letterbox horizontal position multiplier is " + multiplier);
private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
if (peekNextArg() == null) {
getErrPrintWriter().println("Error: No arguments provided.");
}
while (peekNextArg() != null) {
String arg = getNextArg();
switch (arg) {
case "--aspectRatio":
runSetFixedOrientationLetterboxAspectRatio(pw);
break;
case "--cornerRadius":
runSetLetterboxActivityCornersRadius(pw);
break;
case "--backgroundType":
runSetLetterboxBackgroundType(pw);
break;
case "--backgroundColor":
runSetLetterboxBackgroundColor(pw);
break;
case "--wallpaperBlurRadius":
runSetLetterboxBackgroundWallpaperBlurRadius(pw);
break;
case "--wallpaperDarkScrimAlpha":
runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
break;
case "--horizontalPositionMultiplier":
runSeLetterboxHorizontalPositionMultiplier(pw);
break;
default:
getErrPrintWriter().println(
"Error: Unrecognized letterbox style option: " + arg);
return -1;
}
}
return 0;
}
private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException {
if (peekNextArg() == null) {
resetLetterboxStyle();
}
synchronized (mInternal.mGlobalLock) {
while (peekNextArg() != null) {
String arg = getNextArg();
switch (arg) {
case "aspectRatio":
mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
break;
case "cornerRadius":
mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
break;
case "backgroundType":
mLetterboxConfiguration.resetLetterboxBackgroundType();
break;
case "backgroundColor":
mLetterboxConfiguration.resetLetterboxBackgroundColor();
break;
case "wallpaperBlurRadius":
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
break;
case "wallpaperDarkScrimAlpha":
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
break;
case "horizontalPositionMultiplier":
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
break;
default:
getErrPrintWriter().println(
"Error: Unrecognized letterbox style option: " + arg);
return -1;
}
}
}
return 0;
}
private void resetLetterboxStyle() {
synchronized (mInternal.mGlobalLock) {
mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
mLetterboxConfiguration.resetLetterboxBackgroundType();
mLetterboxConfiguration.resetLetterboxBackgroundColor();
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
}
}
private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException {
synchronized (mInternal.mGlobalLock) {
pw.println("Corner radius: "
+ mLetterboxConfiguration.getLetterboxActivityCornersRadius());
pw.println("Horizontal position multiplier: "
+ mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
pw.println("Aspect ratio: "
+ mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
pw.println("Background type: "
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
mLetterboxConfiguration.getLetterboxBackgroundType()));
pw.println(" Background color: " + Integer.toHexString(
mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb()));
pw.println(" Wallpaper blur radius: "
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
pw.println(" Wallpaper dark scrim alpha: "
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
}
return 0;
}
private int runReset(PrintWriter pw) throws RemoteException {
int displayId = getDisplayId(getNextArg());
@@ -911,26 +870,8 @@ public class WindowManagerShellCommand extends ShellCommand {
// set-ignore-orientation-request
mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */);
// set-fixed-orientation-letterbox-aspect-ratio
mInternal.resetFixedOrientationLetterboxAspectRatio();
// set-letterbox-activity-corners-radius
mInternal.resetLetterboxActivityCornersRadius();
// set-letterbox-background-type
mInternal.resetLetterboxBackgroundType();
// set-letterbox-background-color
mInternal.resetLetterboxBackgroundColor();
// set-letterbox-background-wallpaper-blur-radius
mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
// set-letterbox-background-wallpaper-dark-scrim-alpha
mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
// set-letterbox-horizontal-position-multiplier
mInternal.resetLetterboxHorizontalPositionMultiplier();
// set-letterbox-style
resetLetterboxStyle();
// set-sandbox-display-apis
mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
@@ -966,47 +907,13 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]");
pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] ");
pw.println(" If app requested orientation should be ignored.");
pw.println(" set-fixed-orientation-letterbox-aspect-ratio [reset|aspectRatio]");
pw.println(" get-fixed-orientation-letterbox-aspect-ratio");
pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
+ WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will be");
pw.println(" ignored and framework implementation will determine aspect ratio.");
pw.println(" set-letterbox-activity-corners-radius [reset|cornersRadius]");
pw.println(" get-letterbox-activity-corners-radius");
pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,");
pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be");
pw.println(" ignored and corners of the activity won't be rounded.");
pw.println(" set-letterbox-background-color [reset|colorName|'\\#RRGGBB']");
pw.println(" get-letterbox-background-color");
pw.println(" Color of letterbox background which is be used when letterbox background");
pw.println(" type is 'solid-color'. Use get(set)-letterbox-background-type to check");
pw.println(" and control letterbox background type. See Color#parseColor for allowed");
pw.println(" color formats (#RRGGBB and some colors by name, e.g. magenta or olive). ");
pw.println(" set-letterbox-background-type [reset|solid_color|app_color_background");
pw.println(" |app_color_background_floating|wallpaper]");
pw.println(" get-letterbox-background-type");
pw.println(" Type of background used in the letterbox mode.");
pw.println(" set-letterbox-background-wallpaper-blur-radius [reset|radius]");
pw.println(" get-letterbox-background-wallpaper-blur-radius");
pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius are ");
pw.println(" ignored and 0 is used.");
pw.println(" set-letterbox-background-wallpaper-dark-scrim-alpha [reset|alpha]");
pw.println(" get-letterbox-background-wallpaper-dark-scrim-alpha");
pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored and ");
pw.println(" 0.0 (transparent) is used instead.");
pw.println(" set-letterbox-horizontal-position-multiplier [reset|multiplier]");
pw.println(" get-letterbox-horizontal-position-multiplier");
pw.println(" horizontal position of a center of a letterboxed app. If it < 0 or > 1");
pw.println(" then both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
pw.println(" are ignored and central position (0.5) is used.");
pw.println(" set-sandbox-display-apis [true|1|false|0]");
pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect ");
pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or");
pw.println(" Size Compat Mode.");
printLetterboxHelp(pw);
pw.println(" reset [-d DISPLAY_ID]");
pw.println(" Reset all override settings.");
if (!IS_USER) {
@@ -1016,4 +923,47 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" Logging settings.");
}
}
private void printLetterboxHelp(PrintWriter pw) {
pw.println(" set-letterbox-style");
pw.println(" Sets letterbox style using the following options:");
pw.println(" --aspectRatio aspectRatio");
pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
+ LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
pw.println(" be ignored and framework implementation will determine aspect ratio.");
pw.println(" --cornerRadius radius");
pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,");
pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be");
pw.println(" ignored and corners of the activity won't be rounded.");
pw.println(" --backgroundType [reset|solid_color|app_color_background");
pw.println(" |app_color_background_floating|wallpaper]");
pw.println(" Type of background used in the letterbox mode.");
pw.println(" --backgroundColor color");
pw.println(" Color of letterbox which is be used when letterbox background type");
pw.println(" is 'solid-color'. Use (set)get-letterbox-style to check and control");
pw.println(" letterbox background type. See Color#parseColor for allowed color");
pw.println(" formats (#RRGGBB and some colors by name, e.g. magenta or olive).");
pw.println(" --wallpaperBlurRadius radius");
pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius");
pw.println(" are ignored and 0 is used.");
pw.println(" --wallpaperDarkScrimAlpha alpha");
pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored");
pw.println(" and 0.0 (transparent) is used instead.");
pw.println(" --horizontalPositionMultiplier multiplier");
pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,");
pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
pw.println(" are ignored and central position (0.5) is used.");
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
pw.println(" |horizontalPositionMultiplier]");
pw.println(" Resets overrides to default values for specified properties separated");
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
pw.println(" If no arguments provided, all values will be reset.");
pw.println(" get-letterbox-style");
pw.println(" Prints letterbox style configuration.");
}
}

View File

@@ -1971,7 +1971,8 @@ public class DisplayContentTests extends WindowTestsBase {
// test misc display overrides
assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
assertEquals(fixedOrientationLetterboxRatio,
mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
0 /* delta */);
}
@@ -2011,7 +2012,8 @@ public class DisplayContentTests extends WindowTestsBase {
// test misc display overrides
assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
assertEquals(fixedOrientationLetterboxRatio,
mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
0 /* delta */);
}

View File

@@ -335,11 +335,11 @@ public class SizeCompatTests extends WindowTestsBase {
final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window");
assertEquals(window, mActivity.findMainWindow());
assertTrue(mActivity.isLetterboxed(mActivity.findMainWindow()));
assertTrue(mActivity.mLetterboxUiController.isLetterboxed(mActivity.findMainWindow()));
window.mAttrs.flags |= FLAG_SHOW_WALLPAPER;
assertFalse(mActivity.isLetterboxed(mActivity.findMainWindow()));
assertFalse(mActivity.mLetterboxUiController.isLetterboxed(mActivity.findMainWindow()));
}
@Test
@@ -1023,7 +1023,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
// orientation letterbox.
mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(1.1f);
mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
mActivity.info.setMinAspectRatio(3);
prepareUnresizable(mActivity, /* maxAspect= */ 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -1054,7 +1054,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app with max aspect ratio lower that aspect ratio override for fixed
// orientation letterbox.
mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(3);
mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(3);
prepareUnresizable(mActivity, /* maxAspect= */ 2, SCREEN_ORIENTATION_PORTRAIT);
final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
@@ -1085,7 +1085,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
// orientation letterbox.
final float fixedOrientationLetterboxAspectRatio = 1.1f;
mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(
mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
fixedOrientationLetterboxAspectRatio);
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -1586,7 +1586,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mActivity.mWmService.setLetterboxHorizontalPositionMultiplier(
mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
@@ -1624,7 +1624,7 @@ public class SizeCompatTests extends WindowTestsBase {
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
mActivity.mWmService.setLetterboxHorizontalPositionMultiplier(
mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);

View File

@@ -208,11 +208,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
// Ensure letterbox aspect ratio is not overridden on any device target.
// {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
// on some device form factors.
mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(0);
mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0);
// Ensure letterbox position multiplier is not overridden on any device target.
// {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
// may be set on some device form factors.
mAtm.mWindowManager.setLetterboxHorizontalPositionMultiplier(0.5f);
mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
checkDeviceSpecificOverridesNotApplied();
}
@@ -220,10 +220,10 @@ class WindowTestsBase extends SystemServiceTestsBase {
@After
public void tearDown() throws Exception {
// Revert back to device overrides.
mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(
mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
mContext.getResources().getFloat(
com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio));
mAtm.mWindowManager.setLetterboxHorizontalPositionMultiplier(
mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier));
}
@@ -235,7 +235,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
private void checkDeviceSpecificOverridesNotApplied() {
// Check global overrides
if (!sGlobalOverridesChecked) {
assertEquals(0, mWm.getFixedOrientationLetterboxAspectRatio(), 0 /* delta */);
assertEquals(0, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
0 /* delta */);
sGlobalOverridesChecked = true;
}
// Check display-specific overrides