Merge "Don’t bring App to FG if only creator is allowed to do BAL(1/2)" into main
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 009b8e0..5e0a449 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -133,6 +133,7 @@
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import com.android.server.wm.BackgroundActivityStartController.BalCode;
+import com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import com.android.server.wm.LaunchParamsController.LaunchParams;
import com.android.server.wm.TaskFragment.EmbeddingCheckResult;
@@ -1090,14 +1091,14 @@
ActivityOptions checkedOptions = options != null
? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
- @BalCode int balCode = BAL_ALLOW_DEFAULT;
+ final BalVerdict balVerdict;
if (!abort) {
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
"shouldAbortBackgroundActivityStart");
BackgroundActivityStartController balController =
mSupervisor.getBackgroundActivityLaunchController();
- BackgroundActivityStartController.BalVerdict balVerdict =
+ balVerdict =
balController.checkBackgroundActivityStart(
callingUid,
callingPid,
@@ -1109,13 +1110,13 @@
request.forcedBalByPiSender,
intent,
checkedOptions);
- balCode = balVerdict.getCode();
- request.logMessage.append(" (").append(
- BackgroundActivityStartController.balCodeToString(balCode))
- .append(")");
+ request.logMessage.append(" (").append(balVerdict).append(")");
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
+ } else {
+ // Sets ALLOW_BY_DEFAULT as default value as the activity launch will be aborted anyway.
+ balVerdict = BalVerdict.ALLOW_BY_DEFAULT;
}
if (request.allowPendingRemoteAnimationRegistryLookup) {
@@ -1293,13 +1294,13 @@
WindowProcessController homeProcess = mService.mHomeProcess;
boolean isHomeProcess = homeProcess != null
&& aInfo.applicationInfo.uid == homeProcess.mUid;
- if (balCode != BAL_BLOCK && !isHomeProcess) {
+ if (balVerdict.allows() && !isHomeProcess) {
mService.resumeAppSwitches();
}
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, checkedOptions,
- inTask, inTaskFragment, balCode, intentGrants, realCallingUid);
+ inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
@@ -1449,7 +1450,8 @@
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, ActivityOptions options, Task inTask,
- TaskFragment inTaskFragment, @BalCode int balCode,
+ TaskFragment inTaskFragment,
+ BalVerdict balVerdict,
NeededUriGrants intentGrants, int realCallingUid) {
int result = START_CANCELED;
final Task startedActivityRootTask;
@@ -1468,7 +1470,7 @@
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, options, inTask, inTaskFragment, balCode,
+ startFlags, options, inTask, inTaskFragment, balVerdict,
intentGrants, realCallingUid);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
@@ -1615,10 +1617,10 @@
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, ActivityOptions options, Task inTask,
- TaskFragment inTaskFragment, @BalCode int balCode,
+ TaskFragment inTaskFragment, BalVerdict balVerdict,
NeededUriGrants intentGrants, int realCallingUid) {
setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
- voiceSession, voiceInteractor, balCode, realCallingUid);
+ voiceSession, voiceInteractor, balVerdict.getCode(), realCallingUid);
computeLaunchingTaskFlags();
mIntent.setFlags(mLaunchFlags);
@@ -1696,7 +1698,8 @@
}
recordTransientLaunchIfNeeded(targetTaskTop);
// Recycle the target task for this launch.
- startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
+ startResult =
+ recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants, balVerdict);
if (startResult != START_SUCCESS) {
return startResult;
}
@@ -1730,6 +1733,7 @@
recordTransientLaunchIfNeeded(mLastStartActivityRecord);
if (!mAvoidMoveToFront && mDoResume) {
+ logOnlyCreatorAllowsBAL(balVerdict, realCallingUid, newTask);
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
&& !dreamStopping) {
@@ -1800,6 +1804,7 @@
// now update the focused root-task accordingly.
if (!mAvoidMoveToFront && mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
+ logOnlyCreatorAllowsBAL(balVerdict, realCallingUid, newTask);
mTargetRootTask.moveToFront("startActivityInner");
}
mRootWindowContainer.resumeFocusedTasksTopActivities(
@@ -1817,7 +1822,7 @@
// Note that mStartActivity and source should be in the same Task at this point.
if (mOptions != null && mOptions.isLaunchIntoPip()
&& sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
- && balCode != BAL_BLOCK) {
+ && balVerdict.allows()) {
mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
sourceRecord, "launch-into-pip");
}
@@ -1828,6 +1833,24 @@
return START_SUCCESS;
}
+ private void logOnlyCreatorAllowsBAL(BalVerdict balVerdict,
+ int realCallingUid, boolean newTask) {
+ // TODO (b/296478675) eventually, we will prevent such case from happening
+ // and probably also log that a BAL is prevented by android V.
+ if (!newTask && balVerdict.onlyCreatorAllows()) {
+ String realCallingPackage =
+ mService.mContext.getPackageManager().getNameForUid(realCallingUid);
+ if (realCallingPackage == null) {
+ realCallingPackage = "uid=" + realCallingUid;
+ }
+ Slog.wtf(TAG, "A background app is brought to the foreground due to 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);
+ }
+ }
+
private void recordTransientLaunchIfNeeded(ActivityRecord r) {
if (r == null || !mTransientLaunch) return;
final TransitionController controller = r.mTransitionController;
@@ -1995,7 +2018,7 @@
*/
@VisibleForTesting
int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
- NeededUriGrants intentGrants) {
+ NeededUriGrants intentGrants, BalVerdict balVerdict) {
// Should not recycle task which is from a different user, just adding the starting
// activity to the task.
if (targetTask.mUserId != mStartActivity.mUserId) {
@@ -2024,7 +2047,7 @@
mRootWindowContainer.startPowerModeLaunchIfNeeded(false /* forceSend */,
targetTaskTop);
- setTargetRootTaskIfNeeded(targetTaskTop);
+ setTargetRootTaskIfNeeded(targetTaskTop, balVerdict);
// When there is a reused activity and the current result is a trampoline activity,
// set the reused activity as the result.
@@ -2040,6 +2063,7 @@
if (!mMovedToFront && mDoResume) {
ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask,
targetTaskTop);
+ logOnlyCreatorAllowsBAL(balVerdict, mRealCallingUid, false);
mTargetRootTask.moveToFront("intentActivityFound");
}
resumeTargetRootTaskIfNeeded();
@@ -2068,6 +2092,7 @@
targetTaskTop.showStartingWindow(true /* taskSwitch */);
} else if (mDoResume) {
// Make sure the root task and its belonging display are moved to topmost.
+ logOnlyCreatorAllowsBAL(balVerdict, mRealCallingUid, false);
mTargetRootTask.moveToFront("intentActivityFound");
}
// We didn't do anything... but it was needed (a.k.a., client don't use that intent!)
@@ -2663,7 +2688,7 @@
* @param intentActivity Existing matching activity.
* @return {@link ActivityRecord} brought to front.
*/
- private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity) {
+ private void setTargetRootTaskIfNeeded(ActivityRecord intentActivity, BalVerdict balVerdict) {
intentActivity.getTaskFragment().clearLastPausedActivity();
Task intentTask = intentActivity.getTask();
// The intent task might be reparented while in getOrCreateRootTask, caches the original
@@ -2730,6 +2755,7 @@
// task on top there.
// Defer resuming the top activity while moving task to top, since the
// current task-top activity may not be the activity that should be resumed.
+ logOnlyCreatorAllowsBAL(balVerdict, mRealCallingUid, false);
mTargetRootTask.moveTaskToFront(intentTask, mNoAnimation, mOptions,
mStartActivity.appTimeTracker, DEFER_RESUME,
"bringingFoundTaskToFront");
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index b66c4c3..287aaf9 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -433,10 +433,15 @@
static class BalVerdict {
static final BalVerdict BLOCK = new BalVerdict(BAL_BLOCK, false, "Blocked");
+ static final BalVerdict ALLOW_BY_DEFAULT =
+ new BalVerdict(BAL_ALLOW_DEFAULT, false, "Default");
private final @BalCode int mCode;
private final boolean mBackground;
private final String mMessage;
private String mProcessInfo;
+ // indicates BAL would be blocked because only creator of the PI has the privilege to allow
+ // BAL, the sender does not have the privilege to allow BAL.
+ private boolean mOnlyCreatorAllows;
BalVerdict(@BalCode int balCode, boolean background, String message) {
this.mBackground = background;
@@ -457,6 +462,15 @@
return !blocks();
}
+ BalVerdict setOnlyCreatorAllows(boolean onlyCreatorAllows) {
+ mOnlyCreatorAllows = onlyCreatorAllows;
+ return this;
+ }
+
+ boolean onlyCreatorAllows() {
+ return mOnlyCreatorAllows;
+ }
+
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(balCodeToString(mCode));
@@ -566,6 +580,10 @@
BalVerdict resultForRealCaller = state.callerIsRealCaller() && resultForCaller.allows()
? resultForCaller
: checkBackgroundActivityStartAllowedBySender(state, checkedOptions);
+ if (state.isPendingIntent()) {
+ resultForCaller.setOnlyCreatorAllows(
+ resultForCaller.allows() && resultForRealCaller.blocks());
+ }
if (resultForCaller.allows()
&& checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
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 e2bb115..98055fa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -118,6 +118,7 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
import com.android.server.wm.utils.MockTracker;
@@ -1378,7 +1379,8 @@
.setUserId(10)
.build();
- final int result = starter.recycleTask(task, null, null, null);
+ final int result = starter.recycleTask(task, null, null, null,
+ BalVerdict.ALLOW_BY_DEFAULT);
assertThat(result == START_SUCCESS).isTrue();
assertThat(starter.mAddingToTask).isTrue();
}
@@ -1892,7 +1894,7 @@
starter.startActivityInner(target, source, null /* voiceSession */,
null /* voiceInteractor */, 0 /* startFlags */,
options, inTask, inTaskFragment,
- BackgroundActivityStartController.BAL_ALLOW_DEFAULT, null /* intentGrants */,
- -1 /* realCallingUid */);
+ BalVerdict.ALLOW_BY_DEFAULT,
+ null /* intentGrants */, -1 /* realCallingUid */);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index cf620fe..c404c77 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -21,6 +21,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -186,7 +187,7 @@
/* options */null,
/* inTask */null,
/* inTaskFragment */ null,
- /* balCode */ BackgroundActivityStartController.BAL_ALLOW_DEFAULT,
+ BalVerdict.ALLOW_BY_DEFAULT,
/* intentGrants */null,
/* realCaiingUid */ -1);
@@ -216,7 +217,7 @@
/* options= */null,
/* inTask= */null,
/* inTaskFragment= */ null,
- /* balCode= */ BackgroundActivityStartController.BAL_ALLOW_DEFAULT,
+ BalVerdict.ALLOW_BY_DEFAULT,
/* intentGrants= */null,
/* realCaiingUid */ -1);