Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d162de93 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Remove activity without process before killing from force-stop

Otherwise when killing the process, the died process cannot match
the activities without process, then the process which should be
killed may be started again by resuming the next top activity
while handling visible app died.

Bug: 161334165
Bug: 160236531
Test: atest RootWindowContainerTests#testForceStopPackage
Test: atest CtsAppTestCases:ActivityManagerTest# \
            testForceStopPackageWontRestartProcess
Change-Id: I71b07681f39a8d4e84f5c5c2cd63e064561c3091
parent 82658d6c
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -4900,7 +4900,13 @@ public class ActivityManagerService extends IActivityManager.Stub
            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
        }
        boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,
        // Notify first that the package is stopped, so its process won't be restarted unexpectedly
        // if there is an activity of the package without attached process becomes visible when
        // killing its other processes with visible activities.
        boolean didSomething =
                mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId);
        didSomething |= mProcessList.killPackageProcessesLocked(packageName, appId, userId,
                ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,
                evenPersistent, true /* setRemoved */,
                packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
@@ -4909,9 +4915,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                (packageName == null ? ("stop user " + userId) : ("stop " + packageName))
                + " due to " + reason);
        didSomething |=
                mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId);
        if (mServices.bringDownDisabledPackageServicesLocked(
                packageName, null /* filterByClasses */, userId, evenPersistent, doit)) {
            if (!doit) {
+2 −2
Original line number Diff line number Diff line
@@ -2952,8 +2952,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                null /* resultData */, null /* resultGrants */);
        makeFinishingLocked();
        if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE) {
            Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack callers="
                    + Debug.getCallers(5));
            Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " from stack, reason="
                    + reason + ", callers=" + Debug.getCallers(5));
        }

        takeFromHistory();
+7 −2
Original line number Diff line number Diff line
@@ -6820,7 +6820,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            synchronized (mGlobalLock) {
                // Clean-up disabled activities.
                if (mRootWindowContainer.finishDisabledPackageActivities(
                        packageName, disabledClasses, true, false, userId) && booted) {
                        packageName, disabledClasses, true /* doit */, false /* evenPersistent */,
                        userId, false /* onlyRemoveNoProcess */) && booted) {
                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                    mStackSupervisor.scheduleIdle();
                }
@@ -6839,7 +6840,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                boolean didSomething =
                        getActivityStartController().clearPendingActivityLaunches(packageName);
                didSomething |= mRootWindowContainer.finishDisabledPackageActivities(packageName,
                        null, doit, evenPersistent, userId);
                        null /* filterByClasses */, doit, evenPersistent, userId,
                        // Only remove the activities without process because the activities with
                        // attached process will be removed when handling process died with
                        // WindowProcessController#isRemoved == true.
                        true /* onlyRemoveNoProcess */);
                return didSomething;
            }
        }
+27 −9
Original line number Diff line number Diff line
@@ -3092,6 +3092,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    }

    boolean handleAppDied(WindowProcessController app) {
        if (app.isRemoved()) {
            // The package of the died process should be force-stopped, so make its activities as
            // finishing to prevent the process from being started again if the next top (or being
            // visible) activity also resides in the same process.
            app.makeFinishingForProcessRemoved();
        }
        return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> {
            for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
                final Task stack = taskDisplayArea.getStackAt(sNdx);
@@ -3129,24 +3135,26 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        private boolean mDoit;
        private boolean mEvenPersistent;
        private int mUserId;
        private boolean mOnlyRemoveNoProcess;
        private Task mLastTask;
        private ComponentName mHomeActivity;

        private void reset(String packageName, Set<String> filterByClasses,
                boolean doit, boolean evenPersistent, int userId) {
                boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
            mDidSomething = false;
            mPackageName = packageName;
            mFilterByClasses = filterByClasses;
            mDoit = doit;
            mEvenPersistent = evenPersistent;
            mUserId = userId;
            mOnlyRemoveNoProcess = onlyRemoveNoProcess;
            mLastTask = null;
            mHomeActivity = null;
        }

        boolean process(String packageName, Set<String> filterByClasses,
                boolean doit, boolean evenPersistent, int userId) {
            reset(packageName, filterByClasses, doit, evenPersistent, userId);
                boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
            reset(packageName, filterByClasses, doit, evenPersistent, userId, onlyRemoveNoProcess);

            final PooledFunction f = PooledLambda.obtainFunction(
                    FinishDisabledPackageActivitiesHelper::processActivity, this,
@@ -3161,9 +3169,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                    (r.packageName.equals(mPackageName) && (mFilterByClasses == null
                            || mFilterByClasses.contains(r.mActivityComponent.getClassName())))
                            || (mPackageName == null && r.mUserId == mUserId);
            final boolean noProcess = !r.hasProcess();
            if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId)
                    && (sameComponent || r.getTask() == mLastTask)
                    && (r.app == null || mEvenPersistent || !r.app.isPersistent())) {
                    && (noProcess || mEvenPersistent || !r.app.isPersistent())) {
                if (!mDoit) {
                    if (r.finishing) {
                        // If this activity is just finishing, then it is not
@@ -3180,10 +3189,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                        mHomeActivity = r.mActivityComponent;
                    }
                }
                if (mOnlyRemoveNoProcess) {
                    if (noProcess) {
                        mDidSomething = true;
                Slog.i(TAG, "  Force finishing activity " + r);
                        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 */);
                }
                mLastTask = r.getTask();
                r.finishIfPossible("force-stop", true);
            }

            return false;
@@ -3192,9 +3210,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>

    /** @return true if some activity was finished (or would have finished if doit were true). */
    boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses,
            boolean doit, boolean evenPersistent, int userId) {
            boolean doit, boolean evenPersistent, int userId, boolean onlyRemoveNoProcess) {
        return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit,
                evenPersistent, userId);
                evenPersistent, userId, onlyRemoveNoProcess);
    }

    void updateActivityApplicationInfo(ApplicationInfo aInfo) {
+0 −6
Original line number Diff line number Diff line
@@ -771,12 +771,6 @@ class Task extends WindowContainer<WindowContainer> {
            mHasVisibleActivities = false;
            mApp = app;
            mIsProcessRemoved = app.isRemoved();
            if (mIsProcessRemoved) {
                // The package of the died process should be force-stopped, so make its activities
                // as finishing to prevent the process from being started again if the next top
                // (or being visible) activity also resides in the same process.
                app.makeFinishingForProcessRemoved();
            }

            final PooledConsumer c = PooledLambda.obtainConsumer(
                    RemoveHistoryRecordsForApp::addActivityToRemove, this,
Loading