Merge "Allow bar to be transparent if letterbox contains bar" into rvc-dev

This commit is contained in:
Wei Sheng Shih
2020-04-23 13:32:15 +00:00
committed by Android (Google) Code Review
6 changed files with 127 additions and 39 deletions

View File

@@ -395,14 +395,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
return false; return false;
} }
/**
* Returns true if the window has a letterbox and any part of that letterbox overlaps with
* the given {@code rect}.
*/
default boolean isLetterboxedOverlappingWith(Rect rect) {
return false;
}
/** @return the current windowing mode of this window. */ /** @return the current windowing mode of this window. */
int getWindowingMode(); int getWindowingMode();

View File

@@ -1419,11 +1419,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} }
/** /**
* @return {@code true} if there is a letterbox and any part of that letterbox overlaps with * @see Letterbox#notIntersectsOrFullyContains(Rect)
* the given {@code rect}.
*/ */
boolean isLetterboxOverlappingWith(Rect rect) { boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
return mLetterbox != null && mLetterbox.isOverlappingWith(rect); return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
} }
static class Token extends IApplicationToken.Stub { static class Token extends IApplicationToken.Stub {

View File

@@ -168,7 +168,7 @@ public class BarController {
} }
boolean isTransparentAllowed(WindowState win) { boolean isTransparentAllowed(WindowState win) {
return win == null || !win.isLetterboxedOverlappingWith(mContentFrame); return win == null || win.letterboxNotIntersectsOrFullyContains(mContentFrame);
} }
boolean setBarShowingLw(final boolean show) { boolean setBarShowingLw(final boolean show) {

View File

@@ -77,10 +77,10 @@ public class Letterbox {
mOuter.set(outer); mOuter.set(outer);
mInner.set(inner); mInner.set(inner);
mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin); mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin);
mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin); mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin);
mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin); mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin); mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin);
} }
@@ -101,17 +101,29 @@ public class Letterbox {
} }
/** /**
* Returns true if any part of the letterbox overlaps with the given {@code rect}. * Returns {@code true} if the letterbox does not overlap with the bar, or the letterbox can
* fully cover the window frame.
*
* @param rect The area of the window frame.
*/ */
public boolean isOverlappingWith(Rect rect) { boolean notIntersectsOrFullyContains(Rect rect) {
int emptyCount = 0;
int noOverlappingCount = 0;
for (LetterboxSurface surface : mSurfaces) { for (LetterboxSurface surface : mSurfaces) {
if (surface.isOverlappingWith(rect)) { final Rect surfaceRect = surface.mLayoutFrameGlobal;
if (surfaceRect.isEmpty()) {
// empty letterbox
emptyCount++;
} else if (!Rect.intersects(surfaceRect, rect)) {
// no overlapping
noOverlappingCount++;
} else if (surfaceRect.contains(rect)) {
// overlapping and covered
return true; return true;
} }
} }
return false; return (emptyCount + noOverlappingCount) == mSurfaces.length;
} }
/** /**
* Hides the letterbox. * Hides the letterbox.
* *
@@ -282,17 +294,6 @@ public class Letterbox {
return Math.max(0, mLayoutFrameGlobal.height()); return Math.max(0, mLayoutFrameGlobal.height());
} }
/**
* Returns if the given {@code rect} overlaps with this letterbox piece.
* @param rect the area to check for overlap in global coordinates
*/
public boolean isOverlappingWith(Rect rect) {
if (mLayoutFrameGlobal.isEmpty()) {
return false;
}
return Rect.intersects(rect, mLayoutFrameGlobal);
}
public void applySurfaceChanges(SurfaceControl.Transaction t) { public void applySurfaceChanges(SurfaceControl.Transaction t) {
if (mSurfaceFrameRelative.equals(mLayoutFrameRelative)) { if (mSurfaceFrameRelative.equals(mLayoutFrameRelative)) {
// Nothing changed. // Nothing changed.

View File

@@ -3660,9 +3660,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mActivityRecord.getBounds().equals(mTmpRect); return mActivityRecord.getBounds().equals(mTmpRect);
} }
@Override /**
public boolean isLetterboxedOverlappingWith(Rect rect) { * @see Letterbox#notIntersectsOrFullyContains(Rect)
return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect); */
boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
return mActivityRecord == null
|| mActivityRecord.letterboxNotIntersectsOrFullyContains(rect);
} }
boolean isDragResizeChanged() { boolean isDragResizeChanged() {

View File

@@ -16,6 +16,7 @@
package com.android.server.wm; package com.android.server.wm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
@@ -53,10 +54,102 @@ public class LetterboxTest {
mTransaction = spy(StubTransaction.class); mTransaction = spy(StubTransaction.class);
} }
private static final int TOP_BAR = 0x1;
private static final int BOTTOM_BAR = 0x2;
private static final int LEFT_BAR = 0x4;
private static final int RIGHT_BAR = 0x8;
@Test @Test
public void testOverlappingWith_usesGlobalCoordinates() { public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() {
mLetterbox.layout(new Rect(0, 0, 10, 50), new Rect(0, 2, 10, 45), new Point(1000, 2000)); final Rect outer = new Rect(0, 0, 10, 50);
assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1))); final Point surfaceOrig = new Point(1000, 2000);
final Rect topBar = new Rect(0, 0, 10, 2);
final Rect bottomBar = new Rect(0, 45, 10, 50);
final Rect leftBar = new Rect(0, 0, 2, 50);
final Rect rightBar = new Rect(8, 0, 10, 50);
final LetterboxLayoutVerifier verifier =
new LetterboxLayoutVerifier(outer, surfaceOrig, mLetterbox);
verifier.setBarRect(topBar, bottomBar, leftBar, rightBar);
// top
verifier.setInner(0, 2, 10, 50).verifyPositions(TOP_BAR | BOTTOM_BAR, BOTTOM_BAR);
// bottom
verifier.setInner(0, 0, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, TOP_BAR);
// left
verifier.setInner(2, 0, 10, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, RIGHT_BAR);
// right
verifier.setInner(0, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, LEFT_BAR);
// top + bottom
verifier.setInner(0, 2, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, 0);
// left + right
verifier.setInner(2, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, 0);
// top + left
verifier.setInner(2, 2, 10, 50).verifyPositions(TOP_BAR | LEFT_BAR, 0);
// top + left + right
verifier.setInner(2, 2, 8, 50).verifyPositions(TOP_BAR | LEFT_BAR | RIGHT_BAR, 0);
// left + right + bottom
verifier.setInner(2, 0, 8, 45).verifyPositions(LEFT_BAR | RIGHT_BAR | BOTTOM_BAR, 0);
// all
verifier.setInner(2, 2, 8, 45)
.verifyPositions(TOP_BAR | BOTTOM_BAR | LEFT_BAR | RIGHT_BAR, 0);
}
private static class LetterboxLayoutVerifier {
final Rect mOuter;
final Rect mInner = new Rect();
final Point mSurfaceOrig;
final Letterbox mLetterbox;
final Rect mTempRect = new Rect();
final Rect mTop = new Rect();
final Rect mBottom = new Rect();
final Rect mLeft = new Rect();
final Rect mRight = new Rect();
LetterboxLayoutVerifier(Rect outer, Point surfaceOrig, Letterbox letterbox) {
mOuter = new Rect(outer);
mSurfaceOrig = new Point(surfaceOrig);
mLetterbox = letterbox;
}
LetterboxLayoutVerifier setInner(int left, int top, int right, int bottom) {
mInner.set(left, top, right, bottom);
mLetterbox.layout(mOuter, mInner, mSurfaceOrig);
return this;
}
void setBarRect(Rect top, Rect bottom, Rect left, Rect right) {
mTop.set(top);
mBottom.set(bottom);
mLeft.set(left);
mRight.set(right);
}
void verifyPositions(int allowedPos, int noOverlapPos) {
assertEquals(mLetterbox.notIntersectsOrFullyContains(mTop),
(allowedPos & TOP_BAR) != 0);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mBottom),
(allowedPos & BOTTOM_BAR) != 0);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mLeft),
(allowedPos & LEFT_BAR) != 0);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mRight),
(allowedPos & RIGHT_BAR) != 0);
mTempRect.set(mTop.left, mTop.top, mTop.right, mTop.bottom + 1);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
(noOverlapPos & TOP_BAR) != 0);
mTempRect.set(mLeft.left, mLeft.top, mLeft.right + 1, mLeft.bottom);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
(noOverlapPos & LEFT_BAR) != 0);
mTempRect.set(mRight.left - 1, mRight.top, mRight.right, mRight.bottom);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
(noOverlapPos & RIGHT_BAR) != 0);
mTempRect.set(mBottom.left, mBottom.top - 1, mBottom.right, mBottom.bottom);
assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
(noOverlapPos & BOTTOM_BAR) != 0);
}
} }
@Test @Test