Grant BAL privileges when starting for result
When an app starts an Activity for a result (e.g. using
Activity.startIntentSenderForResult) and passes in a valid (>=0)
resultCode, we consider this as an implicit opt-in to start that
Activity from the background using the the sender's privileges.
Test: atest BackgroundActivityLaunchTest
Bug: 314033453
Change-Id: I8593f13dc82a1d23b2ece7cf51fd8b7247dc1b48
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e5794a1..dfb2a5f 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1121,6 +1121,7 @@
callerApp,
request.originatingPendingIntent,
request.forcedBalByPiSender,
+ resultRecord,
intent,
checkedOptions);
request.logMessage.append(" (").append(balVerdict).append(")");
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 91f45a7..53f798e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -103,6 +103,7 @@
import static com.android.server.wm.ActivityInterceptorCallback.SYSTEM_LAST_ORDERED_ID;
import static com.android.server.wm.ActivityRecord.State.PAUSING;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -118,6 +119,7 @@
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
+import static com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
@@ -2242,7 +2244,7 @@
}
final BackgroundActivityStartController balController =
mTaskSupervisor.getBackgroundActivityLaunchController();
- if (balController.shouldAbortBackgroundActivityStart(
+ final BalVerdict balVerdict = balController.checkBackgroundActivityStart(
callingUid,
callingPid,
callingPackage,
@@ -2252,10 +2254,14 @@
null,
BackgroundStartPrivileges.NONE,
null,
- null)) {
- if (!isBackgroundActivityStartsEnabled()) {
- return;
- }
+ null,
+ null);
+ if (balVerdict.blocks() && !isBackgroundActivityStartsEnabled()) {
+ Slog.w(TAG, "moveTaskToFront blocked: " + balVerdict);
+ return;
+ }
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "moveTaskToFront allowed: " + balVerdict);
}
try {
final Task task = mRootWindowContainer.anyTaskForId(taskId);
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 761b0a8..50de0b0 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
+import static com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
@@ -31,6 +33,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.Slog;
/**
* An implementation of IAppTask, that allows an app to manage its own tasks via
@@ -123,7 +126,7 @@
}
final BackgroundActivityStartController balController =
mService.mTaskSupervisor.getBackgroundActivityLaunchController();
- if (balController.shouldAbortBackgroundActivityStart(
+ BalVerdict balVerdict = balController.checkBackgroundActivityStart(
callingUid,
callingPid,
callingPackage,
@@ -133,10 +136,14 @@
null,
BackgroundStartPrivileges.NONE,
null,
- null)) {
- if (!mService.isBackgroundActivityStartsEnabled()) {
- return;
- }
+ null,
+ null);
+ if (balVerdict.blocks() && !mService.isBackgroundActivityStartsEnabled()) {
+ Slog.w(TAG, "moveTaskToFront blocked: : " + balVerdict);
+ return;
+ }
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "moveTaskToFront allowed: " + balVerdict);
}
}
mService.mTaskSupervisor.startActivityFromRecents(callingPid, callingUid, mTaskId,
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 07dac54..92665af 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -205,27 +205,6 @@
return activity != null && packageName.equals(activity.getPackageName());
}
- /**
- * @see #checkBackgroundActivityStart(int, int, String, int, int, WindowProcessController,
- * PendingIntentRecord, BackgroundStartPrivileges, Intent, ActivityOptions)
- */
- boolean shouldAbortBackgroundActivityStart(
- int callingUid,
- int callingPid,
- final String callingPackage,
- int realCallingUid,
- int realCallingPid,
- WindowProcessController callerApp,
- PendingIntentRecord originatingPendingIntent,
- BackgroundStartPrivileges forcedBalByPiSender,
- Intent intent,
- ActivityOptions checkedOptions) {
- return checkBackgroundActivityStart(callingUid, callingPid, callingPackage,
- realCallingUid, realCallingPid,
- callerApp, originatingPendingIntent,
- forcedBalByPiSender, intent, checkedOptions).blocks();
- }
-
private class BalState {
private final String mCallingPackage;
@@ -255,6 +234,7 @@
WindowProcessController callerApp,
PendingIntentRecord originatingPendingIntent,
BackgroundStartPrivileges forcedBalByPiSender,
+ ActivityRecord resultRecord,
Intent intent,
ActivityOptions checkedOptions) {
this.mCallingPackage = callingPackage;
@@ -267,7 +247,9 @@
mOriginatingPendingIntent = originatingPendingIntent;
mIntent = intent;
mRealCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid);
- if (originatingPendingIntent == null) {
+ if (originatingPendingIntent == null // not a PendingIntent
+ || resultRecord != null // sent for result
+ ) {
// grant BAL privileges unless explicitly opted out
mBalAllowedByPiCreatorWithHardening = mBalAllowedByPiCreator =
checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
@@ -535,6 +517,7 @@
* @param forcedBalByPiSender If set to allow, the
* PendingIntent's sender will try to force allow background activity starts.
* This is only possible if the sender of the PendingIntent is a system process.
+ * @param resultRecord If not null, this indicates that the caller expects a result.
* @param intent Intent that should be started.
* @param checkedOptions ActivityOptions to allow specific opt-ins/opt outs.
*
@@ -550,6 +533,7 @@
WindowProcessController callerApp,
PendingIntentRecord originatingPendingIntent,
BackgroundStartPrivileges forcedBalByPiSender,
+ ActivityRecord resultRecord,
Intent intent,
ActivityOptions checkedOptions) {
@@ -560,7 +544,7 @@
BalState state = new BalState(callingUid, callingPid, callingPackage,
realCallingUid, realCallingPid, callerApp, originatingPendingIntent,
- forcedBalByPiSender, intent, checkedOptions);
+ forcedBalByPiSender, resultRecord, intent, checkedOptions);
// In the case of an SDK sandbox calling uid, check if the corresponding app uid has a
// visible window.