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

Commit 4cc2a1c0 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Kill AppZygote when a package is removed with DONT_KILL.

When a package is being removed with DONT_KILL, we should still
kill any App Zygote instances that may be running, since they
are referring to old code, and will not be able to spawn any
new processes anyway. New service requests will automatically
spawn a new app zygote process.

Bug: 144095172
Test: Manual test with Chrome
Change-Id: I2e5de604312bb7739ba3ef6abb63d534c74522f2
parent 79150a0a
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -1763,7 +1763,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                case KILL_APP_ZYGOTE_MSG: {
                    synchronized (ActivityManagerService.this) {
                        final AppZygote appZygote = (AppZygote) msg.obj;
                        mProcessList.killAppZygoteIfNeededLocked(appZygote);
                        mProcessList.killAppZygoteIfNeededLocked(appZygote, false /* force */);
                    }
                } break;
            case CHECK_EXCESSIVE_POWER_USE_MSG: {
@@ -4619,6 +4619,22 @@ public class ActivityManagerService extends IActivityManager.Stub
        return didSomething;
    }
    @GuardedBy("this")
    final void forceStopAppZygoteLocked(String packageName, int appId, int userId) {
        if (packageName == null) {
            return;
        }
        if (appId < 0) {
            try {
                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
            } catch (RemoteException e) {
            }
        }
        mProcessList.killAppZygotesLocked(packageName, appId, userId, true /* force */);
    }
    @GuardedBy("this")
    final boolean forceStopPackageLocked(String packageName, int appId,
            boolean callerWillRestart, boolean purgeCache, boolean doit,
@@ -15583,6 +15599,12 @@ public class ActivityManagerService extends IActivityManager.Stub
                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                false, true, true, false, fullUninstall, userId,
                                                removed ? "pkg removed" : "pkg changed");
                                    } else {
                                        // Kill any app zygotes always, since they can't fork new
                                        // processes with references to the old code
                                        forceStopAppZygoteLocked(ssp, UserHandle.getAppId(
                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                userId);
                                    }
                                    final int cmd = killProcess
                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
+32 −27
Original line number Diff line number Diff line
@@ -1858,11 +1858,11 @@ public final class ProcessList {
    }

    @GuardedBy("mService")
    public void killAppZygoteIfNeededLocked(AppZygote appZygote) {
    public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
        final ApplicationInfo appInfo = appZygote.getAppInfo();
        ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
        if (zygoteProcesses != null && zygoteProcesses.size() == 0) {
            // Only remove if no longer in use now
        if (zygoteProcesses != null && (force || zygoteProcesses.size() == 0)) {
            // Only remove if no longer in use now, or forced kill
            mAppZygotes.remove(appInfo.processName, appInfo.uid);
            mAppZygoteProcesses.remove(appZygote);
            mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo);
@@ -1890,7 +1890,7 @@ public final class ProcessList {
                if (app.removed) {
                    // If we stopped this process because the package hosting it was removed,
                    // there's no point in delaying the app zygote kill.
                    killAppZygoteIfNeededLocked(appZygote);
                    killAppZygoteIfNeededLocked(appZygote, false /* force */);
                } else {
                    Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG);
                    msg.obj = appZygote;
@@ -2400,6 +2400,33 @@ public final class ProcessList {
                false /* evenPersistent */, false /* setRemoved */, reason);
    }

    @GuardedBy("mService")
    void killAppZygotesLocked(String packageName, int appId, int userId, boolean force) {
        // See if there are any app zygotes running for this packageName / UID combination,
        // and kill it if so.
        final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
        for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
            for (int i = 0; i < appZygotes.size(); ++i) {
                final int appZygoteUid = appZygotes.keyAt(i);
                if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
                    continue;
                }
                if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
                    continue;
                }
                final AppZygote appZygote = appZygotes.valueAt(i);
                if (packageName != null
                        && !packageName.equals(appZygote.getAppInfo().packageName)) {
                    continue;
                }
                zygotesToKill.add(appZygote);
            }
        }
        for (AppZygote appZygote : zygotesToKill) {
            killAppZygoteIfNeededLocked(appZygote, force);
        }
    }

    @GuardedBy("mService")
    final boolean killPackageProcessesLocked(String packageName, int appId,
            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
@@ -2477,29 +2504,7 @@ public final class ProcessList {
        for (int i=0; i<N; i++) {
            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
        }
        // See if there are any app zygotes running for this packageName / UID combination,
        // and kill it if so.
        final ArrayList<AppZygote> zygotesToKill = new ArrayList<>();
        for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) {
            for (int i = 0; i < appZygotes.size(); ++i) {
                final int appZygoteUid = appZygotes.keyAt(i);
                if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) {
                    continue;
                }
                if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) {
                    continue;
                }
                final AppZygote appZygote = appZygotes.valueAt(i);
                if (packageName != null
                        && !packageName.equals(appZygote.getAppInfo().packageName)) {
                    continue;
                }
                zygotesToKill.add(appZygote);
            }
        }
        for (AppZygote appZygote : zygotesToKill) {
            killAppZygoteIfNeededLocked(appZygote);
        }
        killAppZygotesLocked(packageName, appId, userId, false /* force */);
        mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
        return N > 0;
    }