summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-10-03 14:19:38 +0000
committer Riddle Hsu <riddlehsu@google.com> 2023-10-05 13:28:11 +0000
commit8f42ef5660bbc7cef1cb635dfe1fb9f1eb98680e (patch)
tree3ee1a624c61f8b2412ba9a732662069c5e9f893c
parent6c29a6fb047c2426201e7bc855afd9ba6526607a (diff)
Update visibility when visible activity crashed
Previously, if a top fullscreen app is crashed when a display transition is collecting, the transition will be ready and sent directly from finishTopCrashedActivityLocked -> finishIfPossible -> continueWindowLayout -> BLASTSyncEngine.SyncGroup#tryFinish. That causes the transition to contain a change to hide display area because nothing is visible in it. Now finishTopCrashedActivities has similar steps as handleAppDied. If there is perceptible activity in the crashed process, the next top activity will be requested to visible at the same time. Then the transition can recognize that the display area is visible. Note that finishTopCrashedActivityLocked calls finishIfPossible, so it may already adjust focusable task. But because the crashing activity is pausing (pause->resume from switch display and then resume -> pausing when finishing for crash), the next activity won't resume until the pausing is gone. Then it requires ensureActivitiesVisible to make the current top activity (its task was moved to front when adjusting focusable task) visible. Bug: 300790517 Test: RootWindowContainerTests#testRemovingRootTaskOnAppCrash Change-Id: I935121ed53638720ec3c8ef872f7c78e90edd714
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java28
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java4
3 files changed, 39 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 237bc9203415..62f22f0f95e5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6420,19 +6420,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (!restarting && hasVisibleActivities) {
deferWindowLayout();
try {
- final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
- if (topTask != null
- && topTask.topRunningActivity(true /* focusableOnly */) == null) {
- topTask.adjustFocusToNextFocusableTask("handleAppDied");
- }
- if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
- // If there was nothing to resume, and we are not already restarting
- // this process, but there is a visible activity that is hosted by the
- // process...then make sure all visible activities are running, taking
- // care of restarting this process.
- mRootWindowContainer.ensureActivitiesVisible(null, 0,
- !PRESERVE_WINDOWS);
- }
+ mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(
+ "handleAppDied");
} finally {
continueWindowLayout();
}
@@ -6873,7 +6862,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
synchronized (mGlobalLock) {
- return mRootWindowContainer.finishTopCrashedActivities(crashedApp, reason);
+ deferWindowLayout();
+ try {
+ final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
+ crashedApp, reason);
+ if (finishedTask != null) {
+ mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(reason);
+ return finishedTask.mTaskId;
+ }
+ return INVALID_TASK_ID;
+ } finally {
+ continueWindowLayout();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2a3391807a2c..f1586cdb5690 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2297,19 +2297,36 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
*
* @param app The app that crashed.
* @param reason Reason to perform this action.
- * @return The task id that was finished in this root task, or INVALID_TASK_ID if none was
- * finished.
+ * @return The finished task which was on top or visible, otherwise {@code null} if the crashed
+ * app doesn't have activity in visible task.
*/
- int finishTopCrashedActivities(WindowProcessController app, String reason) {
+ @Nullable
+ Task finishTopCrashedActivities(WindowProcessController app, String reason) {
Task focusedRootTask = getTopDisplayFocusedRootTask();
final Task[] finishedTask = new Task[1];
forAllRootTasks(rootTask -> {
+ final boolean recordTopOrVisible = finishedTask[0] == null
+ && (focusedRootTask == rootTask || rootTask.isVisibleRequested());
final Task t = rootTask.finishTopCrashedActivityLocked(app, reason);
- if (rootTask == focusedRootTask || finishedTask[0] == null) {
+ if (recordTopOrVisible) {
finishedTask[0] = t;
}
});
- return finishedTask[0] != null ? finishedTask[0].mTaskId : INVALID_TASK_ID;
+ return finishedTask[0];
+ }
+
+ void ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason) {
+ final Task topTask = getTopDisplayFocusedRootTask();
+ if (topTask != null && topTask.topRunningActivity(true /* focusableOnly */) == null) {
+ // Move the next focusable task to front.
+ topTask.adjustFocusToNextFocusableTask(reason);
+ }
+ if (!resumeFocusedTasksTopActivities()) {
+ // It may be nothing to resume because there are pausing activities or all the top
+ // activities are resumed. Then it still needs to make sure all visible activities are
+ // running in case the tasks were reordered or there are non-top visible activities.
+ ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
+ }
}
boolean resumeFocusedTasksTopActivities() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 3bc6450ae591..c241033c69d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -549,10 +549,12 @@ public class RootWindowContainerTests extends WindowTestsBase {
// Let's pretend that the app has crashed.
firstActivity.app.setThread(null);
- mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
+ final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
+ firstActivity.app, "test");
// Verify that the root task was removed.
assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount());
+ assertEquals(rootTask, finishedTask);
}
/**