diff options
| author | 2019-09-04 14:09:14 +0000 | |
|---|---|---|
| committer | 2019-09-04 14:09:14 +0000 | |
| commit | f7a1488e90c485b2b0cc7d002c2ad286782acb3c (patch) | |
| tree | 97dfce896fb3d21d15d18e0cf546a1a9390d6876 | |
| parent | fcc598d1e7cccd38a9e0eb83910dcb3fed829780 (diff) | |
| parent | 7b03ad9511ac66d28b790da4a2bac44efedbc76a (diff) | |
Merge "Fix resumeWhilePausing not working"
9 files changed, 58 insertions, 66 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java index e76078fb31b1..f3e7384fa9ce 100644 --- a/services/core/java/com/android/server/wm/ActivityDisplay.java +++ b/services/core/java/com/android/server/wm/ActivityDisplay.java @@ -574,11 +574,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> * then we should explicitly pause that stack's top activity. * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). * @param resuming The resuming activity. - * @param dontWait The resuming activity isn't going to wait for all activities to be paused - * before resuming. * @return {@code true} if any activity was paused as a result of this call. */ - boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) { + boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming) { boolean someActivityPaused = false; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); @@ -588,8 +586,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> || !stack.isFocusable())) { if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack + " mResumedActivity=" + resumedActivity); - someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, - dontWait); + someActivityPaused |= stack.startPausingLocked(userLeaving, false /* uiSleeping*/, + resuming); } } return someActivityPaused; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 8e42943e1f58..12cb94db0a8e 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -118,7 +118,6 @@ import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING; import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE; -import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; @@ -1664,11 +1663,10 @@ final class ActivityRecord extends ConfigurationContainer { @interface FinishRequest {} /** - * See {@link #finishIfPossible(int, Intent, String, boolean, boolean)} + * See {@link #finishIfPossible(int, Intent, String, boolean)} */ @FinishRequest int finishIfPossible(String reason, boolean oomAdj) { - return finishIfPossible(Activity.RESULT_CANCELED, null /* resultData */, reason, - oomAdj, !PAUSE_IMMEDIATELY); + return finishIfPossible(Activity.RESULT_CANCELED, null /* resultData */, reason, oomAdj); } /** @@ -1683,7 +1681,7 @@ final class ActivityRecord extends ConfigurationContainer { * request to finish it was not ignored. */ @FinishRequest int finishIfPossible(int resultCode, Intent resultData, String reason, - boolean oomAdj, boolean pauseImmediately) { + boolean oomAdj) { if (DEBUG_RESULTS || DEBUG_STATES) { Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode + ", data=" + resultData + ", reason=" + reason); @@ -1768,7 +1766,8 @@ final class ActivityRecord extends ConfigurationContainer { if (DEBUG_USER_LEAVING) { Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false"); } - stack.startPausingLocked(false, false, null, pauseImmediately); + stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, + null /* resuming */); } if (endTask) { @@ -2104,7 +2103,7 @@ final class ActivityRecord extends ConfigurationContainer { // TODO: If the callers to removeTask() changes such that we have multiple places // where we are destroying the task, move this back into removeTask() mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, - !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY, reason); + !REMOVE_FROM_RECENTS, reason); } // We must keep the task around until all activities are destroyed. The following diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index a8eaaa4c2438..f5f6625c8728 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -63,7 +63,6 @@ import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStack.ActivityState.STARTED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; -import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; @@ -1547,7 +1546,7 @@ class ActivityStack extends ConfigurationContainer { if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "Sleep => pause with userLeaving=false"); - startPausingLocked(false, true, null, false); + startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */); shouldSleep = false ; } else if (mPausingActivity != null) { // Still waiting for something to pause; can't sleep yet. @@ -1617,13 +1616,11 @@ class ActivityStack extends ConfigurationContainer { * @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 pauseImmediately True if the caller does not want to wait for the activity callback to - * complete pausing. * @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, boolean pauseImmediately) { + ActivityRecord resuming) { if (mPausingActivity != null) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + " state=" + mPausingActivity.getState()); @@ -1661,6 +1658,19 @@ class ActivityStack extends ConfigurationContainer { mService.updateCpuStats(); + boolean pauseImmediately = false; + if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) { + // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous + // activity to be paused, while at the same time resuming the new resume activity + // only if the previous activity can't go into Pip since we want to give Pip + // activities a chance to enter Pip before resuming the next activity. + final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState( + "shouldResumeWhilePausing", userLeaving); + if (!lastResumedCanPip) { + pauseImmediately = true; + } + } + if (prev.attachedToProcess()) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); try { @@ -1758,7 +1768,8 @@ class ActivityStack extends ConfigurationContainer { mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); } - private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { + @VisibleForTesting + void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { ActivityRecord prev = mPausingActivity; if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); @@ -2594,7 +2605,6 @@ class ActivityStack extends ConfigurationContainer { mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid); - boolean lastResumedCanPip = false; ActivityRecord lastResumed = null; final ActivityStack lastFocusedStack = display.getLastFocusedStack(); if (lastFocusedStack != null && lastFocusedStack != this) { @@ -2608,23 +2618,15 @@ class ActivityStack extends ConfigurationContainer { + " next=" + next + " lastResumed=" + lastResumed); userLeaving = false; } - lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState( - "resumeTopActivity", userLeaving /* beforeStopping */); } - // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity - // to be paused, while at the same time resuming the new resume activity only if the - // previous activity can't go into Pip since we want to give Pip activities a chance to - // enter Pip before resuming the next activity. - final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0 - && !lastResumedCanPip; - boolean pausing = display.pauseBackStacks(userLeaving, next, false); + boolean pausing = display.pauseBackStacks(userLeaving, next); if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); - pausing |= startPausingLocked(userLeaving, false, next, false); + pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next); } - if (pausing && !resumeWhilePausing) { + if (pausing) { if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, "resumeTopActivityLocked: Skip resume: need to start pausing"); // At this point we want to put the upcoming activity's process @@ -3802,8 +3804,7 @@ class ActivityStack extends ConfigurationContainer { final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { final ActivityRecord r = activities.get(i); - r.finishIfPossible(resultCode, resultData, "navigate-up", true /* oomAdj */, - !PAUSE_IMMEDIATELY); + r.finishIfPossible(resultCode, resultData, "navigate-up", true /* oomAdj */); // Only return the supplied result for the first activity finished resultCode = Activity.RESULT_CANCELED; resultData = null; @@ -3840,8 +3841,7 @@ class ActivityStack extends ConfigurationContainer { } catch (RemoteException e) { foundParentInTask = false; } - parent.finishIfPossible(resultCode, resultData, "navigate-top", - true /* oomAdj */, !PAUSE_IMMEDIATELY); + parent.finishIfPossible(resultCode, resultData, "navigate-top", true /* oomAdj */); } } Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index a06b9ce5d645..a480fb8f110f 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -200,10 +200,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // Used to indicate that a task is removed it should also be removed from recents. static final boolean REMOVE_FROM_RECENTS = true; - // Used to indicate that pausing an activity should occur immediately without waiting for - // the activity callback indicating that it has completed pausing - static final boolean PAUSE_IMMEDIATELY = true; - /** True if the docked stack is currently being resized. */ private boolean mDockedStackResizing; @@ -1778,30 +1774,19 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } /** - * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)} - */ - boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, - String reason) { - return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY, - reason); - } - - /** * Removes the task with the specified task id. * * @param taskId Identifier of the task to be removed. * @param killProcess Kill any process associated with the task if possible. * @param removeFromRecents Whether to also remove the task from recents. - * @param pauseImmediately Pauses all task activities immediately without waiting for the - * pause-complete callback from the activity. * @return Returns true if the given task was found and removed. */ boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, - boolean pauseImmediately, String reason) { + String reason) { final TaskRecord tr = mRootActivityContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS); if (tr != null) { - tr.removeTaskActivitiesLocked(pauseImmediately, reason); + tr.removeTaskActivitiesLocked(reason); cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); mService.getLockTaskController().clearLockedTask(tr); if (tr.isPersistable) { @@ -1925,7 +1910,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // Task was trimmed from the recent tasks list -- remove the active task record as well // since the user won't really be able to go back to it removeTaskByIdLocked(task.taskId, killProcess, false /* removeFromRecents */, - !PAUSE_IMMEDIATELY, "recent-task-trimmed"); + "recent-task-trimmed"); } task.removedFromRecents(); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 8d40f871f8fe..ee56c0902e78 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -87,7 +87,6 @@ import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING; import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; -import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; @@ -1616,8 +1615,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // Explicitly dismissing the activity so reset its relaunch flag. r.mRelaunchReason = RELAUNCH_REASON_NONE; } else { - r.finishIfPossible(resultCode, resultData, "app-request", - true /* oomAdj */, !PAUSE_IMMEDIATELY); + r.finishIfPossible(resultCode, resultData, "app-request", true /* oomAdj */); res = r.finishing; if (!res) { Slog.i(TAG, "Failed to finish by app-request"); diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java index ede2f568e69e..e25ca73e457d 100644 --- a/services/core/java/com/android/server/wm/TaskRecord.java +++ b/services/core/java/com/android/server/wm/TaskRecord.java @@ -71,7 +71,6 @@ import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING; import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP; import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; -import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK; @@ -702,7 +701,7 @@ class TaskRecord extends ConfigurationContainer { && toStack.topRunningActivityLocked() != 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 */, false /* pauseImmediately */); + null /* resuming */); } final int toStackWindowingMode = toStack.getWindowingMode(); @@ -1405,8 +1404,7 @@ class TaskRecord extends ConfigurationContainer { * Completely remove all activities associated with an existing * task starting at a specified index. */ - final void performClearTaskAtIndexLocked(int activityNdx, boolean pauseImmediately, - String reason) { + final void performClearTaskAtIndexLocked(int activityNdx, String reason) { int numActivities = mActivities.size(); for ( ; activityNdx < numActivities; ++activityNdx) { final ActivityRecord r = mActivities.get(activityNdx); @@ -1419,8 +1417,8 @@ class TaskRecord extends ConfigurationContainer { mActivities.remove(activityNdx); --activityNdx; --numActivities; - } else if (r.finishIfPossible(Activity.RESULT_CANCELED, - null /* resultData */, reason, false /* oomAdj */, pauseImmediately) + } else if (r.finishIfPossible(Activity.RESULT_CANCELED, null /* resultData */, reason, + false /* oomAdj */) == FINISH_RESULT_REMOVED) { --activityNdx; --numActivities; @@ -1433,7 +1431,7 @@ class TaskRecord extends ConfigurationContainer { */ void performClearTaskLocked() { mReuseTask = true; - performClearTaskAtIndexLocked(0, !PAUSE_IMMEDIATELY, "clear-task-all"); + performClearTaskAtIndexLocked(0, "clear-task-all"); mReuseTask = false; } @@ -1501,9 +1499,9 @@ class TaskRecord extends ConfigurationContainer { return null; } - void removeTaskActivitiesLocked(boolean pauseImmediately, String reason) { + void removeTaskActivitiesLocked(String reason) { // Just remove the entire task. - performClearTaskAtIndexLocked(0, pauseImmediately, reason); + performClearTaskAtIndexLocked(0, reason); } String lockTaskAuthToString() { diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 242b116b0315..8c51452075b7 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -620,7 +620,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio final ActivityStack stack = mPreQTopResumedActivity.getActivityStack(); if (stack != null) { stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, - null /* resuming */, false /* pauseImmediately */); + activity); } } mPreQTopResumedActivity = activity; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index f54822557569..7b064908565c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -820,7 +820,7 @@ public class ActivityRecordTests extends ActivityTestsBase { mActivity.setState(RESUMED, "test"); mActivity.finishIfPossible(0 /* resultCode */, null /* resultData */, "test", - false /* oomAdj */, false /* pauseImmediately */); + false /* oomAdj */); assertTrue(stack1.isTopStackOnDisplay()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index c83e5cb71feb..2a8b4c88c000 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -980,6 +981,19 @@ public class ActivityStackTests extends ActivityTestsBase { } @Test + public void testCompletePauseOnResumeWhilePausingActivity() { + final ActivityRecord bottomActivity = new ActivityBuilder(mService).setTask(mTask).build(); + doReturn(true).when(bottomActivity).attachedToProcess(); + mStack.mPausingActivity = null; + mStack.mResumedActivity = bottomActivity; + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.info.flags |= FLAG_RESUME_WHILE_PAUSING; + + mStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */, topActivity); + verify(mStack).completePauseLocked(anyBoolean(), eq(topActivity)); + } + + @Test public void testAdjustFocusedStackToHomeWhenNoActivity() { final ActivityStack homeStask = mDefaultDisplay.getHomeStack(); TaskRecord homeTask = homeStask.topTask(); |