Properly clean up broadcast-receiver ANR
Specifically, if the only receiver component was disabled while the
broadcast was in flight *and* the app ANRed, we were failing to properly
abandon the broadcast and wound up stuck waiting for delivery completion
that would never happen.
Bug: 64854337
Test: manual
Change-Id: I9181830eca17981bf1ca403ac36f88c84c548360
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 7c7eda7..d835454 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1445,20 +1445,19 @@
r.receiverTime = now;
r.anrCount++;
- // Current receiver has passed its expiration date.
- if (r.nextReceiver <= 0) {
- Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
- return;
- }
-
ProcessRecord app = null;
String anrMessage = null;
- Object curReceiver = r.receivers.get(r.nextReceiver-1);
- r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
- Slog.w(TAG, "Receiver during timeout: " + curReceiver);
+ Object curReceiver;
+ if (r.nextReceiver > 0) {
+ curReceiver = r.receivers.get(r.nextReceiver-1);
+ r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
+ } else {
+ curReceiver = r.curReceiver;
+ }
+ Slog.w(TAG, "Receiver during timeout of " + r + " : " + curReceiver);
logBroadcastReceiverDiscardLocked(r);
- if (curReceiver instanceof BroadcastFilter) {
+ if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
BroadcastFilter bf = (BroadcastFilter)curReceiver;
if (bf.receiverList.pid != 0
&& bf.receiverList.pid != ActivityManagerService.MY_PID) {