Debug issue #10876433 java.lang.IllegalStateException...

...in ActivityManagerService.updateLruProcessInternalLocked on bluetooth

Add more debug output to help track down what is going on.

Also fix a little problem where, when a service ANRs, if you ask to
wait and it still wasn't responding, the ANR dialog wouldn't be
shown again.

Change-Id: I5be2b1705a0a39ca2992624ae683945c5f38065d
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 4379c70..fa1769f 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -1009,23 +1009,15 @@
                 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
             }
             if (r.app != null) {
-                if (r.app.executingServices.size() == 0) {
-                    Message msg = mAm.mHandler.obtainMessage(
-                            ActivityManagerService.SERVICE_TIMEOUT_MSG);
-                    msg.obj = r.app;
-                    mAm.mHandler.sendMessageAtTime(msg,
-                            fg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
-                }
                 r.app.executingServices.add(r);
                 r.app.execServicesFg |= fg;
+                if (r.app.executingServices.size() == 1) {
+                    scheduleServiceTimeoutLocked(r.app);
+                }
             }
         } else if (r.app != null && fg && !r.app.execServicesFg) {
-            mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG);
-            Message msg = mAm.mHandler.obtainMessage(
-                    ActivityManagerService.SERVICE_TIMEOUT_MSG);
-            msg.obj = r.app;
-            mAm.mHandler.sendMessageAtTime(msg,now+SERVICE_TIMEOUT);
             r.app.execServicesFg = true;
+            scheduleServiceTimeoutLocked(r.app);
         }
         r.executeFg |= fg;
         r.executeNesting++;
@@ -2144,7 +2136,7 @@
                         ActivityManagerService.SERVICE_TIMEOUT_MSG);
                 msg.obj = proc;
                 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
-                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime+ SERVICE_BACKGROUND_TIMEOUT));
+                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
             }
         }
 
@@ -2153,6 +2145,18 @@
         }
     }
 
+    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
+        if (proc.executingServices.size() == 0 || proc.thread == null) {
+            return;
+        }
+        long now = SystemClock.uptimeMillis();
+        Message msg = mAm.mHandler.obtainMessage(
+                ActivityManagerService.SERVICE_TIMEOUT_MSG);
+        msg.obj = proc;
+        mAm.mHandler.sendMessageAtTime(msg,
+                proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
+    }
+
     /**
      * Prints a list of ServiceRecords (dumpsys activity services)
      */
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 47297c0..cbe97d2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2230,7 +2230,8 @@
         mHandler.sendMessage(msg);
     }
 
-    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index) {
+    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
+            String what, Object obj, ProcessRecord srcApp) {
         app.lastActivityTime = now;
 
         if (app.activities.size() > 0) {
@@ -2241,7 +2242,7 @@
         int lrui = mLruProcesses.lastIndexOf(app);
         if (lrui < 0) {
             throw new IllegalStateException("Adding dependent process " + app
-                    + " not on LRU list!");
+                    + " not on LRU list: " + what + obj + " from " + srcApp);
         }
 
         if (lrui >= mLruProcessActivityStart) {
@@ -2309,13 +2310,15 @@
             if (cr.binding != null && cr.binding.service != null
                     && cr.binding.service.app != null
                     && cr.binding.service.app.lruSeq != mLruSeq) {
-                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex);
+                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
+                        "service connection", cr, app);
             }
         }
         for (int j=app.conProviders.size()-1; j>=0; j--) {
             ContentProviderRecord cpr = app.conProviders.get(j).provider;
             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
-                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex);
+                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
+                        "provider reference", cpr, app);
             }
         }
 
@@ -3863,7 +3866,13 @@
                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
                 if (res != 0) {
-                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
+                    if (res < 0 && app.pid != MY_PID) {
+                        Process.killProcess(app.pid);
+                    } else {
+                        synchronized (this) {
+                            mServices.scheduleServiceTimeoutLocked(app);
+                        }
+                    }
                     return;
                 }
             } catch (RemoteException e) {
diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java
index b5e0715..d0a0441 100644
--- a/services/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/java/com/android/server/am/AppNotRespondingDialog.java
@@ -128,6 +128,7 @@
                         if (app.anrDialog == AppNotRespondingDialog.this) {
                             app.anrDialog = null;
                         }
+                        mService.mServices.scheduleServiceTimeoutLocked(app);
                     }
                     break;
             }
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 448117e..ac14da9 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -253,6 +253,7 @@
                     pw.print(" executeFg="); pw.print(executeFg);
                     pw.print(" executingStart=");
                     TimeUtils.formatDuration(executingStart, now, pw);
+                    pw.println();
         }
         if (crashCount != 0 || restartCount != 0
                 || restartDelay != 0 || nextRestartTime != 0) {