Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 300d2f77 authored by riddle_hsu's avatar riddle_hsu Committed by Steve Kondik
Browse files

[ActivityManager] Skip receiver precisely.

Symptom:
Report broadcast ANR on a dead process.

Detail and sample:
http://code.google.com/p/android/issues/detail?id=158329

Root cause:
app.curReceiver can only remember the last running.
If an application is both receiving FG and BG broadcast,
only one of queue can discard, the remain one will still
count as timeout.

Solution:
Select the skip-tartget-receiver by comparing the skipping app
to the first record of mOrderedBroadcasts of each broadcast queues.

Change-Id: Ic68d56f21b417a34f2d30d64ecfbed09c5e1764d
parent 332ac726
Loading
Loading
Loading
Loading
+11 −16
Original line number Diff line number Diff line
@@ -301,28 +301,23 @@ public final class BroadcastQueue {
    }

    public void skipCurrentReceiverLocked(ProcessRecord app) {
        boolean reschedule = false;
        BroadcastRecord r = app.curReceiver;
        if (r != null && r.queue == this) {
            // The current broadcast is waiting for this app's receiver
            // to be finished.  Looks like that's not going to happen, so
            // let the broadcast continue.
            logBroadcastReceiverDiscardLocked(r);
            finishReceiverLocked(r, r.resultCode, r.resultData,
                    r.resultExtras, r.resultAbort, false);
            reschedule = true;
        BroadcastRecord r = null;
        if (mOrderedBroadcasts.size() > 0) {
            BroadcastRecord br = mOrderedBroadcasts.get(0);
            if (br.curApp == app) {
                r = br;
            }

        r = mPendingBroadcast;
        if (r != null && r.curApp == app) {
        }
        if (r == null && mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
            if (DEBUG_BROADCAST) Slog.v(TAG,
                    "[" + mQueueName + "] skip & discard pending app " + r);
            r = mPendingBroadcast;
        }

        if (r != null) {
            logBroadcastReceiverDiscardLocked(r);
            finishReceiverLocked(r, r.resultCode, r.resultData,
                    r.resultExtras, r.resultAbort, false);
            reschedule = true;
        }
        if (reschedule) {
            scheduleBroadcastsLocked();
        }
    }