Loading services/core/java/com/android/server/wm/ActivityStarter.java +13 −6 Original line number Diff line number Diff line Loading @@ -738,7 +738,8 @@ class ActivityStarter { // not sure if we need to create START_ABORTED_BACKGROUND so for now piggybacking // on START_ABORTED if (!abort) { abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, callerApp); abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, realCallingUid, callerApp); } // Merge the two options bundles, while realCallerOptions takes precedence. Loading Loading @@ -886,7 +887,7 @@ class ActivityStarter { } private boolean shouldAbortBackgroundActivityStart(int callingUid, final String callingPackage, WindowProcessController callerApp) { int realCallingUid, WindowProcessController callerApp) { if (mService.isBackgroundActivityStartsEnabled()) { return false; } Loading @@ -898,12 +899,12 @@ class ActivityStarter { if (callerApp != null && callerApp.hasForegroundActivities()) { return false; } // don't abort if the callingUid's process is important enough if (mService.getUidStateLocked(callingUid) <= ActivityManager.PROCESS_STATE_TOP) { // don't abort if the callingUid is in the foreground if (isUidForeground(callingUid)) { return false; } // don't abort if the callingUid has any visible window if (mService.mWindowManager.isAnyWindowVisibleForUid(callingUid)) { // don't abort if the realCallingUid is in the foreground and callingUid isn't if ((realCallingUid != callingUid) && isUidForeground(realCallingUid)) { return false; } // don't abort if the caller has the same uid as the recents component Loading @@ -920,6 +921,12 @@ class ActivityStarter { return true; } /** Returns true if uid has a visible window or its process is in top or persistent state. */ private boolean isUidForeground(int uid) { return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_TOP) || mService.mWindowManager.isAnyWindowVisibleForUid(uid); } private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid, Intent intent, WindowProcessController callerApp, ActivityRecord r, PendingIntentRecord originatingPendingIntent, boolean abortedStart) { Loading services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +64 −25 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ public class ActivityStarterTests extends ActivityTestsBase { private static final int FAKE_REAL_CALLING_UID = 667; private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude"; private static final int UNIMPORTANT_UID = 12345; private static final int UNIMPORTANT_UID2 = 12346; @Before public void setUp() throws Exception { Loading Loading @@ -561,8 +562,10 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsAllowed_noStartsAborted() { doReturn(true).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); } /** Loading @@ -573,8 +576,11 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsDisallowed_unsupportedStartsAborted() { doReturn(false).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("disallowed_unsupportedUsecase_aborted", true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_unsupportedUsecase_aborted", true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); } /** Loading @@ -586,44 +592,77 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() { doReturn(false).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasVisibleWindow_notAborted", false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_processStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasForegroundActivities_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, true, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, true); runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_hasForegroundActivities_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, true, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, true); } private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted, int testCallingUid, boolean hasVisibleWindow, int procState, int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState, int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState, boolean hasForegroundActivities, boolean callerIsRecents) { // window visibility doReturn(hasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid( testCallingUid); doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid( callingUid); doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager) .isAnyWindowVisibleForUid(realCallingUid); // process importance doReturn(procState).when(mService).getUidStateLocked(testCallingUid); doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid); doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid); // foreground activities final IApplicationThread caller = mock(IApplicationThread.class); final ApplicationInfo ai = new ApplicationInfo(); ai.uid = testCallingUid; ai.uid = callingUid; final WindowProcessController callerApp = new WindowProcessController(mService, ai, null, testCallingUid, -1, null, null); new WindowProcessController(mService, ai, null, callingUid, -1, null, null); callerApp.setHasForegroundActivities(hasForegroundActivities); doReturn(callerApp).when(mService).getProcessController(caller); // caller is recents RecentTasks recentTasks = mock(RecentTasks.class); mService.mStackSupervisor.setRecentTasks(recentTasks); doReturn(callerIsRecents).when(recentTasks).isCallerRecents(testCallingUid); doReturn(callerIsRecents).when(recentTasks).isCallerRecents(callingUid); final ActivityOptions options = spy(ActivityOptions.makeBasic()); ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK).setCaller(caller) .setCallingUid(testCallingUid).setActivityOptions(new SafeActivityOptions(options)); ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK) .setCaller(caller) .setCallingUid(callingUid) .setRealCallingUid(realCallingUid) .setActivityOptions(new SafeActivityOptions(options)); final int result = starter.setReason("testBackgroundActivityStarts_" + name).execute(); Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +13 −6 Original line number Diff line number Diff line Loading @@ -738,7 +738,8 @@ class ActivityStarter { // not sure if we need to create START_ABORTED_BACKGROUND so for now piggybacking // on START_ABORTED if (!abort) { abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, callerApp); abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, realCallingUid, callerApp); } // Merge the two options bundles, while realCallerOptions takes precedence. Loading Loading @@ -886,7 +887,7 @@ class ActivityStarter { } private boolean shouldAbortBackgroundActivityStart(int callingUid, final String callingPackage, WindowProcessController callerApp) { int realCallingUid, WindowProcessController callerApp) { if (mService.isBackgroundActivityStartsEnabled()) { return false; } Loading @@ -898,12 +899,12 @@ class ActivityStarter { if (callerApp != null && callerApp.hasForegroundActivities()) { return false; } // don't abort if the callingUid's process is important enough if (mService.getUidStateLocked(callingUid) <= ActivityManager.PROCESS_STATE_TOP) { // don't abort if the callingUid is in the foreground if (isUidForeground(callingUid)) { return false; } // don't abort if the callingUid has any visible window if (mService.mWindowManager.isAnyWindowVisibleForUid(callingUid)) { // don't abort if the realCallingUid is in the foreground and callingUid isn't if ((realCallingUid != callingUid) && isUidForeground(realCallingUid)) { return false; } // don't abort if the caller has the same uid as the recents component Loading @@ -920,6 +921,12 @@ class ActivityStarter { return true; } /** Returns true if uid has a visible window or its process is in top or persistent state. */ private boolean isUidForeground(int uid) { return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_TOP) || mService.mWindowManager.isAnyWindowVisibleForUid(uid); } private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid, Intent intent, WindowProcessController callerApp, ActivityRecord r, PendingIntentRecord originatingPendingIntent, boolean abortedStart) { Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +64 −25 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ public class ActivityStarterTests extends ActivityTestsBase { private static final int FAKE_REAL_CALLING_UID = 667; private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude"; private static final int UNIMPORTANT_UID = 12345; private static final int UNIMPORTANT_UID2 = 12346; @Before public void setUp() throws Exception { Loading Loading @@ -561,8 +562,10 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsAllowed_noStartsAborted() { doReturn(true).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); } /** Loading @@ -573,8 +576,11 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsDisallowed_unsupportedStartsAborted() { doReturn(false).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("disallowed_unsupportedUsecase_aborted", true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_unsupportedUsecase_aborted", true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); } /** Loading @@ -586,44 +592,77 @@ public class ActivityStarterTests extends ActivityTestsBase { public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() { doReturn(false).when(mService).isBackgroundActivityStartsEnabled(); runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasVisibleWindow_notAborted", false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_processStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasForegroundActivities_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, true, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, true); runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidHasVisibleWindow_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_realCallingUidProcessStateTop_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP, false, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_hasForegroundActivities_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, true, false); runAndVerifyBackgroundActivityStartsSubtest( "disallowed_callerIsRecents_notAborted", false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1, false, true); } private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted, int testCallingUid, boolean hasVisibleWindow, int procState, int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState, int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState, boolean hasForegroundActivities, boolean callerIsRecents) { // window visibility doReturn(hasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid( testCallingUid); doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid( callingUid); doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager) .isAnyWindowVisibleForUid(realCallingUid); // process importance doReturn(procState).when(mService).getUidStateLocked(testCallingUid); doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid); doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid); // foreground activities final IApplicationThread caller = mock(IApplicationThread.class); final ApplicationInfo ai = new ApplicationInfo(); ai.uid = testCallingUid; ai.uid = callingUid; final WindowProcessController callerApp = new WindowProcessController(mService, ai, null, testCallingUid, -1, null, null); new WindowProcessController(mService, ai, null, callingUid, -1, null, null); callerApp.setHasForegroundActivities(hasForegroundActivities); doReturn(callerApp).when(mService).getProcessController(caller); // caller is recents RecentTasks recentTasks = mock(RecentTasks.class); mService.mStackSupervisor.setRecentTasks(recentTasks); doReturn(callerIsRecents).when(recentTasks).isCallerRecents(testCallingUid); doReturn(callerIsRecents).when(recentTasks).isCallerRecents(callingUid); final ActivityOptions options = spy(ActivityOptions.makeBasic()); ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK).setCaller(caller) .setCallingUid(testCallingUid).setActivityOptions(new SafeActivityOptions(options)); ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK) .setCaller(caller) .setCallingUid(callingUid) .setRealCallingUid(realCallingUid) .setActivityOptions(new SafeActivityOptions(options)); final int result = starter.setReason("testBackgroundActivityStarts_" + name).execute(); Loading