Loading services/core/java/com/android/server/wm/WindowManagerService.java +30 −33 Original line number Diff line number Diff line Loading @@ -8843,49 +8843,46 @@ 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)) { if (effective) { mHidingNonSystemOverlayWindows.add(win); int uid = win.getOwningUid(); int count = mHidingNonSystemOverlayWindowsCountPerUid.getOrDefault(uid, 0); mHidingNonSystemOverlayWindowsCountPerUid.put(uid, count + 1); } } 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 { if (systemAlertWindowsHidden == hideSystemAlertWindows) { return; 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 { // 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 */); } } /** Called from Accessibility Controller to apply magnification spec */ public void applyMagnificationSpecLocked(int displayId, MagnificationSpec spec) { Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -1485,6 +1485,46 @@ public class WindowManagerServiceTests extends WindowTestsBase { verify(overlayWindow).setForceHideNonSystemOverlayWindowIfNeeded(true); } @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() { Loading Loading
services/core/java/com/android/server/wm/WindowManagerService.java +30 −33 Original line number Diff line number Diff line Loading @@ -8843,49 +8843,46 @@ 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)) { if (effective) { mHidingNonSystemOverlayWindows.add(win); int uid = win.getOwningUid(); int count = mHidingNonSystemOverlayWindowsCountPerUid.getOrDefault(uid, 0); mHidingNonSystemOverlayWindowsCountPerUid.put(uid, count + 1); } } 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 { if (systemAlertWindowsHidden == hideSystemAlertWindows) { return; 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 { // 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 */); } } /** Called from Accessibility Controller to apply magnification spec */ public void applyMagnificationSpecLocked(int displayId, MagnificationSpec spec) { Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -1485,6 +1485,46 @@ public class WindowManagerServiceTests extends WindowTestsBase { verify(overlayWindow).setForceHideNonSystemOverlayWindowIfNeeded(true); } @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() { Loading