Merge "Defer pausing apps when bringing up recents" into sc-dev

This commit is contained in:
Evan Rosky
2021-05-18 18:55:30 +00:00
committed by Android (Google) Code Review
5 changed files with 59 additions and 9 deletions

View File

@@ -327,6 +327,9 @@ public class ActivityOptions {
private static final String KEY_LAUNCHED_FROM_BUBBLE = private static final String KEY_LAUNCHED_FROM_BUBBLE =
"android.activity.launchTypeBubble"; "android.activity.launchTypeBubble";
/** See {@link #setTransientLaunch()}. */
private static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";
/** /**
* @see #setLaunchCookie * @see #setLaunchCookie
* @hide * @hide
@@ -414,6 +417,7 @@ public class ActivityOptions {
private int mSplashScreenThemeResId; private int mSplashScreenThemeResId;
private boolean mRemoveWithTaskOrganizer; private boolean mRemoveWithTaskOrganizer;
private boolean mLaunchedFromBubble; private boolean mLaunchedFromBubble;
private boolean mTransientLaunch;
/** /**
* Create an ActivityOptions specifying a custom animation to run when * Create an ActivityOptions specifying a custom animation to run when
@@ -1166,6 +1170,7 @@ public class ActivityOptions {
mSplashScreenThemeResId = opts.getInt(KEY_SPLASH_SCREEN_THEME); mSplashScreenThemeResId = opts.getInt(KEY_SPLASH_SCREEN_THEME);
mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER); mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE); mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
} }
/** /**
@@ -1662,6 +1667,28 @@ public class ActivityOptions {
return mLaunchedFromBubble; return mLaunchedFromBubble;
} }
/**
* Sets whether the activity launch is part of a transient operation. If it is, it will not
* cause lifecycle changes in existing activities even if it were to occlude them (ie. other
* activities occluded by this one will not be paused or stopped until the launch is committed).
* As a consequence, it will start immediately since it doesn't need to wait for other
* lifecycles to evolve. Current user is recents.
* @hide
*/
public ActivityOptions setTransientLaunch() {
mTransientLaunch = true;
return this;
}
/**
* @see #setTransientLaunch()
* @return whether the activity launch is part of a transient operation.
* @hide
*/
public boolean getTransientLaunch() {
return mTransientLaunch;
}
/** /**
* Update the current values in this ActivityOptions from those supplied * Update the current values in this ActivityOptions from those supplied
* in <var>otherOptions</var>. Any values * in <var>otherOptions</var>. Any values
@@ -1902,6 +1929,9 @@ public class ActivityOptions {
if (mLaunchedFromBubble) { if (mLaunchedFromBubble) {
b.putBoolean(KEY_LAUNCHED_FROM_BUBBLE, mLaunchedFromBubble); b.putBoolean(KEY_LAUNCHED_FROM_BUBBLE, mLaunchedFromBubble);
} }
if (mTransientLaunch) {
b.putBoolean(KEY_TRANSIENT_LAUNCH, mTransientLaunch);
}
return b; return b;
} }

View File

@@ -192,6 +192,7 @@ class ActivityStarter {
private boolean mKeepCurTransition; private boolean mKeepCurTransition;
private boolean mAvoidMoveToFront; private boolean mAvoidMoveToFront;
private boolean mFrozeTaskList; private boolean mFrozeTaskList;
private boolean mTransientLaunch;
// We must track when we deliver the new intent since multiple code paths invoke // We must track when we deliver the new intent since multiple code paths invoke
// {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
@@ -1792,7 +1793,7 @@ class ActivityStarter {
mTargetRootTask.moveToFront("startActivityInner"); mTargetRootTask.moveToFront("startActivityInner");
} }
mRootWindowContainer.resumeFocusedTasksTopActivities( mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions); mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
} }
} }
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
@@ -2209,6 +2210,7 @@ class ActivityStarter {
mKeepCurTransition = false; mKeepCurTransition = false;
mAvoidMoveToFront = false; mAvoidMoveToFront = false;
mFrozeTaskList = false; mFrozeTaskList = false;
mTransientLaunch = false;
mVoiceSession = null; mVoiceSession = null;
mVoiceInteractor = null; mVoiceInteractor = null;
@@ -2311,6 +2313,7 @@ class ActivityStarter {
mDoResume = false; mDoResume = false;
mAvoidMoveToFront = true; mAvoidMoveToFront = true;
} }
mTransientLaunch = mOptions.getTransientLaunch();
mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask());
} }
@@ -2642,7 +2645,7 @@ class ActivityStarter {
} }
if (mTargetRootTask.isFocusable()) { if (mTargetRootTask.isFocusable()) {
mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null, mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, null,
mOptions); mOptions, mTransientLaunch);
} else { } else {
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
} }

View File

@@ -2293,7 +2293,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean resumeFocusedTasksTopActivities( boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) { Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {
return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions,
false /* deferPause */);
}
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
if (!mTaskSupervisor.readyToResume()) { if (!mTaskSupervisor.readyToResume()) {
return false; return false;
} }
@@ -2301,7 +2307,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean result = false; boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea() if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) { || getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions); result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
} }
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {

View File

@@ -6066,6 +6066,7 @@ class Task extends WindowContainer<WindowContainer> {
* @param prev The previously resumed activity, for when in the process * @param prev The previously resumed activity, for when in the process
* of pausing; can be null to call from elsewhere. * of pausing; can be null to call from elsewhere.
* @param options Activity options. * @param options Activity options.
* @param deferPause When {@code true}, this will not pause back tasks.
* *
* @return Returns true if something is being resumed, or false if * @return Returns true if something is being resumed, or false if
* nothing happened. * nothing happened.
@@ -6076,7 +6077,8 @@ class Task extends WindowContainer<WindowContainer> {
* right activity for the current system state. * right activity for the current system state.
*/ */
@GuardedBy("mService") @GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (mInResumeTopActivity) { if (mInResumeTopActivity) {
// Don't even start recursing. // Don't even start recursing.
return false; return false;
@@ -6089,7 +6091,7 @@ class Task extends WindowContainer<WindowContainer> {
if (isLeafTask()) { if (isLeafTask()) {
if (isFocusableAndVisible()) { if (isFocusableAndVisible()) {
someActivityResumed = resumeTopActivityInnerLocked(prev, options); someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
} }
} else { } else {
int idx = mChildren.size() - 1; int idx = mChildren.size() - 1;
@@ -6102,7 +6104,8 @@ class Task extends WindowContainer<WindowContainer> {
break; break;
} }
someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options); someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
deferPause);
// Doing so in order to prevent IndexOOB since hierarchy might changes while // Doing so in order to prevent IndexOOB since hierarchy might changes while
// resuming activities, for example dismissing split-screen while starting // resuming activities, for example dismissing split-screen while starting
// non-resizeable activity. // non-resizeable activity.
@@ -6130,8 +6133,15 @@ class Task extends WindowContainer<WindowContainer> {
return someActivityResumed; return someActivityResumed;
} }
/** @see #resumeTopActivityUncheckedLocked(ActivityRecord, ActivityOptions, boolean) */
@GuardedBy("mService") @GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
}
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) { if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
// Not ready yet! // Not ready yet!
return false; return false;
@@ -6227,7 +6237,7 @@ class Task extends WindowContainer<WindowContainer> {
lastResumed = lastFocusedRootTask.getResumedActivity(); lastResumed = lastFocusedRootTask.getResumedActivity();
} }
boolean pausing = taskDisplayArea.pauseBackTasks(next); boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) { if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity); ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);
pausing |= startPausingLocked(false /* uiSleeping */, next, pausing |= startPausingLocked(false /* uiSleeping */, next,

View File

@@ -560,7 +560,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
// Verify the target task should resume its activity. // Verify the target task should resume its activity.
verify(rootTask, times(1)).resumeTopActivityUncheckedLocked( verify(rootTask, times(1)).resumeTopActivityUncheckedLocked(
eq(activity), eq(null /* targetOptions */)); eq(activity), eq(null /* targetOptions */), eq(false));
} }
/** /**