Pausing the resumed activity when making it invisible

A resumed activity was added to stopping activity lists while
making it invisible without having state changes. So, the
activity won't be resumed if it became visible again because
the activity is already in resumed state.

Also adding the reason of why the activity should be paused.

Bug: 160435184
Test: atest ActivityRecordTests
Change-Id: Ie92fdef045cb0ba06fee9575878f8849f7eda1d9
This commit is contained in:
Louis Chang
2020-08-28 14:35:31 +08:00
parent 1570626a6c
commit 9b8ece2069
6 changed files with 20 additions and 16 deletions

View File

@@ -2606,7 +2606,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false");
}
stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */);
null /* resuming */, "finish");
}
if (endTask) {
@@ -4770,14 +4770,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
supportsEnterPipOnTaskSwitch = false;
break;
case RESUMED:
// If the app is capable of entering PIP, we should try pausing it now
// so it can PIP correctly.
if (deferHidingClient) {
getRootTask().startPausingLocked(
mStackSupervisor.mUserLeaving /* userLeaving */,
false /* uiSleeping */, null /* resuming */);
// Do nothing if currently in the process of resuming the activity. Otherwise,
// starting to pause it since it is not visible.
if (!mSetToSleep) {
break;
}
getRootTask().startPausingLocked(mStackSupervisor.mUserLeaving,
false /* uiSleeping */, null /* resuming */, "makeInvisible");
// fall through
case INITIALIZING:
case PAUSING:
case PAUSED:

View File

@@ -26,7 +26,7 @@ option java_package com.android.server.wm
# The Activity Manager failed to pause the given activity.
30012 wm_failed_to_pause (User|1|5),(Token|1|5),(Wanting to pause|3),(Currently pausing|3)
# Attempting to pause the current activity
30013 wm_pause_activity (User|1|5),(Token|1|5),(Component Name|3),(User Leaving|3)
30013 wm_pause_activity (User|1|5),(Token|1|5),(Component Name|3),(User Leaving|3),(Reason|3)
# Application process has been started
# An activity is being destroyed:

View File

@@ -1102,7 +1102,7 @@ class Task extends WindowContainer<WindowContainer> {
&& toStack.topRunningActivity() != null) {
// Pause the resumed activity on the target stack while re-parenting task on top of it.
toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */);
null /* resuming */, "reparent");
}
final int toStackWindowingMode = toStack.getWindowingMode();
@@ -5340,7 +5340,8 @@ class Task extends WindowContainer<WindowContainer> {
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"Sleep => pause with userLeaving=false");
startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */);
startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */,
"sleep");
shouldSleep = false ;
} else if (mPausingActivity != null) {
// Still waiting for something to pause; can't sleep yet.
@@ -5400,11 +5401,12 @@ class Task extends WindowContainer<WindowContainer> {
* @param resuming The activity we are currently trying to resume or null if this is not being
* called as part of resuming the top activity, so we shouldn't try to instigate
* a resume here if not null.
* @param reason The reason of pausing the activity.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming) {
ActivityRecord resuming, String reason) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
@@ -5471,7 +5473,7 @@ class Task extends WindowContainer<WindowContainer> {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
@@ -5995,7 +5997,8 @@ class Task extends WindowContainer<WindowContainer> {
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next,
"resumeTopActivityInnerLocked");
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,

View File

@@ -1219,7 +1219,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
+ " mResumedActivity=" + resumedActivity);
}
someActivityPaused |= stack.startPausingLocked(userLeaving, false /* uiSleeping*/,
resuming);
resuming, "pauseBackStacks");
}
}
return someActivityPaused;

View File

@@ -768,7 +768,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final Task stack = mPreQTopResumedActivity.getRootTask();
if (stack != null) {
stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
activity);
activity, "top-resumed-changed");
}
}
mPreQTopResumedActivity = activity;

View File

@@ -1142,7 +1142,8 @@ public class ActivityStackTests extends WindowTestsBase {
final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(mTask).build();
topActivity.info.flags |= FLAG_RESUME_WHILE_PAUSING;
mStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, topActivity);
mStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, topActivity,
"test");
verify(mStack).completePauseLocked(anyBoolean(), eq(topActivity));
}