diff options
6 files changed, 120 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index b100ecdb0e73..a207354f6c88 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -945,7 +945,7 @@ class ActivityStarter { /** Returns true if uid has a visible window or its process is in a top state. */ private boolean isUidForeground(int uid) { return (mService.getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP) - || mService.mWindowManager.isAnyWindowVisibleForUid(uid); + || mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid); } /** Returns true if uid is in a persistent state. */ @@ -968,18 +968,19 @@ class ActivityStarter { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart"); final int callingUidProcState = mService.getUidStateLocked(callingUid); final boolean callingUidHasAnyVisibleWindow = - mService.mWindowManager.isAnyWindowVisibleForUid(callingUid); + mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid); final int realCallingUidProcState = (callingUid == realCallingUid) ? callingUidProcState : mService.getUidStateLocked(realCallingUid); final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid) ? callingUidHasAnyVisibleWindow - : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid); + : mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid( + realCallingUid); final String targetPackage = (r != null) ? r.packageName : null; final int targetUid = (r!= null) ? ((r.appInfo != null) ? r.appInfo.uid : -1) : -1; final int targetUidProcState = mService.getUidStateLocked(targetUid); final boolean targetUidHasAnyVisibleWindow = (targetUid != -1) - ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid) + ? mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(targetUid) : false; final String targetWhitelistTag = (targetUid != -1) ? mService.getPendingTempWhitelistTagForUidLocked(targetUid) diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 4e70bbc277d8..8fb79477eb2f 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE; import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; +import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; @@ -280,6 +281,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** + * Returns true if the callingUid has any non-toast window currently visible to the user. + */ + boolean isAnyNonToastWindowVisibleForUid(int callingUid) { + return forAllWindows(w -> { + return w.getOwningUid() == callingUid && w.isVisible() && w.mAttrs.type != TYPE_TOAST; + }, true /* traverseTopToBottom */); + } + + /** * Returns the app window token for the input binder if it exist in the system. * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since * AppWindowToken represents an activity which can only exist on one display. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9b82f5c66a1d..90506e744250 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5716,17 +5716,6 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * Returns true if the callingUid has any window currently visible to the user. - */ - public boolean isAnyWindowVisibleForUid(int callingUid) { - synchronized (mGlobalLock) { - return mRoot.forAllWindows(w -> { - return w.getOwningUid() == callingUid && w.isVisible(); - }, true /* traverseTopToBottom */); - } - } - - /** * Called when a task has been removed from the recent tasks list. * <p> * Note: This doesn't go through {@link TaskWindowContainerController} yet as the window diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 7a6b2b50d1e1..ec88718dab5d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -643,10 +643,10 @@ public class ActivityStarterTests extends ActivityTestsBase { boolean hasForegroundActivities, boolean callerIsRecents, boolean callerIsTempWhitelisted) { // window visibility - doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid( - callingUid); - doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager) - .isAnyWindowVisibleForUid(realCallingUid); + doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot) + .isAnyNonToastWindowVisibleForUid(callingUid); + doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager.mRoot) + .isAnyNonToastWindowVisibleForUid(realCallingUid); // process importance doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid); doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java new file mode 100644 index 000000000000..45fe5d24adf5 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_TOAST; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Tests for RootWindowContainer. + * + * Build/Install/Run: + * atest WmTests:RootWindowContainerTests + */ +@SmallTest +@Presubmit +public class RootWindowContainerTests extends WindowTestsBase { + + private static final int FAKE_CALLING_UID = 667; + + @Test + public void testIsAnyNonToastWindowVisibleForUid_oneToastOneNonToastBothVisible() { + final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID); + toastyToast.mHasSurface = true; + app.mHasSurface = true; + + assertTrue(toastyToast.isVisible()); + assertTrue(app.isVisible()); + assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); + } + + @Test + public void testIsAnyNonToastWindowVisibleForUid_onlyToastVisible() { + final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID); + toastyToast.mHasSurface = true; + + assertTrue(toastyToast.isVisible()); + assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); + } + + @Test + public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() { + final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID); + + assertFalse(topBar.isVisible()); + assertFalse(app.isVisible()); + assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); + } +} + diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 638cb03f4707..cdc0a477b9c6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -257,6 +257,14 @@ class WindowTestsBase { } } + WindowState createWindow(WindowState parent, int type, String name, int ownerId) { + synchronized (mWm.mGlobalLock) { + return (parent == null) + ? createWindow(parent, type, mDisplayContent, name, ownerId) + : createWindow(parent, type, parent.mToken, name, ownerId); + } + } + WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType, int type, DisplayContent dc, String name) { synchronized (mWm.mGlobalLock) { @@ -277,7 +285,16 @@ class WindowTestsBase { synchronized (mWm.mGlobalLock) { final WindowToken token = createWindowToken( dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type); - return createWindow(parent, type, token, name); + return createWindow(parent, type, token, name, 0 /* ownerId */); + } + } + + WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name, + int ownerId) { + synchronized (mWm.mGlobalLock) { + final WindowToken token = createWindowToken( + dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type); + return createWindow(parent, type, token, name, ownerId); } } @@ -299,6 +316,14 @@ class WindowTestsBase { } WindowState createWindow(WindowState parent, int type, WindowToken token, String name, + int ownerId) { + synchronized (mWm.mGlobalLock) { + return createWindow(parent, type, token, name, ownerId, + false /* ownerCanAddInternalSystemWindow */); + } + } + + WindowState createWindow(WindowState parent, int type, WindowToken token, String name, int ownerId, boolean ownerCanAddInternalSystemWindow) { return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow, mWm, mMockSession, mIWindow); |