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

Commit 5b03a709 authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15921002

Change-Id: Ib68ea3032db81b704d299c0c40b6bf9e12532dfe
parents 9169cf65 a752da8c
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