Loading services/core/java/com/android/server/wm/ActivityStarter.java +5 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading @@ -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; Loading Loading @@ -1061,8 +1057,7 @@ class ActivityStarter { final ArraySet<Integer> 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; } } Loading services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -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); /** Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading services/core/java/com/android/server/wm/RootWindowContainer.java +4 −3 Original line number Diff line number Diff line Loading @@ -314,9 +314,10 @@ 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 */); return forAllWindows(w -> w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST && w.isVisibleNow(), true /* traverseTopToBottom */); } /** Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +16 −16 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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, Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +5 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading @@ -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; Loading Loading @@ -1061,8 +1057,7 @@ class ActivityStarter { final ArraySet<Integer> 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; } } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -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); /** Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -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) { Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +4 −3 Original line number Diff line number Diff line Loading @@ -314,9 +314,10 @@ 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 */); return forAllWindows(w -> w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST && w.isVisibleNow(), true /* traverseTopToBottom */); } /** Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +16 −16 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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, Loading