Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −4 Original line number Diff line number Diff line Loading @@ -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); } Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +91 −67 Original line number Diff line number Diff line Loading @@ -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; } } Loading @@ -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, Loading @@ -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(); Loading @@ -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( Loading @@ -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. Loading services/core/java/com/android/server/wm/AppTaskImpl.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +24 −7 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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 Loading Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +2 −4 Original line number Diff line number Diff line Loading @@ -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); } Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +91 −67 Original line number Diff line number Diff line Loading @@ -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; } } Loading @@ -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, Loading @@ -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(); Loading @@ -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( Loading @@ -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. Loading
services/core/java/com/android/server/wm/AppTaskImpl.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +24 −7 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading Loading @@ -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 Loading