Start really collecting PSS data for process stats.

The activity manager now uses some heuristics to try to
sample PSS data from processes so that it can get enough
data to over reasonable time have something useful, without
doing it too aggressively.

The current policy is:

1. Whenever a significant global change happens (memory state,
   sceen on or off), we collect PSS from all processes; this will
   not happen more than every 10 minutes.
2. When all activities become idle, we will collect PSS from the
   current top process; this will not happen more than every 2
   minutes per process.
3. We will sample the top-most process's PSS every 5 minutes.
4. When an process's oom adj changes and it has been more than
   30 minutes since PSS has been collected from it, we will
   collect a new PSS sample.
5. If a process changes from service A to service B (meaning it
   has been running a service for a long time), we will collect
   a PSS sample from it.
6. If someone explicitly requests PSS data (for running services
   UI or dumpsys), record that.

Also:

- Finish moving the procstats output all to the new format.
- Record information about processes being killed due to excessive
  wake locks or CPU use in procstats.
- Rework how we structure common vs. per-package process stats to
  make it simpler to deal with.
- Optimize the Debug.getPss() implementation (we use it a lot now).
  Should probably optimize it further at some point.

Change-Id: I179f1f7ae5852c7e567de4127d8457b50d27e0f0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bf89fa6..4568525 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -552,7 +552,7 @@
         private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
 
         // Formatting for checkin service - update version if row format changes
-        private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 2;
+        private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
 
         private void updatePendingConfiguration(Configuration config) {
             synchronized (mPackages) {
@@ -972,43 +972,48 @@
                 pw.print(memInfo.nativePss); pw.print(',');
                 pw.print(memInfo.dalvikPss); pw.print(',');
                 pw.print(memInfo.otherPss); pw.print(',');
-                pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
+                pw.print(memInfo.getTotalPss()); pw.print(',');
 
-                // Heap info - proportional set size
+                // Heap info - swappable set size
                 pw.print(memInfo.nativeSwappablePss); pw.print(',');
                 pw.print(memInfo.dalvikSwappablePss); pw.print(',');
                 pw.print(memInfo.otherSwappablePss); pw.print(',');
-                pw.print(memInfo.nativeSwappablePss + memInfo.dalvikSwappablePss + memInfo.otherSwappablePss); pw.print(',');
+                pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
 
                 // Heap info - shared dirty
                 pw.print(memInfo.nativeSharedDirty); pw.print(',');
                 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
                 pw.print(memInfo.otherSharedDirty); pw.print(',');
-                pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
-                        + memInfo.otherSharedDirty); pw.print(',');
+                pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
 
                 // Heap info - shared clean
                 pw.print(memInfo.nativeSharedClean); pw.print(',');
                 pw.print(memInfo.dalvikSharedClean); pw.print(',');
                 pw.print(memInfo.otherSharedClean); pw.print(',');
-                pw.print(memInfo.nativeSharedClean + memInfo.dalvikSharedClean
-                        + memInfo.otherSharedClean); pw.print(',');
+                pw.print(memInfo.getTotalSharedClean()); pw.print(',');
 
                 // Heap info - private Dirty
                 pw.print(memInfo.nativePrivateDirty); pw.print(',');
                 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
                 pw.print(memInfo.otherPrivateDirty); pw.print(',');
-                pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
-                        + memInfo.otherPrivateDirty); pw.print(',');
-
+                pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
 
                 // Heap info - private Clean
                 pw.print(memInfo.nativePrivateClean); pw.print(',');
                 pw.print(memInfo.dalvikPrivateClean); pw.print(',');
                 pw.print(memInfo.otherPrivateClean); pw.print(',');
-                pw.print(memInfo.nativePrivateClean + memInfo.dalvikPrivateClean
-                        + memInfo.otherPrivateClean); pw.print(',');
+                pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
 
+                // Heap info - other areas
+                for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
+                    pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPss(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
+                }
 
                 // Object counts
                 pw.print(viewInstanceCount); pw.print(',');
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index f4cf2ee..8b7f3dd 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -394,12 +394,16 @@
     if (fp == 0) return 0;
 
     while (true) {
-        if (fgets(line, 1024, fp) == 0) {
+        if (fgets(line, 1024, fp) == NULL) {
             break;
         }
 
-        if (sscanf(line, "Pss: %d kB", &temp) == 1) {
-            pss += temp;
+        if (strncmp(line, "Pss: ", 5) == 0) {
+            char* c = line + 5;
+            while (*c != 0 && (*c < '0' || *c > '9')) {
+                c++;
+            }
+            pss += atoi(c);
         }
     }