Improve some docs, fix some debugging.

- Add docs to Binder, Messenger, ResultReceier to explain their
  relation (or lack there-of) to process lifecycle.
- Clarify some aspects of process lifecycle for services.
- Fix help text of am command.
- Fix per-package dumping of battery stats to not include history.
- Fix per-package dumping of proc stats to only include aggregated
  and current stats and fix some formatting.
- Fix per-process dumping of meminfo to have an option to interpret
  the input as a package, so including all processes that are
  running code of that package.
- Fix top-level per-package debug output to correctly include all
  of these improvements and give them a little more time (10s) to
  complete for timing out.

Change-Id: I2a04c0f862bd47b08329443d722345a13ad9b6e2
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index cc0d51c..ba11a81 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -114,11 +114,7 @@
                 "       am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
                 "       am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
                 "               [--user <USER_ID> | current]\n" +
-                "               [--no-window-animation]\n" +
-                "               [--abi <ABI>]\n : Launch the instrumented process with the "  +
-                "                   selected ABI. This assumes that the process supports the" +
-                "                   selected ABI." +
-                "               <COMPONENT>\n" +
+                "               [--no-window-animation] [--abi <ABI>] <COMPONENT>\n" +
                 "       am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
                 "       am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
                 "       am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
@@ -194,6 +190,8 @@
                 "    --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
                 "        current user if not specified.\n" +
                 "    --no-window-animation: turn off window animations while running.\n" +
+                "    --abi <ABI>: Launch the instrumented process with the selected ABI.\n"  +
+                "        This assumes that the process supports the selected ABI.\n" +
                 "\n" +
                 "am profile: start and stop profiler on a process.  The given <PROCESS> argument\n" +
                 "  may be either a process name or pid.  Options are:\n" +
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2cd7379..37e8aa4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2621,17 +2621,17 @@
     public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
         FileOutputStream fout = new FileOutputStream(fd);
         PrintWriter pw = new FastPrintWriter(fout);
+        dumpService(pw, fd, "package", new String[] { packageName });
+        pw.println();
         dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] {
                 "-a", "package", packageName });
         pw.println();
-        dumpService(pw, fd, "meminfo", new String[] { "--local", packageName });
+        dumpService(pw, fd, "meminfo", new String[] { "--local", "--package", packageName });
         pw.println();
-        dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { "-a", packageName });
+        dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
         pw.println();
         dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
         pw.println();
-        dumpService(pw, fd, "package", new String[] { packageName });
-        pw.println();
         dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName });
         pw.flush();
     }
@@ -2649,7 +2649,7 @@
             tp = new TransferPipe();
             tp.setBufferPrefix("  ");
             service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
-            tp.go(fd);
+            tp.go(fd, 10000);
         } catch (Throwable e) {
             if (tp != null) {
                 tp.kill();
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index ec9960d..c8e0031 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -192,7 +192,7 @@
  * When running low on memory and needing to kill existing processes, the
  * priority of a process hosting the service will be the higher of the
  * following possibilities:
- * 
+ *
  * <ul>
  * <li><p>If the service is currently executing code in its
  * {@link #onCreate onCreate()}, {@link #onStartCommand onStartCommand()},
@@ -203,11 +203,19 @@
  * to be less important than any processes that are currently visible to the
  * user on-screen, but more important than any process not visible.  Because
  * only a few processes are generally visible to the user, this means that
- * the service should not be killed except in extreme low memory conditions.
+ * the service should not be killed except in low memory conditions.  However, since
+ * the user is not directly aware of a background service, in that state it <em>is</em>
+ * considered a valid candidate to kill, and you should be prepared for this to
+ * happen.  In particular, long-running services will be increasingly likely to
+ * kill and are guaranteed to be killed (and restarted if appropriate) if they
+ * remain started long enough.
  * <li><p>If there are clients bound to the service, then the service's hosting
  * process is never less important than the most important client.  That is,
  * if one of its clients is visible to the user, then the service itself is
- * considered to be visible.
+ * considered to be visible.  The way a client's importance impacts the service's
+ * importance can be adjusted through {@link Context#BIND_ABOVE_CLIENT},
+ * {@link Context#BIND_ALLOW_OOM_MANAGEMENT}, {@link Context#BIND_WAIVE_PRIORITY},
+ * {@link Context#BIND_IMPORTANT}, and {@link Context#BIND_ADJUST_WITH_ACTIVITY}.
  * <li><p>A started service can use the {@link #startForeground(int, Notification)}
  * API to put the service in a foreground state, where the system considers
  * it to be something the user is actively aware of and thus not a candidate
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index bbf6ed8..b4a4624 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -31,15 +31,32 @@
  * Base class for a remotable object, the core part of a lightweight
  * remote procedure call mechanism defined by {@link IBinder}.
  * This class is an implementation of IBinder that provides
- * the standard support creating a local implementation of such an object.
- * 
+ * standard local implementation of such an object.
+ *
  * <p>Most developers will not implement this class directly, instead using the
  * <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired
  * interface, having it generate the appropriate Binder subclass.  You can,
  * however, derive directly from Binder to implement your own custom RPC
  * protocol or simply instantiate a raw Binder object directly to use as a
  * token that can be shared across processes.
- * 
+ *
+ * <p>This class is just a basic IPC primitive; it has no impact on an application's
+ * lifecycle, and is valid only as long as the process that created it continues to run.
+ * To use this correctly, you must be doing so within the context of a top-level
+ * application component (a {@link android.app.Service}, {@link android.app.Activity},
+ * or {@link android.content.ContentProvider}) that lets the system know your process
+ * should remain running.</p>
+ *
+ * <p>You must keep in mind the situations in which your process
+ * could go away, and thus require that you later re-create a new Binder and re-attach
+ * it when the process starts again.  For example, if you are using this within an
+ * {@link android.app.Activity}, your activity's process may be killed any time the
+ * activity is not started; if the activity is later re-created you will need to
+ * create a new Binder and hand it back to the correct place again; you need to be
+ * aware that your process may be started for another reason (for example to receive
+ * a broadcast) that will not involve re-creating the activity and thus run its code
+ * to create a new Binder.</p>
+ *
  * @see IBinder
  */
 public class Binder implements IBinder {
diff --git a/core/java/android/os/Messenger.java b/core/java/android/os/Messenger.java
index ad55abdd..f362f56 100644
--- a/core/java/android/os/Messenger.java
+++ b/core/java/android/os/Messenger.java
@@ -21,6 +21,13 @@
  * This allows for the implementation of message-based communication across
  * processes, by creating a Messenger pointing to a Handler in one process,
  * and handing that Messenger to another process.
+ *
+ * <p>Note: the implementation underneath is just a simple wrapper around
+ * a {@link Binder} that is used to perform the communication.  This means
+ * semantically you should treat it as such: this class does not impact process
+ * lifecycle management (you must be using some higher-level component to tell
+ * the system that your process needs to continue running), the connection will
+ * break if your process goes away for any reason, etc.</p>
  */
 public final class Messenger implements Parcelable {
     private final IMessenger mTarget;
diff --git a/core/java/android/os/ResultReceiver.java b/core/java/android/os/ResultReceiver.java
index 711d4d9e..34a66b6 100644
--- a/core/java/android/os/ResultReceiver.java
+++ b/core/java/android/os/ResultReceiver.java
@@ -23,6 +23,13 @@
  * by creating a subclass and implement {@link #onReceiveResult}, which you can
  * then pass to others and send through IPC, and receive results they
  * supply with {@link #send}.
+ *
+ * <p>Note: the implementation underneath is just a simple wrapper around
+ * a {@link Binder} that is used to perform the communication.  This means
+ * semantically you should treat it as such: this class does not impact process
+ * lifecycle management (you must be using some higher-level component to tell
+ * the system that your process needs to continue running), the connection will
+ * break if your process goes away for any reason, etc.</p>
  */
 public class ResultReceiver implements Parcelable {
     final boolean mLocal;
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index a92cb74..e3e5647 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -2159,13 +2159,14 @@
             boolean dumpAll, boolean activeOnly) {
         long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
                 mStartTime, now);
+        boolean sepNeeded = false;
         if (mSysMemUsageTable != null) {
             pw.println("System memory usage:");
             dumpSysMemUsage(pw, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
+            sepNeeded = true;
         }
         ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
         boolean printedHeader = false;
-        boolean sepNeeded = false;
         for (int ip=0; ip<pkgMap.size(); ip++) {
             final String pkgName = pkgMap.keyAt(ip);
             final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
@@ -2193,6 +2194,7 @@
                     }
                     if (NPROCS > 0 || NSRVS > 0) {
                         if (!printedHeader) {
+                            if (sepNeeded) pw.println();
                             pw.println("Per-Package Stats:");
                             printedHeader = true;
                             sepNeeded = true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bb4db90..0c8e26e 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12588,7 +12588,7 @@
 
     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
-        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
+        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
 
         boolean printedAnything = false;
 
@@ -13686,7 +13686,8 @@
         return true;
     }
 
-    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
+    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
+            String[] args) {
         ArrayList<ProcessRecord> procs;
         synchronized (this) {
             if (args != null && args.length > start
@@ -13701,6 +13702,9 @@
                     ProcessRecord proc = mLruProcesses.get(i);
                     if (proc.pid == pid) {
                         procs.add(proc);
+                    } else if (allPkgs && proc.pkgList != null
+                            && proc.pkgList.containsKey(args[start])) {
+                        procs.add(proc);
                     } else if (proc.processName.equals(args[start])) {
                         procs.add(proc);
                     }
@@ -13717,7 +13721,7 @@
 
     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
             PrintWriter pw, String[] args) {
-        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
+        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
         if (procs == null) {
             pw.println("No process found for: " + args[0]);
             return;
@@ -13753,7 +13757,7 @@
     }
 
     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
-        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
+        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
         if (procs == null) {
             pw.println("No process found for: " + args[0]);
             return;
@@ -13921,6 +13925,7 @@
         boolean oomOnly = false;
         boolean isCompact = false;
         boolean localOnly = false;
+        boolean packages = false;
         
         int opti = 0;
         while (opti < args.length) {
@@ -13941,6 +13946,8 @@
                 oomOnly = true;
             } else if ("--local".equals(opt)) {
                 localOnly = true;
+            } else if ("--package".equals(opt)) {
+                packages = true;
             } else if ("-h".equals(opt)) {
                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
                 pw.println("  -a: include all available information for each process.");
@@ -13948,6 +13955,8 @@
                 pw.println("  -c: dump in a compact machine-parseable representation.");
                 pw.println("  --oom: only show processes organized by oom adj.");
                 pw.println("  --local: only collect details locally, don't call process.");
+                pw.println("  --package: interpret process arg as package, dumping all");
+                pw.println("             processes that have loaded that package.");
                 pw.println("If [process] is specified it can be the name or ");
                 pw.println("pid of a specific process to dump.");
                 return;
@@ -13961,7 +13970,7 @@
         long realtime = SystemClock.elapsedRealtime();
         final long[] tmpLong = new long[1];
 
-        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
+        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
         if (procs == null) {
             // No Java processes.  Maybe they want to print a native process.
             if (args != null && args.length > opti
@@ -14016,7 +14025,7 @@
             return;
         }
 
-        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
+        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
             dumpDetails = true;
         }
 
@@ -14132,7 +14141,7 @@
 
         long nativeProcTotalPss = 0;
 
-        if (!isCheckinRequest && procs.size() > 1) {
+        if (!isCheckinRequest && procs.size() > 1 && !packages) {
             // If we are showing aggregations, also look for native processes to
             // include so that our aggregations are more accurate.
             updateCpuStatsNow();
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index a021919..6983ec4 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -871,6 +871,16 @@
         if (BatteryStatsHelper.checkWifiOnly(mContext)) {
             flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
         }
+        if (reqUid >= 0) {
+            // By default, if the caller is only interested in a specific package, then
+            // we only dump the aggregated data since charged.
+            if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_UNPLUGGED_ONLY
+                    |BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
+                flags |= BatteryStats.DUMP_CHARGED_ONLY;
+                // Also if they are doing -c, we don't want history.
+                flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
+            }
+        }
         if (useCheckinFormat) {
             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
             if (isRealCheckin) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 28e46a4..bffb541 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -791,7 +791,7 @@
                     reqPackage = arg;
                     // Include all details, since we know we are only going to
                     // be dumping a smaller set of data.  In fact only the details
-                    // container per-package data, so that are needed to be able
+                    // contain per-package data, so this is needed to be able
                     // to dump anything at all when filtering by package.
                     dumpDetails = true;
                 }