diff options
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 24 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ProcessList.java | 59 |
2 files changed, 55 insertions, 28 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c987dea43283..8b547c6bda42 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1799,7 +1799,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: { @@ -4657,6 +4657,22 @@ public class ActivityManagerService extends IActivityManager.Stub } @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, boolean evenPersistent, boolean uninstalling, int userId, String reason) { @@ -15636,6 +15652,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 diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 38cb501111ca..b269c38307e7 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1875,11 +1875,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); @@ -1907,7 +1907,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; @@ -2385,6 +2385,33 @@ public final class ProcessList { } @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, boolean doit, boolean evenPersistent, boolean setRemoved, String reason) { @@ -2461,29 +2488,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; } |