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

Commit 307ea7a2 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Collect NeededUriGrants without holding locks.

In preparation for a future security fix, we need to determine Uri
permission grants before acquiring the WM lock.  This CL is mostly
mechanical refactoring to split the calculation and granting logic
into two phases, and pass around the calculated NeededUriGrants.

There is no other logic changes included in this CL, so it should
have no effects.

Bug: 115619667
Test: atest WmTests:ActivityStarterTests
Test: atest FrameworksServicesTests:com.android.server.uri
Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert
Test: atest CtsWindowManagerDeviceTestCases:CrossAppDragAndDropTests
Test: atest CtsWindowManagerDeviceTestCases:ActivityStarterTests
Change-Id: I07f331a53e27ae5c9d4bade50d70544d02bcd7b1
parent 938089f3
Loading
Loading
Loading
Loading
+15 −18
Original line number Diff line number Diff line
@@ -2436,7 +2436,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * Sets the result for activity that started this one, clears the references to activities
     * started for result from this one, and clears new intents.
     */
    private void finishActivityResults(int resultCode, Intent resultData) {
    private void finishActivityResults(int resultCode, Intent resultData,
            NeededUriGrants resultGrants) {
        // Send the result if needed
        if (resultTo != null) {
            if (DEBUG_RESULTS) {
@@ -2450,10 +2451,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                }
            }
            if (info.applicationInfo.uid > 0) {
                final NeededUriGrants needed = mAtmService.mUgmInternal
                        .checkGrantUriPermissionFromIntent(resultData, info.applicationInfo.uid,
                                resultTo.packageName, resultTo.mUserId);
                mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(needed,
                mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
                        resultTo.getUriPermissionsLocked());
            }
            resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
@@ -2490,7 +2488,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * See {@link #finishIfPossible(int, Intent, String, boolean)}
     */
    @FinishRequest int finishIfPossible(String reason, boolean oomAdj) {
        return finishIfPossible(Activity.RESULT_CANCELED, null /* resultData */, reason, oomAdj);
        return finishIfPossible(Activity.RESULT_CANCELED,
                null /* resultData */, null /* resultGrants */, reason, oomAdj);
    }

    /**
@@ -2504,8 +2503,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the
     * request to finish it was not ignored.
     */
    @FinishRequest int finishIfPossible(int resultCode, Intent resultData, String reason,
            boolean oomAdj) {
    @FinishRequest int finishIfPossible(int resultCode, Intent resultData,
            NeededUriGrants resultGrants, String reason, boolean oomAdj) {
        if (DEBUG_RESULTS || DEBUG_STATES) {
            Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode
                    + ", data=" + resultData + ", reason=" + reason);
@@ -2557,7 +2556,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                        shouldAdjustGlobalFocus);
            }

            finishActivityResults(resultCode, resultData);
            finishActivityResults(resultCode, resultData, resultGrants);

            final boolean endTask = task.getActivityBelow(this) == null
                    && !task.isClearingToReuseTask();
@@ -2915,7 +2914,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

    /** Note: call {@link #cleanUp(boolean, boolean)} before this method. */
    void removeFromHistory(String reason) {
        finishActivityResults(Activity.RESULT_CANCELED, null /* resultData */);
        finishActivityResults(Activity.RESULT_CANCELED,
                null /* resultData */, null /* resultGrants */);
        makeFinishingLocked();
        if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE) {
            Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack callers="
@@ -3664,11 +3664,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
            Intent data) {
            Intent data, NeededUriGrants dataGrants) {
        if (callingUid > 0) {
            final NeededUriGrants needed = mAtmService.mUgmInternal
                    .checkGrantUriPermissionFromIntent(data, callingUid, packageName, mUserId);
            mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(needed,
            mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(dataGrants,
                    getUriPermissionsLocked());
        }

@@ -3708,11 +3706,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * Deliver a new Intent to an existing activity, so that its onNewIntent()
     * method will be called at the proper time.
     */
    final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
    final void deliverNewIntentLocked(int callingUid, Intent intent, NeededUriGrants intentGrants,
            String referrer) {
        // The activity now gets access to the data associated with this Intent.
        final NeededUriGrants needed = mAtmService.mUgmInternal.checkGrantUriPermissionFromIntent(
                intent, callingUid, packageName, mUserId);
        mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(needed,
        mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
                getUriPermissionsLocked());
        final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
        boolean unsent = true;
+10 −6
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.AppTimeTracker;
import com.android.server.uri.NeededUriGrants;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -2365,8 +2366,8 @@ class ActivityStack extends Task {
        return false;
    }

    boolean navigateUpTo(ActivityRecord srec, Intent destIntent, int resultCode,
            Intent resultData) {
    boolean navigateUpTo(ActivityRecord srec, Intent destIntent, NeededUriGrants destGrants,
            int resultCode, Intent resultData, NeededUriGrants resultGrants) {
        if (!srec.attachedToProcess()) {
            // Nothing to do if the caller is not attached, because this method should be called
            // from an alive activity.
@@ -2417,12 +2418,14 @@ class ActivityStack extends Task {
        resultCodeHolder[0] = resultCode;
        final Intent[] resultDataHolder = new Intent[1];
        resultDataHolder[0] = resultData;
        final NeededUriGrants[] resultGrantsHolder = new NeededUriGrants[1];
        resultGrantsHolder[0] = resultGrants;
        final ActivityRecord finalParent = parent;
        task.forAllActivities((ar) -> {
            if (ar == finalParent) return true;

            ar.finishIfPossible(
                    resultCodeHolder[0], resultDataHolder[0], "navigate-up", true /* oomAdj */);
            ar.finishIfPossible(resultCodeHolder[0], resultDataHolder[0], resultGrantsHolder[0],
                    "navigate-up", true /* oomAdj */);
            // Only return the supplied result for the first activity finished
            resultCodeHolder[0] = Activity.RESULT_CANCELED;
            resultDataHolder[0] = null;
@@ -2439,7 +2442,7 @@ class ActivityStack extends Task {
                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
                parent.deliverNewIntentLocked(callingUid, destIntent, destGrants, srec.packageName);
            } else {
                try {
                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -2463,7 +2466,8 @@ class ActivityStack extends Task {
                } catch (RemoteException e) {
                    foundParentInTask = false;
                }
                parent.finishIfPossible(resultCode, resultData, "navigate-top", true /* oomAdj */);
                parent.finishIfPossible(resultCode, resultData, resultGrants,
                        "navigate-top", true /* oomAdj */);
            }
        }
        Binder.restoreCallingIdentity(origId);
+12 −8
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.UserState;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;

import java.io.FileDescriptor;
@@ -379,14 +380,17 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
        final int startFlags;
        final ActivityStack stack;
        final WindowProcessController callerApp;
        final NeededUriGrants intentGrants;

        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
                int _startFlags, ActivityStack _stack, WindowProcessController app) {
            r = _r;
            sourceRecord = _sourceRecord;
            startFlags = _startFlags;
            stack = _stack;
            callerApp = app;
        PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord,
                int startFlags, ActivityStack stack, WindowProcessController callerApp,
                NeededUriGrants intentGrants) {
            this.r = r;
            this.sourceRecord = sourceRecord;
            this.startFlags = startFlags;
            this.stack = stack;
            this.callerApp = callerApp;
            this.intentGrants = intentGrants;
        }

        void sendErrorResult(String message) {
@@ -1003,7 +1007,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
                || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
                        Activity.RESULT_CANCELED, null /* data */);
                        Activity.RESULT_CANCELED, null /* data */, null /* dataGrants */);
            }
            final String msg;
            if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
+1 −1
Original line number Diff line number Diff line
@@ -512,7 +512,7 @@ public class ActivityStartController {
                    "pendingActivityLaunch");
            try {
                starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags,
                        resume, pal.r.pendingOptions, null);
                        resume, pal.r.pendingOptions, null, pal.intentGrants);
            } catch (Exception e) {
                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                pal.sendErrorResult(e.getMessage());
+67 −27
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@ class ActivityStarter {

        IApplicationThread caller;
        Intent intent;
        NeededUriGrants intentGrants;
        // A copy of the original requested intent, in case for ephemeral app launch.
        Intent ephemeralIntent;
        String resolvedType;
@@ -362,6 +363,7 @@ class ActivityStarter {
        void reset() {
            caller = null;
            intent = null;
            intentGrants = null;
            ephemeralIntent = null;
            resolvedType = null;
            activityInfo = null;
@@ -401,6 +403,7 @@ class ActivityStarter {
        void set(Request request) {
            caller = request.caller;
            intent = request.intent;
            intentGrants = request.intentGrants;
            ephemeralIntent = request.ephemeralIntent;
            resolvedType = request.resolvedType;
            activityInfo = request.activityInfo;
@@ -455,6 +458,20 @@ class ActivityStarter {
                callingPid = callingUid = -1;
            }

            // To determine the set of needed Uri permission grants, we need the
            // "resolved" calling UID, where we try our best to identify the
            // actual caller that is starting this activity
            int resolvedCallingUid = callingUid;
            if (caller != null) {
                synchronized (supervisor.mService.mGlobalLock) {
                    final WindowProcessController callerApp = supervisor.mService
                            .getProcessController(caller);
                    if (callerApp != null) {
                        resolvedCallingUid = callerApp.mInfo.uid;
                    }
                }
            }

            // Save a copy in case ephemeral needs it
            ephemeralIntent = new Intent(intent);
            // Don't modify the client's object!
@@ -504,6 +521,13 @@ class ActivityStarter {
            // Collect information about the target of the Intent.
            activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
                    profilerInfo);

            // Carefully collect grants without holding lock
            if (activityInfo != null) {
                intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(
                        intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,
                        UserHandle.getUserId(activityInfo.applicationInfo.uid));
            }
        }
    }

@@ -578,7 +602,8 @@ class ActivityStarter {
     */
    void startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask) {
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            NeededUriGrants intentGrants) {
        try {
            final LaunchingState launchingState = mSupervisor.getActivityMetricsLogger()
                    .notifyActivityLaunching(r.intent, r.resultTo);
@@ -587,7 +612,7 @@ class ActivityStarter {
            mLastStartActivityRecord = r;
            mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                    voiceInteractor, startFlags, doResume, options, inTask,
                    false /* restrictedBgActivity */);
                    false /* restrictedBgActivity */, intentGrants);
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
                    mLastStartActivityResult, mLastStartActivityRecord);
        } finally {
@@ -814,6 +839,7 @@ class ActivityStarter {

        final IApplicationThread caller = request.caller;
        Intent intent = request.intent;
        NeededUriGrants intentGrants = request.intentGrants;
        String resolvedType = request.resolvedType;
        ActivityInfo aInfo = request.activityInfo;
        ResolveInfo rInfo = request.resolveInfo;
@@ -961,7 +987,7 @@ class ActivityStarter {
        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */);
                        null /* data */, null /* dataGrants */);
            }
            SafeActivityOptions.abort(options);
            return err;
@@ -1023,12 +1049,16 @@ class ActivityStarter {
            callingPid = mInterceptor.mCallingPid;
            callingUid = mInterceptor.mCallingUid;
            checkedOptions = mInterceptor.mActivityOptions;

            // The interception target shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;
        }

        if (abort) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */);
                        null /* data */, null /* dataGrants */);
            }
            // We pretend to the caller that it was really started, but they will just get a
            // cancel result.
@@ -1074,6 +1104,10 @@ class ActivityStarter {
                }
                intent = newIntent;

                // The permissions review target shouldn't get any permission
                // grants intended for the original destination
                intentGrants = null;

                resolvedType = null;
                callingUid = realCallingUid;
                callingPid = realCallingPid;
@@ -1106,6 +1140,10 @@ class ActivityStarter {
            callingUid = realCallingUid;
            callingPid = realCallingPid;

            // The ephemeral installer shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;

            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
        }

@@ -1132,7 +1170,7 @@ class ActivityStarter {
                    realCallingPid, realCallingUid, "Activity start")) {
                if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
                    mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                            sourceRecord, startFlags, stack, callerApp));
                            sourceRecord, startFlags, stack, callerApp, intentGrants));
                }
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SWITCHES_CANCELED;
@@ -1144,7 +1182,7 @@ class ActivityStarter {

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity);
                restrictedBgActivity, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
@@ -1169,7 +1207,7 @@ class ActivityStarter {
        int requestCode = r.requestCode;
        if (resultRecord != null) {
            resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                    null /* data */);
                    null /* data */, null /* dataGrants */);
        }
        // We pretend to the caller that it was really started to make it backward compatible, but
        // they will just get a cancel result.
@@ -1471,14 +1509,14 @@ class ActivityStarter {
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity) {
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity);
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            startedActivityStack = handleStartResult(r, result);
@@ -1546,7 +1584,7 @@ class ActivityStarter {
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity) {
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);

@@ -1583,7 +1621,7 @@ class ActivityStarter {
                ? null : targetTask.getTopNonFinishingActivity();
        if (targetTaskTop != null) {
            // Recycle the target task for this launch.
            startResult = recycleTask(targetTask, targetTaskTop, reusedTask);
            startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
            if (startResult != START_SUCCESS) {
                return startResult;
            }
@@ -1595,7 +1633,7 @@ class ActivityStarter {
        // we need to check if it should only be launched once.
        final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
        if (topStack != null) {
            startResult = deliverToCurrentTopIfNeeded(topStack);
            startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
            if (startResult != START_SUCCESS) {
                return startResult;
            }
@@ -1626,9 +1664,7 @@ class ActivityStarter {
            }
        }

        final NeededUriGrants needed = mService.mUgmInternal.checkGrantUriPermissionFromIntent(
                mIntent, mCallingUid, mStartActivity.packageName, mStartActivity.mUserId);
        mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(needed,
        mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
                mStartActivity.getUriPermissionsLocked());
        if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
            // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
@@ -1755,7 +1791,8 @@ class ActivityStarter {
        if (mStartActivity.packageName == null) {
            if (mStartActivity.resultTo != null) {
                mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
                        mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
                        mStartActivity.requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            ActivityOptions.abort(mOptions);
            return START_CLASS_NOT_FOUND;
@@ -1800,7 +1837,8 @@ class ActivityStarter {
     * - Determine whether need to add a new activity on top or just brought the task to front.
     */
    @VisibleForTesting
    int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask) {
    int recycleTask(Task targetTask, ActivityRecord targetTaskTop, Task reusedTask,
            NeededUriGrants intentGrants) {
        // Should not recycle task which is from a different user, just adding the starting
        // activity to the task.
        if (targetTask.mUserId != mStartActivity.mUserId) {
@@ -1860,7 +1898,7 @@ class ActivityStarter {
        }

        complyActivityFlags(targetTask,
                reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null);
                reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);

        if (clearTaskForReuse) {
            // Clear task for re-use so later code to methods
@@ -1896,7 +1934,7 @@ class ActivityStarter {
     * Check if the activity being launched is the same as the one currently at the top and it
     * should only be launched once.
     */
    private int deliverToCurrentTopIfNeeded(ActivityStack topStack) {
    private int deliverToCurrentTopIfNeeded(ActivityStack topStack, NeededUriGrants intentGrants) {
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
@@ -1924,7 +1962,7 @@ class ActivityStarter {
            return START_RETURN_INTENT_TO_CALLER;
        }

        deliverNewIntent(top);
        deliverNewIntent(top, intentGrants);

        // Don't use mStartActivity.task to show the toast. We're not starting a new activity but
        // reusing 'top'. Fields in mStartActivity may not be fully initialized.
@@ -1938,7 +1976,8 @@ class ActivityStarter {
     * Applying the launching flags to the task, which might clear few or all the activities in the
     * task.
     */
    private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity) {
    private void complyActivityFlags(Task targetTask, ActivityRecord reusedActivity,
            NeededUriGrants intentGrants) {
        ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
        final boolean resetTask =
                reusedActivity != null && (mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0;
@@ -1982,7 +2021,7 @@ class ActivityStarter {
                    // so make sure the task now has the identity of the new intent.
                    top.getTask().setIntent(mStartActivity);
                }
                deliverNewIntent(top);
                deliverNewIntent(top, intentGrants);
            } else {
                // A special case: we need to start the activity because it is not currently
                // running, and the caller has asked to clear the current task to have this
@@ -2008,7 +2047,7 @@ class ActivityStarter {
                final Task task = act.getTask();
                task.moveActivityToFrontLocked(act);
                act.updateOptionsLocked(mOptions);
                deliverNewIntent(act);
                deliverNewIntent(act, intentGrants);
                mTargetStack.mLastPausedActivity = null;
            } else {
                mAddingToTask = true;
@@ -2028,7 +2067,7 @@ class ActivityStarter {
                if (targetTaskTop.isRootOfTask()) {
                    targetTaskTop.getTask().setIntent(mStartActivity);
                }
                deliverNewIntent(targetTaskTop);
                deliverNewIntent(targetTaskTop, intentGrants);
            } else if (!targetTask.isSameIntentFilter(mStartActivity)) {
                // In this case we are launching the root activity of the task, but with a
                // different intent. We should start a new instance on top.
@@ -2236,7 +2275,8 @@ class ActivityStarter {
            // as normal without a dependency on its originator.
            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
            mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
                    mStartActivity.requestCode, RESULT_CANCELED, null /* data */);
                    mStartActivity.requestCode, RESULT_CANCELED,
                    null /* data */, null /* dataGrants */);
            mStartActivity.resultTo = null;
        }
    }
@@ -2515,13 +2555,13 @@ class ActivityStarter {
        }
    }

    private void deliverNewIntent(ActivityRecord activity) {
    private void deliverNewIntent(ActivityRecord activity, NeededUriGrants intentGrants) {
        if (mIntentDelivered) {
            return;
        }

        activity.logStartActivity(EventLogTags.WM_NEW_INTENT, activity.getTask());
        activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
        activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, intentGrants,
                mStartActivity.launchedFromPackage);
        mIntentDelivered = true;
    }
Loading