Cap the size of StrictMode buffering we do before calling DropBox.

Change-Id: I46ea767bd0153c745e9b7eff945dacf5130f8807
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c605b38..bcbda3e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6170,7 +6170,7 @@
         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
 
         boolean bufferWasEmpty;
-
+        boolean needsFlush;
         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
         synchronized (sb) {
             bufferWasEmpty = sb.length() == 0;
@@ -6185,18 +6185,32 @@
                 sb.append(crashInfo.stackTrace);
             }
             sb.append("\n");
+
+            // Only buffer up to ~64k.  Various logging bits truncate
+            // things at 128k.
+            needsFlush = (sb.length() > 64 * 1024);
         }
 
-        // Non-system apps are isolated with a different tag & policy.
-        // They're also not batched.  Batching is useful during system
-        // boot with strict system-wide logging policies and lots of
-        // things firing, but not common with regular apps, which
-        // won't ship with StrictMode dropboxing enabled.
-        if (!isSystemApp) {
+        // Flush immediately if the buffer's grown too large, or this
+        // is a non-system app.  Non-system apps are isolated with a
+        // different tag & policy and not batched.
+        //
+        // Batching is useful during internal testing with
+        // StrictMode settings turned up high.  Without batching,
+        // thousands of separate files could be created on boot.
+        if (!isSystemApp || needsFlush) {
             new Thread("Error dump: " + dropboxTag) {
                 @Override
                 public void run() {
-                    dbox.addText(dropboxTag, sb.toString());
+                    String report;
+                    synchronized (sb) {
+                        report = sb.toString();
+                        sb.delete(0, sb.length());
+                        sb.trimToSize();
+                    }
+                    if (report.length() != 0) {
+                        dbox.addText(dropboxTag, report);
+                    }
                 }
             }.start();
             return;
@@ -6204,8 +6218,9 @@
 
         // System app batching:
         if (!bufferWasEmpty) {
-            // An existing dropbox-writing thread is outstanding and
-            // will handle it.
+            // An existing dropbox-writing thread is outstanding, so
+            // we don't need to start it up.  The existing thread will
+            // catch the buffer appends we just did.
             return;
         }