summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Achim Thesmann <achim@google.com> 2025-01-28 10:55:19 -0800
committer Achim Thesmann <achim@google.com> 2025-01-28 10:57:09 -0800
commit051fc54272fd6014d62cf0f2e95d45f203b65bdf (patch)
tree303f946b172707add27ba9e322a72c2d1855b297
parentac6c0a5c880b06c4e9417ef3cd4c92a5383a820d (diff)
Revert "Remove wtf log for PendingIntent only creator allows BAL"
This reverts commit ac6c0a5c880b06c4e9417ef3cd4c92a5383a820d. Reason for revert: Without a log it is impossible to identify why a task stack is not moved to front Change-Id: I266445743ae203f9ba8db22bd46304ae046b34f9
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java144
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java6
3 files changed, 114 insertions, 41 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 81c7807311dd..c7d4467a6e98 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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;
@@ -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.
@@ -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();
@@ -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)) {
@@ -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());
}
@@ -1966,28 +2003,32 @@ class ActivityStarter {
// After activity is attached to task, but before actual start
recordTransientLaunchIfNeeded(mLastStartActivityRecord);
- if (!mAvoidMoveToFront && mDoResume) {
- mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
+ if (mDoResume) {
+ if (!avoidMoveToFront()) {
+ mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
+
+ final boolean launchBehindDream;
+ if (com.android.window.flags.Flags.removeActivityStarterDreamCallback()) {
+ final TaskDisplayArea tda = mTargetRootTask.getTaskDisplayArea();
+ final Task top = (tda != null ? tda.getTopRootTask() : null);
+ launchBehindDream = (top != null && top != mTargetRootTask)
+ && top.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_DREAM
+ && top.getTopNonFinishingActivity() != null;
+ } else {
+ launchBehindDream = !mTargetRootTask.isTopRootTaskInDisplayArea()
+ && mService.isDreaming()
+ && !dreamStopping;
+ }
- final boolean launchBehindDream;
- if (com.android.window.flags.Flags.removeActivityStarterDreamCallback()) {
- final TaskDisplayArea tda = mTargetRootTask.getTaskDisplayArea();
- final Task top = (tda != null ? tda.getTopRootTask() : null);
- launchBehindDream = (top != null && top != mTargetRootTask)
- && top.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_DREAM
- && top.getTopNonFinishingActivity() != null;
+ if (launchBehindDream) {
+ // Launching underneath dream activity (fullscreen, always-on-top). Run the
+ // launch--behind transition so the Activity gets created and starts
+ // in visible state.
+ mLaunchTaskBehind = true;
+ r.mLaunchTaskBehind = true;
+ }
} else {
- launchBehindDream = !mTargetRootTask.isTopRootTaskInDisplayArea()
- && mService.isDreaming()
- && !dreamStopping;
- }
-
- if (launchBehindDream) {
- // Launching underneath dream activity (fullscreen, always-on-top). Run the
- // launch--behind transition so the Activity gets created and starts
- // in visible state.
- mLaunchTaskBehind = true;
- r.mLaunchTaskBehind = true;
+ logPIOnlyCreatorAllowsBAL();
}
}
@@ -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)) {
- mTargetRootTask.moveToFront("startActivityInner");
+ if (!avoidMoveToFront()) {
+ mTargetRootTask.moveToFront("startActivityInner");
+ } else {
+ logPIOnlyCreatorAllowsBAL();
+ }
}
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
@@ -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;
@@ -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;
}
@@ -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;
@@ -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();
@@ -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());
@@ -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;
}
}
@@ -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) {
@@ -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) {
@@ -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);
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 6df01f4b328b..119709e86551 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -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;
@@ -619,6 +620,8 @@ public class BackgroundActivityStartController {
// features
sb.append("; balRequireOptInByPendingIntentCreator: ")
.append(balRequireOptInByPendingIntentCreator());
+ sb.append("; balDontBringExistingBackgroundTaskStackToFg: ")
+ .append(balDontBringExistingBackgroundTaskStackToFg());
sb.append("]");
return sb.toString();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
index 902a58379ae0..51706d72cb35 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
@@ -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
@@ -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]");
}
}