From 94f342b161f763a2f7eac8f704813e1817bfbf4b Mon Sep 17 00:00:00 2001 From: Mariia Sandrikova Date: Tue, 6 Jul 2021 19:59:12 +0100 Subject: [PATCH] Use one surface for blurred wallpaper letterbox background option. This is required to avoid having visible border between letterbox surfaces in size compat mode. Fix: 192952692 Test: atest WmTests:LetterboxTest Change-Id: I4dcd8f9103e889f4ed36aa585999727bd7e2e298 --- .../java/com/android/server/wm/Letterbox.java | 59 +++++++++++++------ .../com/android/server/wm/LetterboxTest.java | 33 +++++++---- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 3dbe79df67220..5a249a5599bbb 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -58,10 +58,12 @@ public class Letterbox { 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"); + // One surface that fills the whole window is used over multiple surfaces to: + // - Prevents wallpaper from peeking through near rounded corners. + // - For "blurred wallpaper" background, to avoid having visible border between surfaces. + // One surface approach isn't always preferred over multiple surfaces due to rendering cost + // for overlaping an app window and letterbox surfaces. + private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow"); private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom }; /** @@ -104,7 +106,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); + mFullWindowSurface.layout(outer.left, outer.top, outer.right, outer.bottom, surfaceOrigin); } @@ -168,37 +170,46 @@ public class Letterbox { for (LetterboxSurface surface : mSurfaces) { surface.remove(); } - mBehind.remove(); + mFullWindowSurface.remove(); } /** Returns whether a call to {@link #applySurfaceChanges} would change the surface. */ public boolean needsApplySurfaceChanges() { + if (useFullWindowSurface()) { + return mFullWindowSurface.needsApplySurfaceChanges(); + } for (LetterboxSurface surface : mSurfaces) { if (surface.needsApplySurfaceChanges()) { return true; } } - if (mAreCornersRounded.get() && mBehind.needsApplySurfaceChanges()) { - return true; - } return false; } public void applySurfaceChanges(SurfaceControl.Transaction t) { - for (LetterboxSurface surface : mSurfaces) { - surface.applySurfaceChanges(t); - } - if (mAreCornersRounded.get()) { - mBehind.applySurfaceChanges(t); + if (useFullWindowSurface()) { + mFullWindowSurface.applySurfaceChanges(t); + + for (LetterboxSurface surface : mSurfaces) { + surface.remove(); + } } else { - mBehind.remove(); + for (LetterboxSurface surface : mSurfaces) { + surface.applySurfaceChanges(t); + } + + mFullWindowSurface.remove(); } } /** Enables touches to slide into other neighboring surfaces. */ void attachInput(WindowState win) { - for (LetterboxSurface surface : mSurfaces) { - surface.attachInput(win); + if (useFullWindowSurface()) { + mFullWindowSurface.attachInput(win); + } else { + for (LetterboxSurface surface : mSurfaces) { + surface.attachInput(win); + } } } @@ -208,6 +219,16 @@ public class Letterbox { surface.mInputInterceptor.mWindowHandle.displayId = displayId; } } + if (mFullWindowSurface.mInputInterceptor != null) { + mFullWindowSurface.mInputInterceptor.mWindowHandle.displayId = displayId; + } + } + + /** + * Returns {@code true} when using {@link #mFullWindowSurface} instead of {@link mSurfaces}. + */ + private boolean useFullWindowSurface() { + return mAreCornersRounded.get() || mHasWallpaperBackgroundSupplier.get(); } private static class InputInterceptor { @@ -308,6 +329,10 @@ public class Letterbox { mInputInterceptor = new InputInterceptor("Letterbox_" + mType + "_", win); } + boolean isRemoved() { + return mSurface != null || mInputInterceptor != null; + } + public void remove() { if (mSurface != null) { mTransactionFactory.get().remove(mSurface).apply(); diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index 647a898a53614..609d15937b2e2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -200,28 +200,37 @@ public class LetterboxTest { assertTrue(mLetterbox.needsApplySurfaceChanges()); mLetterbox.applySurfaceChanges(mTransaction); - verify(mTransaction).setAlpha(mSurfaces.top, mDarkScrimAlpha); + verify(mTransaction).setAlpha(mSurfaces.fullWindowSurface, mDarkScrimAlpha); } @Test - public void testApplySurfaceChanges_cornersNotRounded_surfaceBehindNotCreated() { + public void testApplySurfaceChanges_cornersNotRounded_surfaceFullWindowSurfaceNotCreated() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); mLetterbox.applySurfaceChanges(mTransaction); - assertNull(mSurfaces.behind); + assertNull(mSurfaces.fullWindowSurface); } @Test - public void testApplySurfaceChanges_cornersRounded_surfaceBehindCreated() { + public void testApplySurfaceChanges_cornersRounded_surfaceFullWindowSurfaceCreated() { mAreCornersRounded = true; mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); mLetterbox.applySurfaceChanges(mTransaction); - assertNotNull(mSurfaces.behind); + assertNotNull(mSurfaces.fullWindowSurface); } @Test - public void testNotIntersectsOrFullyContains_cornersRounded_doesNotCheckSurfaceBehind() { + public void testApplySurfaceChanges_wallpaperBackground_surfaceFullWindowSurfaceCreated() { + mHasWallpaperBackground = true; + mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); + mLetterbox.applySurfaceChanges(mTransaction); + + assertNotNull(mSurfaces.fullWindowSurface); + } + + @Test + public void testNotIntersectsOrFullyContains_cornersRounded() { mAreCornersRounded = true; mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(0, 0)); mLetterbox.applySurfaceChanges(mTransaction); @@ -249,8 +258,8 @@ public class LetterboxTest { public SurfaceControl right; private SurfaceControl.Builder mBottomBuilder; public SurfaceControl bottom; - private SurfaceControl.Builder mBehindBuilder; - public SurfaceControl behind; + private SurfaceControl.Builder mFullWindowSurfaceBuilder; + public SurfaceControl fullWindowSurface; @Override public SurfaceControl.Builder get() { @@ -265,8 +274,8 @@ public class LetterboxTest { mRightBuilder = (SurfaceControl.Builder) i.getMock(); } else if (((String) i.getArgument(0)).contains("bottom")) { mBottomBuilder = (SurfaceControl.Builder) i.getMock(); - } else if (((String) i.getArgument(0)).contains("behind")) { - mBehindBuilder = (SurfaceControl.Builder) i.getMock(); + } else if (((String) i.getArgument(0)).contains("fullWindow")) { + mFullWindowSurfaceBuilder = (SurfaceControl.Builder) i.getMock(); } return i.getMock(); }); @@ -281,8 +290,8 @@ public class LetterboxTest { right = control; } else if (i.getMock() == mBottomBuilder) { bottom = control; - } else if (i.getMock() == mBehindBuilder) { - behind = control; + } else if (i.getMock() == mFullWindowSurfaceBuilder) { + fullWindowSurface = control; } return control; }).when(builder).build();