From ef15e6ff608ca44b507f1a29b4cf067c84a42ce4 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 8 Dec 2022 07:36:24 +0000 Subject: [PATCH] Remove duplicated field of activity stopped state It is leftover since merging AppWindowToken and ActivityRecord. Both "stopped" and "mAppStopped" are set to true if the activity completed stopped, and set to false if the activity is going to resume. While "mAppStopped" will change to false if the activity is requested to be visible. That is closer to the definition about the relation of visibility and lifecycle state, so choose to keep "mAppStopped". Also inline notifyAppStopped() into activityStopped() because there is only one usage since the methods were migrated from 2 files for handling stopped activity. Bug: 163976519 Test: CtsWindowManagerDeviceTestCases Change-Id: Ieb2b4ebf91c08be1977bf619981454c8222ac20d --- .../com/android/server/wm/ActivityRecord.java | 103 ++++++++---------- .../com/android/server/wm/TaskFragment.java | 8 +- .../server/wm/WindowProcessController.java | 6 +- 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index aec06f0a25dd5..0cfbe3344f322 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -513,7 +513,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // dies. After an activity is launched it follows the value // of #mIcicle. boolean launchFailed; // set if a launched failed, to abort on 2nd try - boolean stopped; // is activity pause finished? boolean delayedResume; // not yet resumed because of stopped app switches? boolean finishing; // activity in pending finish list? boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is @@ -881,6 +880,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A boolean mOverrideTaskTransition; boolean mDismissKeyguard; + /** True if the activity has reported stopped; False if the activity becomes visible. */ boolean mAppStopped; // A hint to override the window specified rotation animation, or -1 to use the window specified // value. We use this so that we can select the right animation in the cases of starting @@ -1141,7 +1141,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState); pw.print(" mIcicle="); pw.println(mIcicle); pw.print(prefix); pw.print("state="); pw.print(mState); - pw.print(" stopped="); pw.print(stopped); pw.print(" delayedResume="); pw.print(delayedResume); pw.print(" finishing="); pw.println(finishing); pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused); @@ -2033,7 +2032,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A requestCode = _reqCode; setState(INITIALIZING, "ActivityRecord ctor"); launchFailed = false; - stopped = false; delayedResume = false; finishing = false; deferRelaunchUntilPaused = false; @@ -3883,7 +3881,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } taskFragment.sendTaskFragmentInfoChanged(); } - if (stopped) { + if (mAppStopped) { abortAndClearOptionsAnimation(); } } @@ -5724,11 +5722,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } - void notifyAppResumed(boolean wasStopped) { + void notifyAppResumed() { if (getParent() == null) { Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token); return; } + final boolean wasStopped = mAppStopped; ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppResumed: wasStopped=%b %s", wasStopped, this); mAppStopped = false; @@ -5742,32 +5741,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } - /** - * Notify that the app has stopped, and it is okay to destroy any surfaces which were - * keeping alive in case they were still being used. - */ - void notifyAppStopped() { - ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this); - mAppStopped = true; - firstWindowDrawn = false; - // This is to fix the edge case that auto-enter-pip is finished in Launcher but app calls - // setAutoEnterEnabled(false) and transitions to STOPPED state, see b/191930787. - // Clear any surface transactions and content overlay in this case. - if (task != null && task.mLastRecentsAnimationTransaction != null) { - task.clearLastRecentsAnimationTransaction(true /* forceRemoveOverlay */); - } - // Reset the last saved PiP snap fraction on app stop. - mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent); - mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); - if (isClientVisible()) { - // Though this is usually unlikely to happen, still make sure the client is invisible. - setClientVisible(false); - } - destroySurfaces(); - // Remove any starting window that was added for this app if they are still around. - removeStartingWindow(); - } - /** * Suppress transition until the new activity becomes ready, otherwise the keyguard can appear * for a short amount of time before the new process with the new activity had the ability to @@ -6128,7 +6101,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastNewIntent = newIntents.get(newIntents.size() - 1); } newIntents = null; - stopped = false; if (isActivityTypeHome()) { mTaskSupervisor.updateHomeProcess(task.getBottomMostActivity().app); @@ -6250,7 +6222,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } resumeKeyDispatchingLocked(); try { - stopped = false; ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPING: %s (stop requested)", this); setState(STOPPING, "stopIfPossible"); @@ -6268,7 +6239,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // notification will clean things up. Slog.w(TAG, "Exception thrown during pause", e); // Just in case, assume it to be stopped. - stopped = true; + mAppStopped = true; ProtoLog.v(WM_DEBUG_STATES, "Stop failed; moving to STOPPED: %s", this); setState(STOPPED, "stopIfPossible"); if (deferRelaunchUntilPaused) { @@ -6277,12 +6248,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + /** + * Notifies that the activity has stopped, and it is okay to destroy any surfaces which were + * keeping alive in case they were still being used. + */ void activityStopped(Bundle newIcicle, PersistableBundle newPersistentState, CharSequence description) { + removeStopTimeout(); final boolean isStopping = mState == STOPPING; if (!isStopping && mState != RESTARTING_PROCESS) { Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this + " " + mState); - removeStopTimeout(); return; } if (newPersistentState != null) { @@ -6298,28 +6273,42 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A updateTaskDescription(description); } ProtoLog.i(WM_DEBUG_STATES, "Saving icicle of %s: %s", this, mIcicle); - if (!stopped) { + + if (isStopping) { ProtoLog.v(WM_DEBUG_STATES, "Moving to STOPPED: %s (stop complete)", this); - removeStopTimeout(); - stopped = true; - if (isStopping) { - setState(STOPPED, "activityStoppedLocked"); - } - - notifyAppStopped(); - - if (finishing) { - abortAndClearOptionsAnimation(); - } else { - if (deferRelaunchUntilPaused) { - destroyImmediately("stop-config"); - mRootWindowContainer.resumeFocusedTasksTopActivities(); - } else { - mAtmService.updatePreviousProcess(this); - } - } - mTaskSupervisor.checkReadyForSleepLocked(true /* allowDelay */); + setState(STOPPED, "activityStopped"); } + + mAppStopped = true; + firstWindowDrawn = false; + // This is to fix the edge case that auto-enter-pip is finished in Launcher but app calls + // setAutoEnterEnabled(false) and transitions to STOPPED state, see b/191930787. + // Clear any surface transactions and content overlay in this case. + if (task.mLastRecentsAnimationTransaction != null) { + task.clearLastRecentsAnimationTransaction(true /* forceRemoveOverlay */); + } + // Reset the last saved PiP snap fraction on app stop. + mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent); + mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); + if (isClientVisible()) { + // Though this is usually unlikely to happen, still make sure the client is invisible. + setClientVisible(false); + } + destroySurfaces(); + // Remove any starting window that was added for this app if they are still around. + removeStartingWindow(); + + if (finishing) { + abortAndClearOptionsAnimation(); + } else { + if (deferRelaunchUntilPaused) { + destroyImmediately("stop-config"); + mRootWindowContainer.resumeFocusedTasksTopActivities(); + } else { + mAtmService.updatePreviousProcess(this); + } + } + mTaskSupervisor.checkReadyForSleepLocked(true /* allowDelay */); } void addToStopping(boolean scheduleIdle, boolean idleDelayed, String reason) { @@ -6857,7 +6846,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private ActivityRecord getWaitingHistoryRecordLocked() { // First find the real culprit... if this activity has stopped, then the key dispatching // timeout should not be caused by this. - if (stopped) { + if (mAppStopped) { final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); if (rootTask == null) { return this; @@ -6938,7 +6927,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } if (isState(RESUMED) || getRootTask() == null || this == getTaskFragment().getPausingActivity() - || !mHaveState || !stopped) { + || !mHaveState || !mAppStopped) { // We're not ready for this kind of thing. return false; } diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 66b868a9107ce..84bea8c39bfce 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -1355,7 +1355,7 @@ class TaskFragment extends WindowContainer { if (next.attachedToProcess()) { if (DEBUG_SWITCH) { - Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped + Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.mAppStopped + " visibleRequested=" + next.isVisibleRequested()); } @@ -1370,7 +1370,7 @@ class TaskFragment extends WindowContainer { || mLastPausedActivity != null && !mLastPausedActivity.occludesParent(); // This activity is now becoming visible. - if (!next.isVisibleRequested() || next.stopped || lastActivityTranslucent) { + if (!next.isVisibleRequested() || next.mAppStopped || lastActivityTranslucent) { next.app.addToPendingTop(); next.setVisibility(true); } @@ -1421,7 +1421,7 @@ class TaskFragment extends WindowContainer { // Do over! mTaskSupervisor.scheduleResumeTopActivities(); } - if (!next.isVisibleRequested() || next.stopped) { + if (!next.isVisibleRequested() || next.mAppStopped) { next.setVisibility(true); } next.completeResumeLocked(); @@ -1450,7 +1450,7 @@ class TaskFragment extends WindowContainer { // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. - next.notifyAppResumed(next.stopped); + next.notifyAppResumed(); EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), next.getTask().mTaskId, next.shortComponentName); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index d2cd8f8e8b0b0..e9b81ec030817 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -903,7 +903,7 @@ public class WindowProcessController extends ConfigurationContainer