Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65da5ea8 authored by Nan Wu's avatar Nan Wu Committed by Android (Google) Code Review
Browse files

Merge "Don’t bring App to FG if only creator is allowed to do BAL(1/2)" into main

parents fae25ec1 66f117cc
Loading
Loading
Loading
Loading
+43 −17
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ import com.android.server.statusbar.StatusBarManagerInternal;
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 @@ class ActivityStarter {
        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 @@ class ActivityStarter {
                            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 @@ class ActivityStarter {
        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 @@ class ActivityStarter {
    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 @@ class ActivityStarter {
            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 @@ class ActivityStarter {
    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 @@ class ActivityStarter {
            }
            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 @@ class ActivityStarter {
        recordTransientLaunchIfNeeded(mLastStartActivityRecord);

        if (!mAvoidMoveToFront && mDoResume) {
            logOnlyCreatorAllowsBAL(balVerdict, realCallingUid, newTask);
            mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
            if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
                    && !dreamStopping) {
@@ -1800,6 +1804,7 @@ class ActivityStarter {
                // 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 @@ class ActivityStarter {
        // 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 @@ class ActivityStarter {
        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 @@ class ActivityStarter {
     */
    @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 @@ class ActivityStarter {
        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 @@ class ActivityStarter {
            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 @@ class ActivityStarter {
            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 @@ class ActivityStarter {
     * @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 @@ class ActivityStarter {
                    // 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");
+18 −0
Original line number Diff line number Diff line
@@ -433,10 +433,15 @@ public class BackgroundActivityStartController {
    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 @@ public class BackgroundActivityStartController {
            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 @@ public class BackgroundActivityStartController {
        BalVerdict resultForRealCaller = state.callerIsRealCaller() && resultForCaller.allows()
                ? resultForCaller
                : checkBackgroundActivityStartAllowedBySender(state, checkedOptions);
        if (state.isPendingIntent()) {
            resultForCaller.setOnlyCreatorAllows(
                    resultForCaller.allows() && resultForRealCaller.blocks());
        }

        if (resultForCaller.allows()
                && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+5 −3
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ import com.android.compatibility.common.util.DeviceConfigStateHelper;
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 @@ public class ActivityStarterTests extends WindowTestsBase {
                .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 @@ public class ActivityStarterTests extends WindowTestsBase {
        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 */);
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
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 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
                /* options */null,
                /* inTask */null,
                /* inTaskFragment */ null,
                /* balCode */ BackgroundActivityStartController.BAL_ALLOW_DEFAULT,
                BalVerdict.ALLOW_BY_DEFAULT,
                /* intentGrants */null,
                /* realCaiingUid */ -1);

@@ -216,7 +217,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
                /* options= */null,
                /* inTask= */null,
                /* inTaskFragment= */ null,
                /* balCode= */ BackgroundActivityStartController.BAL_ALLOW_DEFAULT,
                BalVerdict.ALLOW_BY_DEFAULT,
                /* intentGrants= */null,
                /* realCaiingUid */ -1);