Merge "Switch IProcessObserver to report process state"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 018e949..9239faf 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1627,13 +1627,6 @@
         public int lastTrimLevel;
 
         /**
-         * Constant for {@link #importance}: this is a persistent process.
-         * Only used when reporting to process observers.
-         * @hide
-         */
-        public static final int IMPORTANCE_PERSISTENT = 50;
-
-        /**
          * Constant for {@link #importance}: this process is running the
          * foreground UI.
          */
@@ -1748,9 +1741,16 @@
          */
         public int importanceReasonImportance;
 
+        /**
+         * Current process state, as per PROCESS_STATE_* constants.
+         * @hide
+         */
+        public int processState;
+
         public RunningAppProcessInfo() {
             importance = IMPORTANCE_FOREGROUND;
             importanceReasonCode = REASON_UNKNOWN;
+            processState = PROCESS_STATE_IMPORTANT_FOREGROUND;
         }
         
         public RunningAppProcessInfo(String pProcessName, int pPid, String pArr[]) {
@@ -1776,6 +1776,7 @@
             dest.writeInt(importanceReasonPid);
             ComponentName.writeToParcel(importanceReasonComponent, dest);
             dest.writeInt(importanceReasonImportance);
+            dest.writeInt(processState);
         }
 
         public void readFromParcel(Parcel source) {
@@ -1791,6 +1792,7 @@
             importanceReasonPid = source.readInt();
             importanceReasonComponent = ComponentName.readFromParcel(source);
             importanceReasonImportance = source.readInt();
+            processState = source.readInt();
         }
 
         public static final Creator<RunningAppProcessInfo> CREATOR = 
diff --git a/core/java/android/app/IProcessObserver.aidl b/core/java/android/app/IProcessObserver.aidl
index e587912..ecf2c73 100644
--- a/core/java/android/app/IProcessObserver.aidl
+++ b/core/java/android/app/IProcessObserver.aidl
@@ -20,7 +20,7 @@
 oneway interface IProcessObserver {
 
     void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
-    void onImportanceChanged(int pid, int uid, int importance);
+    void onProcessStateChanged(int pid, int uid, int procState);
     void onProcessDied(int pid, int uid);
 
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0c91907..9eaddbd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1017,11 +1017,11 @@
 
     static class ProcessChangeItem {
         static final int CHANGE_ACTIVITIES = 1<<0;
-        static final int CHANGE_IMPORTANCE= 1<<1;
+        static final int CHANGE_PROCESS_STATE = 1<<1;
         int changes;
         int uid;
         int pid;
-        int importance;
+        int processState;
         boolean foregroundActivities;
     }
 
@@ -3200,11 +3200,10 @@
                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
                                     item.foregroundActivities);
                         }
-                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
-                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
-                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
-                            observer.onImportanceChanged(item.pid, item.uid,
-                                    item.importance);
+                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
+                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
+                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
+                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
                         }
                     }
                 } catch (RemoteException e) {
@@ -10635,6 +10634,7 @@
         int adj = app.curAdj;
         outInfo.importance = oomAdjToImportance(adj, outInfo);
         outInfo.importanceReasonCode = app.adjTypeCode;
+        outInfo.processState = app.curProcState;
     }
 
     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
@@ -14690,7 +14690,7 @@
             app.keeping = true;
             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
-            // System process can do UI, and when they do we want to have
+            // System processes can do UI, and when they do we want to have
             // them trim their memory after the user leaves the UI.  To
             // facilitate this, here we need to determine whether or not it
             // is currently showing UI.
@@ -15308,86 +15308,7 @@
         adj = app.modifyRawOomAdj(adj);
 
         app.curProcState = procState;
-
-        int importance = app.memImportance;
-        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
-            app.curAdj = adj;
-            app.curSchedGroup = schedGroup;
-            if (!interesting) {
-                // For this reporting, if there is not something explicitly
-                // interesting in this process then we will push it to the
-                // background importance.
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
-            } 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;
-            } else if (adj >= ProcessList.HOME_APP_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
-            } else if (adj >= ProcessList.SERVICE_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
-            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
-            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
-            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
-            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
-            } else {
-                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
-            }
-        }
-
-        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
-        if (foregroundActivities != app.foregroundActivities) {
-            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
-        }
-        if (changes != 0) {
-            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
-            app.memImportance = importance;
-            app.foregroundActivities = foregroundActivities;
-            int i = mPendingProcessChanges.size()-1;
-            ProcessChangeItem item = null;
-            while (i >= 0) {
-                item = mPendingProcessChanges.get(i);
-                if (item.pid == app.pid) {
-                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
-                    break;
-                }
-                i--;
-            }
-            if (i < 0) {
-                // No existing item in pending changes; need a new one.
-                final int NA = mAvailProcessChanges.size();
-                if (NA > 0) {
-                    item = mAvailProcessChanges.remove(NA-1);
-                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
-                } else {
-                    item = new ProcessChangeItem();
-                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
-                }
-                item.changes = 0;
-                item.pid = app.pid;
-                item.uid = app.info.uid;
-                if (mPendingProcessChanges.size() == 0) {
-                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
-                            "*** Enqueueing dispatch processes changed!");
-                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
-                }
-                mPendingProcessChanges.add(item);
-            }
-            item.changes |= changes;
-            item.importance = importance;
-            item.foregroundActivities = foregroundActivities;
-            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
-                    + Integer.toHexString(System.identityHashCode(item))
-                    + " " + app.toShortString() + ": changes=" + item.changes
-                    + " importance=" + item.importance
-                    + " foreground=" + item.foregroundActivities
-                    + " type=" + app.adjType + " source=" + app.adjSource
-                    + " target=" + app.adjTarget);
-        }
+        app.foregroundActivities = foregroundActivities;
 
         return app.curRawAdj;
     }
@@ -15660,7 +15581,7 @@
     }
 
     private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
-            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
+            ProcessRecord TOP_APP, boolean doingAll, long now) {
         boolean success = true;
 
         if (app.curRawAdj != app.setRawAdj) {
@@ -15679,6 +15600,8 @@
             app.setRawAdj = app.curRawAdj;
         }
 
+        int changes = 0;
+
         if (app.curAdj != app.setAdj) {
             ProcessList.setOomAdj(app.pid, app.curAdj);
             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
@@ -15720,9 +15643,14 @@
                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
             }
         }
+        if (app.repForegroundActivities != app.foregroundActivities) {
+            app.repForegroundActivities = app.foregroundActivities;
+            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
+        }
         if (app.repProcState != app.curProcState) {
             app.repProcState = app.curProcState;
-            if (!reportingProcessState && app.thread != null) {
+            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
+            if (app.thread != null) {
                 try {
                     if (false) {
                         //RuntimeException h = new RuntimeException("here");
@@ -15767,6 +15695,51 @@
                 app.procStateChanged = true;
             }
         }
+
+        if (changes != 0) {
+            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
+            int i = mPendingProcessChanges.size()-1;
+            ProcessChangeItem item = null;
+            while (i >= 0) {
+                item = mPendingProcessChanges.get(i);
+                if (item.pid == app.pid) {
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
+                    break;
+                }
+                i--;
+            }
+            if (i < 0) {
+                // No existing item in pending changes; need a new one.
+                final int NA = mAvailProcessChanges.size();
+                if (NA > 0) {
+                    item = mAvailProcessChanges.remove(NA-1);
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
+                } else {
+                    item = new ProcessChangeItem();
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
+                }
+                item.changes = 0;
+                item.pid = app.pid;
+                item.uid = app.info.uid;
+                if (mPendingProcessChanges.size() == 0) {
+                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
+                            "*** Enqueueing dispatch processes changed!");
+                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
+                }
+                mPendingProcessChanges.add(item);
+            }
+            item.changes |= changes;
+            item.processState = app.repProcState;
+            item.foregroundActivities = app.repForegroundActivities;
+            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
+                    + Integer.toHexString(System.identityHashCode(item))
+                    + " " + app.toShortString() + ": changes=" + item.changes
+                    + " procState=" + item.processState
+                    + " foreground=" + item.foregroundActivities
+                    + " type=" + app.adjType + " source=" + app.adjSource
+                    + " target=" + app.adjTarget);
+        }
+
         return success;
     }
 
@@ -15777,7 +15750,7 @@
     }
 
     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
-            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
+            ProcessRecord TOP_APP, boolean doingAll, long now) {
         if (app.thread == null) {
             return false;
         }
@@ -15786,8 +15759,7 @@
 
         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
 
-        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
-                reportingProcessState, now);
+        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
     }
 
     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
@@ -15853,10 +15825,6 @@
     }
 
     final boolean updateOomAdjLocked(ProcessRecord app) {
-        return updateOomAdjLocked(app, false);
-    }
-
-    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
         final boolean wasCached = app.cached;
@@ -15869,7 +15837,7 @@
         // need to do a complete oom adj.
         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
-        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
+        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
                 SystemClock.uptimeMillis());
         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
             // Changed to/from cached state, so apps after it in the LRU
@@ -16002,7 +15970,7 @@
                     }
                 }
 
-                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
+                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
 
                 // Count the number of process types.
                 switch (app.curProcState) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b15fa5d..9d6481a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -503,7 +503,7 @@
                     // are already core system stuff so don't matter for this.
                     r.curApp = filter.receiverList.app;
                     filter.receiverList.app.curReceiver = r;
-                    mService.updateOomAdjLocked(r.curApp, true);
+                    mService.updateOomAdjLocked(r.curApp);
                 }
             }
             try {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index d04a6b2..8d7d300 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -77,7 +77,6 @@
     int curSchedGroup;          // Currently desired scheduling class
     int setSchedGroup;          // Last set to background scheduling class
     int trimMemoryLevel;        // Last selected memory trimming level
-    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
@@ -91,6 +90,7 @@
     boolean hasStartedServices; // Are there any started services running in this process?
     boolean foregroundServices; // Running any services that are foreground?
     boolean foregroundActivities; // Running any activities that are foreground?
+    boolean repForegroundActivities; // Last reported foreground activities.
     boolean systemNoUi;         // This is a system process, but not currently showing UI.
     boolean hasShownUi;         // Has UI been shown in this process since it was started?
     boolean pendingUiClean;     // Want to clean up resources from showing UI?
@@ -267,9 +267,10 @@
             pw.print(prefix); pw.print("persistent="); pw.print(persistent);
                     pw.print(" removed="); pw.println(removed);
         }
-        if (hasClientActivities || foregroundActivities) {
+        if (hasClientActivities || foregroundActivities || repForegroundActivities) {
             pw.print(prefix); pw.print("hasClientActivities="); pw.print(hasClientActivities);
-                    pw.print(" foregroundActivities="); pw.println(foregroundActivities);
+                    pw.print(" foregroundActivities="); pw.print(foregroundActivities);
+                    pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")");
         }
         if (hasStartedServices) {
             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 855ae23..416a6b1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -410,7 +410,7 @@
         }
 
         @Override
-        public void onImportanceChanged(int pid, int uid, int importance) {
+        public void onProcessStateChanged(int pid, int uid, int procState) {
         }
 
         @Override