summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java27
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java19
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.