diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 473a8757f09fd..895744424ee1f 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -937,7 +937,7 @@ class ActivityStarter { || callingUid == Process.NFC_UID) { return false; } - // don't abort if the callingUid is in the foreground or is a persistent system process + // don't abort if the callingUid has a visible window or is a persistent system process final int callingUidProcState = mService.getUidState(callingUid); final boolean callingUidHasAnyVisibleWindow = mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid); @@ -946,7 +946,7 @@ class ActivityStarter { || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID) || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; - if (isCallingUidForeground || isCallingUidPersistentSystemProcess) { + if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) { return false; } // take realCallingUid into consideration @@ -965,8 +965,8 @@ class ActivityStarter { : (realCallingUid == Process.SYSTEM_UID) || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (realCallingUid != callingUid) { - // don't abort if the realCallingUid is in the foreground and callingUid isn't - if (isRealCallingUidForeground) { + // don't abort if the realCallingUid has a visible window + if (realCallingUidHasAnyVisibleWindow) { return false; } // if the realCallingUid is a persistent system process, abort if the IntentSender @@ -988,10 +988,6 @@ class ActivityStarter { callerApp = mService.getProcessController(realCallingPid, realCallingUid); } if (callerApp != null) { - // don't abort if the callerApp has any visible activity - if (callerApp.hasForegroundActivities()) { - return false; - } // don't abort if the callerApp is instrumenting with background activity starts privs if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) { return false; @@ -1061,8 +1057,7 @@ class ActivityStarter { final ArraySet boundClientUids = callerApp.getBoundClientUids(); for (int i = boundClientUids.size() - 1; i >= 0; --i) { final int uid = boundClientUids.valueAt(i); - if (mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid) - || mService.getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) { + if (mService.isUidForeground(uid)) { return true; } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 7d25466bf348a..48aee200ccc06 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -503,7 +503,7 @@ public abstract class ActivityTaskManagerInternal { public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution); - /** Returns true if uid has a visible window or its process is in a top state. */ + /** Returns true if uid is considered foreground for activity start purposes. */ public abstract boolean isUidForeground(int uid); /** diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index b4249046c1b58..22e6a35732b4b 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -5872,8 +5872,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } boolean isUidForeground(int uid) { - return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) - || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid); + // A uid is considered to be foreground if it has a visible non-toast window. + return mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid); } boolean isDeviceOwner(int uid) { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 1ca31f127b0d7..f9fd54178ca72 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -314,9 +314,10 @@ class RootWindowContainer extends WindowContainer * 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 */); + return forAllWindows(w -> + w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST + && w.isVisibleNow(), + true /* traverseTopToBottom */); } /** 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 44aa55d07133d..45d52195c5fde 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -577,12 +577,27 @@ public class ActivityStarterTests extends ActivityTestsBase { UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false, false, false, false, false); + runAndVerifyBackgroundActivityStartsSubtest( + "disallowed_callingUidProcessStateTop_aborted", true, + UNIMPORTANT_UID, false, PROCESS_STATE_TOP, + UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, + false, false, false, false, false, false); + runAndVerifyBackgroundActivityStartsSubtest( + "disallowed_realCallingUidProcessStateTop_aborted", true, + UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, + UNIMPORTANT_UID2, false, PROCESS_STATE_TOP, + false, false, false, false, false, false); + runAndVerifyBackgroundActivityStartsSubtest( + "disallowed_hasForegroundActivities_aborted", true, + UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, + UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, + true, false, false, false, false, false); } /** * This test ensures that supported usecases aren't aborted when background starts are * disallowed. - * The scenarios each have only one condidion that makes them supported. + * The scenarios each have only one condition that makes them supported. */ @Test public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() { @@ -605,26 +620,11 @@ public class ActivityStarterTests extends ActivityTestsBase { UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false, false, false, false, false); - runAndVerifyBackgroundActivityStartsSubtest( - "disallowed_callingUidProcessStateTop_notAborted", false, - UNIMPORTANT_UID, false, PROCESS_STATE_TOP, - UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - false, false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1, false, false, false, false, false, false); - runAndVerifyBackgroundActivityStartsSubtest( - "disallowed_realCallingUidProcessStateTop_notAborted", false, - UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, - UNIMPORTANT_UID2, false, PROCESS_STATE_TOP, - false, false, false, false, false, false); - runAndVerifyBackgroundActivityStartsSubtest( - "disallowed_hasForegroundActivities_notAborted", false, - UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, - UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, - true, false, false, false, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 35a8ec37c758a..263f6501bbf6e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -50,8 +50,8 @@ public class RootWindowContainerTests extends WindowTestsBase { toastyToast.mHasSurface = true; app.mHasSurface = true; - assertTrue(toastyToast.isVisible()); - assertTrue(app.isVisible()); + assertTrue(toastyToast.isVisibleNow()); + assertTrue(app.isVisibleNow()); assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); } @@ -60,7 +60,7 @@ public class RootWindowContainerTests extends WindowTestsBase { final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID); toastyToast.mHasSurface = true; - assertTrue(toastyToast.isVisible()); + assertTrue(toastyToast.isVisibleNow()); assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); } @@ -69,8 +69,8 @@ public class RootWindowContainerTests extends WindowTestsBase { 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(topBar.isVisibleNow()); + assertFalse(app.isVisibleNow()); assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); }