Work on issue #18486438: Reduce size of bugreport output

Reduce how much stuff ProcessStats spews, and do collapsing of
repeated intent filter targets when dumping IntentResolvers.

Also add to pm's checkout output to include shared user ids,
and fix output formatting in a few places.

Change-Id: Ic9fc6731f0439101ba9343535e66cdbbad47e291
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 387eabc..cea1ebe 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -23,7 +23,6 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import android.net.Uri;
@@ -31,6 +30,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.MutableInt;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.LogPrinter;
@@ -213,36 +213,65 @@
     }
 
     boolean dumpMap(PrintWriter out, String titlePrefix, String title,
-            String prefix, Map<String, F[]> map, String packageName,
-            boolean printFilter) {
-        String eprefix = prefix + "  ";
-        String fprefix = prefix + "    ";
+            String prefix, ArrayMap<String, F[]> map, String packageName,
+            boolean printFilter, boolean collapseDuplicates) {
+        final String eprefix = prefix + "  ";
+        final String fprefix = prefix + "    ";
+        final ArrayMap<Object, MutableInt> found = new ArrayMap<>();
         boolean printedSomething = false;
         Printer printer = null;
-        for (Map.Entry<String, F[]> e : map.entrySet()) {
-            F[] a = e.getValue();
+        for (int mapi=0; mapi<map.size(); mapi++) {
+            F[] a = map.valueAt(mapi);
             final int N = a.length;
             boolean printedHeader = false;
             F filter;
-            for (int i=0; i<N && (filter=a[i]) != null; i++) {
-                if (packageName != null && !isPackageForFilter(packageName, filter)) {
-                    continue;
-                }
-                if (title != null) {
-                    out.print(titlePrefix); out.println(title);
-                    title = null;
-                }
-                if (!printedHeader) {
-                    out.print(eprefix); out.print(e.getKey()); out.println(":");
-                    printedHeader = true;
-                }
-                printedSomething = true;
-                dumpFilter(out, fprefix, filter);
-                if (printFilter) {
-                    if (printer == null) {
-                        printer = new PrintWriterPrinter(out);
+            if (collapseDuplicates) {
+                found.clear();
+                for (int i=0; i<N && (filter=a[i]) != null; i++) {
+                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
+                        continue;
                     }
-                    filter.dump(printer, fprefix + "  ");
+                    Object label = filterToLabel(filter);
+                    int index = found.indexOfKey(label);
+                    if (index < 0) {
+                        found.put(label, new MutableInt(1));
+                    } else {
+                        found.valueAt(index).value++;
+                    }
+                }
+                for (int i=0; i<found.size(); i++) {
+                    if (title != null) {
+                        out.print(titlePrefix); out.println(title);
+                        title = null;
+                    }
+                    if (!printedHeader) {
+                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
+                        printedHeader = true;
+                    }
+                    printedSomething = true;
+                    dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value);
+                }
+            } else {
+                for (int i=0; i<N && (filter=a[i]) != null; i++) {
+                    if (packageName != null && !isPackageForFilter(packageName, filter)) {
+                        continue;
+                    }
+                    if (title != null) {
+                        out.print(titlePrefix); out.println(title);
+                        title = null;
+                    }
+                    if (!printedHeader) {
+                        out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
+                        printedHeader = true;
+                    }
+                    printedSomething = true;
+                    dumpFilter(out, fprefix, filter);
+                    if (printFilter) {
+                        if (printer == null) {
+                            printer = new PrintWriterPrinter(out);
+                        }
+                        filter.dump(printer, fprefix + "  ");
+                    }
                 }
             }
         }
@@ -250,32 +279,32 @@
     }
 
     public boolean dump(PrintWriter out, String title, String prefix, String packageName,
-            boolean printFilter) {
+            boolean printFilter, boolean collapseDuplicates) {
         String innerPrefix = prefix + "  ";
         String sepPrefix = "\n" + prefix;
         String curPrefix = title + "\n" + prefix;
         if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
-                mTypeToFilter, packageName, printFilter)) {
+                mTypeToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
-                mBaseTypeToFilter, packageName, printFilter)) {
+                mBaseTypeToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
-                mWildTypeToFilter, packageName, printFilter)) {
+                mWildTypeToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
-                mSchemeToFilter, packageName, printFilter)) {
+                mSchemeToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
-                mActionToFilter, packageName, printFilter)) {
+                mActionToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
-                mTypedActionToFilter, packageName, printFilter)) {
+                mTypedActionToFilter, packageName, printFilter, collapseDuplicates)) {
             curPrefix = sepPrefix;
         }
         return curPrefix == sepPrefix;
@@ -479,6 +508,14 @@
         out.print(prefix); out.println(filter);
     }
 
+    protected Object filterToLabel(F filter) {
+        return "IntentFilter";
+    }
+
+    protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+        out.print(prefix); out.print(label); out.print(": "); out.println(count);
+    }
+
     private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
         F[] array = map.get(name);
         if (array == null) {