summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author wilsonshih <wilsonshih@google.com> 2020-07-14 13:15:09 +0800
committer Wei Sheng Shih <wilsonshih@google.com> 2020-07-16 02:46:32 +0000
commit42eb13de583a6910186d12a1bffdfd085c9fbbed (patch)
treed4cb31eb146a8c112b759e96441b0cb2dd2c5ced
parentc42d4b65c82496591612a6eaec25689d53564f86 (diff)
Allow status bar to be transparent, and clear LIGHT flags.
Combines I1f458394a8c6a2ac53a461b6819a026090d62898 back. Add another check for LIGHT appearance, if letterbox is overlapping with bar then clear the light appearance flag. Bug: 152273579 Test: manualy test on Camera/PDF viewer, verify the visibility of the status bar. Test: atest DisplayPolicyTests LetterboxTest Change-Id: I82057920066e9c6c6d380ecdd2254ff7f317a4ff
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java7
-rw-r--r--services/core/java/com/android/server/wm/BarController.java17
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java33
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java33
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java99
7 files changed, 176 insertions, 30 deletions
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 8868a6c2e6d8..b3e162d473db 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -396,14 +396,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
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. */
int getWindowingMode();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 40e558c09965..3e9377ed0664 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1395,6 +1395,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
+ * @see Letterbox#notIntersectsOrFullyContains(Rect)
+ */
+ boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+ return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
+ }
+
+ /**
* @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
* the given {@code rect}.
*/
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 123fb6c9d8e3..c1447553ba31 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static com.android.server.wm.BarControllerProto.STATE;
import static com.android.server.wm.BarControllerProto.TRANSIENT_STATE;
+import android.annotation.NonNull;
import android.app.StatusBarManager;
import android.graphics.Rect;
import android.os.Handler;
@@ -169,13 +170,23 @@ public class BarController {
return vis;
}
+ private Rect getContentFrame(@NonNull WindowState win) {
+ final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
+ return rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
+ }
+
+ boolean isLightAppearanceAllowed(WindowState win) {
+ if (win == null) {
+ return true;
+ }
+ return !win.isLetterboxedOverlappingWith(getContentFrame(win));
+ }
+
boolean isTransparentAllowed(WindowState win) {
if (win == null) {
return true;
}
- final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
- final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
- return !win.isLetterboxedOverlappingWith(contentFrame);
+ return win.letterboxNotIntersectsOrFullyContains(getContentFrame(win));
}
boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 68051ab59599..605d0b2cc127 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -3437,17 +3437,22 @@ public class DisplayPolicy {
WindowState opaqueOrDimming) {
final boolean onKeyguard = isKeyguardShowing() && !isKeyguardOccluded();
final WindowState statusColorWin = onKeyguard ? mNotificationShade : opaqueOrDimming;
- if (statusColorWin != null && (statusColorWin == opaque || onKeyguard)) {
- // If the top fullscreen-or-dimming window is also the top fullscreen, respect
- // its light flag.
- appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
- final int legacyAppearance = InsetsFlags.getAppearance(
- PolicyControl.getSystemUiVisibility(statusColorWin, null));
- appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
- & APPEARANCE_LIGHT_STATUS_BARS;
- } else if (statusColorWin != null && statusColorWin.isDimming()) {
- // Otherwise if it's dimming, clear the light flag.
- appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ if (statusColorWin != null) {
+ if (statusColorWin == opaque || onKeyguard) {
+ // If the top fullscreen-or-dimming window is also the top fullscreen, respect
+ // its light flag.
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ final int legacyAppearance = InsetsFlags.getAppearance(
+ PolicyControl.getSystemUiVisibility(statusColorWin, null));
+ appearance |= (statusColorWin.mAttrs.insetsFlags.appearance | legacyAppearance)
+ & APPEARANCE_LIGHT_STATUS_BARS;
+ } else if (statusColorWin.isDimming()) {
+ // Otherwise if it's dimming, clear the light flag.
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ }
+ if (!mStatusBarController.isLightAppearanceAllowed(statusColorWin)) {
+ appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+ }
}
return appearance;
}
@@ -3512,8 +3517,7 @@ public class DisplayPolicy {
return vis;
}
- @VisibleForTesting
- static int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque,
+ private int updateLightNavigationBarAppearanceLw(int appearance, WindowState opaque,
WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) {
if (navColorWin != null) {
@@ -3526,6 +3530,9 @@ public class DisplayPolicy {
// Clear the light flag for dimming window.
appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
}
+ if (!mNavigationBarController.isLightAppearanceAllowed(navColorWin)) {
+ appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
+ }
}
return appearance;
}
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index a685886da032..28dcbcdf3cc7 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -77,10 +77,10 @@ public class Letterbox {
mOuter.set(outer);
mInner.set(inner);
- mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin);
- mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin);
- mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
- mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin);
+ mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin);
+ 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);
}
@@ -101,6 +101,31 @@ public class Letterbox {
}
/**
+ * 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.
+ */
+ boolean notIntersectsOrFullyContains(Rect rect) {
+ int emptyCount = 0;
+ int noOverlappingCount = 0;
+ for (LetterboxSurface surface : mSurfaces) {
+ 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 (emptyCount + noOverlappingCount) == mSurfaces.length;
+ }
+
+ /**
* Returns true if any part of the letterbox overlaps with the given {@code rect}.
*/
public boolean isOverlappingWith(Rect rect) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 26bcf3b285ec..1f2a8f052a3e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3797,7 +3797,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mActivityRecord.getBounds().equals(mTmpRect);
}
- @Override
+ /**
+ * @see Letterbox#notIntersectsOrFullyContains(Rect)
+ */
+ boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+ return mActivityRecord == null
+ || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect);
+ }
+
public boolean isLetterboxedOverlappingWith(Rect rect) {
return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect);
}
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 bf84aecdb6a0..2f3004bf6832 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
@@ -60,6 +60,103 @@ public class LetterboxTest {
assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1)));
}
+ 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
+ public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() {
+ final Rect outer = new Rect(0, 0, 10, 50);
+ 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
public void testSurfaceOrigin_applied() {
mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));