diff --git a/services/java/com/android/server/ProcessMap.java b/services/java/com/android/server/ProcessMap.java index 6b264035b1460..20c97ba247894 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 { - final HashMap> mMap - = new HashMap>(); + final ArrayMap> mMap + = new ArrayMap>(); public E get(String name, int uid) { SparseArray uids = mMap.get(name); @@ -50,7 +49,7 @@ public class ProcessMap { } } - public HashMap> getMap() { + public ArrayMap> getMap() { return mMap; } } diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java index a77379e32c4a2..98c43521208eb 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 bb201743321d2..f06b9a62fc78c 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; @@ -400,6 +401,12 @@ public final class ActivityManagerService extends ActivityManagerNative */ final ProcessMap mProcessNames = new ProcessMap(); + /** + * 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. */ @@ -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>> mStickyBroadcasts = - new SparseArray>>(); + final SparseArray>> mStickyBroadcasts = + new SparseArray>>(); 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 procs = new ArrayList(); synchronized(this) { - for (SparseArray apps : mProcessNames.getMap().values()) { + final int NP = mProcessNames.getMap().size(); + for (int ip=0; ip apps = mProcessNames.getMap().valueAt(ip); final int NA = apps.size(); for (int ia=0; ia