Switch proc stats to use new process state constants.

These new constants are a better mapping to the kind of
information that procstats is wanting to collect about
processes.  In doing this, the process states are tweaked
to have a bit more information that we care about for
procstats.

This changes the format of the data printed by procstats,
so the checkin version is bumped to 2.  The structure is
the same, however the codes for process states have all
changed.  The new codes are, in order of precedence:

p -- persistent system process.
t -- top activity; actually any visible activity.
f -- important foreground process (ime, wallpaper, etc).
b -- important background process
u -- performing backup operation.
w -- heavy-weight process (currently not used).
s -- background process running a service.
r -- process running a receiver.
h -- process hosting home/launcher app when not on top.
l -- process hosting the last app the user was in.
a -- cached process hosting a previous activity.
c -- cached process hosting a client activity.
e -- cached process that is empty.

In addition, we are now collecting uss along with pss
data for each process, so the pss checkin entries now
have three new values at the end of the min/avg/max uss
values of that process.

With this switch to using process state constants more
fundamentally, I realized that they could actually be
used by the core oom adj code to make it a lot cleaner.
So that change has been made, that code has changed quite
radically, and lost a lot of its secondary states and flags
that it used to use in its computation, now relying on
primarily the oom_adj and proc state values for the process.

This also cleaned up a few problems -- for example for
purposes of determing the memory level of the device, if a
long-running service dropped into the cached oom_adj level,
it would start being counted as a cached process and thus
make us think that the memory state is better than it is.
Now we do this based on the proc state, which always stays
as a service regardless of what is happening like this, giving
as a more consistent view of the memory state of the device.

Making proc state a more fundamentally part of the oom adj
computation means that the values can also be more carefully
tuned in semantic meaning so the value assigned to a process
doesn't tend to change unless the semantics of the process
has really significantly changed.

For example, a process will be assigned the service state
regardless of whether that services is executing operations
in the foreground, running normally, or has been dropped to
the lru list for pruning.  The top state is used for everything
related to activities visible to the user: when actually on
top, visible but not on top, currently pausing, etc.

There is a new Context.BIND_SHOWING_UI added for when system
services bind to apps, to explicitly indicate that the app
is showing UI for the system.  This gives us a better metric
to determine when it is showing UI, and thus when it needs
to do a memory trim when it is no longer in that state.  Without
this, services could get in bad states of continually trimming.

Finally, more HashSet containers have been changed to ArraySet,
reducing the temporary iterators created for iterating over
them.

Change-Id: I1724113f42abe7862e8aecb6faae5a7620245e89
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index cb9a76d..5c1b7f24 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.util.ArraySet;
 import com.android.internal.os.BatteryStatsImpl;
 
 import android.app.ActivityManager;
@@ -64,12 +65,8 @@
     long lruWeight;             // Weight for ordering in LRU list
     long lastPssTime;           // Last time we requested PSS data
     int maxAdj;                 // Maximum OOM adjustment for this process
-    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
-    int nonStoppingAdj;         // Adjustment not counting any stopping activities
     int curAdj;                 // Current OOM adjustment for this process
     int setAdj;                 // Last set OOM adjustment for this process
     int curSchedGroup;          // Currently desired scheduling class
@@ -78,6 +75,7 @@
     int memImportance;          // Importance constant computed from curAdj
     int curProcState = -1;      // Currently computed process state: ActivityManager.PROCESS_STATE_*
     int repProcState = -1;      // Last reported process state
+    int setProcState = -1;      // Last set process state in process tracker
     boolean serviceb;           // Process currently is on the service B list
     boolean keeping;            // Actively running code so don't kill due to that?
     boolean setIsForeground;    // Running foreground UI when last set?
@@ -92,7 +90,7 @@
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
     boolean bad;                // True if disabled in the bad process list
     boolean killedBackground;   // True when proc has been killed due to too many bg
-    boolean setAdjChanged;      // Keep track of whether we changed 'setAdj'.
+    boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
     String waitingToKill;       // Process is waiting to be killed when in the bg; reason
     IBinder forcingToForeground;// Token that is forcing this process to be foreground
     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
@@ -125,15 +123,15 @@
     // contains HistoryRecord objects
     final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
     // all ServiceRecord running in this process
-    final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();
+    final ArraySet<ServiceRecord> services = new ArraySet<ServiceRecord>();
     // services that are currently executing code (need to remain foreground).
-    final HashSet<ServiceRecord> executingServices
-             = new HashSet<ServiceRecord>();
+    final ArraySet<ServiceRecord> executingServices
+             = new ArraySet<ServiceRecord>();
     // All ConnectionRecord this process holds
-    final HashSet<ConnectionRecord> connections
-            = new HashSet<ConnectionRecord>();  
+    final ArraySet<ConnectionRecord> connections
+            = new ArraySet<ConnectionRecord>();
     // all IIntentReceivers that are registered from this process.
-    final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
+    final ArraySet<ReceiverList> receivers = new ArraySet<ReceiverList>();
     // class (String) -> ContentProviderRecord
     final ArrayMap<String, ContentProviderRecord> pubProviders
             = new ArrayMap<String, ContentProviderRecord>();
@@ -215,12 +213,8 @@
                 pw.print(" cached="); pw.print(cached);
                 pw.print(" empty="); pw.println(empty);
         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
-                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);
-                pw.print(" nonStopping="); pw.print(nonStoppingAdj);
                 pw.print(" cur="); pw.print(curAdj);
                 pw.print(" set="); pw.println(setAdj);
         pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
@@ -228,7 +222,8 @@
                 pw.print(" systemNoUi="); pw.print(systemNoUi);
                 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
         pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
-                pw.print(" repProcState="); pw.println(repProcState);
+                pw.print(" repProcState="); pw.print(repProcState);
+                pw.print(" setProcState="); pw.println(setProcState);
         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
                 pw.print(" lruSeq="); pw.print(lruSeq);
                 pw.print(" lastPssTime="); pw.println(lastPssTime);
@@ -301,20 +296,20 @@
         }
         if (services.size() > 0) {
             pw.print(prefix); pw.println("Services:");
-            for (ServiceRecord sr : services) {
-                pw.print(prefix); pw.print("  - "); pw.println(sr);
+            for (int i=0; i<services.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(services.valueAt(i));
             }
         }
         if (executingServices.size() > 0) {
             pw.print(prefix); pw.println("Executing Services:");
-            for (ServiceRecord sr : executingServices) {
-                pw.print(prefix); pw.print("  - "); pw.println(sr);
+            for (int i=0; i<executingServices.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(executingServices.valueAt(i));
             }
         }
         if (connections.size() > 0) {
             pw.print(prefix); pw.println("Connections:");
-            for (ConnectionRecord cr : connections) {
-                pw.print(prefix); pw.print("  - "); pw.println(cr);
+            for (int i=0; i<connections.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(connections.valueAt(i));
             }
         }
         if (pubProviders.size() > 0) {
@@ -335,8 +330,8 @@
         }
         if (receivers.size() > 0) {
             pw.print(prefix); pw.println("Receivers:");
-            for (ReceiverList rl : receivers) {
-                pw.print(prefix); pw.print("  - "); pw.println(rl);
+            for (int i=0; i<receivers.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(receivers.valueAt(i));
             }
         }
     }
@@ -353,8 +348,7 @@
         baseProcessTracker = tracker;
         pkgList.put(_info.packageName, tracker);
         thread = _thread;
-        maxAdj = ProcessList.CACHED_APP_MAX_ADJ;
-        cachedAdj = clientCachedAdj = emptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
+        maxAdj = ProcessList.UNKNOWN_ADJ;
         curRawAdj = setRawAdj = -100;
         curAdj = setAdj = -100;
         persistent = false;
@@ -400,16 +394,37 @@
 
     void updateHasAboveClientLocked() {
         hasAboveClient = false;
-        if (connections.size() > 0) {
-            for (ConnectionRecord cr : connections) {
-                if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
-                    hasAboveClient = true;
-                    break;
-                }
+        for (int i=connections.size()-1; i>=0; i--) {
+            ConnectionRecord cr = connections.valueAt(i);
+            if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+                hasAboveClient = true;
+                break;
             }
         }
     }
 
+    int modifyRawOomAdj(int adj) {
+        if (hasAboveClient) {
+            // If this process has bound to any services with BIND_ABOVE_CLIENT,
+            // then we need to drop its adjustment to be lower than the service's
+            // in order to honor the request.  We want to drop it by one adjustment
+            // level...  but there is special meaning applied to various levels so
+            // we will skip some of them.
+            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
+                // System process will not get dropped, ever
+            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
+                adj = ProcessList.VISIBLE_APP_ADJ;
+            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+            } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
+                adj = ProcessList.CACHED_APP_MIN_ADJ;
+            } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) {
+                adj++;
+            }
+        }
+        return adj;
+    }
+
     public String toShortString() {
         if (shortStringName != null) {
             return shortStringName;
@@ -483,11 +498,8 @@
         }
     }
 
-    public void setProcessTrackerState(ProcessRecord TOP_APP, int memFactor, long now,
-            ProcessList plist) {
-        int state = this == TOP_APP ? ProcessTracker.STATE_TOP
-                : plist.adjToTrackedState(getSetAdjWithServices());
-        baseProcessTracker.setState(state, memFactor, now, pkgList);
+    public void setProcessTrackerState(int memFactor, long now) {
+        baseProcessTracker.setState(repProcState, memFactor, now, pkgList);
     }
 
     /*