Fix issue #18827122: system server crashed on broadcasting...

...an intent with invalid or null package uri

Also tweak battery stats to record in the history when we shut
down, to understand when restarts are due to clean shutdowns or
crashes.

Change-Id: I6443dafc23e356be9f569906f6081152d4f92d2b
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 5fd697a..c0dca0e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -604,6 +604,7 @@
         public static final byte CMD_CURRENT_TIME = 5;
         public static final byte CMD_OVERFLOW = 6;
         public static final byte CMD_RESET = 7;
+        public static final byte CMD_SHUTDOWN = 8;
 
         public byte cmd = CMD_NULL;
         
@@ -3529,6 +3530,11 @@
                     pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
                             rec.currentTime).toString());
                 }
+            } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
+                if (checkin) {
+                    pw.print(":");
+                }
+                pw.println("SHUTDOWN");
             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
                 if (checkin) {
                     pw.print(":");
@@ -3849,7 +3855,8 @@
                 if (histStart >= 0 && !printed) {
                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
                             || rec.cmd == HistoryItem.CMD_RESET
-                            || rec.cmd == HistoryItem.CMD_START) {
+                            || rec.cmd == HistoryItem.CMD_START
+                            || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
                         printed = true;
                         hprinter.printNextItem(pw, rec, baseTime, checkin,
                                 (flags&DUMP_VERBOSE) != 0);
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 9df8ad5..eff44bd 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -24,6 +24,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
+import android.util.Slog;
 import com.android.internal.os.BackgroundThread;
 
 import java.util.HashSet;
@@ -279,8 +280,8 @@
         mChangeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                 UserHandle.USER_NULL);
         if (mChangeUserId == UserHandle.USER_NULL) {
-            throw new IllegalArgumentException(
-                    "Intent broadcast does not contain user handle: " + intent);
+            Slog.w("PackageMonitor", "Intent broadcast does not contain user handle: " + intent);
+            return;
         }
         onBeginPackageChanges();
         
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8ceee20..20bb95e 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6955,6 +6955,17 @@
         }
     }
 
+    private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
+        if (mRecordingHistory) {
+            mHistoryCur.currentTime = System.currentTimeMillis();
+            mLastRecordedClockTime = mHistoryCur.currentTime;
+            mLastRecordedClockRealtime = elapsedRealtimeMs;
+            addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
+                    mHistoryCur);
+            mHistoryCur.currentTime = 0;
+        }
+    }
+
     // This should probably be exposed in the API, though it's not critical
     private static final int BATTERY_PLUGGED_NONE = 0;
 
@@ -7627,6 +7638,7 @@
     }
 
     public void shutdownLocked() {
+        recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
         writeSyncLocked();
         mShuttingDown = true;
     }