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.