From b7c1ba2dfa699c583604765160bff36cb7ee3b76 Mon Sep 17 00:00:00 2001 From: Wei Sheng Shih Date: Mon, 15 Apr 2024 04:07:10 +0000 Subject: Revert^2 "Correct activity's lifecycle when the process was killed in background." The lifecycle of an invisible activity would stay in pause stage if it's process was died and restore from attachApplication. The incorrect status can affect transition since it won't be removed from UnknownAppVisibilityController. Stopping the invisible activity so it won't stay in paused. Bug: 327596503 Test: atest RecentsAnimationTest Test: launch a translucent app, entering keyguard, kill home process. Verify the activity of home process would be stopped after attach the process back. Change-Id: I7560c40ddf1a223e2a2aaba463124d06cc3c0051 Merged-In: I80756609fe643877971408934b19ad97aa0ae746 --- .../java/com/android/server/wm/ActivityTaskSupervisor.java | 11 +++++++++-- .../src/com/android/server/wm/RecentsAnimationTest.java | 5 ++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 2cda1f55b038..a3a06d404a2e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -57,6 +57,7 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED; import static com.android.server.wm.ActivityRecord.State.PAUSING; import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS; import static com.android.server.wm.ActivityRecord.State.RESUMED; +import static com.android.server.wm.ActivityRecord.State.STOPPING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE; @@ -104,6 +105,7 @@ import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.LaunchActivityItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.ResumeActivityItem; +import android.app.servertransaction.StopActivityItem; import android.companion.virtual.VirtualDeviceManager; import android.content.ComponentName; import android.content.Context; @@ -944,8 +946,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { if (andResume) { lifecycleItem = ResumeActivityItem.obtain(r.token, isTransitionForward, r.shouldSendCompatFakeFocus()); - } else { + } else if (r.isVisibleRequested()) { lifecycleItem = PauseActivityItem.obtain(r.token); + } else { + lifecycleItem = StopActivityItem.obtain(r.token, 0 /* configChanges */); } // Schedule transaction. @@ -1012,7 +1016,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // As part of the process of launching, ActivityThread also performs // a resume. rootTask.minimalResumeActivityLocked(r); - } else { + } else if (r.isVisibleRequested()) { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the // current icicle and other state. @@ -1020,6 +1024,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { + "(starting in paused state)", r); r.setState(PAUSED, "realStartActivityLocked"); mRootWindowContainer.executeAppTransitionForAllDisplay(); + } else { + // This activity is starting while invisible, so it should be stopped. + r.setState(STOPPING, "realStartActivityLocked"); } // Perform OOM scoring after the activity state is set, so the process can be updated with // the latest state. diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 32b3558ba397..da437c4d1d18 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityRecord.State.PAUSED; +import static com.android.server.wm.ActivityRecord.State.STOPPING; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -164,13 +165,12 @@ public class RecentsAnimationTest extends WindowTestsBase { ActivityRecord recentsActivity = recentsStack.getTopNonFinishingActivity(); // The activity is started in background so it should be invisible and will be stopped. assertThat(recentsActivity).isNotNull(); - assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity); + assertThat(recentsActivity.getState()).isEqualTo(STOPPING); assertFalse(recentsActivity.isVisibleRequested()); // Assume it is stopped to test next use case. recentsActivity.activityStopped(null /* newIcicle */, null /* newPersistentState */, null /* description */); - mSupervisor.mStoppingActivities.remove(recentsActivity); spyOn(recentsActivity); // Start when the recents activity exists. It should ensure the configuration. @@ -178,7 +178,6 @@ public class RecentsAnimationTest extends WindowTestsBase { null /* recentsAnimationRunner */); verify(recentsActivity).ensureActivityConfiguration(eq(true) /* ignoreVisibility */); - assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity); } @Test -- cgit v1.2.3-59-g8ed1b