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) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f0fb9e6..c9e7da8 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13224,7 +13224,7 @@
if (mReceiverResolver.dump(pw, needSep ?
"\n Receiver Resolver Table:" : " Receiver Resolver Table:",
- " ", dumpPackage, false)) {
+ " ", dumpPackage, false, false)) {
needSep = true;
printedAnything = true;
}
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index bffb541..d05910b 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -582,9 +582,10 @@
pw.println("Process stats (procstats) dump options:");
pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
pw.println(" [--details] [--full-details] [--current] [--hours N] [--last N]");
- pw.println(" [--active] [--commit] [--reset] [--clear] [--write] [-h] [<package.name>]");
+ pw.println(" [--max N] --active] [--commit] [--reset] [--clear] [--write] [-h]");
+ pw.println(" [<package.name>]");
pw.println(" --checkin: perform a checkin: print and delete old committed states.");
- pw.println(" --c: print only state in checkin format.");
+ pw.println(" -c: print only state in checkin format.");
pw.println(" --csv: output data suitable for putting in a spreadsheet.");
pw.println(" --csv-screen: on, off.");
pw.println(" --csv-mem: norm, mod, low, crit.");
@@ -595,6 +596,7 @@
pw.println(" --current: only dump current state.");
pw.println(" --hours: aggregate over about N last hours.");
pw.println(" --last: only show the last committed stats at index N (starting at 1).");
+ pw.println(" --max: for -a, max num of historical batches to print.");
pw.println(" --active: only show currently active processes/services.");
pw.println(" --commit: commit current stats to disk and reset to start new stats.");
pw.println(" --reset: reset current stats, without committing.");
@@ -636,6 +638,7 @@
boolean dumpAll = false;
int aggregateHours = 0;
int lastIndex = 0;
+ int maxNum = 2;
boolean activeOnly = false;
String reqPackage = null;
boolean csvSepScreenStats = false;
@@ -734,6 +737,20 @@
dumpHelp(pw);
return;
}
+ } else if ("--max".equals(arg)) {
+ i++;
+ if (i >= args.length) {
+ pw.println("Error: argument required for --max");
+ dumpHelp(pw);
+ return;
+ }
+ try {
+ maxNum = Integer.parseInt(args[i]);
+ } catch (NumberFormatException e) {
+ pw.println("Error: --max argument not an int -- " + args[i]);
+ dumpHelp(pw);
+ return;
+ }
} else if ("--active".equals(arg)) {
activeOnly = true;
currentOnly = true;
@@ -892,7 +909,11 @@
try {
ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
if (files != null) {
- for (int i=0; i<files.size(); i++) {
+ int start = isCheckin ? 0 : (files.size() - maxNum);
+ if (start < 0) {
+ start = 0;
+ }
+ for (int i=start; i<files.size(); i++) {
if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
try {
AtomicFile file = new AtomicFile(new File(files.get(i)));
@@ -947,19 +968,6 @@
}
}
if (!isCheckin) {
- if (!currentOnly) {
- if (sepNeeded) {
- pw.println();
- }
- pw.println("AGGREGATED OVER LAST 24 HOURS:");
- dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
- dumpDetails, dumpFullDetails, dumpAll, activeOnly);
- pw.println();
- pw.println("AGGREGATED OVER LAST 3 HOURS:");
- dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
- dumpDetails, dumpFullDetails, dumpAll, activeOnly);
- sepNeeded = true;
- }
synchronized (mAm) {
if (isCompact) {
mProcessStats.dumpCheckinLocked(pw, reqPackage);
@@ -977,8 +985,21 @@
} else {
mProcessStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
}
+ sepNeeded = true;
}
}
+ if (!currentOnly) {
+ if (sepNeeded) {
+ pw.println();
+ }
+ pw.println("AGGREGATED OVER LAST 24 HOURS:");
+ dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
+ dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+ pw.println();
+ pw.println("AGGREGATED OVER LAST 3 HOURS:");
+ dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
+ dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 195a886..b891d0c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7379,6 +7379,23 @@
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
+ return filter.activity;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Activity activity = (PackageParser.Activity)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(activity)));
+ out.print(' ');
+ activity.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
// final Iterator<ResolveInfo> i = resolveInfoList.iterator();
// final List<ResolveInfo> retList = Lists.newArrayList();
@@ -7578,6 +7595,23 @@
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
+ return filter.service;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Service service = (PackageParser.Service)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(service)));
+ out.print(' ');
+ service.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
// final Iterator<ResolveInfo> i = resolveInfoList.iterator();
// final List<ResolveInfo> retList = Lists.newArrayList();
@@ -7785,6 +7819,23 @@
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
+ return filter.provider;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Provider provider = (PackageParser.Provider)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(provider)));
+ out.print(' ');
+ provider.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
= new ArrayMap<ComponentName, PackageParser.Provider>();
private int mFlags;
@@ -12555,22 +12606,22 @@
if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
: "Activity Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
: "Receiver Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
: "Service Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
: "Provider Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
}
@@ -12583,7 +12634,7 @@
dumpState.getTitlePrinted()
? "\nPreferred Activities User " + user + ":"
: "Preferred Activities User " + user + ":", " ",
- packageName, true)) {
+ packageName, true, false)) {
dumpState.setTitlePrinted(true);
}
}
@@ -12676,8 +12727,8 @@
mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
}
- if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
- mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
+ if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
+ mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f0506a6..393ebd6 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3608,31 +3608,36 @@
}
}
- void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState,
+ boolean checkin) {
boolean printedSomething = false;
for (SharedUserSetting su : mSharedUsers.values()) {
if (packageName != null && su != dumpState.getSharedUser()) {
continue;
}
- if (!printedSomething) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Shared users:");
- printedSomething = true;
- }
- pw.print(" SharedUser [");
- pw.print(su.name);
- pw.print("] (");
- pw.print(Integer.toHexString(System.identityHashCode(su)));
- pw.println("):");
- pw.print(" userId=");
- pw.print(su.userId);
- pw.print(" gids=");
- pw.println(PackageManagerService.arrayToString(su.gids));
- pw.println(" grantedPermissions:");
- for (String s : su.grantedPermissions) {
- pw.print(" ");
- pw.println(s);
+ if (!checkin) {
+ if (!printedSomething) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Shared users:");
+ printedSomething = true;
+ }
+ pw.print(" SharedUser [");
+ pw.print(su.name);
+ pw.print("] (");
+ pw.print(Integer.toHexString(System.identityHashCode(su)));
+ pw.println("):");
+ pw.print(" userId=");
+ pw.print(su.userId);
+ pw.print(" gids=");
+ pw.println(PackageManagerService.arrayToString(su.gids));
+ pw.println(" grantedPermissions:");
+ for (String s : su.grantedPermissions) {
+ pw.print(" ");
+ pw.println(s);
+ }
+ } else {
+ pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
}
}
}