Make sure to acknowledge stale broadcasts

If a broadcast arrives at a process but the receiver has been unregistered in
the interval between dispatch and its arrival on the receiving process's side,
we were simply dropping the broadcast entirely, leading to spurious ANRs and
potentially issues involving future broadcasts being timed out incorrectly.  Fix
this by making sure to correctly 'finish' a broadcast even when the recipient
app no longer has any receiver that matches the broadcast's profile.

Change-Id: If990cab021a26668052cb536753f6c308d80a5b4
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 467812e..1115f92 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -691,6 +691,20 @@
                     if (rd != null) {
                         rd.performReceive(intent, resultCode, data, extras,
                                 ordered, sticky);
+                    } else {
+                        // The activity manager dispatched a broadcast to a registered
+                        // receiver in this process, but before it could be delivered the
+                        // receiver was unregistered.  Acknowledge the broadcast on its
+                        // behalf so that the system's broadcast sequence can continue.
+                        if (DEBUG_BROADCAST) {
+                            Log.i(TAG, "Broadcast to unregistered receiver");
+                        }
+                        IActivityManager mgr = ActivityManagerNative.getDefault();
+                        try {
+                            mgr.finishReceiver(this, resultCode, data, extras, false);
+                        } catch (RemoteException e) {
+                            Log.w(TAG, "Couldn't finish broadcast to unregistered receiver");
+                        }
                     }
                 }
             }
@@ -716,8 +730,8 @@
                     BroadcastReceiver receiver = mReceiver;
                     if (DEBUG_BROADCAST) {
                         int seq = mCurIntent.getIntExtra("seq", -1);
-                        Log.i(TAG, "Dispathing broadcast " + mCurIntent.getAction() + " seq=" + seq
-                                + " to " + mReceiver);
+                        Log.i(TAG, "Dispatching broadcast " + mCurIntent.getAction()
+                                + " seq=" + seq + " to " + mReceiver);
                     }
                     if (receiver == null) {
                         return;