diff options
3 files changed, 38 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 4857b02eaf7c..70a8f563275f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -344,6 +344,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { private ActivityRecord mTopResumedActivity; /** + * Cached value of the topmost resumed activity that reported to the client. + */ + private ActivityRecord mLastReportedTopResumedActivity; + + /** * Flag indicating whether we're currently waiting for the previous top activity to handle the * loss of the state and report back before making new activity top resumed. */ @@ -2287,15 +2292,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * sent to the new top resumed activity. */ ActivityRecord updateTopResumedActivityIfNeeded(String reason) { - if (!readyToResume()) { - return mTopResumedActivity; - } final ActivityRecord prevTopActivity = mTopResumedActivity; final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) { if (topRootTask == null) { // There's no focused task and there won't have any resumed activity either. scheduleTopResumedActivityStateLossIfNeeded(); + mTopResumedActivity = null; } if (mService.isSleepingLocked()) { // There won't be a next resumed activity. The top process should still be updated @@ -2339,25 +2342,27 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { /** Schedule current top resumed activity state loss */ private void scheduleTopResumedActivityStateLossIfNeeded() { - if (mTopResumedActivity == null) { + if (mLastReportedTopResumedActivity == null) { return; } // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity // before the prevTopActivity one hasn't reported back yet. So server never sent the top // resumed state change message to prevTopActivity. - if (!mTopResumedActivityWaitingForPrev - && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) { - scheduleTopResumedStateLossTimeout(mTopResumedActivity); + if (!mTopResumedActivityWaitingForPrev && readyToResume() + && mLastReportedTopResumedActivity.scheduleTopResumedActivityChanged( + false /* onTop */)) { + scheduleTopResumedStateLossTimeout(mLastReportedTopResumedActivity); mTopResumedActivityWaitingForPrev = true; + mLastReportedTopResumedActivity = null; } - mTopResumedActivity = null; } /** Schedule top resumed state change if previous top activity already reported back. */ private void scheduleTopResumedActivityStateIfNeeded() { - if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) { + if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev && readyToResume()) { mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); + mLastReportedTopResumedActivity = mTopResumedActivity; } } @@ -2611,6 +2616,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ void endDeferResume() { mDeferResumeCount--; + if (readyToResume() && mLastReportedTopResumedActivity != null + && mTopResumedActivity != mLastReportedTopResumedActivity) { + scheduleTopResumedActivityStateLossIfNeeded(); + } } /** @return True if resume can be called. */ diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 091896590b6b..c42aa37d847b 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -788,9 +788,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub deferResume = false; // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible(); - if (!mService.mRootWindowContainer.resumeFocusedTasksTopActivities()) { - mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT-effects"); - } + mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { for (int i = haveConfigChanges.size() - 1; i >= 0; --i) { haveConfigChanges.valueAt(i).forAllActivities(r -> { @@ -816,10 +814,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); if (deferResume) { mService.mTaskSupervisor.endDeferResume(); - // Transient launching the Recents via HIERARCHY_OP_TYPE_PENDING_INTENT directly - // resume the Recents activity with no TRANSACT_EFFECTS_LIFECYCLE. Explicitly - // checks if the top resumed activity should be updated after defer-resume ended. - mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT"); } mService.continueWindowLayout(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java index 7f260f85a755..70f57eb40385 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java @@ -357,6 +357,25 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { assertEquals(activity1.app, mAtm.mTopApp); } + @Test + public void testTopResumedActivity_deferResume() { + final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build(); + final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build(); + activity2.setState(ActivityRecord.State.RESUMED, "test"); + assertEquals(activity2.app, mAtm.mTopApp); + reset(activity2); + + // Verify that no top-resumed activity changes to the client while defer-resume enabled. + mSupervisor.beginDeferResume(); + activity1.getTask().moveToFront("test"); + activity1.setState(ActivityRecord.State.RESUMED, "test"); + verify(activity2, never()).scheduleTopResumedActivityChanged(eq(false)); + + // Verify that the change is scheduled to the client after defer-resumed disabled + mSupervisor.endDeferResume(); + verify(activity2).scheduleTopResumedActivityChanged(eq(false)); + } + /** * We need to launch home again after user unlocked for those displays that do not have * encryption aware home app. |