summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/java/com/android/server/ProcessMap.java9
-rw-r--r--services/java/com/android/server/am/ActiveServices.java2
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java473
-rw-r--r--services/java/com/android/server/am/ActivityResult.java2
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java2
-rw-r--r--services/java/com/android/server/am/AppBindRecord.java2
-rw-r--r--services/java/com/android/server/am/AppErrorDialog.java2
-rw-r--r--services/java/com/android/server/am/AppErrorResult.java3
-rw-r--r--services/java/com/android/server/am/AppNotRespondingDialog.java2
-rw-r--r--services/java/com/android/server/am/AppWaitingForDebuggerDialog.java2
-rw-r--r--services/java/com/android/server/am/BackupRecord.java2
-rw-r--r--services/java/com/android/server/am/BroadcastFilter.java2
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java2
-rw-r--r--services/java/com/android/server/am/BroadcastRecord.java2
-rw-r--r--services/java/com/android/server/am/CompatModeDialog.java2
-rw-r--r--services/java/com/android/server/am/CompatModePackages.java2
-rw-r--r--services/java/com/android/server/am/ConnectionRecord.java2
-rw-r--r--services/java/com/android/server/am/ContentProviderConnection.java2
-rw-r--r--services/java/com/android/server/am/ContentProviderRecord.java2
-rw-r--r--services/java/com/android/server/am/CoreSettingsObserver.java2
-rw-r--r--services/java/com/android/server/am/DeviceMonitor.java234
-rw-r--r--services/java/com/android/server/am/FactoryErrorDialog.java2
-rw-r--r--services/java/com/android/server/am/IntentBindRecord.java2
-rw-r--r--services/java/com/android/server/am/LaunchWarningWindow.java2
-rw-r--r--services/java/com/android/server/am/NativeCrashListener.java2
-rw-r--r--services/java/com/android/server/am/PendingIntentRecord.java2
-rw-r--r--services/java/com/android/server/am/PendingThumbnailsRecord.java2
-rw-r--r--services/java/com/android/server/am/ProcessList.java55
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java23
-rw-r--r--services/java/com/android/server/am/ProcessTracker.java110
-rw-r--r--services/java/com/android/server/am/ProviderMap.java2
-rw-r--r--services/java/com/android/server/am/ReceiverList.java2
-rw-r--r--services/java/com/android/server/am/ServiceRecord.java2
-rw-r--r--services/java/com/android/server/am/StrictModeViolationDialog.java2
-rw-r--r--services/java/com/android/server/am/TaskRecord.java2
-rw-r--r--services/java/com/android/server/am/TransferPipe.java2
-rw-r--r--services/java/com/android/server/am/UriPermission.java2
-rw-r--r--services/java/com/android/server/am/UriPermissionOwner.java2
-rw-r--r--services/java/com/android/server/am/UserStartedState.java2
39 files changed, 464 insertions, 507 deletions
diff --git a/services/java/com/android/server/ProcessMap.java b/services/java/com/android/server/ProcessMap.java
index 6b26403..20c97ba 100644
--- a/services/java/com/android/server/ProcessMap.java
+++ b/services/java/com/android/server/ProcessMap.java
@@ -16,13 +16,12 @@
package com.android.server;
+import android.util.ArrayMap;
import android.util.SparseArray;
-import java.util.HashMap;
-
public class ProcessMap<E> {
- final HashMap<String, SparseArray<E>> mMap
- = new HashMap<String, SparseArray<E>>();
+ final ArrayMap<String, SparseArray<E>> mMap
+ = new ArrayMap<String, SparseArray<E>>();
public E get(String name, int uid) {
SparseArray<E> uids = mMap.get(name);
@@ -50,7 +49,7 @@ public class ProcessMap<E> {
}
}
- public HashMap<String, SparseArray<E>> getMap() {
+ public ArrayMap<String, SparseArray<E>> getMap() {
return mMap;
}
}
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index a77379e..98c4352 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -57,7 +57,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
-public class ActiveServices {
+public final class ActiveServices {
static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index bb20174..f06b9a6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -26,6 +26,7 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import android.app.AppOpsManager;
import android.appwidget.AppWidgetManager;
+import android.util.ArrayMap;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
@@ -401,6 +402,12 @@ public final class ActivityManagerService extends ActivityManagerNative
final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
/**
+ * Tracking long-term execution of processes to look for abuse and other
+ * bad app behavior.
+ */
+ final ProcessTracker mProcessTracker = new ProcessTracker();
+
+ /**
* The currently running isolated processes.
*/
final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
@@ -614,8 +621,8 @@ public final class ActivityManagerService extends ActivityManagerNative
* by the user ID the sticky is for, and can include UserHandle.USER_ALL
* for stickies that are sent to all users.
*/
- final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
- new SparseArray<HashMap<String, ArrayList<Intent>>>();
+ final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
+ new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
final ActiveServices mServices;
@@ -803,16 +810,16 @@ public final class ActivityManagerService extends ActivityManagerNative
int mLruSeq = 0;
/**
- * Keep track of the non-hidden/empty process we last found, to help
- * determine how to distribute hidden/empty processes next time.
+ * Keep track of the non-cached/empty process we last found, to help
+ * determine how to distribute cached/empty processes next time.
*/
- int mNumNonHiddenProcs = 0;
+ int mNumNonCachedProcs = 0;
/**
- * Keep track of the number of hidden procs, to balance oom adj
+ * Keep track of the number of cached procs, to balance oom adj
* distribution between those and empty procs.
*/
- int mNumHiddenProcs = 0;
+ int mNumCachedProcs = 0;
/**
* Keep track of the number of service processes we last found, to
@@ -895,7 +902,7 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
boolean mBooted = false;
- int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
+ int mProcessLimit = ProcessList.MAX_CACHED_APPS;
int mProcessLimitOverride = -1;
WindowManagerService mWindowManager;
@@ -1476,6 +1483,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
+ ServiceManager.addService("procstats", new ProcBinder(m));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
@@ -1692,6 +1700,26 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ static class ProcBinder extends Binder {
+ ActivityManagerService mActivityManagerService;
+ ProcBinder(ActivityManagerService activityManagerService) {
+ mActivityManagerService = activityManagerService;
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump procstats from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " without permission " + android.Manifest.permission.DUMP);
+ return;
+ }
+
+ mActivityManagerService.dumpProcessTracker(fd, pw, args);
+ }
+ }
+
private ActivityManagerService() {
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
@@ -1780,7 +1808,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// We need to tell all apps about the system property change.
ArrayList<IBinder> procs = new ArrayList<IBinder>();
synchronized(this) {
- for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
final int NA = apps.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord app = apps.valueAt(ia);
@@ -2000,22 +2030,22 @@ public final class ActivityManagerService extends ActivityManagerNative
// If this process contains content providers, we want to keep
// it a little more strongly.
app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
- // Also don't let it kick out the first few "real" hidden processes.
- skipTop = ProcessList.MIN_HIDDEN_APPS;
+ // Also don't let it kick out the first few "real" cached processes.
+ skipTop = ProcessList.MIN_CACHED_APPS;
} else {
// If this process doesn't have activities, we less strongly
// want to keep it around, and generally want to avoid getting
// in front of any very recently used activities.
app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
- // Also don't let it kick out the first few "real" hidden processes.
- skipTop = ProcessList.MIN_HIDDEN_APPS;
+ // Also don't let it kick out the first few "real" cached processes.
+ skipTop = ProcessList.MIN_CACHED_APPS;
}
while (i >= 0) {
ProcessRecord p = mLruProcesses.get(i);
// If this app shouldn't be in front of the first N background
- // apps, then skip over that many that are currently hidden.
- if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+ // apps, then skip over that many that are currently cached.
+ if (skipTop > 0 && p.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
skipTop--;
}
if (p.lruWeight <= app.lruWeight || i < bestPos) {
@@ -3179,7 +3209,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean haveBg = false;
for (int i=mLruProcesses.size()-1; i>=0; i--) {
ProcessRecord rec = mLruProcesses.get(i);
- if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+ if (rec.thread != null && rec.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
haveBg = true;
break;
}
@@ -3703,7 +3733,9 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
synchronized(this) {
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
- for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
final int NA = apps.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord app = apps.valueAt(ia);
@@ -3713,7 +3745,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (app.removed) {
procs.add(app);
- } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+ } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
app.removed = true;
procs.add(app);
}
@@ -3940,7 +3972,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// same UID (except for the system or root user), and all whose name
// matches the package name.
final String procNamePrefix = packageName != null ? (packageName + ":") : null;
- for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
final int NA = apps.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord app = apps.valueAt(ia);
@@ -4026,9 +4060,9 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
}
- Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
- while (badApps.hasNext()) {
- SparseArray<Long> ba = badApps.next();
+ final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+ for (int ip=pmap.size()-1; ip>=0; ip--) {
+ SparseArray<Long> ba = pmap.valueAt(ip);
for (i=ba.size()-1; i>=0; i--) {
boolean remove = false;
final int entUid = ba.keyAt(i);
@@ -4050,7 +4084,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (ba.size() == 0) {
- badApps.remove();
+ pmap.removeAt(ip);
}
}
}
@@ -4974,7 +5008,7 @@ public final class ActivityManagerService extends ActivityManagerNative
enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
"setProcessLimit()");
synchronized (this) {
- mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
+ mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
mProcessLimitOverride = max;
}
trimApplications();
@@ -5945,12 +5979,12 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
- final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
+ final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
outInfo.availMem = Process.getFreeMemory();
outInfo.totalMem = Process.getTotalMemory();
outInfo.threshold = homeAppMem;
- outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
- outInfo.hiddenAppThreshold = hiddenAppMem;
+ outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
+ outInfo.hiddenAppThreshold = cachedAppMem;
outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
ProcessList.SERVICE_ADJ);
outInfo.visibleAppThreshold = mProcessList.getMemLevel(
@@ -6177,10 +6211,11 @@ public final class ActivityManagerService extends ActivityManagerNative
// Find any running processes associated with this app.
final String pkg = component.getPackageName();
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
- HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
- for (SparseArray<ProcessRecord> uids : pmap.values()) {
- for (int i=0; i<uids.size(); i++) {
- ProcessRecord proc = uids.valueAt(i);
+ ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+ for (int i=0; i<pmap.size(); i++) {
+ SparseArray<ProcessRecord> uids = pmap.valueAt(i);
+ for (int j=0; j<uids.size(); j++) {
+ ProcessRecord proc = uids.valueAt(j);
if (proc.userId != tr.userId) {
continue;
}
@@ -7279,7 +7314,8 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (stats) {
ps = stats.getProcessStatsLocked(info.uid, proc);
}
- return new ProcessRecord(ps, thread, info, proc, uid);
+ return new ProcessRecord(ps, thread, info, proc, uid,
+ mProcessTracker.getStateLocked(info.processName, info.uid));
}
final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
@@ -7908,11 +7944,11 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- // If the worst oom_adj is somewhere in the hidden proc LRU range,
- // then constrain it so we will kill all hidden procs.
- if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
- && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
- worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
+ // If the worst oom_adj is somewhere in the cached proc LRU range,
+ // then constrain it so we will kill all cached procs.
+ if (worstType < ProcessList.CACHED_APP_MAX_ADJ
+ && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
+ worstType = ProcessList.CACHED_APP_MIN_ADJ;
}
// If this is not a secure call, don't let it kill processes that
@@ -8815,7 +8851,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
synchronized (this) {
- for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
final int NA = apps.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord p = apps.valueAt(ia);
@@ -9174,9 +9212,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
- if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+ if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
if (currApp != null) {
- currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
+ currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
}
return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
} else if (adj >= ProcessList.SERVICE_B_ADJ) {
@@ -9585,7 +9623,9 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
if (dumpAll) {
- for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
final int NA = procs.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord r = procs.valueAt(ia);
@@ -9715,10 +9755,11 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mProcessCrashTimes.getMap().size() > 0) {
boolean printed = false;
long now = SystemClock.uptimeMillis();
- for (Map.Entry<String, SparseArray<Long>> procs
- : mProcessCrashTimes.getMap().entrySet()) {
- String pname = procs.getKey();
- SparseArray<Long> uids = procs.getValue();
+ final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+ final int NP = pmap.size();
+ for (int ip=0; ip<NP; ip++) {
+ String pname = pmap.keyAt(ip);
+ SparseArray<Long> uids = pmap.valueAt(ip);
final int N = uids.size();
for (int i=0; i<N; i++) {
int puid = uids.keyAt(i);
@@ -9745,10 +9786,11 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mBadProcesses.getMap().size() > 0) {
boolean printed = false;
- for (Map.Entry<String, SparseArray<Long>> procs
- : mBadProcesses.getMap().entrySet()) {
- String pname = procs.getKey();
- SparseArray<Long> uids = procs.getValue();
+ final ArrayMap<String, SparseArray<Long>> pmap = mBadProcesses.getMap();
+ final int NP = pmap.size();
+ for (int ip=0; ip<NP; ip++) {
+ String pname = pmap.keyAt(ip);
+ SparseArray<Long> uids = pmap.valueAt(ip);
final int N = uids.size();
for (int i=0; i<N; i++) {
int puid = uids.keyAt(i);
@@ -9915,8 +9957,8 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
- pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
- + " mNumHiddenProcs=" + mNumHiddenProcs
+ pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
+ + " mNumCachedProcs=" + mNumCachedProcs
+ " mNumServiceProcs=" + mNumServiceProcs
+ " mNewNumServiceProcs=" + mNewNumServiceProcs);
}
@@ -9975,8 +10017,8 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
- pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
- pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
+ pw.print(" CACHED_APP_MIN_ADJ: "); pw.println(ProcessList.CACHED_APP_MIN_ADJ);
+ pw.print(" CACHED_APP_MAX_ADJ: "); pw.println(ProcessList.CACHED_APP_MAX_ADJ);
if (needSep) pw.println();
needSep = true;
@@ -10462,8 +10504,8 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=list.size()-1; i>=0; i--) {
ProcessRecord r = list.get(i).first;
String oomAdj;
- if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
- oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
+ if (r.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ oomAdj = buildOomTag("cch", " ", r.setAdj, ProcessList.CACHED_APP_MIN_ADJ);
} else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
} else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
@@ -10538,8 +10580,8 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(prefix);
pw.print(" ");
pw.print("oom: max="); pw.print(r.maxAdj);
- pw.print(" hidden="); pw.print(r.hiddenAdj);
- pw.print(" client="); pw.print(r.clientHiddenAdj);
+ pw.print(" cached="); pw.print(r.cachedAdj);
+ pw.print(" client="); pw.print(r.clientCachedAdj);
pw.print(" empty="); pw.print(r.emptyAdj);
pw.print(" curRaw="); pw.print(r.curRawAdj);
pw.print(" setRaw="); pw.print(r.setRawAdj);
@@ -10548,7 +10590,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(prefix);
pw.print(" ");
pw.print("keeping="); pw.print(r.keeping);
- pw.print(" hidden="); pw.print(r.hidden);
+ pw.print(" cached="); pw.print(r.cached);
pw.print(" empty="); pw.print(r.empty);
pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
@@ -10760,13 +10802,13 @@ public final class ActivityManagerService extends ActivityManagerNative
ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
- ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
+ ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
};
static final String[] DUMP_MEM_OOM_LABEL = new String[] {
"System", "Persistent", "Foreground",
"Visible", "Perceptible", "Heavy Weight",
"Backup", "A Services", "Home", "Previous",
- "B Services", "Background"
+ "B Services", "Cached"
};
final void dumpApplicationMemoryUsage(FileDescriptor fd,
@@ -11034,6 +11076,13 @@ public final class ActivityManagerService extends ActivityManagerNative
return false;
}
+ final void dumpProcessTracker(FileDescriptor fd, PrintWriter pw, String[] args) {
+ synchronized (this) {
+ pw.println("Process Stats:");
+ mProcessTracker.dumpLocked(fd, pw, args);
+ }
+ }
+
private final boolean removeDyingProviderLocked(ProcessRecord proc,
ContentProviderRecord cpr, boolean always) {
final boolean inLaunching = mLaunchingProviders.contains(cpr);
@@ -11679,7 +11728,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private final List getStickiesLocked(String action, IntentFilter filter,
List cur, int userId) {
final ContentResolver resolver = mContext.getContentResolver();
- HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+ ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies == null) {
return cur;
}
@@ -12187,7 +12236,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// But first, if this is not a broadcast to all users, then
// make sure it doesn't conflict with an existing broadcast to
// all users.
- HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
+ ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
UserHandle.USER_ALL);
if (stickies != null) {
ArrayList<Intent> list = stickies.get(intent.getAction());
@@ -12204,9 +12253,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
- HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+ ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies == null) {
- stickies = new HashMap<String, ArrayList<Intent>>();
+ stickies = new ArrayMap<String, ArrayList<Intent>>();
mStickyBroadcasts.put(userId, stickies);
}
ArrayList<Intent> list = stickies.get(intent.getAction());
@@ -12459,7 +12508,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
- HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+ ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies != null) {
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list != null) {
@@ -12952,18 +13001,18 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
- private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
+ private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, int clientCachedAdj,
int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
if (mAdjSeq == app.adjSeq) {
// This adjustment has already been computed. If we are calling
// from the top, we may have already computed our adjustment with
- // an earlier hidden adjustment that isn't really for us... if
- // so, use the new hidden adjustment.
- if (!recursed && app.hidden) {
+ // an earlier cached adjustment that isn't really for us... if
+ // so, use the new cached adjustment.
+ if (!recursed && app.cached) {
if (app.hasActivities) {
- app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = cachedAdj;
} else if (app.hasClientActivities) {
- app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientCachedAdj;
} else {
app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
}
@@ -12974,14 +13023,14 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.thread == null) {
app.adjSeq = mAdjSeq;
app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
- return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
+ return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
}
app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
app.adjSource = null;
app.adjTarget = null;
app.empty = false;
- app.hidden = false;
+ app.cached = false;
app.hasClientActivities = false;
final int activitiesSize = app.activities.size();
@@ -13059,12 +13108,12 @@ public final class ActivityManagerService extends ActivityManagerNative
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "exec-service";
} else {
- // Assume process is hidden (has activities); we will correct
+ // Assume process is cached (has activities); we will correct
// later if this is not the case.
- adj = hiddenAdj;
+ adj = cachedAdj;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
- app.hidden = true;
- app.adjType = "bg-act";
+ app.cached = true;
+ app.adjType = "cch-act";
}
boolean hasStoppingActivities = false;
@@ -13080,7 +13129,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "visible";
}
schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.hidden = false;
+ app.cached = false;
app.hasActivities = true;
foregroundActivities = true;
break;
@@ -13089,13 +13138,13 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.adjType = "pausing";
}
- app.hidden = false;
+ app.cached = false;
foregroundActivities = true;
} else if (r.state == ActivityState.STOPPING) {
// We will apply the actual adjustment later, because
// we want to allow this process to immediately go through
// any memory trimming that is in effect.
- app.hidden = false;
+ app.cached = false;
foregroundActivities = true;
hasStoppingActivities = true;
}
@@ -13105,16 +13154,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- if (adj == hiddenAdj && !app.hasActivities) {
+ if (adj == cachedAdj && !app.hasActivities) {
if (app.hasClientActivities) {
- adj = clientHiddenAdj;
- app.adjType = "bg-client-act";
+ adj = clientCachedAdj;
+ app.adjType = "cch-client-act";
} else {
// Whoops, this process is completely empty as far as we know
// at this point.
adj = emptyAdj;
app.empty = true;
- app.adjType = "bg-empty";
+ app.adjType = "cch-empty";
}
}
@@ -13122,13 +13171,13 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.foregroundServices) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- app.hidden = false;
+ app.cached = false;
app.adjType = "fg-service";
schedGroup = Process.THREAD_GROUP_DEFAULT;
} else if (app.forcingToForeground != null) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- app.hidden = false;
+ app.cached = false;
app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13143,7 +13192,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// We don't want to kill the current heavy-weight process.
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
- app.hidden = false;
+ app.cached = false;
app.adjType = "heavy";
}
@@ -13152,7 +13201,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// home app, so we don't want to let it go into the background.
adj = ProcessList.HOME_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
- app.hidden = false;
+ app.cached = false;
app.adjType = "home";
}
@@ -13163,7 +13212,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// a good experience around switching between two apps.
adj = ProcessList.PREVIOUS_APP_ADJ;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
- app.hidden = false;
+ app.cached = false;
app.adjType = "previous";
}
@@ -13183,7 +13232,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
adj = ProcessList.BACKUP_APP_ADJ;
app.adjType = "backup";
- app.hidden = false;
+ app.cached = false;
}
}
@@ -13202,7 +13251,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// UI stuff. We'll tag it with a label just to help
// debug and understand what is going on.
if (adj > ProcessList.SERVICE_ADJ) {
- app.adjType = "started-bg-ui-services";
+ app.adjType = "cch-started-ui-services";
}
} else {
if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
@@ -13212,14 +13261,14 @@ public final class ActivityManagerService extends ActivityManagerNative
if (adj > ProcessList.SERVICE_ADJ) {
adj = ProcessList.SERVICE_ADJ;
app.adjType = "started-services";
- app.hidden = false;
+ app.cached = false;
}
}
// If we have let the service slide into the background
// state, still have some text describing what it is doing
// even though the service no longer has an impact.
if (adj > ProcessList.SERVICE_ADJ) {
- app.adjType = "started-bg-services";
+ app.adjType = "cch-started-services";
}
}
// Don't kill this process because it is doing work; it
@@ -13245,20 +13294,20 @@ public final class ActivityManagerService extends ActivityManagerNative
if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
ProcessRecord client = cr.binding.client;
int clientAdj = adj;
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
+ int myCachedAdj = cachedAdj;
+ if (myCachedAdj > client.cachedAdj) {
+ if (client.cachedAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myCachedAdj = client.cachedAdj;
} else {
- myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
+ myCachedAdj = ProcessList.VISIBLE_APP_ADJ;
}
}
- int myClientHiddenAdj = clientHiddenAdj;
- if (myClientHiddenAdj > client.clientHiddenAdj) {
- if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
- myClientHiddenAdj = client.clientHiddenAdj;
+ int myClientCachedAdj = clientCachedAdj;
+ if (myClientCachedAdj > client.clientCachedAdj) {
+ if (client.clientCachedAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myClientCachedAdj = client.clientCachedAdj;
} else {
- myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
+ myClientCachedAdj = ProcessList.VISIBLE_APP_ADJ;
}
}
int myEmptyAdj = emptyAdj;
@@ -13269,8 +13318,8 @@ public final class ActivityManagerService extends ActivityManagerNative
myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
}
}
- clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
+ clientAdj = computeOomAdjLocked(client, myCachedAdj,
+ myClientCachedAdj, myEmptyAdj, TOP_APP, true, doingAll);
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
@@ -13281,9 +13330,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// UI stuff. We'll tag it with a label just to help
// debug and understand what is going on.
if (adj > clientAdj) {
- adjType = "bound-bg-ui-services";
+ adjType = "cch-bound-ui-services";
}
- app.hidden = false;
+ app.cached = false;
clientAdj = adj;
} else {
if (now >= (s.lastActivity
@@ -13294,7 +13343,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// it around. We'll also tag it with a label just
// to help debug and undertand what is going on.
if (adj > clientAdj) {
- adjType = "bound-bg-services";
+ adjType = "cch-bound-services";
}
clientAdj = adj;
}
@@ -13305,7 +13354,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// created, then we want to try to better follow
// its memory management semantics for activities.
// That is, if it is sitting in the background
- // LRU list as a hidden process (with activities),
+ // LRU list as a cached process (with activities),
// we don't want the service it is connected to
// to go into the empty LRU and quickly get killed,
// because I'll we'll do is just end up restarting
@@ -13323,7 +13372,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// memory.
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- adjType = "bound-bg-ui-services";
+ adjType = "cch-bound-ui-services";
} else {
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
|Context.BIND_IMPORTANT)) != 0) {
@@ -13340,8 +13389,8 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = ProcessList.VISIBLE_APP_ADJ;
}
}
- if (!client.hidden) {
- app.hidden = false;
+ if (!client.cached) {
+ app.cached = false;
}
if (client.keeping) {
app.keeping = true;
@@ -13372,7 +13421,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
- app.hidden = false;
+ app.cached = false;
app.adjType = "service";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE;
@@ -13390,10 +13439,10 @@ public final class ActivityManagerService extends ActivityManagerNative
// application from running. By default we put the process in
// with the rest of the background processes; as we scan through
// its services we may bump it up from there.
- if (adj > hiddenAdj) {
- adj = hiddenAdj;
- app.hidden = false;
- app.adjType = "bg-services";
+ if (adj > cachedAdj) {
+ adj = cachedAdj;
+ app.cached = false;
+ app.adjType = "cch-services";
}
}
@@ -13412,20 +13461,20 @@ public final class ActivityManagerService extends ActivityManagerNative
// Being our own client is not interesting.
continue;
}
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
+ int myCachedAdj = cachedAdj;
+ if (myCachedAdj > client.cachedAdj) {
+ if (client.cachedAdj > ProcessList.FOREGROUND_APP_ADJ) {
+ myCachedAdj = client.cachedAdj;
} else {
- myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+ myCachedAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
- int myClientHiddenAdj = clientHiddenAdj;
- if (myClientHiddenAdj > client.clientHiddenAdj) {
- if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- myClientHiddenAdj = client.clientHiddenAdj;
+ int myClientCachedAdj = clientCachedAdj;
+ if (myClientCachedAdj > client.clientCachedAdj) {
+ if (client.clientCachedAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ myClientCachedAdj = client.clientCachedAdj;
} else {
- myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+ myClientCachedAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
int myEmptyAdj = emptyAdj;
@@ -13436,19 +13485,19 @@ public final class ActivityManagerService extends ActivityManagerNative
myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
- int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
+ int clientAdj = computeOomAdjLocked(client, myCachedAdj,
+ myClientCachedAdj, myEmptyAdj, TOP_APP, true, doingAll);
if (adj > clientAdj) {
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- app.adjType = "bg-ui-provider";
+ app.adjType = "cch-ui-provider";
} else {
adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
app.adjType = "provider";
}
- if (!client.hidden) {
- app.hidden = false;
+ if (!client.cached) {
+ app.cached = false;
}
if (client.keeping) {
app.keeping = true;
@@ -13470,7 +13519,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (adj > ProcessList.FOREGROUND_APP_ADJ) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.hidden = false;
+ app.cached = false;
app.keeping = true;
app.adjType = "provider";
app.adjTarget = cpr.name;
@@ -13510,7 +13559,7 @@ public final class ActivityManagerService extends ActivityManagerNative
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
- if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
+ if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
app.keeping = true;
}
@@ -13526,9 +13575,9 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = ProcessList.VISIBLE_APP_ADJ;
} else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
- adj = ProcessList.HIDDEN_APP_MIN_ADJ;
- } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
+ } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
+ adj = ProcessList.CACHED_APP_MIN_ADJ;
+ } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) {
adj++;
}
}
@@ -13542,7 +13591,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// interesting in this process then we will push it to the
// background importance.
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
- } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+ } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
} else if (adj >= ProcessList.SERVICE_B_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
@@ -13848,10 +13897,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
- int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
- app.hiddenAdj = hiddenAdj;
- app.clientHiddenAdj = clientHiddenAdj;
+ private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
+ int clientCachedAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
+ app.cachedAdj = cachedAdj;
+ app.clientCachedAdj = clientCachedAdj;
app.emptyAdj = emptyAdj;
if (app.thread == null) {
@@ -13862,7 +13911,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean success = true;
- computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
+ computeOomAdjLocked(app, cachedAdj, clientCachedAdj, emptyAdj, TOP_APP, false, doingAll);
if (app.curRawAdj != app.setRawAdj) {
if (wasKeeping && !app.keeping) {
@@ -13886,6 +13935,10 @@ public final class ActivityManagerService extends ActivityManagerNative
TAG, "Set " + app.pid + " " + app.processName +
" adj " + app.curAdj + ": " + app.adjType);
app.setAdj = app.curAdj;
+ if (app.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ app.tracker.setState(mProcessList.adjToTrackedState(app.setAdj),
+ SystemClock.uptimeMillis());
+ }
} else {
success = false;
Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
@@ -13937,17 +13990,17 @@ public final class ActivityManagerService extends ActivityManagerNative
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
int curAdj = app.curAdj;
- final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
- && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
+ final boolean wasCached = curAdj >= ProcessList.CACHED_APP_MIN_ADJ
+ && curAdj <= ProcessList.CACHED_APP_MAX_ADJ;
mAdjSeq++;
- boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
+ boolean success = updateOomAdjLocked(app, app.cachedAdj, app.clientCachedAdj,
app.emptyAdj, TOP_APP, false);
- final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
- && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
- if (nowHidden != wasHidden) {
- // Changed to/from hidden state, so apps after it in the LRU
+ final boolean nowCached = app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ
+ && app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ;
+ if (nowCached != wasCached) {
+ // Changed to/from cached state, so apps after it in the LRU
// list may also be changed.
updateOomAdjLocked();
}
@@ -13969,100 +14022,100 @@ public final class ActivityManagerService extends ActivityManagerNative
mNewNumServiceProcs = 0;
final int emptyProcessLimit;
- final int hiddenProcessLimit;
+ final int cachedProcessLimit;
if (mProcessLimit <= 0) {
- emptyProcessLimit = hiddenProcessLimit = 0;
+ emptyProcessLimit = cachedProcessLimit = 0;
} else if (mProcessLimit == 1) {
emptyProcessLimit = 1;
- hiddenProcessLimit = 0;
+ cachedProcessLimit = 0;
} else {
emptyProcessLimit = (mProcessLimit*2)/3;
- hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
+ cachedProcessLimit = mProcessLimit - emptyProcessLimit;
}
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
// to put multiple processes in a slot of there are enough of
// them.
- int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
- - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
- int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
- if (numEmptyProcs > hiddenProcessLimit) {
- // If there are more empty processes than our limit on hidden
- // processes, then use the hidden process limit for the factor.
+ int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
+ - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
+ int numEmptyProcs = mLruProcesses.size()- mNumNonCachedProcs - mNumCachedProcs;
+ if (numEmptyProcs > cachedProcessLimit) {
+ // If there are more empty processes than our limit on cached
+ // processes, then use the cached process limit for the factor.
// This ensures that the really old empty processes get pushed
// down to the bottom, so if we are running low on memory we will
- // have a better chance at keeping around more hidden processes
+ // have a better chance at keeping around more cached processes
// instead of a gazillion empty processes.
- numEmptyProcs = hiddenProcessLimit;
+ numEmptyProcs = cachedProcessLimit;
}
int emptyFactor = numEmptyProcs/numSlots;
if (emptyFactor < 1) emptyFactor = 1;
- int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
- if (hiddenFactor < 1) hiddenFactor = 1;
- int stepHidden = 0;
+ int cachedFactor = (mNumCachedProcs > 0 ? mNumCachedProcs : 1)/numSlots;
+ if (cachedFactor < 1) cachedFactor = 1;
+ int stepCached = 0;
int stepEmpty = 0;
- int numHidden = 0;
+ int numCached = 0;
int numEmpty = 0;
int numTrimming = 0;
- mNumNonHiddenProcs = 0;
- mNumHiddenProcs = 0;
+ mNumNonCachedProcs = 0;
+ mNumCachedProcs = 0;
// First update the OOM adjustment for each of the
// application processes based on their current state.
int i = mLruProcesses.size();
- int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
- int nextHiddenAdj = curHiddenAdj+1;
- int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
+ int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
+ int nextCachedAdj = curCachedAdj+1;
+ int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
- int curClientHiddenAdj = curEmptyAdj;
+ int curClientCachedAdj = curEmptyAdj;
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
- //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
- updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
+ //Slog.i(TAG, "OOM " + app + ": cur cached=" + curCachedAdj);
+ updateOomAdjLocked(app, curCachedAdj, curClientCachedAdj, curEmptyAdj, TOP_APP, true);
if (!app.killedBackground) {
- if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
- // This process was assigned as a hidden process... step the
- // hidden level.
- mNumHiddenProcs++;
- if (curHiddenAdj != nextHiddenAdj) {
- stepHidden++;
- if (stepHidden >= hiddenFactor) {
- stepHidden = 0;
- curHiddenAdj = nextHiddenAdj;
- nextHiddenAdj += 2;
- if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
- nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ if (app.curRawAdj == curCachedAdj && app.hasActivities) {
+ // This process was assigned as a cached process... step the
+ // cached level.
+ mNumCachedProcs++;
+ if (curCachedAdj != nextCachedAdj) {
+ stepCached++;
+ if (stepCached >= cachedFactor) {
+ stepCached = 0;
+ curCachedAdj = nextCachedAdj;
+ nextCachedAdj += 2;
+ if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+ nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
- if (curClientHiddenAdj <= curHiddenAdj) {
- curClientHiddenAdj = curHiddenAdj + 1;
- if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
- curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ if (curClientCachedAdj <= curCachedAdj) {
+ curClientCachedAdj = curCachedAdj + 1;
+ if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+ curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
}
}
}
- numHidden++;
- if (numHidden > hiddenProcessLimit) {
+ numCached++;
+ if (numCached > cachedProcessLimit) {
Slog.i(TAG, "No longer want " + app.processName
- + " (pid " + app.pid + "): hidden #" + numHidden);
+ + " (pid " + app.pid + "): cached #" + numCached);
EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "too many background");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
}
- } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
+ } else if (app.curRawAdj == curCachedAdj && app.hasClientActivities) {
// This process has a client that has activities. We will have
- // given it the current hidden adj; here we will just leave it
- // without stepping the hidden adj.
- curClientHiddenAdj++;
- if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
- curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ // given it the current cached adj; here we will just leave it
+ // without stepping the cached adj.
+ curClientCachedAdj++;
+ if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+ curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
} else {
- if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
+ if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curCachedAdj) {
// This process was assigned as an empty process... step the
// empty level.
if (curEmptyAdj != nextEmptyAdj) {
@@ -14071,15 +14124,15 @@ public final class ActivityManagerService extends ActivityManagerNative
stepEmpty = 0;
curEmptyAdj = nextEmptyAdj;
nextEmptyAdj += 2;
- if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
- nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+ nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
}
}
- } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
- mNumNonHiddenProcs++;
+ } else if (app.curRawAdj < ProcessList.CACHED_APP_MIN_ADJ) {
+ mNumNonCachedProcs++;
}
- if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+ if (app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ
&& !app.hasClientActivities) {
if (numEmpty > ProcessList.TRIM_EMPTY_APPS
&& app.lastActivityTime < oldTime) {
@@ -14134,9 +14187,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// are managing to keep around is less than half the maximum we desire;
// if we are keeping a good number around, we'll let them use whatever
// memory they want.
- if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
+ if (numCached <= ProcessList.TRIM_CACHED_APPS
&& numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
- final int numHiddenAndEmpty = numHidden + numEmpty;
+ final int numCachedAndEmpty = numCached + numEmpty;
final int N = mLruProcesses.size();
int factor = numTrimming/3;
int minFactor = 2;
@@ -14145,9 +14198,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (factor < minFactor) factor = minFactor;
int step = 0;
int fgTrimLevel;
- if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+ if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
- } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+ } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
} else {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
@@ -14422,7 +14475,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (proc == null) {
- HashMap<String, SparseArray<ProcessRecord>> all
+ ArrayMap<String, SparseArray<ProcessRecord>> all
= mProcessNames.getMap();
SparseArray<ProcessRecord> procs = all.get(process);
if (procs != null && procs.size() > 0) {
diff --git a/services/java/com/android/server/am/ActivityResult.java b/services/java/com/android/server/am/ActivityResult.java
index 12eba34..6d5bdeb 100644
--- a/services/java/com/android/server/am/ActivityResult.java
+++ b/services/java/com/android/server/am/ActivityResult.java
@@ -23,7 +23,7 @@ import android.os.Bundle;
/**
* Pending result information to send back to an activity.
*/
-class ActivityResult extends ResultInfo {
+final class ActivityResult extends ResultInfo {
final ActivityRecord mFrom;
public ActivityResult(ActivityRecord from, String resultWho,
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index b02a3e8..af61bfb 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -80,7 +80,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
-public class ActivityStackSupervisor {
+public final class ActivityStackSupervisor {
static final boolean DEBUG = ActivityManagerService.DEBUG || false;
static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
static final boolean DEBUG_APP = DEBUG || false;
diff --git a/services/java/com/android/server/am/AppBindRecord.java b/services/java/com/android/server/am/AppBindRecord.java
index f1c54fa..06265fd 100644
--- a/services/java/com/android/server/am/AppBindRecord.java
+++ b/services/java/com/android/server/am/AppBindRecord.java
@@ -23,7 +23,7 @@ import java.util.Iterator;
/**
* An association between a service and one of its client applications.
*/
-class AppBindRecord {
+final class AppBindRecord {
final ServiceRecord service; // The running service.
final IntentBindRecord intent; // The intent we are bound to.
final ProcessRecord client; // Who has started/bound the service.
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index ffa1e92..bfc86b0 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -25,7 +25,7 @@ import android.os.Handler;
import android.os.Message;
import android.view.WindowManager;
-class AppErrorDialog extends BaseErrorDialog {
+final class AppErrorDialog extends BaseErrorDialog {
private final ActivityManagerService mService;
private final AppErrorResult mResult;
private final ProcessRecord mProc;
diff --git a/services/java/com/android/server/am/AppErrorResult.java b/services/java/com/android/server/am/AppErrorResult.java
index ebfcfe2..c6a5720 100644
--- a/services/java/com/android/server/am/AppErrorResult.java
+++ b/services/java/com/android/server/am/AppErrorResult.java
@@ -16,8 +16,7 @@
package com.android.server.am;
-
-class AppErrorResult {
+final class AppErrorResult {
public void set(int res) {
synchronized (this) {
mHasResult = true;
diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java
index af61c9b..b5e0715 100644
--- a/services/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/java/com/android/server/am/AppNotRespondingDialog.java
@@ -28,7 +28,7 @@ import android.os.Message;
import android.util.Slog;
import android.view.WindowManager;
-class AppNotRespondingDialog extends BaseErrorDialog {
+final class AppNotRespondingDialog extends BaseErrorDialog {
private static final String TAG = "AppNotRespondingDialog";
// Event 'what' codes
diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
index d08bb10..27865a8 100644
--- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
+++ b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
@@ -22,7 +22,7 @@ import android.os.Handler;
import android.os.Message;
import android.view.WindowManager;
-class AppWaitingForDebuggerDialog extends BaseErrorDialog {
+final class AppWaitingForDebuggerDialog extends BaseErrorDialog {
final ActivityManagerService mService;
final ProcessRecord mProc;
private CharSequence mAppName;
diff --git a/services/java/com/android/server/am/BackupRecord.java b/services/java/com/android/server/am/BackupRecord.java
index 7e73106..5fa7e6a 100644
--- a/services/java/com/android/server/am/BackupRecord.java
+++ b/services/java/com/android/server/am/BackupRecord.java
@@ -21,7 +21,7 @@ import com.android.internal.os.BatteryStatsImpl;
import android.content.pm.ApplicationInfo;
/** @hide */
-class BackupRecord {
+final class BackupRecord {
// backup/restore modes
public static final int BACKUP_NORMAL = 0;
public static final int BACKUP_FULL = 1;
diff --git a/services/java/com/android/server/am/BroadcastFilter.java b/services/java/com/android/server/am/BroadcastFilter.java
index c631b6e..986b8ea 100644
--- a/services/java/com/android/server/am/BroadcastFilter.java
+++ b/services/java/com/android/server/am/BroadcastFilter.java
@@ -22,7 +22,7 @@ import android.util.Printer;
import java.io.PrintWriter;
-class BroadcastFilter extends IntentFilter {
+final class BroadcastFilter extends IntentFilter {
// Back-pointer to the list this filter is in.
final ReceiverList receiverList;
final String packageName;
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index ac7eb89..c7e6010 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -47,7 +47,7 @@ import android.util.Slog;
* We keep two broadcast queues and associated bookkeeping, one for those at
* foreground priority, and one for normal (background-priority) broadcasts.
*/
-public class BroadcastQueue {
+public final class BroadcastQueue {
static final String TAG = "BroadcastQueue";
static final String TAG_MU = ActivityManagerService.TAG_MU;
static final boolean DEBUG_BROADCAST = ActivityManagerService.DEBUG_BROADCAST;
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index 83cc0ea..eb1df6e 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -36,7 +36,7 @@ import java.util.List;
/**
* An active intent broadcast.
*/
-class BroadcastRecord extends Binder {
+final class BroadcastRecord extends Binder {
final Intent intent; // the original intent that generated us
final ComponentName targetComp; // original component name set on the intent
final ProcessRecord callerApp; // process that sent this
diff --git a/services/java/com/android/server/am/CompatModeDialog.java b/services/java/com/android/server/am/CompatModeDialog.java
index 0442bda..202cc7c 100644
--- a/services/java/com/android/server/am/CompatModeDialog.java
+++ b/services/java/com/android/server/am/CompatModeDialog.java
@@ -28,7 +28,7 @@ import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Switch;
-public class CompatModeDialog extends Dialog {
+public final class CompatModeDialog extends Dialog {
final ActivityManagerService mService;
final ApplicationInfo mAppInfo;
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index e697f88..f56371c 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -25,7 +25,7 @@ import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
-public class CompatModePackages {
+public final class CompatModePackages {
private final String TAG = ActivityManagerService.TAG;
private final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java
index 4ed3c31..dd81493 100644
--- a/services/java/com/android/server/am/ConnectionRecord.java
+++ b/services/java/com/android/server/am/ConnectionRecord.java
@@ -25,7 +25,7 @@ import java.io.PrintWriter;
/**
* Description of a single binding to a service.
*/
-class ConnectionRecord {
+final class ConnectionRecord {
final AppBindRecord binding; // The application/service binding.
final ActivityRecord activity; // If non-null, the owning activity.
final IServiceConnection conn; // The client connection.
diff --git a/services/java/com/android/server/am/ContentProviderConnection.java b/services/java/com/android/server/am/ContentProviderConnection.java
index 7f69b24..f2c9e2f 100644
--- a/services/java/com/android/server/am/ContentProviderConnection.java
+++ b/services/java/com/android/server/am/ContentProviderConnection.java
@@ -23,7 +23,7 @@ import android.util.TimeUtils;
/**
* Represents a link between a content provider and client.
*/
-public class ContentProviderConnection extends Binder {
+public final class ContentProviderConnection extends Binder {
public final ContentProviderRecord provider;
public final ProcessRecord client;
public final long createTime;
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 8fb6a93..646b7d2 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -33,7 +33,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-class ContentProviderRecord {
+final class ContentProviderRecord {
final ActivityManagerService service;
public final ProviderInfo info;
final int uid;
diff --git a/services/java/com/android/server/am/CoreSettingsObserver.java b/services/java/com/android/server/am/CoreSettingsObserver.java
index 585cf2b..10ea67c 100644
--- a/services/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/java/com/android/server/am/CoreSettingsObserver.java
@@ -33,7 +33,7 @@ import java.util.Map;
* disk I/O operations. Note: This class assumes that all core settings reside
* in {@link Settings.Secure}.
*/
-class CoreSettingsObserver extends ContentObserver {
+final class CoreSettingsObserver extends ContentObserver {
private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
// mapping form property name to its type
diff --git a/services/java/com/android/server/am/DeviceMonitor.java b/services/java/com/android/server/am/DeviceMonitor.java
deleted file mode 100644
index 21e7252..0000000
--- a/services/java/com/android/server/am/DeviceMonitor.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import android.os.SELinux;
-import android.util.Slog;
-
-import java.io.*;
-import java.util.Arrays;
-
-/**
- * Monitors device resources periodically for some period of time. Useful for
- * tracking down performance problems.
- */
-class DeviceMonitor {
-
- private static final String LOG_TAG = DeviceMonitor.class.getName();
-
- /** Number of samples to take. */
- private static final int SAMPLE_COUNT = 10;
-
- /** Time to wait in ms between samples. */
- private static final int INTERVAL = 1000;
-
- /** Time to wait in ms between samples. */
- private static final int MAX_FILES = 30;
-
- private final byte[] buffer = new byte[1024];
-
- /** Is the monitor currently running? */
- private boolean running = false;
-
- private DeviceMonitor() {
- new Thread() {
- public void run() {
- monitor();
- }
- }.start();
- }
-
- /**
- * Loops continuously. Pauses until someone tells us to start monitoring.
- */
- @SuppressWarnings("InfiniteLoopStatement")
- private void monitor() {
- while (true) {
- waitForStart();
-
- purge();
-
- for (int i = 0; i < SAMPLE_COUNT; i++) {
- try {
- dump();
- } catch (IOException e) {
- Slog.w(LOG_TAG, "Dump failed.", e);
- }
- pause();
- }
-
- stop();
- }
- }
-
- private static final File PROC = new File("/proc");
- private static final File BASE = new File("/data/anr/");
- static {
- if (!BASE.isDirectory() && !BASE.mkdirs()) {
- throw new AssertionError("Couldn't create " + BASE + ".");
- }
- if (!SELinux.restorecon(BASE)) {
- throw new AssertionError("Couldn't restorecon " + BASE + ".");
- }
- }
-
- private static final File[] PATHS = {
- new File(PROC, "zoneinfo"),
- new File(PROC, "interrupts"),
- new File(PROC, "meminfo"),
- new File(PROC, "slabinfo"),
- };
-
-
- /**
- * Deletes old files.
- */
- private void purge() {
- File[] files = BASE.listFiles();
- int count = files.length - MAX_FILES;
- if (count > 0) {
- Arrays.sort(files);
- for (int i = 0; i < count; i++) {
- if (!files[i].delete()) {
- Slog.w(LOG_TAG, "Couldn't delete " + files[i] + ".");
- }
- }
- }
- }
-
- /**
- * Dumps the current device stats to a new file.
- */
- private void dump() throws IOException {
- OutputStream out = new FileOutputStream(
- new File(BASE, String.valueOf(System.currentTimeMillis())));
- try {
- // Copy /proc/*/stat
- for (File processDirectory : PROC.listFiles()) {
- if (isProcessDirectory(processDirectory)) {
- dump(new File(processDirectory, "stat"), out);
- }
- }
-
- // Copy other files.
- for (File file : PATHS) {
- dump(file, out);
- }
- } finally {
- closeQuietly(out);
- }
- }
-
- /**
- * Returns true if the given file represents a process directory.
- */
- private static boolean isProcessDirectory(File file) {
- try {
- Integer.parseInt(file.getName());
- return file.isDirectory();
- } catch (NumberFormatException e) {
- return false;
- }
- }
-
- /**
- * Copies from a file to an output stream.
- */
- private void dump(File from, OutputStream out) throws IOException {
- writeHeader(from, out);
-
- FileInputStream in = null;
- try {
- in = new FileInputStream(from);
- int count;
- while ((count = in.read(buffer)) != -1) {
- out.write(buffer, 0, count);
- }
- } finally {
- closeQuietly(in);
- }
- }
-
- /**
- * Writes a header for the given file.
- */
- private static void writeHeader(File file, OutputStream out)
- throws IOException {
- String header = "*** " + file.toString() + "\n";
- out.write(header.getBytes());
- }
-
- /**
- * Closes the given resource. Logs exceptions.
- * @param closeable
- */
- private static void closeQuietly(Closeable closeable) {
- try {
- if (closeable != null) {
- closeable.close();
- }
- } catch (IOException e) {
- Slog.w(LOG_TAG, e);
- }
- }
-
- /**
- * Pauses momentarily before we start the next dump.
- */
- private void pause() {
- try {
- Thread.sleep(INTERVAL);
- } catch (InterruptedException e) { /* ignore */ }
- }
-
- /**
- * Stops dumping.
- */
- private synchronized void stop() {
- running = false;
- }
-
- /**
- * Waits until someone starts us.
- */
- private synchronized void waitForStart() {
- while (!running) {
- try {
- wait();
- } catch (InterruptedException e) { /* ignore */ }
- }
- }
-
- /**
- * Instructs the monitoring to start if it hasn't already.
- */
- private synchronized void startMonitoring() {
- if (!running) {
- running = true;
- notifyAll();
- }
- }
-
- private static DeviceMonitor instance = new DeviceMonitor();
-
- /**
- * Starts monitoring if it hasn't started already.
- */
- static void start() {
- instance.startMonitoring();
- }
-}
diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/java/com/android/server/am/FactoryErrorDialog.java
index 0ffb588..f4632c1 100644
--- a/services/java/com/android/server/am/FactoryErrorDialog.java
+++ b/services/java/com/android/server/am/FactoryErrorDialog.java
@@ -22,7 +22,7 @@ import android.os.Handler;
import android.os.Message;
import android.view.WindowManager;
-class FactoryErrorDialog extends BaseErrorDialog {
+final class FactoryErrorDialog extends BaseErrorDialog {
public FactoryErrorDialog(Context context, CharSequence msg) {
super(context);
setCancelable(false);
diff --git a/services/java/com/android/server/am/IntentBindRecord.java b/services/java/com/android/server/am/IntentBindRecord.java
index 0a92964..6c84b9f 100644
--- a/services/java/com/android/server/am/IntentBindRecord.java
+++ b/services/java/com/android/server/am/IntentBindRecord.java
@@ -27,7 +27,7 @@ import java.util.Iterator;
/**
* A particular Intent that has been bound to a Service.
*/
-class IntentBindRecord {
+final class IntentBindRecord {
/** The running service. */
final ServiceRecord service;
/** The intent that is bound.*/
diff --git a/services/java/com/android/server/am/LaunchWarningWindow.java b/services/java/com/android/server/am/LaunchWarningWindow.java
index cb2b7bb..30c3066 100644
--- a/services/java/com/android/server/am/LaunchWarningWindow.java
+++ b/services/java/com/android/server/am/LaunchWarningWindow.java
@@ -26,7 +26,7 @@ import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
-public class LaunchWarningWindow extends Dialog {
+public final class LaunchWarningWindow extends Dialog {
public LaunchWarningWindow(Context context, ActivityRecord cur, ActivityRecord next) {
super(context, R.style.Theme_Toast);
diff --git a/services/java/com/android/server/am/NativeCrashListener.java b/services/java/com/android/server/am/NativeCrashListener.java
index a9454bd..307ab03 100644
--- a/services/java/com/android/server/am/NativeCrashListener.java
+++ b/services/java/com/android/server/am/NativeCrashListener.java
@@ -40,7 +40,7 @@ import java.net.InetUnixAddress;
*
* Note that this component runs in a separate thread.
*/
-class NativeCrashListener extends Thread {
+final class NativeCrashListener extends Thread {
static final String TAG = "NativeCrashListener";
static final boolean DEBUG = false;
static final boolean MORE_DEBUG = DEBUG && false;
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 28593fe..17f24a9 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -31,7 +31,7 @@ import android.util.Slog;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
-class PendingIntentRecord extends IIntentSender.Stub {
+final class PendingIntentRecord extends IIntentSender.Stub {
final ActivityManagerService owner;
final Key key;
final int uid;
diff --git a/services/java/com/android/server/am/PendingThumbnailsRecord.java b/services/java/com/android/server/am/PendingThumbnailsRecord.java
index c460791..e4eb4d0 100644
--- a/services/java/com/android/server/am/PendingThumbnailsRecord.java
+++ b/services/java/com/android/server/am/PendingThumbnailsRecord.java
@@ -24,7 +24,7 @@ import java.util.HashSet;
* This class keeps track of calls to getTasks() that are still
* waiting for thumbnail images.
*/
-class PendingThumbnailsRecord
+final class PendingThumbnailsRecord
{
final IThumbnailReceiver receiver; // who is waiting.
final HashSet<ActivityRecord> pendingRecords; // HistoryRecord objects we still wait for.
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index 1a635a9..e937d35 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -29,7 +29,7 @@ import android.view.Display;
/**
* Activity manager code dealing with processes.
*/
-class ProcessList {
+final class ProcessList {
// The minimum time we allow between crashes, for us to consider this
// application to be bad and stop and its services and reject broadcasts.
static final int MIN_CRASH_INTERVAL = 60*1000;
@@ -38,8 +38,8 @@ class ProcessList {
// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption.
- static final int HIDDEN_APP_MAX_ADJ = 15;
- static int HIDDEN_APP_MIN_ADJ = 9;
+ static final int CACHED_APP_MAX_ADJ = 15;
+ static int CACHED_APP_MIN_ADJ = 9;
// The B list of SERVICE_ADJ -- these are the old and decrepit
// services that aren't as shiny and interesting as the ones in the A list.
@@ -94,37 +94,37 @@ class ProcessList {
// Memory pages are 4K.
static final int PAGE_SIZE = 4*1024;
- // The minimum number of hidden apps we want to be able to keep around,
+ // The minimum number of cached apps we want to be able to keep around,
// without empty apps being able to push them out of memory.
- static final int MIN_HIDDEN_APPS = 2;
+ static final int MIN_CACHED_APPS = 2;
- // The maximum number of hidden processes we will keep around before
+ // The maximum number of cached processes we will keep around before
// killing them; this is just a control to not let us go too crazy with
// keeping around processes on devices with large amounts of RAM.
- static final int MAX_HIDDEN_APPS = 24;
+ static final int MAX_CACHED_APPS = 24;
// We allow empty processes to stick around for at most 30 minutes.
static final long MAX_EMPTY_TIME = 30*60*1000;
- // The number of hidden at which we don't consider it necessary to do
+ // The number of cached at which we don't consider it necessary to do
// memory trimming.
- static final int TRIM_HIDDEN_APPS = 3;
+ static final int TRIM_CACHED_APPS = 3;
// The number of empty apps at which we don't consider it necessary to do
// memory trimming.
static final int TRIM_EMPTY_APPS = 3;
- // Threshold of number of hidden+empty where we consider memory critical.
+ // Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_CRITICAL_THRESHOLD = 3;
- // Threshold of number of hidden+empty where we consider memory critical.
+ // Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_LOW_THRESHOLD = 5;
- // We put empty content processes after any hidden processes that have
+ // We put empty content processes after any cached processes that have
// been idle for less than 15 seconds.
static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
- // We put empty content processes after any hidden processes that have
+ // We put empty content processes after any cached processes that have
// been idle for less than 120 seconds.
static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
@@ -133,7 +133,7 @@ class ProcessList {
// can't give it a different value for every possible kind of process.
private final int[] mOomAdj = new int[] {
FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
- BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ
+ BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
};
// These are the low-end OOM level limits. This is appropriate for an
// HVGA or smaller phone with less than 512MB. Values are in KB.
@@ -154,11 +154,34 @@ class ProcessList {
private boolean mHaveDisplaySize;
+ private final int[] mAdjToTrackedState = new int[CACHED_APP_MAX_ADJ+1];
+
ProcessList() {
MemInfoReader minfo = new MemInfoReader();
minfo.readMemInfo();
mTotalMemMb = minfo.getTotalSize()/(1024*1024);
updateOomLevels(0, 0, false);
+ for (int i=0; i<=CACHED_APP_MAX_ADJ; i++) {
+ if (i <= FOREGROUND_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_FOREGROUND;
+ } else if (i <= VISIBLE_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_VISIBLE;
+ } else if (i <= PERCEPTIBLE_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_PERCEPTIBLE;
+ } else if (i <= BACKUP_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_BACKUP;
+ } else if (i <= SERVICE_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_SERVICE;
+ } else if (i <= HOME_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_HOME;
+ } else if (i <= PREVIOUS_APP_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_PREVIOUS;
+ } else if (i <= SERVICE_B_ADJ) {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_SERVICE;
+ } else {
+ mAdjToTrackedState[i] = ProcessTracker.STATE_CACHED;
+ }
+ }
}
void applyDisplaySize(WindowManagerService wm) {
@@ -220,6 +243,10 @@ class ProcessList {
return mOomMinFree[mOomAdj.length-1] * 1024;
}
+ int adjToTrackedState(int adj) {
+ return mAdjToTrackedState[adj];
+ }
+
private void writeFile(String path, String data) {
FileOutputStream fos = null;
try {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 3a4a34c..6cae67c 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -44,13 +44,14 @@ import java.util.HashSet;
* Full information about a particular process that
* is currently running.
*/
-class ProcessRecord {
+final class ProcessRecord {
final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
final ApplicationInfo info; // all about the first app in the process
final boolean isolated; // true if this is a special isolated process
final int uid; // uid of process; may be different from 'info' if isolated
final int userId; // user of process.
final String processName; // name of the process
+ final ProcessTracker.ProcessState tracker; // tracking execution of process
// List of packages running in the process
final HashSet<String> pkgList = new HashSet<String>();
IApplicationThread thread; // the actual proc... may be null only if
@@ -61,8 +62,8 @@ class ProcessRecord {
long lastActivityTime; // For managing the LRU list
long lruWeight; // Weight for ordering in LRU list
int maxAdj; // Maximum OOM adjustment for this process
- int hiddenAdj; // If hidden, this is the adjustment to use
- int clientHiddenAdj; // If empty but hidden client, this is the adjustment to use
+ int cachedAdj; // If cached, this is the adjustment to use
+ int clientCachedAdj; // If empty but cached client, this is the adjustment to use
int emptyAdj; // If empty, this is the adjustment to use
int curRawAdj; // Current OOM unlimited adjustment for this process
int setRawAdj; // Last set OOM unlimited adjustment for this process
@@ -108,7 +109,7 @@ class ProcessRecord {
long lastLowMemory; // When we last told the app that memory is low
boolean reportLowMemory; // Set to true when waiting to report low mem
boolean empty; // Is this an empty background process?
- boolean hidden; // Is this a hidden process?
+ boolean cached; // Is this a cached process?
int lastPss; // Last pss size reported by app.
String adjType; // Debugging: primary thing impacting oom_adj.
int adjTypeCode; // Debugging: adj code to report to app.
@@ -201,11 +202,11 @@ class ProcessRecord {
pw.print(" lruWeight="); pw.print(lruWeight);
pw.print(" serviceb="); pw.print(serviceb);
pw.print(" keeping="); pw.print(keeping);
- pw.print(" hidden="); pw.print(hidden);
+ pw.print(" cached="); pw.print(cached);
pw.print(" empty="); pw.println(empty);
pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
- pw.print(" hidden="); pw.print(hiddenAdj);
- pw.print(" client="); pw.print(clientHiddenAdj);
+ pw.print(" cached="); pw.print(cachedAdj);
+ pw.print(" client="); pw.print(clientCachedAdj);
pw.print(" empty="); pw.print(emptyAdj);
pw.print(" curRaw="); pw.print(curRawAdj);
pw.print(" setRaw="); pw.print(setRawAdj);
@@ -325,17 +326,19 @@ class ProcessRecord {
}
ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
- ApplicationInfo _info, String _processName, int _uid) {
+ ApplicationInfo _info, String _processName, int _uid,
+ ProcessTracker.ProcessState _tracker) {
batteryStats = _batteryStats;
info = _info;
isolated = _info.uid != _uid;
uid = _uid;
userId = UserHandle.getUserId(_uid);
processName = _processName;
+ tracker = _tracker;
pkgList.add(_info.packageName);
thread = _thread;
- maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
- hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
+ maxAdj = ProcessList.CACHED_APP_MAX_ADJ;
+ cachedAdj = clientCachedAdj = emptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
curRawAdj = setRawAdj = -100;
curAdj = setAdj = -100;
persistent = false;
diff --git a/services/java/com/android/server/am/ProcessTracker.java b/services/java/com/android/server/am/ProcessTracker.java
new file mode 100644
index 0000000..4eb71c7
--- /dev/null
+++ b/services/java/com/android/server/am/ProcessTracker.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.os.SystemClock;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+import com.android.server.ProcessMap;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+public final class ProcessTracker {
+ public static final int STATE_NOTHING = -1;
+ public static final int STATE_TOP = 0;
+ public static final int STATE_FOREGROUND = 1;
+ public static final int STATE_VISIBLE = 2;
+ public static final int STATE_PERCEPTIBLE = 3;
+ public static final int STATE_BACKUP = 4;
+ public static final int STATE_SERVICE = 5;
+ public static final int STATE_HOME = 6;
+ public static final int STATE_PREVIOUS = 7;
+ public static final int STATE_CACHED = 8;
+ public static final int STATE_SCREEN_ON_MOD = STATE_CACHED+1;
+ public static final int STATE_COUNT = STATE_SCREEN_ON_MOD*2;
+
+ static String[] STATE_NAMES = new String[] {
+ "Top ", "Foreground ", "Visible ", "Perceptible", "Backup ",
+ "Service ", "Home ", "Previous ", "Cached "
+ };
+
+ public static final class ProcessState {
+ final long[] mTimes = new long[STATE_COUNT];
+ int mCurState = STATE_NOTHING;
+ long mStartTime;
+
+ public void setState(int state, long now) {
+ if (mCurState != STATE_NOTHING) {
+ mTimes[mCurState] += now - mStartTime;
+ }
+ mCurState = state;
+ mStartTime = now;
+ }
+ }
+
+ static final class State {
+ final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
+ }
+
+ final State mState = new State();
+
+ public ProcessTracker() {
+ }
+
+ public ProcessState getStateLocked(String name, int uid) {
+ ProcessState ps = mState.mProcesses.get(name, uid);
+ if (ps != null) {
+ return ps;
+ }
+ ps = new ProcessState();
+ mState.mProcesses.put(name, uid, ps);
+ return ps;
+ }
+
+ public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
+ final long now = SystemClock.uptimeMillis();
+ ArrayMap<String, SparseArray<ProcessState>> pmap = mState.mProcesses.getMap();
+ for (int ip=0; ip<pmap.size(); ip++) {
+ String procName = pmap.keyAt(ip);
+ SparseArray<ProcessState> procs = pmap.valueAt(ip);
+ for (int iu=0; iu<procs.size(); iu++) {
+ int uid = procs.keyAt(iu);
+ ProcessState state = procs.valueAt(iu);
+ pw.print(" "); pw.print(procName); pw.print(" / "); pw.print(uid); pw.println(":");
+ long totalTime = 0;
+ for (int is=0; is<STATE_NAMES.length; is++) {
+ long time = state.mTimes[is];
+ if (state.mCurState == is) {
+ time += now - state.mStartTime;
+ }
+ if (time != 0) {
+ pw.print(" "); pw.print(STATE_NAMES[is]); pw.print(": ");
+ TimeUtils.formatDuration(time, pw); pw.println();
+ totalTime += time;
+ }
+ }
+ if (totalTime != 0) {
+ pw.print(" TOTAL : ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.println();
+ }
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index ee406c8..5759a44 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -35,7 +35,7 @@ import java.util.Map;
* Keeps track of content providers by authority (name) and class. It separates the mapping by
* user and ones that are not user-specific (system providers).
*/
-public class ProviderMap {
+public final class ProviderMap {
private static final String TAG = "ProviderMap";
diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/java/com/android/server/am/ReceiverList.java
index 9b6701e..b19cc5d 100644
--- a/services/java/com/android/server/am/ReceiverList.java
+++ b/services/java/com/android/server/am/ReceiverList.java
@@ -32,7 +32,7 @@ import java.util.ArrayList;
* A receiver object that has registered for one or more broadcasts.
* The ArrayList holds BroadcastFilter objects.
*/
-class ReceiverList extends ArrayList<BroadcastFilter>
+final class ReceiverList extends ArrayList<BroadcastFilter>
implements IBinder.DeathRecipient {
final ActivityManagerService owner;
public final IIntentReceiver receiver;
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 707e8ee..45e248b 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -47,7 +47,7 @@ import java.util.List;
/**
* A running application service.
*/
-class ServiceRecord extends Binder {
+final class ServiceRecord extends Binder {
// Maximum number of delivery attempts before giving up.
static final int MAX_DELIVERY_COUNT = 3;
diff --git a/services/java/com/android/server/am/StrictModeViolationDialog.java b/services/java/com/android/server/am/StrictModeViolationDialog.java
index 35d50a1..b6d0daa 100644
--- a/services/java/com/android/server/am/StrictModeViolationDialog.java
+++ b/services/java/com/android/server/am/StrictModeViolationDialog.java
@@ -25,7 +25,7 @@ import android.os.Handler;
import android.os.Message;
import android.util.Slog;
-class StrictModeViolationDialog extends BaseErrorDialog {
+final class StrictModeViolationDialog extends BaseErrorDialog {
private final static String TAG = "StrictModeViolationDialog";
private final ActivityManagerService mService;
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 58392ef..d03da20 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -33,7 +33,7 @@ import android.util.Slog;
import java.io.PrintWriter;
import java.util.ArrayList;
-class TaskRecord extends ThumbnailHolder {
+final class TaskRecord extends ThumbnailHolder {
final int taskId; // Unique identifier for this task.
final String affinity; // The affinity name for this task, or null.
Intent intent; // The original intent that started the task.
diff --git a/services/java/com/android/server/am/TransferPipe.java b/services/java/com/android/server/am/TransferPipe.java
index c3f4f93..055c577 100644
--- a/services/java/com/android/server/am/TransferPipe.java
+++ b/services/java/com/android/server/am/TransferPipe.java
@@ -32,7 +32,7 @@ import android.util.Slog;
/**
* Helper for transferring data through a pipe from a client app.
*/
-class TransferPipe implements Runnable {
+final class TransferPipe implements Runnable {
static final String TAG = "TransferPipe";
static final boolean DEBUG = false;
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index cba8e0d..5e2ad00 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -35,7 +35,7 @@ import java.util.HashSet;
* Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
* src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
*/
-class UriPermission {
+final class UriPermission {
private static final String TAG = "UriPermission";
final int userHandle;
diff --git a/services/java/com/android/server/am/UriPermissionOwner.java b/services/java/com/android/server/am/UriPermissionOwner.java
index 90ac88d..7bbd3bc 100644
--- a/services/java/com/android/server/am/UriPermissionOwner.java
+++ b/services/java/com/android/server/am/UriPermissionOwner.java
@@ -24,7 +24,7 @@ import android.os.IBinder;
import java.util.HashSet;
import java.util.Iterator;
-class UriPermissionOwner {
+final class UriPermissionOwner {
final ActivityManagerService service;
final Object owner;
diff --git a/services/java/com/android/server/am/UserStartedState.java b/services/java/com/android/server/am/UserStartedState.java
index 0e71f81..d3e73d5 100644
--- a/services/java/com/android/server/am/UserStartedState.java
+++ b/services/java/com/android/server/am/UserStartedState.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
import android.app.IStopUserCallback;
import android.os.UserHandle;
-public class UserStartedState {
+public final class UserStartedState {
// User is first coming up.
public final static int STATE_BOOTING = 0;
// User is in the normal running state.