From ecc41db6d278f84582f504c2527f46088d5bd97b Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Wed, 2 Mar 2016 10:47:14 -0500 Subject: [PATCH] Check process state when killing background processes for density Previously, we were not killing many processes because we weren't in an actual OOM condition. This CL moves the background killing rules to a separate method and checks the process state. This removes the OOM adjustment check and *will* kill persistent processes. Bug: 27397233 Change-Id: Ibc21e97cfc729a0835e613095acd9a4b648906d8 --- .../android/server/am/ActivityManagerService.java | 67 ++++++++++++++++------ 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 12ebf44cba26..8f18270a1b5a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5359,17 +5359,6 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void killAllBackgroundProcesses() { - killAllBackgroundProcesses(-1); - } - - /** - * Kills all background processes with targetSdkVersion below the specified - * target SDK version. - * - * @param targetSdkVersion the target SDK version below which to kill - * processes, or {@code -1} to kill all processes - */ - private void killAllBackgroundProcesses(int targetSdkVersion) { if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) != PackageManager.PERMISSION_GRANTED) { final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" @@ -5393,10 +5382,6 @@ public final class ActivityManagerService extends ActivityManagerNative // We don't kill persistent processes. continue; } - if (targetSdkVersion > 0 - && app.info.targetSdkVersion >= targetSdkVersion) { - continue; - } if (app.removed) { procs.add(app); } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { @@ -5421,6 +5406,55 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * Kills all background processes, except those matching any of the + * specified properties. + * + * @param minTargetSdk the target SDK version at or above which to preserve + * processes, or {@code -1} to ignore the target SDK + * @param maxProcState the process state at or below which to preserve + * processes, or {@code -1} to ignore the process state + */ + private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { + if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) + != PackageManager.PERMISSION_GRANTED) { + final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid=" + + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (this) { + final ArrayList procs = new ArrayList<>(); + final int NP = mProcessNames.getMap().size(); + for (int ip = 0; ip < NP; ip++) { + final SparseArray apps = mProcessNames.getMap().valueAt(ip); + final int NA = apps.size(); + for (int ia = 0; ia < NA; ia++) { + final ProcessRecord app = apps.valueAt(ia); + if (app.removed) { + procs.add(app); + } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) + && (maxProcState < 0 || app.setProcState > maxProcState)) { + app.removed = true; + procs.add(app); + } + } + } + + final int N = procs.size(); + for (int i = 0; i < N; i++) { + removeProcessLocked(procs.get(i), false, true, "kill all background except"); + } + } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + @Override public void forceStopPackage(final String packageName, int userId) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) @@ -18055,7 +18089,8 @@ public final class ActivityManagerService extends ActivityManagerNative final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; if (isDensityChange) { - killAllBackgroundProcesses(Build.VERSION_CODES.N); + killAllBackgroundProcessesExcept(Build.VERSION_CODES.N, + ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } for (int i=mLruProcesses.size()-1; i>=0; i--) { -- 2.11.0