Allow background activity starts if realCallingUid is in
the foreground
Most notably adds support for:
- shortcuts (not PendingIntent-based, but realCallingUid is launcher,
which is foreground at the time of clicking)
- notifications, slices, actions and widgets (but only those that
are based on PendingIntent.getActivity() - trampolines are not yet
supported)
Note: this currently also allows PendingIntent-based starts for many
use cases where it's a persistent system process calling send(), but
we won't be allowing them anymore in forthcoming CLs (most notably
the AlarmManager use cases).
Bug: 110956953
Test: atest WmTests:ActivityStarterTests
Test: manual
Change-Id: I3c9de8cbe76bef5cc99d721536e19bb39b03405f
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 d78fbcd..f19e28d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -113,6 +113,7 @@
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 {
@@ -561,8 +562,10 @@
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);
}
/**
@@ -573,8 +576,11 @@
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);
}
/**
@@ -586,44 +592,77 @@
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();