From 7d8537cf500cce93848cab7890610119330c0545 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Thu, 2 Jun 2022 15:42:23 +0800 Subject: [PATCH] Prevent IndexOOB when handling app crash 1. Destroy the activity from WPC vs. traverse the wm hierarchy 2. Do not remove the parent task while removing the child task. The parent task should be removed once the child is detached from the hierarchy. 3. Skip duplicated wm_task_removed log. Bug: 234214939 Test: wm presubmit Change-Id: Ia5745ba4df949d62a6cde02555fa5314ced4774e --- .../server/wm/ActivityTaskManagerService.java | 4 ++-- .../server/wm/RootWindowContainer.java | 19 ------------------- .../core/java/com/android/server/wm/Task.java | 11 +---------- .../server/wm/WindowProcessController.java | 14 ++++++++++++++ 4 files changed, 17 insertions(+), 31 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index b8df0a27364e3..a786da76fce9d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -6474,9 +6474,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void onHandleAppCrash(WindowProcessController wpc) { + public void onHandleAppCrash(@NonNull WindowProcessController wpc) { synchronized (mGlobalLock) { - mRootWindowContainer.handleAppCrash(wpc); + wpc.handleAppCrash(); } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 326c450f4d5c4..316f624f0d117 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -32,8 +32,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; -import static android.view.WindowManager.TRANSIT_CLOSE; -import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_PIP; import static android.view.WindowManager.TRANSIT_TO_BACK; @@ -2723,23 +2721,6 @@ class RootWindowContainer extends WindowContainer return result[0]; } - void handleAppCrash(WindowProcessController app) { - final PooledConsumer c = PooledLambda.obtainConsumer( - RootWindowContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app); - forAllActivities(c); - c.recycle(); - } - - private static void handleAppCrash(ActivityRecord r, WindowProcessController app) { - if (r.app != app) return; - Slog.w(TAG, " Force finishing activity " - + r.intent.getComponent().flattenToShortString()); - r.detachFromProcess(); - r.mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_CLOSE, - TRANSIT_FLAG_APP_CRASHED); - r.destroyIfPossible("handleAppCrashed"); - } - ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) { ComponentName cls = intent.getComponent(); if (info.targetActivity != null) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 7c1488b71bf58..8964611e9c0d2 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1512,16 +1512,7 @@ class Task extends TaskFragment { !REMOVE_FROM_RECENTS, reason); } } else if (!mReuseTask && shouldRemoveSelfOnLastChildRemoval()) { - // Remove entire task if it doesn't have any activity left and it isn't marked for reuse - // or created by task organizer. - if (!isRootTask()) { - final WindowContainer parent = getParent(); - if (parent != null) { - parent.asTaskFragment().removeChild(this); - } - } - EventLogTags.writeWmTaskRemoved(mTaskId, - "removeChild:" + reason + " last r=" + r + " in t=" + this); + reason += ", last child = " + r + " in " + this; removeIfPossible(reason); } } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 3ff912cca091b..b39b3e4b05f47 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -22,6 +22,8 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED; import static android.os.Build.VERSION_CODES.Q; import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; +import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.util.Preconditions.checkArgument; @@ -353,6 +355,18 @@ public class WindowProcessController extends ConfigurationContainer= 0; --i) { + final ActivityRecord r = mActivities.get(i); + Slog.w(TAG, " Force finishing activity " + + r.mActivityComponent.flattenToShortString()); + r.detachFromProcess(); + r.mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_CLOSE, + TRANSIT_FLAG_APP_CRASHED); + r.destroyIfPossible("handleAppCrashed"); + } + } + boolean isCrashing() { return mCrashing; }