diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 3b5b5a903544b..1a4ac3fa2007e 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -4964,70 +4964,76 @@ class Task extends TaskFragment { ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s " + "callers: %s", r, task, new RuntimeException("here").fillInStackTrace()); - // The transition animation and starting window are not needed if {@code allowMoveToFront} - // is false, because the activity won't be visible. - if ((!isActivityTypeHomeOrRecents() || hasActivity()) && allowMoveToFront) { - final DisplayContent dc = mDisplayContent; - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, - "Prepare open transition: starting " + r); - if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - dc.prepareAppTransition(TRANSIT_NONE); - mTaskSupervisor.mNoAnimActivities.add(r); - mTransitionController.setNoAnimation(r); - } else { - dc.prepareAppTransition(TRANSIT_OPEN); - mTaskSupervisor.mNoAnimActivities.remove(r); - } - if (newTask && !r.mLaunchTaskBehind) { - // If a new task is being launched, then mark the existing top activity as - // supporting picture-in-picture while pausing only if the starting activity - // would not be considered an overlay on top of the current activity - // (eg. not fullscreen, or the assistant) - enableEnterPipOnTaskSwitch(pipCandidate, - null /* toFrontTask */, r, options); - } - boolean doShow = true; - if (newTask) { - // Even though this activity is starting fresh, we still need - // to reset it to make sure we apply affinities to move any - // existing activities from other tasks in to it. - // If the caller has requested that the target task be - // reset, then do so. - if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { - resetTaskIfNeeded(r, r); - doShow = topRunningNonDelayedActivityLocked(null) == r; - } - } else if (options != null && options.getAnimationType() - == ActivityOptions.ANIM_SCENE_TRANSITION) { - doShow = false; - } - if (options != null && options.getDisableStartingWindow()) { - doShow = false; - } - if (r.mLaunchTaskBehind) { - // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we - // tell WindowManager that r is visible even though it is at the back of the root - // task. - r.setVisibility(true); - ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); - // Go ahead to execute app transition for this activity since the app transition - // will not be triggered through the resume channel. - mDisplayContent.executeAppTransition(); - } else if (SHOW_APP_STARTING_PREVIEW && doShow) { - // Figure out if we are transitioning from another activity that is - // "has the same starting icon" as the next one. This allows the - // window manager to keep the previous window it had previously - // created, if it still had one. - Task baseTask = r.getTask(); - final ActivityRecord prev = baseTask.getActivity( - a -> a.mStartingData != null && a.showToCurrentUser()); - mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask, - isTaskSwitch, sourceRecord); - } - } else { + if (isActivityTypeHomeOrRecents() && getActivityBelow(r) == null) { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. ActivityOptions.abort(options); + return; + } + + if (!allowMoveToFront) { + // The transition animation and starting window are not needed if + // {@code allowMoveToFront} is false, because the activity won't be visible. + ActivityOptions.abort(options); + return; + } + + final DisplayContent dc = mDisplayContent; + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, + "Prepare open transition: starting " + r); + if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { + dc.prepareAppTransition(TRANSIT_NONE); + mTaskSupervisor.mNoAnimActivities.add(r); + mTransitionController.setNoAnimation(r); + } else { + dc.prepareAppTransition(TRANSIT_OPEN); + mTaskSupervisor.mNoAnimActivities.remove(r); + } + if (newTask && !r.mLaunchTaskBehind) { + // If a new task is being launched, then mark the existing top activity as + // supporting picture-in-picture while pausing only if the starting activity + // would not be considered an overlay on top of the current activity + // (eg. not fullscreen, or the assistant) + enableEnterPipOnTaskSwitch(pipCandidate, + null /* toFrontTask */, r, options); + } + boolean doShow = true; + if (newTask) { + // Even though this activity is starting fresh, we still need + // to reset it to make sure we apply affinities to move any + // existing activities from other tasks in to it. + // If the caller has requested that the target task be + // reset, then do so. + if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { + resetTaskIfNeeded(r, r); + doShow = topRunningNonDelayedActivityLocked(null) == r; + } + } else if (options != null && options.getAnimationType() + == ActivityOptions.ANIM_SCENE_TRANSITION) { + doShow = false; + } + if (options != null && options.getDisableStartingWindow()) { + doShow = false; + } + if (r.mLaunchTaskBehind) { + // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we + // tell WindowManager that r is visible even though it is at the back of the root + // task. + r.setVisibility(true); + ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); + // Go ahead to execute app transition for this activity since the app transition + // will not be triggered through the resume channel. + mDisplayContent.executeAppTransition(); + } else if (SHOW_APP_STARTING_PREVIEW && doShow) { + // Figure out if we are transitioning from another activity that is + // "has the same starting icon" as the next one. This allows the + // window manager to keep the previous window it had previously + // created, if it still had one. + Task baseTask = r.getTask(); + final ActivityRecord prev = baseTask.getActivity( + a -> a.mStartingData != null && a.showToCurrentUser()); + mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask, + isTaskSwitch, sourceRecord); } }