Merge "Defer pausing apps when bringing up recents" into sc-dev
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user