Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 947b45ad authored by Mariia Sandrikova's avatar Mariia Sandrikova
Browse files

Wallpaper background for letterbox.

Changes:
- Allows to request 'wallpaper' background for letterbox and to specify blur radius and alpha of dark scrim that will dim the wallpaper in config overlays or via ADB commands.
- To propagate "showing wallpaper for letterbox" property to the rest of system independently from FLAG_SHOW_WALLPAPER
- Checks mShowWallpaperForLetterboxBackground in all places where FLAG_SHOW_WALLPAPER is checked.
- Doesn't show wallpaper background when letterboxed only for display cutout.

Fix: 170215478
Fix: 181679062
Test: atest LetterboxTest and manual with ADB commands
- adb shell cmd window set-letterbox-background-type wallpaper
- adb shell cmd window set-letterbox-background-wallpaper-blur-radius <radius>
- adb shell cmd window set-letterbox-background-wallpaper-dark-scrim-alpha <alpha>

Change-Id: Ic5902b085c0a9d250107c3b5ca2d329a9f47c71b
parent f9060291
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -4673,10 +4673,26 @@
         corners of the activity won't be rounded. -->
    <integer name="config_letterboxActivityCornersRadius">0</integer>

    <!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
        ignored and 0 is used. -->
    <dimen name="config_letterboxBackgroundWallpaperBlurRadius">100dp</dimen>

    <!-- Alpha of a black translucent scrim showed over wallpaper letterbox background when
        the Option 3 is selected for R.integer.config_letterboxBackgroundType.
        Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead. -->
    <item name="config_letterboxBackgroundWallaperDarkScrimAlpha" format="float" type="dimen">
        0.5
    </item>

    <!-- Corners appearance of the letterbox background.
            0 - Solid background using color specified in R.color.config_letterboxBackgroundColor.
            1 - Color specified in R.attr.colorBackground for the letterboxed application.
            2 - Color specified in R.attr.colorBackgroundFloating for the letterboxed application.
            3 - Wallpaper with dimmed with blur or/and dark scrim. At least one of the following
            parameters should be > 0: config_letterboxBackgroundWallpaperBlurRadius,
            config_letterboxBackgroundWallaperDarkScrimAlpha. If it's not the case or blur radius
            provided but blur isn't supported by the device and this option
            is selected then implementation will default to option 0.
        If given value is outside of this range, the option 0 will be assummed. -->
    <integer name="config_letterboxBackgroundType">0</integer>

@@ -4686,6 +4702,9 @@
            R.attr.colorBackground isn't specified for the app.
            - Option 2 is selected for R.integer.config_letterboxBackgroundType and
            R.attr.colorBackgroundFloating isn't specified for the app.
            - Option 3 is selected for R.integer.config_letterboxBackgroundType and blur requested
            but isn't supported on the device or both dark scrim alpha and blur radius aren't
            provided.
        Defaults to black if not specified.
     -->
    <color name="config_letterboxBackgroundColor">#000</color>
+2 −0
Original line number Diff line number Diff line
@@ -4173,7 +4173,9 @@
  <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />

  <java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" />
  <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" />
  <java-symbol type="integer" name="config_letterboxActivityCornersRadius" />
  <java-symbol type="dimen" name="config_letterboxBackgroundWallaperDarkScrimAlpha" />
  <java-symbol type="integer" name="config_letterboxBackgroundType" />
  <java-symbol type="color" name="config_letterboxBackgroundColor" />

+76 −7
Original line number Diff line number Diff line
@@ -218,6 +218,7 @@ 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;
@@ -601,8 +602,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
    private boolean mLastSurfaceShowing = true;

    private Letterbox mLetterbox;

    /**
     * The activity is opaque and fills the entire space of this task.
     * @see WindowContainer#fillsParent()
@@ -640,6 +639,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     */
    private boolean mWillCloseOrEnterPip;

    private Letterbox mLetterbox;

    /**
     * The scale to fit at least one side of the activity to its parent. If the activity uses
     * 1920x1080, and the actually size on the screen is 960x540, then the scale is 0.5.
@@ -667,6 +668,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    @Nullable
    private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;

    private boolean mShowWallpaperForLetterboxBackground;

    // activity is not displayed?
    // TODO: rename to mNoDisplay
    @VisibleForTesting
@@ -1119,6 +1122,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                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());
        }
    }

    /**
@@ -1406,6 +1417,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    // 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) {
@@ -1415,12 +1427,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                || 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::getLetterboxBackgroundColor,
                        this::hasWallpaperBackgroudForLetterbox,
                        this::getLetterboxWallpaperBlurRadius,
                        this::getLetterboxWallpaperDarkScrimAlpha);
                mLetterbox.attachInput(w);
            }
            getPosition(mTmpPoint);
@@ -1452,18 +1468,32 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
                    return Color.valueOf(taskDescription.getBackgroundColorFloating());
                }
                return mWmService.getLetterboxBackgroundColor();
                break;
            case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
                if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
                    return Color.valueOf(taskDescription.getBackgroundColor());
                }
                // Falling through
                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
@@ -1494,6 +1524,45 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    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();
    }

    void updateLetterboxSurface(WindowState winHint) {
        final WindowState w = findMainWindow();
        if (w != winHint && winHint != null && w != null) {
+1 −2
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.wm;

import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
@@ -128,7 +127,7 @@ public class AppTransitionController {
        final ArraySet<WindowContainer> openingWcs = getAnimationTargets(
                mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps, true /* visible */);
        final boolean showWallpaper = wallpaperTarget != null
                && ((wallpaperTarget.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
                && (wallpaperTarget.hasWallpaper()
                // Update task open transition to wallpaper transition when wallpaper is visible.
                // (i.e.launching app info activity from recent tasks)
                || ((firstTransit == TRANSIT_OPEN || firstTransit == TRANSIT_TO_FRONT)
+1 −2
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -913,7 +912,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            // Take care of the window being ready to display.
            final boolean committed = winAnimator.commitFinishDrawingLocked();
            if (isDefaultDisplay && committed) {
                if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                if (w.hasWallpaper()) {
                    if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                            "First draw done in potential wallpaper target " + w);
                    mWallpaperMayChange = true;
Loading