From a431c22fdaefb8d6ce81e929c0074da71fd941ae Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 20 Aug 2020 16:47:22 +0800 Subject: [PATCH] Make the removal in finish-package-activities deterministic Sometimes the removal of activity may be deferred by animating. And it is possible that the deferred record is removed with another finishing activity (finishIfPossible -> performSurfacePlacement -> handleCompleteDeferredRemoval) that causes index of bounds in forAllActivities (next index is size-1, but the size becomes size-2). Now the activities to finish are collected to an independent list so it won't be affected by any changes of hierarchy containers. The checking for home activity can also be removed because if home is restarted, it won't appear in the collected list. Bug: 160752989 Test: ActivityStackTests# \ testFinishDisabledPackageActivities_FinishAliveActivities testFinishDisabledPackageActivities_RemoveNonAliveActivities Change-Id: I2fcbac35fb23295cfe54856c5f08eae97fa6b87f --- .../server/wm/RootWindowContainer.java | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index aeaffd98f8200..78836b49351b7 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -3124,7 +3124,6 @@ class RootWindowContainer extends WindowContainer FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper = new FinishDisabledPackageActivitiesHelper(); class FinishDisabledPackageActivitiesHelper { - private boolean mDidSomething; private String mPackageName; private Set mFilterByClasses; private boolean mDoit; @@ -3132,11 +3131,10 @@ class RootWindowContainer extends WindowContainer private int mUserId; private boolean mOnlyRemoveNoProcess; private Task mLastTask; - private ComponentName mHomeActivity; + private final ArrayList mCollectedActivities = new ArrayList<>(); private void reset(String packageName, Set filterByClasses, boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) { - mDidSomething = false; mPackageName = packageName; mFilterByClasses = filterByClasses; mDoit = doit; @@ -3144,7 +3142,6 @@ class RootWindowContainer extends WindowContainer mUserId = userId; mOnlyRemoveNoProcess = onlyRemoveNoProcess; mLastTask = null; - mHomeActivity = null; } boolean process(String packageName, Set filterByClasses, @@ -3152,14 +3149,35 @@ class RootWindowContainer extends WindowContainer reset(packageName, filterByClasses, doit, evenPersistent, userId, onlyRemoveNoProcess); final PooledFunction f = PooledLambda.obtainFunction( - FinishDisabledPackageActivitiesHelper::processActivity, this, + FinishDisabledPackageActivitiesHelper::collectActivity, this, PooledLambda.__(ActivityRecord.class)); forAllActivities(f); f.recycle(); - return mDidSomething; + + boolean didSomething = false; + final int size = mCollectedActivities.size(); + // Keep the finishing order from top to bottom. + for (int i = 0; i < size; i++) { + final ActivityRecord r = mCollectedActivities.get(i); + if (mOnlyRemoveNoProcess) { + if (!r.hasProcess()) { + didSomething = true; + Slog.i(TAG, " Force removing " + r); + r.cleanUp(false /* cleanServices */, false /* setState */); + r.removeFromHistory("force-stop"); + } + } else { + didSomething = true; + Slog.i(TAG, " Force finishing " + r); + r.finishIfPossible("force-stop", true /* oomAdj */); + } + } + mCollectedActivities.clear(); + + return didSomething; } - private boolean processActivity(ActivityRecord r) { + private boolean collectActivity(ActivityRecord r) { final boolean sameComponent = (r.packageName.equals(mPackageName) && (mFilterByClasses == null || mFilterByClasses.contains(r.mActivityComponent.getClassName()))) @@ -3176,26 +3194,7 @@ class RootWindowContainer extends WindowContainer } return true; } - if (r.isActivityTypeHome()) { - if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) { - Slog.i(TAG, "Skip force-stop again " + r); - return false; - } else { - mHomeActivity = r.mActivityComponent; - } - } - if (mOnlyRemoveNoProcess) { - if (noProcess) { - mDidSomething = true; - Slog.i(TAG, " Force removing " + r); - r.cleanUp(false /* cleanServices */, false /* setState */); - r.removeFromHistory("force-stop"); - } - } else { - mDidSomething = true; - Slog.i(TAG, " Force finishing " + r); - r.finishIfPossible("force-stop", true /* oomAdj */); - } + mCollectedActivities.add(r); mLastTask = r.getTask(); }