summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java63
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java40
2 files changed, 70 insertions, 33 deletions
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a9bb690d4e53..3858ffdd4467 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8835,48 +8835,45 @@ public class WindowManagerService extends IWindowManager.Stub
}
void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
- if (!win.hideNonSystemOverlayWindowsWhenVisible()
- && !mHidingNonSystemOverlayWindows.contains(win)) {
+ final boolean effective = (surfaceShown && win.hideNonSystemOverlayWindowsWhenVisible());
+ if (effective == mHidingNonSystemOverlayWindows.contains(win)) {
return;
}
- final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
- final int numUIDsRequestHidingPreUpdate = mHidingNonSystemOverlayWindowsCountPerUid.size();
- if (surfaceShown && win.hideNonSystemOverlayWindowsWhenVisible()) {
- if (!mHidingNonSystemOverlayWindows.contains(win)) {
- mHidingNonSystemOverlayWindows.add(win);
- int uid = win.getOwningUid();
- int count = mHidingNonSystemOverlayWindowsCountPerUid.getOrDefault(uid, 0);
- mHidingNonSystemOverlayWindowsCountPerUid.put(uid, count + 1);
- }
+
+ if (effective) {
+ mHidingNonSystemOverlayWindows.add(win);
} else {
mHidingNonSystemOverlayWindows.remove(win);
- int uid = win.getOwningUid();
- int count = mHidingNonSystemOverlayWindowsCountPerUid.getOrDefault(uid, 0);
- if (count <= 1) {
- mHidingNonSystemOverlayWindowsCountPerUid.remove(win.getOwningUid());
- } else {
- mHidingNonSystemOverlayWindowsCountPerUid.put(uid, count - 1);
- }
}
- final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
- final int numUIDSRequestHidingPostUpdate = mHidingNonSystemOverlayWindowsCountPerUid.size();
+
+ final boolean changed;
if (Flags.fixHideOverlayApi()) {
- if (numUIDSRequestHidingPostUpdate == numUIDsRequestHidingPreUpdate) {
- return;
- }
- // The visibility of SAWs needs to be refreshed only when the number of uids that
- // request hiding SAWs changes 0->1, 1->0, 1->2 or 2->1.
- if (numUIDSRequestHidingPostUpdate != 1 && numUIDsRequestHidingPreUpdate != 1) {
- return;
+ final int uid = win.getOwningUid();
+ final int numUIDsPreUpdate = mHidingNonSystemOverlayWindowsCountPerUid.size();
+ final int newCount = mHidingNonSystemOverlayWindowsCountPerUid.getOrDefault(uid, 0)
+ + (effective ? +1 : -1);
+ if (newCount <= 0) {
+ mHidingNonSystemOverlayWindowsCountPerUid.remove(uid);
+ } else {
+ mHidingNonSystemOverlayWindowsCountPerUid.put(uid, newCount);
}
+ final int numUIDsPostUpdate = mHidingNonSystemOverlayWindowsCountPerUid.size();
+ // The visibility of SAWs needs to be refreshed when the number of uids that
+ // request hiding SAWs changes between "0", "1", or "2+".
+ changed = (numUIDsPostUpdate != numUIDsPreUpdate)
+ && (numUIDsPostUpdate <= 1 || numUIDsPreUpdate <= 1);
} else {
- if (systemAlertWindowsHidden == hideSystemAlertWindows) {
- return;
- }
+ // The visibility of SAWs needs to be refreshed when the number of windows that
+ // request hiding SAWs changes between "0" or "1+".
+ changed = (effective && mHidingNonSystemOverlayWindows.size() == 1)
+ || (!effective && mHidingNonSystemOverlayWindows.isEmpty());
+ }
+
+ if (changed) {
+ mRoot.forAllWindows((w) -> {
+ w.setForceHideNonSystemOverlayWindowIfNeeded(shouldHideNonSystemOverlayWindow(w));
+ }, false /* traverseTopToBottom */);
}
- mRoot.forAllWindows((w) -> {
- w.setForceHideNonSystemOverlayWindowIfNeeded(shouldHideNonSystemOverlayWindow(w));
- }, false /* traverseTopToBottom */);
}
/** Called from Accessibility Controller to apply magnification spec */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 73102c4478d8..5427dc22e700 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -1486,6 +1486,46 @@ public class WindowManagerServiceTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(Flags.FLAG_FIX_HIDE_OVERLAY_API)
+ public void testUpdateOverlayWindows_multipleWindowsFromSameUid_idempotent() {
+ // Deny INTERNAL_SYSTEM_WINDOW permission for WindowSession so that the saw isn't allowed to
+ // show despite hideNonSystemOverlayWindows.
+ doReturn(PackageManager.PERMISSION_DENIED).when(mWm.mContext).checkPermission(
+ eq(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW), anyInt(), anyInt());
+
+ WindowState saw =
+ newWindowBuilder("saw", TYPE_APPLICATION_OVERLAY).setOwnerId(10123).build();
+ saw.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ saw.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
+ assertThat(saw.mSession.mCanAddInternalSystemWindow).isFalse();
+
+ WindowState app1 = newWindowBuilder("app1", TYPE_APPLICATION).setOwnerId(10456).build();
+ spyOn(app1);
+ doReturn(true).when(app1).hideNonSystemOverlayWindowsWhenVisible();
+
+ WindowState app2 = newWindowBuilder("app2", TYPE_APPLICATION).setOwnerId(10456).build();
+ spyOn(app2);
+ doReturn(true).when(app2).hideNonSystemOverlayWindowsWhenVisible();
+
+ makeWindowVisible(saw, app1, app2);
+ assertThat(saw.isVisibleByPolicy()).isTrue();
+
+ // Two hideNonSystemOverlayWindows windows: SAW is hidden.
+ mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(app1, true);
+ mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(app2, true);
+ assertThat(saw.isVisibleByPolicy()).isFalse();
+
+ // Marking the same window hidden twice: SAW is still hidden.
+ mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(app1, false);
+ mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(app1, false);
+ assertThat(saw.isVisibleByPolicy()).isFalse();
+
+ // Marking the remaining window hidden: SAW can be shown again.
+ mWm.updateNonSystemOverlayWindowsVisibilityIfNeeded(app2, false);
+ assertThat(saw.isVisibleByPolicy()).isTrue();
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
public void reparentWindowContextToDisplayArea_newDisplay_reparented() {
final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,