Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +18 −9 Original line number Original line Diff line number Diff line Loading @@ -343,6 +343,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ */ private ActivityRecord mTopResumedActivity; 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 * 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. * loss of the state and report back before making new activity top resumed. Loading Loading @@ -2287,15 +2292,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * sent to the new top resumed activity. * sent to the new top resumed activity. */ */ ActivityRecord updateTopResumedActivityIfNeeded(String reason) { ActivityRecord updateTopResumedActivityIfNeeded(String reason) { if (!readyToResume()) { return mTopResumedActivity; } final ActivityRecord prevTopActivity = mTopResumedActivity; final ActivityRecord prevTopActivity = mTopResumedActivity; final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) { if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) { if (topRootTask == null) { if (topRootTask == null) { // There's no focused task and there won't have any resumed activity either. // There's no focused task and there won't have any resumed activity either. scheduleTopResumedActivityStateLossIfNeeded(); scheduleTopResumedActivityStateLossIfNeeded(); mTopResumedActivity = null; } } if (mService.isSleepingLocked()) { if (mService.isSleepingLocked()) { // There won't be a next resumed activity. The top process should still be updated // There won't be a next resumed activity. The top process should still be updated Loading Loading @@ -2339,25 +2342,27 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { /** Schedule current top resumed activity state loss */ /** Schedule current top resumed activity state loss */ private void scheduleTopResumedActivityStateLossIfNeeded() { private void scheduleTopResumedActivityStateLossIfNeeded() { if (mTopResumedActivity == null) { if (mLastReportedTopResumedActivity == null) { return; return; } } // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity // 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 // before the prevTopActivity one hasn't reported back yet. So server never sent the top // resumed state change message to prevTopActivity. // resumed state change message to prevTopActivity. if (!mTopResumedActivityWaitingForPrev if (!mTopResumedActivityWaitingForPrev && readyToResume() && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) { && mLastReportedTopResumedActivity.scheduleTopResumedActivityChanged( scheduleTopResumedStateLossTimeout(mTopResumedActivity); false /* onTop */)) { scheduleTopResumedStateLossTimeout(mLastReportedTopResumedActivity); mTopResumedActivityWaitingForPrev = true; mTopResumedActivityWaitingForPrev = true; mLastReportedTopResumedActivity = null; } } mTopResumedActivity = null; } } /** Schedule top resumed state change if previous top activity already reported back. */ /** Schedule top resumed state change if previous top activity already reported back. */ private void scheduleTopResumedActivityStateIfNeeded() { private void scheduleTopResumedActivityStateIfNeeded() { if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) { if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev && readyToResume()) { mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); mLastReportedTopResumedActivity = mTopResumedActivity; } } } } Loading Loading @@ -2611,6 +2616,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ */ void endDeferResume() { void endDeferResume() { mDeferResumeCount--; mDeferResumeCount--; if (readyToResume() && mLastReportedTopResumedActivity != null && mTopResumedActivity != mLastReportedTopResumedActivity) { scheduleTopResumedActivityStateLossIfNeeded(); } } } /** @return True if resume can be called. */ /** @return True if resume can be called. */ Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +1 −7 Original line number Original line Diff line number Diff line Loading @@ -788,9 +788,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub deferResume = false; deferResume = false; // Already calls ensureActivityConfig // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible(); mService.mRootWindowContainer.ensureActivitiesVisible(); if (!mService.mRootWindowContainer.resumeFocusedTasksTopActivities()) { mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT-effects"); } } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { for (int i = haveConfigChanges.size() - 1; i >= 0; --i) { for (int i = haveConfigChanges.size() - 1; i >= 0; --i) { haveConfigChanges.valueAt(i).forAllActivities(r -> { haveConfigChanges.valueAt(i).forAllActivities(r -> { Loading @@ -816,10 +814,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); if (deferResume) { if (deferResume) { mService.mTaskSupervisor.endDeferResume(); 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(); mService.continueWindowLayout(); } } Loading services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +19 −0 Original line number Original line Diff line number Diff line Loading @@ -357,6 +357,25 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { assertEquals(activity1.app, mAtm.mTopApp); 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 * We need to launch home again after user unlocked for those displays that do not have * encryption aware home app. * encryption aware home app. Loading Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +18 −9 Original line number Original line Diff line number Diff line Loading @@ -343,6 +343,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ */ private ActivityRecord mTopResumedActivity; 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 * 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. * loss of the state and report back before making new activity top resumed. Loading Loading @@ -2287,15 +2292,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * sent to the new top resumed activity. * sent to the new top resumed activity. */ */ ActivityRecord updateTopResumedActivityIfNeeded(String reason) { ActivityRecord updateTopResumedActivityIfNeeded(String reason) { if (!readyToResume()) { return mTopResumedActivity; } final ActivityRecord prevTopActivity = mTopResumedActivity; final ActivityRecord prevTopActivity = mTopResumedActivity; final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) { if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) { if (topRootTask == null) { if (topRootTask == null) { // There's no focused task and there won't have any resumed activity either. // There's no focused task and there won't have any resumed activity either. scheduleTopResumedActivityStateLossIfNeeded(); scheduleTopResumedActivityStateLossIfNeeded(); mTopResumedActivity = null; } } if (mService.isSleepingLocked()) { if (mService.isSleepingLocked()) { // There won't be a next resumed activity. The top process should still be updated // There won't be a next resumed activity. The top process should still be updated Loading Loading @@ -2339,25 +2342,27 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { /** Schedule current top resumed activity state loss */ /** Schedule current top resumed activity state loss */ private void scheduleTopResumedActivityStateLossIfNeeded() { private void scheduleTopResumedActivityStateLossIfNeeded() { if (mTopResumedActivity == null) { if (mLastReportedTopResumedActivity == null) { return; return; } } // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity // 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 // before the prevTopActivity one hasn't reported back yet. So server never sent the top // resumed state change message to prevTopActivity. // resumed state change message to prevTopActivity. if (!mTopResumedActivityWaitingForPrev if (!mTopResumedActivityWaitingForPrev && readyToResume() && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) { && mLastReportedTopResumedActivity.scheduleTopResumedActivityChanged( scheduleTopResumedStateLossTimeout(mTopResumedActivity); false /* onTop */)) { scheduleTopResumedStateLossTimeout(mLastReportedTopResumedActivity); mTopResumedActivityWaitingForPrev = true; mTopResumedActivityWaitingForPrev = true; mLastReportedTopResumedActivity = null; } } mTopResumedActivity = null; } } /** Schedule top resumed state change if previous top activity already reported back. */ /** Schedule top resumed state change if previous top activity already reported back. */ private void scheduleTopResumedActivityStateIfNeeded() { private void scheduleTopResumedActivityStateIfNeeded() { if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) { if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev && readyToResume()) { mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */); mLastReportedTopResumedActivity = mTopResumedActivity; } } } } Loading Loading @@ -2611,6 +2616,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { */ */ void endDeferResume() { void endDeferResume() { mDeferResumeCount--; mDeferResumeCount--; if (readyToResume() && mLastReportedTopResumedActivity != null && mTopResumedActivity != mLastReportedTopResumedActivity) { scheduleTopResumedActivityStateLossIfNeeded(); } } } /** @return True if resume can be called. */ /** @return True if resume can be called. */ Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +1 −7 Original line number Original line Diff line number Diff line Loading @@ -788,9 +788,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub deferResume = false; deferResume = false; // Already calls ensureActivityConfig // Already calls ensureActivityConfig mService.mRootWindowContainer.ensureActivitiesVisible(); mService.mRootWindowContainer.ensureActivitiesVisible(); if (!mService.mRootWindowContainer.resumeFocusedTasksTopActivities()) { mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT-effects"); } } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) { for (int i = haveConfigChanges.size() - 1; i >= 0; --i) { for (int i = haveConfigChanges.size() - 1; i >= 0; --i) { haveConfigChanges.valueAt(i).forAllActivities(r -> { haveConfigChanges.valueAt(i).forAllActivities(r -> { Loading @@ -816,10 +814,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */); if (deferResume) { if (deferResume) { mService.mTaskSupervisor.endDeferResume(); 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(); mService.continueWindowLayout(); } } Loading
services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +19 −0 Original line number Original line Diff line number Diff line Loading @@ -357,6 +357,25 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { assertEquals(activity1.app, mAtm.mTopApp); 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 * We need to launch home again after user unlocked for those displays that do not have * encryption aware home app. * encryption aware home app. Loading