Merge "Kill AppZygote when a package is removed with DONT_KILL."
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c987dea..8b547c6 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 @@
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 @@
}
@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 @@
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 38cb501..b269c38 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 @@
}
@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 @@
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 @@
}
@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 @@
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;
}