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

Commit a752da8c authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Do not lock when calling startActivityFromRecents" into sc-v2-dev

parents c1fb8bb5 7bdc21cf
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -1732,10 +1732,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
            return mTaskSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
                    safeOptions);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
+91 −67
Original line number Diff line number Diff line
@@ -2474,30 +2474,39 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        }
    }

    /**
     * Start the given task from the recent tasks. Do not hold WM global lock when calling this
     * method to avoid potential deadlock or permission deny by UriGrantsManager when resolving
     * activity (see {@link ActivityStarter.Request#resolveActivity} and
     * {@link com.android.server.am.ContentProviderHelper#checkContentProviderUriPermission}).
     *
     * @return The result code of starter.
     */
    int startActivityFromRecents(int callingPid, int callingUid, int taskId,
            SafeActivityOptions options) {
        Task task = null;
        final Task task;
        final int taskCallingUid;
        final String callingPackage;
        final String callingFeatureId;
        final Intent intent;
        final int userId;
        int activityType = ACTIVITY_TYPE_UNDEFINED;
        int windowingMode = WINDOWING_MODE_UNDEFINED;
        final ActivityOptions activityOptions = options != null
                ? options.getOptions(this)
                : null;
        boolean moveHomeTaskForward = true;
        synchronized (mService.mGlobalLock) {
            int activityType = ACTIVITY_TYPE_UNDEFINED;
            if (activityOptions != null) {
                activityType = activityOptions.getLaunchActivityType();
            windowingMode = activityOptions.getLaunchWindowingMode();
                final int windowingMode = activityOptions.getLaunchWindowingMode();
                if (activityOptions.freezeRecentTasksReordering()
                        && mRecentTasks.isCallerRecents(callingUid)) {
                    mRecentTasks.setFreezeTaskListReordering();
                }
                if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                        || activityOptions.getLaunchRootTask() != null) {
                // Don't move home activity forward if we are launching into primary split or there
                // is a launch root set.
                    // Don't move home activity forward if we are launching into primary split or
                    // there is a launch root set.
                    moveHomeTaskForward = false;
                }
            }
@@ -2506,6 +2515,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                        + taskId + " can't be launch in the home/recents root task.");
            }

            boolean shouldStartActivity = false;
            mService.deferWindowLayout();
            try {
                task = mRootWindowContainer.anyTaskForId(taskId,
@@ -2517,16 +2527,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                }

                if (moveHomeTaskForward) {
                // We always want to return to the home activity instead of the recents activity
                // from whatever is started from the recents activity, so move the home root task
                // forward.
                    // We always want to return to the home activity instead of the recents
                    // activity from whatever is started from the recents activity, so move
                    // the home root task forward.
                    // TODO (b/115289124): Multi-display supports for recents.
                    mRootWindowContainer.getDefaultTaskDisplayArea().moveHomeRootTaskToFront(
                            "startActivityFromRecents");
                }

            // If the user must confirm credentials (e.g. when first launching a work app and the
            // Work Challenge is present) let startActivityInPackage handle the intercepting.
                // If the user must confirm credentials (e.g. when first launching a work
                // app and the Work Challenge is present) let startActivityInPackage handle
                // the intercepting.
                if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId)
                        && task.getRootActivity() != null) {
                    final ActivityRecord targetActivity = task.getTopNonFinishingActivity();
@@ -2536,16 +2547,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                    final LaunchingState launchingState =
                            mActivityMetricsLogger.notifyActivityLaunching(task.intent);
                    try {
                    mService.moveTaskToFrontLocked(null /* appThread */, null /* callingPackage */,
                            task.mTaskId, 0, options);
                    // Apply options to prevent pendingOptions be taken when scheduling activity
                    // lifecycle transaction to make sure the override pending app transition will
                    // be applied immediately.
                        mService.moveTaskToFrontLocked(null /* appThread */,
                                null /* callingPackage */, task.mTaskId, 0, options);
                        // Apply options to prevent pendingOptions be taken when scheduling
                        // activity lifecycle transaction to make sure the override pending app
                        // transition will be applied immediately.
                        targetActivity.applyOptionsAnimation();
                    } finally {
                        mActivityMetricsLogger.notifyActivityLaunched(launchingState,
                            START_TASK_TO_FRONT, false /* newActivityCreated */, targetActivity,
                            activityOptions);
                                START_TASK_TO_FRONT, false /* newActivityCreated */,
                                targetActivity, activityOptions);
                    }

                    mService.getActivityStartController().postStartActivityProcessingForLastStarter(
@@ -2555,23 +2566,36 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                    // As it doesn't go to ActivityStarter.executeRequest() path, we need to resume
                    // app switching here also.
                    mService.resumeAppSwitches();

                    return ActivityManager.START_TASK_TO_FRONT;
                }
                // The task is empty or needs to show the confirmation for credential.
                shouldStartActivity = true;
            } finally {
                if (!shouldStartActivity) {
                    mService.continueWindowLayout();
                }
            }
            taskCallingUid = task.mCallingUid;
            callingPackage = task.mCallingPackage;
            callingFeatureId = task.mCallingFeatureId;
            intent = task.intent;
            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
            userId = task.mUserId;
            return mService.getActivityStartController().startActivityInPackage(task.mCallingUid,
        }
        // ActivityStarter will acquire the lock where the places need, so execute the request
        // outside of the lock.
        try {
            return mService.getActivityStartController().startActivityInPackage(taskCallingUid,
                    callingPid, callingUid, callingPackage, callingFeatureId, intent, null, null,
                    null, 0, 0, options, userId, task, "startActivityFromRecents",
                    false /* validateIncomingUser */, null /* originatingPendingIntent */,
                    false /* allowBackgroundActivityStart */);
        } finally {
            synchronized (mService.mGlobalLock) {
                mService.continueWindowLayout();
            }
        }
    }

    /**
     * Internal container to store a match qualifier alongside a WaitResult.
+5 −5
Original line number Diff line number Diff line
@@ -35,10 +35,10 @@ import android.os.UserHandle;
 */
class AppTaskImpl extends IAppTask.Stub {
    private static final String TAG = "AppTaskImpl";
    private ActivityTaskManagerService mService;
    private final ActivityTaskManagerService mService;

    private int mTaskId;
    private int mCallingUid;
    private final int mTaskId;
    private final int mCallingUid;

    public AppTaskImpl(ActivityTaskManagerService service, int taskId, int callingUid) {
        mService = service;
@@ -113,9 +113,9 @@ class AppTaskImpl extends IAppTask.Stub {
                        return;
                    }
                }
                mService.mTaskSupervisor.startActivityFromRecents(callingPid,
                        callingUid, mTaskId, null);
            }
            mService.mTaskSupervisor.startActivityFromRecents(callingPid, callingUid, mTaskId,
                    null /* options */);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
+24 −7
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
     * @param caller Info about the calling process.
     */
    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
            @Nullable Transition transition, @Nullable CallerInfo caller) {
            @Nullable Transition transition, @NonNull CallerInfo caller) {
        int effects = 0;
        ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
        mService.deferWindowLayout();
@@ -540,7 +540,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub

    private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
            int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
            @Nullable CallerInfo caller, @Nullable IBinder errorCallbackToken,
            @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken,
            @Nullable ITaskFragmentOrganizer organizer) {
        final int type = hop.getType();
        switch (type) {
@@ -628,11 +628,28 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                final int taskId = launchOpts.getInt(
                        WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
                launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
                final SafeActivityOptions safeOptions = caller != null
                        ? SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid)
                        : SafeActivityOptions.fromBundle(launchOpts);
                mService.mTaskSupervisor.startActivityFromRecents(caller.mPid, caller.mUid,
                        taskId, safeOptions);
                final SafeActivityOptions safeOptions =
                        SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid);
                final Integer[] starterResult = { null };
                // startActivityFromRecents should not be called in lock.
                mService.mH.post(() -> {
                    try {
                        starterResult[0] = mService.mTaskSupervisor.startActivityFromRecents(
                                caller.mPid, caller.mUid, taskId, safeOptions);
                    } catch (Throwable t) {
                        starterResult[0] = ActivityManager.START_CANCELED;
                        Slog.w(TAG, t);
                    }
                    synchronized (mGlobalLock) {
                        mGlobalLock.notifyAll();
                    }
                });
                while (starterResult[0] == null) {
                    try {
                        mGlobalLock.wait();
                    } catch (InterruptedException ignored) {
                    }
                }
                break;
            case HIERARCHY_OP_TYPE_PENDING_INTENT:
                String resolvedType = hop.getActivityIntent() != null