From c3bc633fb8a4f750ec86c9cf54fd73a564c43e43 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Wed, 31 May 2023 03:29:19 +0000 Subject: [PATCH] Reports top resumed activity state loss when no focused task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was no other focusable task while the top resumed activity finished. So, the system didn’t report top-resumed-loss at that moment, but was reported to the client after home activity started and resumed afterward. That resulted in an app crash since the activity client record was already destroyed. Bug: 284552716 Test: verified locally by keeping one focused app task and force stopped all others tasks Change-Id: Ibe6d38e1c4db328b8bfc7bae70fd14ba6f131a25 --- .../server/wm/ActivityTaskSupervisor.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 0171c200b56c8..3c976725cfee9 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2367,6 +2367,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { 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(); + } if (mService.isSleepingLocked()) { // There won't be a next resumed activity. The top process should still be updated // according to the current top focused activity. @@ -2376,16 +2380,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } // Ask previous activity to release the top state. - final boolean prevActivityReceivedTopState = - prevTopActivity != null && !mTopResumedActivityWaitingForPrev; - // 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 (prevActivityReceivedTopState - && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) { - scheduleTopResumedStateLossTimeout(prevTopActivity); - mTopResumedActivityWaitingForPrev = true; - } + scheduleTopResumedActivityStateLossIfNeeded(); // Update the current top activity. mTopResumedActivity = topRootTask.getTopResumedActivity(); @@ -2410,6 +2405,23 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mService.updateTopApp(mTopResumedActivity); } + /** Schedule current top resumed activity state loss */ + private void scheduleTopResumedActivityStateLossIfNeeded() { + if (mTopResumedActivity == 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); + mTopResumedActivityWaitingForPrev = true; + mTopResumedActivity = null; + } + } + /** Schedule top resumed state change if previous top activity already reported back. */ private void scheduleTopResumedActivityStateIfNeeded() { if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {