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

Commit 544ee86b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Letterbox: configurable rounded corners." into sc-dev

parents e83fcb8c 22045dba
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4632,6 +4632,10 @@
         maximum screen area that can be occupied by the app in the letterbox mode. -->
    <item name="config_taskLetterboxAspectRatio" format="float" type="dimen">0.0</item>

    <!-- Corners radius for activity presented the letterbox mode. Values < 0 will be ignored and
         corners of the activity won't be rounded. -->
    <integer name="config_letterboxActivityCornersRadius">0</integer>

    <!-- If true, hide the display cutout with display area -->
    <bool name="config_hideDisplayCutoutWithDisplayArea">false</bool>

+1 −0
Original line number Diff line number Diff line
@@ -4132,6 +4132,7 @@
  <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />

  <java-symbol type="dimen" name="config_taskLetterboxAspectRatio" />
  <java-symbol type="integer" name="config_letterboxActivityCornersRadius" />

  <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />

+32 −5
Original line number Diff line number Diff line
@@ -1355,11 +1355,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final boolean surfaceReady = w.isDrawn()  // Regular case
                || w.mWinAnimator.mSurfaceDestroyDeferred  // The preserved surface is still ready.
                || w.isDragResizeChanged();  // Waiting for relayoutWindow to call preserveSurface.
        final boolean needsLetterbox = surfaceReady && w.isLetterboxedAppWindow() && fillsParent();
        final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
        updateRoundedCorners(w);
        if (needsLetterbox) {
            if (mLetterbox == null) {
                mLetterbox = new Letterbox(() -> makeChildSurface(null),
                        mWmService.mTransactionFactory);
                        mWmService.mTransactionFactory,
                        mWmService::isLetterboxActivityCornersRounded);
                mLetterbox.attachInput(w);
            }
            getPosition(mTmpPoint);
@@ -1379,6 +1381,27 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    /** @return {@code true} when main window is letterboxed and activity isn't transparent. */
    private boolean isLetterboxed(WindowState mainWindow) {
        return mainWindow.isLetterboxedAppWindow() && fillsParent();
    }

    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 = getPendingTransaction();
            transaction.setCornerRadius(windowSurface, cornersRadius);
        }
    }

    void updateLetterboxSurface(WindowState winHint) {
        final WindowState w = findMainWindow();
        if (w != winHint && winHint != null && w != null) {
@@ -1408,10 +1431,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    /**
     * @see Letterbox#notIntersectsOrFullyContains(Rect)
     * @return {@code true} if bar shown within a given rectangle is allowed to be transparent
     *     when the current activity is displayed.
     */
    boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
        return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
    boolean isTransparentBarAllowed(Rect rect) {
        // TODO(b/175482966): Allow status and navigation bars to be semi-transparent black
        // in letterbox mode.
        return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect)
                || mWmService.isLetterboxActivityCornersRounded();
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -56,6 +56,6 @@ public class BarController {
        if (win == null) {
            return true;
        }
        return win.letterboxNotIntersectsOrFullyContains(getContentFrame(win));
        return win.isTransparentBarAllowed(getContentFrame(win));
    }
}
+18 −1
Original line number Diff line number Diff line
@@ -44,12 +44,17 @@ public class Letterbox {

    private final Supplier<SurfaceControl.Builder> mSurfaceControlFactory;
    private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
    private final Supplier<Boolean> mAreCornersRounded;
    private final Rect mOuter = new Rect();
    private final Rect mInner = new Rect();
    private final LetterboxSurface mTop = new LetterboxSurface("top");
    private final LetterboxSurface mLeft = new LetterboxSurface("left");
    private final LetterboxSurface mBottom = new LetterboxSurface("bottom");
    private final LetterboxSurface mRight = new LetterboxSurface("right");
    // Prevents wallpaper from peeking through near rounded corners. It's not included in
    // mSurfaces array since it isn't needed in methods like notIntersectsOrFullyContains
    // or attachInput.
    private final LetterboxSurface mBehind = new LetterboxSurface("behind");
    private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom };

    /**
@@ -58,9 +63,11 @@ public class Letterbox {
     * @param surfaceControlFactory a factory for creating the managed {@link SurfaceControl}s
     */
    public Letterbox(Supplier<SurfaceControl.Builder> surfaceControlFactory,
            Supplier<SurfaceControl.Transaction> transactionFactory) {
            Supplier<SurfaceControl.Transaction> transactionFactory,
            Supplier<Boolean> areCornersRounded) {
        mSurfaceControlFactory = surfaceControlFactory;
        mTransactionFactory = transactionFactory;
        mAreCornersRounded = areCornersRounded;
    }

    /**
@@ -82,6 +89,7 @@ public class Letterbox {
        mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin);
        mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
        mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin);
        mBehind.layout(inner.left, inner.top, inner.right, inner.bottom, surfaceOrigin);
    }


@@ -157,6 +165,7 @@ public class Letterbox {
        for (LetterboxSurface surface : mSurfaces) {
            surface.remove();
        }
        mBehind.remove();
    }

    /** Returns whether a call to {@link #applySurfaceChanges} would change the surface. */
@@ -166,6 +175,9 @@ public class Letterbox {
                return true;
            }
        }
        if (mBehind.needsApplySurfaceChanges()) {
            return true;
        }
        return false;
    }

@@ -173,6 +185,11 @@ public class Letterbox {
        for (LetterboxSurface surface : mSurfaces) {
            surface.applySurfaceChanges(t);
        }
        if (mAreCornersRounded.get()) {
            mBehind.applySurfaceChanges(t);
        } else {
            mBehind.remove();
        }
    }

    /** Enables touches to slide into other neighboring surfaces. */
Loading