Merge "Fix issue #2619247: Music sometimes stops playing when navigation talks" into froyo
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 7e095b5..436bd17 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -315,6 +315,11 @@
     // without empty apps being able to push them out of memory.
     static final int MIN_HIDDEN_APPS = 2;
     
+    // The maximum number of hidden 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 = 15;
+    
     // We put empty content processes after any hidden processes that have
     // been idle for less than 30 seconds.
     static final long CONTENT_APP_IDLE_OFFSET = 30*1000;
@@ -8488,8 +8493,7 @@
                 }
                 int adj = proc.setAdj;
                 if (adj >= worstType) {
-                    Slog.w(TAG, "Killing " + reason + " : " + proc + " (adj "
-                            + adj + ")");
+                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
                             proc.processName, adj, reason);
                     killed = true;
@@ -8904,9 +8908,10 @@
             }
             if (app.pid > 0 && app.pid != MY_PID) {
                 handleAppCrashLocked(app);
-                Slog.i(ActivityManagerService.TAG, "Killing process "
-                        + app.processName
-                        + " (pid=" + app.pid + ") at user's request");
+                Slog.i(ActivityManagerService.TAG, "Killing "
+                        + app.processName + " (pid=" + app.pid + "): user's request");
+                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+                        app.processName, app.setAdj, "user's request after error");
                 Process.killProcess(app.pid);
             }
         }
@@ -10434,10 +10439,11 @@
             if (!capp.persistent && capp.thread != null
                     && capp.pid != 0
                     && capp.pid != MY_PID) {
-                Slog.i(TAG, "Killing app " + capp.processName
-                        + " (pid " + capp.pid
-                        + ") because provider " + cpr.info.name
-                        + " is in dying process " + proc.processName);
+                Slog.i(TAG, "Kill " + capp.processName
+                        + " (pid " + capp.pid + "): provider " + cpr.info.name
+                        + " in dying process " + proc.processName);
+                EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
+                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
                 Process.killProcess(capp.pid);
             }
         }
@@ -11522,6 +11528,7 @@
                     if (r.isForeground) {
                         r.isForeground = false;
                         if (r.app != null) {
+                            updateLruProcessLocked(r.app, false, true);
                             updateServiceForegroundLocked(r.app, true);
                         }
                     }
@@ -14244,6 +14251,7 @@
         int factor = (mLruProcesses.size()-4)/numSlots;
         if (factor < 1) factor = 1;
         int step = 0;
+        int numHidden = 0;
         
         // First try updating the OOM adjustment for each of the
         // application processes based on their current state.
@@ -14262,6 +14270,17 @@
                         curHiddenAdj++;
                     }
                 }
+                if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
+                    numHidden++;
+                    if (numHidden > MAX_HIDDEN_APPS) {
+                        Slog.i(TAG, "Kill " + app.processName
+                                + " (pid " + app.pid + "): hidden #" + numHidden
+                                + " beyond limit " + MAX_HIDDEN_APPS);
+                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+                                app.processName, app.setAdj, "too many background");
+                        Process.killProcess(app.pid);
+                    }
+                }
             } else {
                 didOomAdj = false;
             }