Tweak how we skip transitions for first activity
The first home activity is inserted into a task and then started from ActivityStarter by Task.startActivityLocked. Previously we checked for the first ever activity by checking for isHome (=true) and not hasActivity (=true). This was intended to come back false if there was no activity before this one. However the activity is already created by this point so we wrongly treated this first launch the same as any other launch. Another way of checking for this condition is to do what the comment says: see if getActivityBelow(x) exists, if not we have nothing to animate in on top of. Bug: 258882804 Change-Id: I6ffa281bad6bf5ffcf738e281c987f3a21a7ace1
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user