Loading services/core/java/com/android/server/wm/ActivityStarter.java +106 −38 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; Loading @@ -89,7 +91,9 @@ import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; Loading Loading @@ -153,6 +157,8 @@ import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import com.android.wm.shell.Flags; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.DateFormat; import java.util.Date; import java.util.function.Supplier; Loading @@ -166,6 +172,8 @@ import java.util.function.Supplier; class ActivityStarter { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM; private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; private static final int INVALID_LAUNCH_MODE = -1; Loading Loading @@ -247,7 +255,26 @@ class ActivityStarter { private boolean mIsTaskCleared; private boolean mMovedToFront; private boolean mNoAnimation; private boolean mAvoidMoveToFront; // TODO mAvoidMoveToFront before V is changed from a boolean to a int code mCanMoveToFrontCode // for the purpose of attribution of new BAL V feature. This should be reverted back to the // boolean flag post V. @IntDef(prefix = {"MOVE_TO_FRONT_"}, value = { MOVE_TO_FRONT_ALLOWED, MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS, MOVE_TO_FRONT_AVOID_LEGACY, }) @Retention(RetentionPolicy.SOURCE) public @interface MoveToFrontCode {} // Allows a task move to front. private static final int MOVE_TO_FRONT_ALLOWED = 0; // Avoid a task move to front because the Pending Intent that starts the activity only // its creator has the BAL privilege, its sender does not. private static final int MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS = 1; // Avoid a task move to front because of all other legacy reasons. private static final int MOVE_TO_FRONT_AVOID_LEGACY = 2; private @MoveToFrontCode int mCanMoveToFrontCode = MOVE_TO_FRONT_ALLOWED; private boolean mFrozeTaskList; private boolean mTransientLaunch; // The task which was above the targetTask before starting this activity. null if the targetTask Loading Loading @@ -744,7 +771,7 @@ class ActivityStarter { mIsTaskCleared = starter.mIsTaskCleared; mMovedToFront = starter.mMovedToFront; mNoAnimation = starter.mNoAnimation; mAvoidMoveToFront = starter.mAvoidMoveToFront; mCanMoveToFrontCode = starter.mCanMoveToFrontCode; mFrozeTaskList = starter.mFrozeTaskList; mVoiceSession = starter.mVoiceSession; Loading Loading @@ -1684,6 +1711,14 @@ class ActivityStarter { return result; } private boolean avoidMoveToFront() { return mCanMoveToFrontCode != MOVE_TO_FRONT_ALLOWED; } private boolean avoidMoveToFrontPIOnlyCreatorAllows() { return mCanMoveToFrontCode == MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS; } /** * If the start result is success, ensure that the configuration of the started activity matches * the current display. Otherwise clean up unassociated containers to avoid leakage. Loading Loading @@ -1733,7 +1768,7 @@ class ActivityStarter { startedActivityRootTask.setAlwaysOnTop(true); } if (isIndependentLaunch && !mDoResume && mAvoidMoveToFront && !mTransientLaunch if (isIndependentLaunch && !mDoResume && avoidMoveToFront() && !mTransientLaunch && !started.shouldBeVisible(true /* ignoringKeyguard */)) { Slog.i(TAG, "Abort " + transition + " of invisible launch " + started); transition.abort(); Loading @@ -1749,7 +1784,7 @@ class ActivityStarter { currentTop, currentTop.mDisplayContent, false /* deferResume */); } if (!mAvoidMoveToFront && mDoResume if (!avoidMoveToFront() && mDoResume && !mService.getUserManagerInternal().isVisibleBackgroundFullUser(started.mUserId) && mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade( started.launchedFromUid)) { Loading Loading @@ -1899,17 +1934,19 @@ class ActivityStarter { } // When running transient transition, the transient launch target should keep on top. // So disallow the transient hide activity to move itself to front, e.g. trampoline. if (!mAvoidMoveToFront && (mService.mHomeProcess == null if (!avoidMoveToFront() && (mService.mHomeProcess == null || mService.mHomeProcess.mUid != realCallingUid) && (prevTopTask != null && prevTopTask.isActivityTypeHomeOrRecents()) && r.mTransitionController.isTransientHide(targetTask)) { mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } // If the activity is started by sending a pending intent and only its creator has the // privilege to allow BAL (its sender does not), avoid move it to the front. Only do // this when it is not a new task and not already been marked as avoid move to front. if (!mAvoidMoveToFront && balVerdict.onlyCreatorAllows()) { mAvoidMoveToFront = true; // Guarded by a flag: balDontBringExistingBackgroundTaskStackToFg if (balDontBringExistingBackgroundTaskStackToFg() && !avoidMoveToFront() && balVerdict.onlyCreatorAllows()) { mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS; } mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask()); } Loading Loading @@ -1966,7 +2003,8 @@ class ActivityStarter { // After activity is attached to task, but before actual start recordTransientLaunchIfNeeded(mLastStartActivityRecord); if (!mAvoidMoveToFront && mDoResume) { if (mDoResume) { if (!avoidMoveToFront()) { mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask); final boolean launchBehindDream; Loading @@ -1989,6 +2027,9 @@ class ActivityStarter { mLaunchTaskBehind = true; r.mLaunchTaskBehind = true; } } else { logPIOnlyCreatorAllowsBAL(); } } mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, Loading Loading @@ -2048,9 +2089,13 @@ class ActivityStarter { // root-task to the will not update the focused root-task. If starting the new // activity now allows the task root-task to be focusable, then ensure that we // now update the focused root-task accordingly. if (!mAvoidMoveToFront && mTargetRootTask.isTopActivityFocusable() if (mTargetRootTask.isTopActivityFocusable() && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) { if (!avoidMoveToFront()) { mTargetRootTask.moveToFront("startActivityInner"); } else { logPIOnlyCreatorAllowsBAL(); } } mRootWindowContainer.resumeFocusedTasksTopActivities( mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); Loading Loading @@ -2078,6 +2123,26 @@ class ActivityStarter { return START_SUCCESS; } // TODO (b/316135632) Post V release, remove this log method. private void logPIOnlyCreatorAllowsBAL() { if (!avoidMoveToFrontPIOnlyCreatorAllows()) return; String realCallingPackage = mService.mContext.getPackageManager().getNameForUid(mRealCallingUid); if (realCallingPackage == null) { realCallingPackage = "uid=" + mRealCallingUid; } Slog.wtf(TAG, "Without Android 15 BAL hardening this activity would be moved to the " + "foreground. The activity is started by a PendingIntent. However, only the " + "creator of the PendingIntent allows BAL while the sender does not allow BAL. " + "realCallingPackage: " + realCallingPackage + "; callingPackage: " + mRequest.callingPackage + "; mTargetRootTask:" + mTargetRootTask + "; mIntent: " + mIntent + "; mTargetRootTask.getTopNonFinishingActivity: " + mTargetRootTask.getTopNonFinishingActivity() + "; mTargetRootTask.getRootActivity: " + mTargetRootTask.getRootActivity()); } private void recordTransientLaunchIfNeeded(ActivityRecord r) { if (r == null || !mTransientLaunch) return; final TransitionController controller = r.mTransitionController; Loading Loading @@ -2222,7 +2287,7 @@ class ActivityStarter { } if (!mSupervisor.getBackgroundActivityLaunchController().checkActivityAllowedToStart( mSourceRecord, r, newTask, mAvoidMoveToFront, targetTask, mLaunchFlags, mBalCode, mSourceRecord, r, newTask, avoidMoveToFront(), targetTask, mLaunchFlags, mBalCode, mCallingUid, mRealCallingUid, mPreferredTaskDisplayArea)) { return START_ABORTED; } Loading Loading @@ -2570,7 +2635,7 @@ class ActivityStarter { mIsTaskCleared = false; mMovedToFront = false; mNoAnimation = false; mAvoidMoveToFront = false; mCanMoveToFrontCode = MOVE_TO_FRONT_ALLOWED; mFrozeTaskList = false; mTransientLaunch = false; mPriorAboveTask = null; Loading Loading @@ -2682,12 +2747,12 @@ class ActivityStarter { // The caller specifies that we'd like to be avoided to be moved to the // front, so be it! mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } } } else if (mOptions.getAvoidMoveToFront()) { mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } mTransientLaunch = mOptions.getTransientLaunch(); final KeyguardController kc = mSupervisor.getKeyguardController(); Loading @@ -2697,7 +2762,7 @@ class ActivityStarter { if (mTransientLaunch && mDisplayLockAndOccluded && mService.getTransitionController().isShellTransitionsEnabled()) { mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); Loading Loading @@ -2754,7 +2819,7 @@ class ActivityStarter { mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) { mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; mDoResume = false; } } Loading Loading @@ -2985,7 +3050,7 @@ class ActivityStarter { differentTopTask = true; } if (differentTopTask && !mAvoidMoveToFront) { if (differentTopTask && !avoidMoveToFront()) { mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); // We really do want to push this one into the user's face, right now. if (mLaunchTaskBehind && mSourceRecord != null) { Loading Loading @@ -3029,6 +3094,9 @@ class ActivityStarter { } mOptions = null; } if (differentTopTask) { logPIOnlyCreatorAllowsBAL(); } // Update the target's launch cookie and pending remote animation to those specified in the // options if set. if (mStartActivity.mLaunchCookie != null) { Loading Loading @@ -3069,7 +3137,7 @@ class ActivityStarter { } private void setNewTask(Task taskToAffiliate) { final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront; final boolean toTop = !mLaunchTaskBehind && !avoidMoveToFront(); final Task task = mTargetRootTask.reuseOrCreateTask( mStartActivity.info, mIntent, mVoiceSession, mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); Loading services/core/java/com/android/server/wm/BackgroundActivityStartController.java +4 −1 Original line number Diff line number Diff line Loading @@ -45,11 +45,12 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONL import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel; import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS; import static com.android.window.flags.Flags.balAdditionalStartModes; import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg; import static com.android.window.flags.Flags.balImprovedMetrics; import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator; import static com.android.window.flags.Flags.balShowToastsBlocked; import static com.android.window.flags.Flags.balStrictModeGracePeriod; import static com.android.window.flags.Flags.balStrictModeRo; import static com.android.window.flags.Flags.balStrictModeGracePeriod; import static java.lang.annotation.RetentionPolicy.SOURCE; import static java.util.Objects.requireNonNull; Loading Loading @@ -619,6 +620,8 @@ public class BackgroundActivityStartController { // features sb.append("; balRequireOptInByPendingIntentCreator: ") .append(balRequireOptInByPendingIntentCreator()); sb.append("; balDontBringExistingBackgroundTaskStackToFg: ") .append(balDontBringExistingBackgroundTaskStackToFg()); sb.append("]"); return sb.toString(); } Loading services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java +4 −2 Original line number Diff line number Diff line Loading @@ -589,7 +589,8 @@ public class BackgroundActivityStartControllerTests { + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_BAL; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true]"); + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } @Test Loading Loading @@ -691,6 +692,7 @@ public class BackgroundActivityStartControllerTests { + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_FGS; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true]"); + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } } Loading
services/core/java/com/android/server/wm/ActivityStarter.java +106 −38 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; Loading @@ -89,7 +91,9 @@ import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; Loading Loading @@ -153,6 +157,8 @@ import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import com.android.wm.shell.Flags; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.DateFormat; import java.util.Date; import java.util.function.Supplier; Loading @@ -166,6 +172,8 @@ import java.util.function.Supplier; class ActivityStarter { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM; private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; private static final int INVALID_LAUNCH_MODE = -1; Loading Loading @@ -247,7 +255,26 @@ class ActivityStarter { private boolean mIsTaskCleared; private boolean mMovedToFront; private boolean mNoAnimation; private boolean mAvoidMoveToFront; // TODO mAvoidMoveToFront before V is changed from a boolean to a int code mCanMoveToFrontCode // for the purpose of attribution of new BAL V feature. This should be reverted back to the // boolean flag post V. @IntDef(prefix = {"MOVE_TO_FRONT_"}, value = { MOVE_TO_FRONT_ALLOWED, MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS, MOVE_TO_FRONT_AVOID_LEGACY, }) @Retention(RetentionPolicy.SOURCE) public @interface MoveToFrontCode {} // Allows a task move to front. private static final int MOVE_TO_FRONT_ALLOWED = 0; // Avoid a task move to front because the Pending Intent that starts the activity only // its creator has the BAL privilege, its sender does not. private static final int MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS = 1; // Avoid a task move to front because of all other legacy reasons. private static final int MOVE_TO_FRONT_AVOID_LEGACY = 2; private @MoveToFrontCode int mCanMoveToFrontCode = MOVE_TO_FRONT_ALLOWED; private boolean mFrozeTaskList; private boolean mTransientLaunch; // The task which was above the targetTask before starting this activity. null if the targetTask Loading Loading @@ -744,7 +771,7 @@ class ActivityStarter { mIsTaskCleared = starter.mIsTaskCleared; mMovedToFront = starter.mMovedToFront; mNoAnimation = starter.mNoAnimation; mAvoidMoveToFront = starter.mAvoidMoveToFront; mCanMoveToFrontCode = starter.mCanMoveToFrontCode; mFrozeTaskList = starter.mFrozeTaskList; mVoiceSession = starter.mVoiceSession; Loading Loading @@ -1684,6 +1711,14 @@ class ActivityStarter { return result; } private boolean avoidMoveToFront() { return mCanMoveToFrontCode != MOVE_TO_FRONT_ALLOWED; } private boolean avoidMoveToFrontPIOnlyCreatorAllows() { return mCanMoveToFrontCode == MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS; } /** * If the start result is success, ensure that the configuration of the started activity matches * the current display. Otherwise clean up unassociated containers to avoid leakage. Loading Loading @@ -1733,7 +1768,7 @@ class ActivityStarter { startedActivityRootTask.setAlwaysOnTop(true); } if (isIndependentLaunch && !mDoResume && mAvoidMoveToFront && !mTransientLaunch if (isIndependentLaunch && !mDoResume && avoidMoveToFront() && !mTransientLaunch && !started.shouldBeVisible(true /* ignoringKeyguard */)) { Slog.i(TAG, "Abort " + transition + " of invisible launch " + started); transition.abort(); Loading @@ -1749,7 +1784,7 @@ class ActivityStarter { currentTop, currentTop.mDisplayContent, false /* deferResume */); } if (!mAvoidMoveToFront && mDoResume if (!avoidMoveToFront() && mDoResume && !mService.getUserManagerInternal().isVisibleBackgroundFullUser(started.mUserId) && mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade( started.launchedFromUid)) { Loading Loading @@ -1899,17 +1934,19 @@ class ActivityStarter { } // When running transient transition, the transient launch target should keep on top. // So disallow the transient hide activity to move itself to front, e.g. trampoline. if (!mAvoidMoveToFront && (mService.mHomeProcess == null if (!avoidMoveToFront() && (mService.mHomeProcess == null || mService.mHomeProcess.mUid != realCallingUid) && (prevTopTask != null && prevTopTask.isActivityTypeHomeOrRecents()) && r.mTransitionController.isTransientHide(targetTask)) { mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } // If the activity is started by sending a pending intent and only its creator has the // privilege to allow BAL (its sender does not), avoid move it to the front. Only do // this when it is not a new task and not already been marked as avoid move to front. if (!mAvoidMoveToFront && balVerdict.onlyCreatorAllows()) { mAvoidMoveToFront = true; // Guarded by a flag: balDontBringExistingBackgroundTaskStackToFg if (balDontBringExistingBackgroundTaskStackToFg() && !avoidMoveToFront() && balVerdict.onlyCreatorAllows()) { mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS; } mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask()); } Loading Loading @@ -1966,7 +2003,8 @@ class ActivityStarter { // After activity is attached to task, but before actual start recordTransientLaunchIfNeeded(mLastStartActivityRecord); if (!mAvoidMoveToFront && mDoResume) { if (mDoResume) { if (!avoidMoveToFront()) { mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask); final boolean launchBehindDream; Loading @@ -1989,6 +2027,9 @@ class ActivityStarter { mLaunchTaskBehind = true; r.mLaunchTaskBehind = true; } } else { logPIOnlyCreatorAllowsBAL(); } } mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, Loading Loading @@ -2048,9 +2089,13 @@ class ActivityStarter { // root-task to the will not update the focused root-task. If starting the new // activity now allows the task root-task to be focusable, then ensure that we // now update the focused root-task accordingly. if (!mAvoidMoveToFront && mTargetRootTask.isTopActivityFocusable() if (mTargetRootTask.isTopActivityFocusable() && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) { if (!avoidMoveToFront()) { mTargetRootTask.moveToFront("startActivityInner"); } else { logPIOnlyCreatorAllowsBAL(); } } mRootWindowContainer.resumeFocusedTasksTopActivities( mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); Loading Loading @@ -2078,6 +2123,26 @@ class ActivityStarter { return START_SUCCESS; } // TODO (b/316135632) Post V release, remove this log method. private void logPIOnlyCreatorAllowsBAL() { if (!avoidMoveToFrontPIOnlyCreatorAllows()) return; String realCallingPackage = mService.mContext.getPackageManager().getNameForUid(mRealCallingUid); if (realCallingPackage == null) { realCallingPackage = "uid=" + mRealCallingUid; } Slog.wtf(TAG, "Without Android 15 BAL hardening this activity would be moved to the " + "foreground. The activity is started by a PendingIntent. However, only the " + "creator of the PendingIntent allows BAL while the sender does not allow BAL. " + "realCallingPackage: " + realCallingPackage + "; callingPackage: " + mRequest.callingPackage + "; mTargetRootTask:" + mTargetRootTask + "; mIntent: " + mIntent + "; mTargetRootTask.getTopNonFinishingActivity: " + mTargetRootTask.getTopNonFinishingActivity() + "; mTargetRootTask.getRootActivity: " + mTargetRootTask.getRootActivity()); } private void recordTransientLaunchIfNeeded(ActivityRecord r) { if (r == null || !mTransientLaunch) return; final TransitionController controller = r.mTransitionController; Loading Loading @@ -2222,7 +2287,7 @@ class ActivityStarter { } if (!mSupervisor.getBackgroundActivityLaunchController().checkActivityAllowedToStart( mSourceRecord, r, newTask, mAvoidMoveToFront, targetTask, mLaunchFlags, mBalCode, mSourceRecord, r, newTask, avoidMoveToFront(), targetTask, mLaunchFlags, mBalCode, mCallingUid, mRealCallingUid, mPreferredTaskDisplayArea)) { return START_ABORTED; } Loading Loading @@ -2570,7 +2635,7 @@ class ActivityStarter { mIsTaskCleared = false; mMovedToFront = false; mNoAnimation = false; mAvoidMoveToFront = false; mCanMoveToFrontCode = MOVE_TO_FRONT_ALLOWED; mFrozeTaskList = false; mTransientLaunch = false; mPriorAboveTask = null; Loading Loading @@ -2682,12 +2747,12 @@ class ActivityStarter { // The caller specifies that we'd like to be avoided to be moved to the // front, so be it! mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } } } else if (mOptions.getAvoidMoveToFront()) { mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } mTransientLaunch = mOptions.getTransientLaunch(); final KeyguardController kc = mSupervisor.getKeyguardController(); Loading @@ -2697,7 +2762,7 @@ class ActivityStarter { if (mTransientLaunch && mDisplayLockAndOccluded && mService.getTransitionController().isShellTransitionsEnabled()) { mDoResume = false; mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; } mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); Loading Loading @@ -2754,7 +2819,7 @@ class ActivityStarter { mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; if (mBalCode == BAL_BLOCK && !mService.isBackgroundActivityStartsEnabled()) { mAvoidMoveToFront = true; mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY; mDoResume = false; } } Loading Loading @@ -2985,7 +3050,7 @@ class ActivityStarter { differentTopTask = true; } if (differentTopTask && !mAvoidMoveToFront) { if (differentTopTask && !avoidMoveToFront()) { mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); // We really do want to push this one into the user's face, right now. if (mLaunchTaskBehind && mSourceRecord != null) { Loading Loading @@ -3029,6 +3094,9 @@ class ActivityStarter { } mOptions = null; } if (differentTopTask) { logPIOnlyCreatorAllowsBAL(); } // Update the target's launch cookie and pending remote animation to those specified in the // options if set. if (mStartActivity.mLaunchCookie != null) { Loading Loading @@ -3069,7 +3137,7 @@ class ActivityStarter { } private void setNewTask(Task taskToAffiliate) { final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront; final boolean toTop = !mLaunchTaskBehind && !avoidMoveToFront(); final Task task = mTargetRootTask.reuseOrCreateTask( mStartActivity.info, mIntent, mVoiceSession, mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); Loading
services/core/java/com/android/server/wm/BackgroundActivityStartController.java +4 −1 Original line number Diff line number Diff line Loading @@ -45,11 +45,12 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONL import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel; import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS; import static com.android.window.flags.Flags.balAdditionalStartModes; import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg; import static com.android.window.flags.Flags.balImprovedMetrics; import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator; import static com.android.window.flags.Flags.balShowToastsBlocked; import static com.android.window.flags.Flags.balStrictModeGracePeriod; import static com.android.window.flags.Flags.balStrictModeRo; import static com.android.window.flags.Flags.balStrictModeGracePeriod; import static java.lang.annotation.RetentionPolicy.SOURCE; import static java.util.Objects.requireNonNull; Loading Loading @@ -619,6 +620,8 @@ public class BackgroundActivityStartController { // features sb.append("; balRequireOptInByPendingIntentCreator: ") .append(balRequireOptInByPendingIntentCreator()); sb.append("; balDontBringExistingBackgroundTaskStackToFg: ") .append(balDontBringExistingBackgroundTaskStackToFg()); sb.append("]"); return sb.toString(); } Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java +4 −2 Original line number Diff line number Diff line Loading @@ -589,7 +589,8 @@ public class BackgroundActivityStartControllerTests { + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_BAL; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true]"); + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } @Test Loading Loading @@ -691,6 +692,7 @@ public class BackgroundActivityStartControllerTests { + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_FGS; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true]"); + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } }