Merge "Use one surface for blurred wallpaper letterbox background option." into sc-v2-dev

This commit is contained in:
Mariia Sandrikova
2021-07-08 13:37:47 +00:00
committed by Android (Google) Code Review
2 changed files with 63 additions and 29 deletions

View File

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

View File

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