OSDN Git Service

Merge "Avoid calling updateOomAdj an extra time" into pi-dev
authorAmith Yamasani <yamasani@google.com>
Wed, 16 May 2018 12:54:14 +0000 (12:54 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 16 May 2018 12:54:14 +0000 (12:54 +0000)
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/BroadcastQueue.java

index f83d9e6..cddda58 100644 (file)
@@ -22011,12 +22011,13 @@ public class ActivityManagerService extends IActivityManager.Stub
                     doNext = r.queue.finishReceiverLocked(r, resultCode,
                         resultData, resultExtras, resultAbort, true);
                 }
+                if (doNext) {
+                    r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
+                }
+                // updateOomAdjLocked() will be done here
+                trimApplicationsLocked();
             }
 
-            if (doNext) {
-                r.queue.processNextBroadcast(false);
-            }
-            trimApplications();
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -25747,40 +25748,43 @@ public class ActivityManagerService extends IActivityManager.Stub
 
     final void trimApplications() {
         synchronized (this) {
-            int i;
-
-            // First remove any unused application processes whose package
-            // has been removed.
-            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
-                final ProcessRecord app = mRemovedProcesses.get(i);
-                if (app.activities.size() == 0 && app.recentTasks.size() == 0
-                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
-                    Slog.i(
-                        TAG, "Exiting empty application process "
-                        + app.toShortString() + " ("
-                        + (app.thread != null ? app.thread.asBinder() : null)
-                        + ")\n");
-                    if (app.pid > 0 && app.pid != MY_PID) {
-                        app.kill("empty", false);
-                    } else if (app.thread != null) {
-                        try {
-                            app.thread.scheduleExit();
-                        } catch (Exception e) {
-                            // Ignore exceptions.
-                        }
+            trimApplicationsLocked();
+        }
+    }
+
+    final void trimApplicationsLocked() {
+        // First remove any unused application processes whose package
+        // has been removed.
+        for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
+            final ProcessRecord app = mRemovedProcesses.get(i);
+            if (app.activities.size() == 0 && app.recentTasks.size() == 0
+                    && app.curReceivers.isEmpty() && app.services.size() == 0) {
+                Slog.i(
+                    TAG, "Exiting empty application process "
+                    + app.toShortString() + " ("
+                    + (app.thread != null ? app.thread.asBinder() : null)
+                    + ")\n");
+                if (app.pid > 0 && app.pid != MY_PID) {
+                    app.kill("empty", false);
+                } else if (app.thread != null) {
+                    try {
+                        app.thread.scheduleExit();
+                    } catch (Exception e) {
+                        // Ignore exceptions.
                     }
-                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
-                    mRemovedProcesses.remove(i);
+                }
+                cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
+                mRemovedProcesses.remove(i);
 
-                    if (app.persistent) {
-                        addAppLocked(app.info, null, false, null /* ABI override */);
-                    }
+                if (app.persistent) {
+                    addAppLocked(app.info, null, false, null /* ABI override */);
                 }
             }
-
-            // Now update the oom adj for all processes.
-            updateOomAdjLocked();
         }
+
+        // Now update the oom adj for all processes. Don't skip this, since other callers
+        // might be depending on it.
+        updateOomAdjLocked();
     }
 
     /** This method sends the specified signal to each of the persistent apps */
index cc3a887..c9a26cb 100644 (file)
@@ -271,7 +271,7 @@ public final class BroadcastQueue {
     }
 
     private final void processCurBroadcastLocked(BroadcastRecord r,
-            ProcessRecord app) throws RemoteException {
+            ProcessRecord app, boolean skipOomAdj) throws RemoteException {
         if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                 "Process cur broadcast " + r + " for app " + app);
         if (app.thread == null) {
@@ -287,7 +287,9 @@ public final class BroadcastQueue {
         app.curReceivers.add(r);
         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
         mService.updateLruProcessLocked(app, false, null);
-        mService.updateOomAdjLocked();
+        if (!skipOomAdj) {
+            mService.updateOomAdjLocked();
+        }
 
         // Tell the application to launch this receiver.
         r.intent.setComponent(r.curComponent);
@@ -328,7 +330,7 @@ public final class BroadcastQueue {
             }
             try {
                 mPendingBroadcast = null;
-                processCurBroadcastLocked(br, app);
+                processCurBroadcastLocked(br, app, false);
                 didSomething = true;
             } catch (Exception e) {
                 Slog.w(TAG, "Exception in new application when starting receiver "
@@ -819,577 +821,581 @@ public final class BroadcastQueue {
     }
 
     final void processNextBroadcast(boolean fromMsg) {
-        synchronized(mService) {
-            BroadcastRecord r;
+        synchronized (mService) {
+            processNextBroadcastLocked(fromMsg, false);
+        }
+    }
+
+    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
+        BroadcastRecord r;
 
-            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
-                    + mQueueName + "]: "
-                    + mParallelBroadcasts.size() + " parallel broadcasts, "
-                    + mOrderedBroadcasts.size() + " ordered broadcasts");
+        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
+                + mQueueName + "]: "
+                + mParallelBroadcasts.size() + " parallel broadcasts, "
+                + mOrderedBroadcasts.size() + " ordered broadcasts");
+
+        mService.updateCpuStats();
+
+        if (fromMsg) {
+            mBroadcastsScheduled = false;
+        }
 
-            mService.updateCpuStats();
+        // First, deliver any non-serialized broadcasts right away.
+        while (mParallelBroadcasts.size() > 0) {
+            r = mParallelBroadcasts.remove(0);
+            r.dispatchTime = SystemClock.uptimeMillis();
+            r.dispatchClockTime = System.currentTimeMillis();
 
-            if (fromMsg) {
-                mBroadcastsScheduled = false;
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                    System.identityHashCode(r));
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                    System.identityHashCode(r));
             }
 
-            // First, deliver any non-serialized broadcasts right away.
-            while (mParallelBroadcasts.size() > 0) {
-                r = mParallelBroadcasts.remove(0);
-                r.dispatchTime = SystemClock.uptimeMillis();
-                r.dispatchClockTime = System.currentTimeMillis();
-
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
-                        System.identityHashCode(r));
-                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
-                        System.identityHashCode(r));
-                }
+            final int N = r.receivers.size();
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+                    + mQueueName + "] " + r);
+            for (int i=0; i<N; i++) {
+                Object target = r.receivers.get(i);
+                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                        "Delivering non-ordered on [" + mQueueName + "] to registered "
+                        + target + ": " + r);
+                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
+            }
+            addBroadcastToHistoryLocked(r);
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+                    + mQueueName + "] " + r);
+        }
 
-                final int N = r.receivers.size();
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
-                        + mQueueName + "] " + r);
-                for (int i=0; i<N; i++) {
-                    Object target = r.receivers.get(i);
-                    if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                            "Delivering non-ordered on [" + mQueueName + "] to registered "
-                            + target + ": " + r);
-                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
+        // Now take care of the next serialized one...
+
+        // If we are waiting for a process to come up to handle the next
+        // broadcast, then do nothing at this point.  Just in case, we
+        // check that the process we're waiting for still exists.
+        if (mPendingBroadcast != null) {
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
+                    "processNextBroadcast [" + mQueueName + "]: waiting for "
+                    + mPendingBroadcast.curApp);
+
+            boolean isDead;
+            if (mPendingBroadcast.curApp.pid > 0) {
+                synchronized (mService.mPidsSelfLocked) {
+                    ProcessRecord proc = mService.mPidsSelfLocked.get(
+                            mPendingBroadcast.curApp.pid);
+                    isDead = proc == null || proc.crashing;
                 }
-                addBroadcastToHistoryLocked(r);
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
-                        + mQueueName + "] " + r);
+            } else {
+                final ProcessRecord proc = mService.mProcessNames.get(
+                        mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
+                isDead = proc == null || !proc.pendingStart;
+            }
+            if (!isDead) {
+                // It's still alive, so keep waiting
+                return;
+            } else {
+                Slog.w(TAG, "pending app  ["
+                        + mQueueName + "]" + mPendingBroadcast.curApp
+                        + " died before responding to broadcast");
+                mPendingBroadcast.state = BroadcastRecord.IDLE;
+                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
+                mPendingBroadcast = null;
             }
+        }
 
-            // Now take care of the next serialized one...
+        boolean looped = false;
 
-            // If we are waiting for a process to come up to handle the next
-            // broadcast, then do nothing at this point.  Just in case, we
-            // check that the process we're waiting for still exists.
-            if (mPendingBroadcast != null) {
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
-                        "processNextBroadcast [" + mQueueName + "]: waiting for "
-                        + mPendingBroadcast.curApp);
-
-                boolean isDead;
-                if (mPendingBroadcast.curApp.pid > 0) {
-                    synchronized (mService.mPidsSelfLocked) {
-                        ProcessRecord proc = mService.mPidsSelfLocked.get(
-                                mPendingBroadcast.curApp.pid);
-                        isDead = proc == null || proc.crashing;
-                    }
-                } else {
-                    final ProcessRecord proc = mService.mProcessNames.get(
-                            mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
-                    isDead = proc == null || !proc.pendingStart;
+        do {
+            if (mOrderedBroadcasts.size() == 0) {
+                // No more broadcasts pending, so all done!
+                mService.scheduleAppGcsLocked();
+                if (looped) {
+                    // If we had finished the last ordered broadcast, then
+                    // make sure all processes have correct oom and sched
+                    // adjustments.
+                    mService.updateOomAdjLocked();
                 }
-                if (!isDead) {
-                    // It's still alive, so keep waiting
-                    return;
-                } else {
-                    Slog.w(TAG, "pending app  ["
-                            + mQueueName + "]" + mPendingBroadcast.curApp
-                            + " died before responding to broadcast");
-                    mPendingBroadcast.state = BroadcastRecord.IDLE;
-                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
-                    mPendingBroadcast = null;
+                return;
+            }
+            r = mOrderedBroadcasts.get(0);
+            boolean forceReceive = false;
+
+            // Ensure that even if something goes awry with the timeout
+            // detection, we catch "hung" broadcasts here, discard them,
+            // and continue to make progress.
+            //
+            // This is only done if the system is ready so that PRE_BOOT_COMPLETED
+            // receivers don't get executed with timeouts. They're intended for
+            // one time heavy lifting after system upgrades and can take
+            // significant amounts of time.
+            int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
+            if (mService.mProcessesReady && r.dispatchTime > 0) {
+                long now = SystemClock.uptimeMillis();
+                if ((numReceivers > 0) &&
+                        (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
+                    Slog.w(TAG, "Hung broadcast ["
+                            + mQueueName + "] discarded after timeout failure:"
+                            + " now=" + now
+                            + " dispatchTime=" + r.dispatchTime
+                            + " startTime=" + r.receiverTime
+                            + " intent=" + r.intent
+                            + " numReceivers=" + numReceivers
+                            + " nextReceiver=" + r.nextReceiver
+                            + " state=" + r.state);
+                    broadcastTimeoutLocked(false); // forcibly finish this broadcast
+                    forceReceive = true;
+                    r.state = BroadcastRecord.IDLE;
                 }
             }
 
-            boolean looped = false;
-            
-            do {
-                if (mOrderedBroadcasts.size() == 0) {
-                    // No more broadcasts pending, so all done!
-                    mService.scheduleAppGcsLocked();
-                    if (looped) {
-                        // If we had finished the last ordered broadcast, then
-                        // make sure all processes have correct oom and sched
-                        // adjustments.
-                        mService.updateOomAdjLocked();
-                    }
-                    return;
-                }
-                r = mOrderedBroadcasts.get(0);
-                boolean forceReceive = false;
-
-                // Ensure that even if something goes awry with the timeout
-                // detection, we catch "hung" broadcasts here, discard them,
-                // and continue to make progress.
-                //
-                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
-                // receivers don't get executed with timeouts. They're intended for
-                // one time heavy lifting after system upgrades and can take
-                // significant amounts of time.
-                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
-                if (mService.mProcessesReady && r.dispatchTime > 0) {
-                    long now = SystemClock.uptimeMillis();
-                    if ((numReceivers > 0) &&
-                            (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
-                        Slog.w(TAG, "Hung broadcast ["
-                                + mQueueName + "] discarded after timeout failure:"
-                                + " now=" + now
-                                + " dispatchTime=" + r.dispatchTime
-                                + " startTime=" + r.receiverTime
-                                + " intent=" + r.intent
-                                + " numReceivers=" + numReceivers
-                                + " nextReceiver=" + r.nextReceiver
-                                + " state=" + r.state);
-                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
-                        forceReceive = true;
-                        r.state = BroadcastRecord.IDLE;
-                    }
-                }
+            if (r.state != BroadcastRecord.IDLE) {
+                if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
+                        "processNextBroadcast("
+                        + mQueueName + ") called when not idle (state="
+                        + r.state + ")");
+                return;
+            }
 
-                if (r.state != BroadcastRecord.IDLE) {
-                    if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
-                            "processNextBroadcast("
-                            + mQueueName + ") called when not idle (state="
-                            + r.state + ")");
-                    return;
-                }
+            if (r.receivers == null || r.nextReceiver >= numReceivers
+                    || r.resultAbort || forceReceive) {
+                // No more receivers for this broadcast!  Send the final
+                // result if requested...
+                if (r.resultTo != null) {
+                    try {
+                        if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
+                                "Finishing broadcast [" + mQueueName + "] "
+                                + r.intent.getAction() + " app=" + r.callerApp);
+                        performReceiveLocked(r.callerApp, r.resultTo,
+                            new Intent(r.intent), r.resultCode,
+                            r.resultData, r.resultExtras, false, false, r.userId);
+                        // Set this to null so that the reference
+                        // (local and remote) isn't kept in the mBroadcastHistory.
+                        r.resultTo = null;
+                    } catch (RemoteException e) {
+                        r.resultTo = null;
+                        Slog.w(TAG, "Failure ["
+                                + mQueueName + "] sending broadcast result of "
+                                + r.intent, e);
 
-                if (r.receivers == null || r.nextReceiver >= numReceivers
-                        || r.resultAbort || forceReceive) {
-                    // No more receivers for this broadcast!  Send the final
-                    // result if requested...
-                    if (r.resultTo != null) {
-                        try {
-                            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
-                                    "Finishing broadcast [" + mQueueName + "] "
-                                    + r.intent.getAction() + " app=" + r.callerApp);
-                            performReceiveLocked(r.callerApp, r.resultTo,
-                                new Intent(r.intent), r.resultCode,
-                                r.resultData, r.resultExtras, false, false, r.userId);
-                            // Set this to null so that the reference
-                            // (local and remote) isn't kept in the mBroadcastHistory.
-                            r.resultTo = null;
-                        } catch (RemoteException e) {
-                            r.resultTo = null;
-                            Slog.w(TAG, "Failure ["
-                                    + mQueueName + "] sending broadcast result of "
-                                    + r.intent, e);
-
-                        }
                     }
+                }
 
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
-                    cancelBroadcastTimeoutLocked();
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
+                cancelBroadcastTimeoutLocked();
 
-                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
-                            "Finished with ordered broadcast " + r);
+                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
+                        "Finished with ordered broadcast " + r);
 
-                    // ... and on to the next...
-                    addBroadcastToHistoryLocked(r);
-                    if (r.intent.getComponent() == null && r.intent.getPackage() == null
-                            && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
-                        // This was an implicit broadcast... let's record it for posterity.
-                        mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
-                                r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
-                    }
-                    mOrderedBroadcasts.remove(0);
-                    r = null;
-                    looped = true;
-                    continue;
-                }
-            } while (r == null);
-
-            // Get the next receiver...
-            int recIdx = r.nextReceiver++;
-
-            // Keep track of when this receiver started, and make sure there
-            // is a timeout message pending to kill it if need be.
-            r.receiverTime = SystemClock.uptimeMillis();
-            if (recIdx == 0) {
-                r.dispatchTime = r.receiverTime;
-                r.dispatchClockTime = System.currentTimeMillis();
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
-                        System.identityHashCode(r));
-                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
-                        System.identityHashCode(r));
+                // ... and on to the next...
+                addBroadcastToHistoryLocked(r);
+                if (r.intent.getComponent() == null && r.intent.getPackage() == null
+                        && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
+                    // This was an implicit broadcast... let's record it for posterity.
+                    mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
+                            r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
                 }
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
-                        + mQueueName + "] " + r);
+                mOrderedBroadcasts.remove(0);
+                r = null;
+                looped = true;
+                continue;
             }
-            if (! mPendingBroadcastTimeoutMessage) {
-                long timeoutTime = r.receiverTime + mTimeoutPeriod;
-                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
-                        "Submitting BROADCAST_TIMEOUT_MSG ["
-                        + mQueueName + "] for " + r + " at " + timeoutTime);
-                setBroadcastTimeoutLocked(timeoutTime);
+        } while (r == null);
+
+        // Get the next receiver...
+        int recIdx = r.nextReceiver++;
+
+        // Keep track of when this receiver started, and make sure there
+        // is a timeout message pending to kill it if need be.
+        r.receiverTime = SystemClock.uptimeMillis();
+        if (recIdx == 0) {
+            r.dispatchTime = r.receiverTime;
+            r.dispatchClockTime = System.currentTimeMillis();
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                    System.identityHashCode(r));
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                    System.identityHashCode(r));
             }
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
+                    + mQueueName + "] " + r);
+        }
+        if (! mPendingBroadcastTimeoutMessage) {
+            long timeoutTime = r.receiverTime + mTimeoutPeriod;
+            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
+                    "Submitting BROADCAST_TIMEOUT_MSG ["
+                    + mQueueName + "] for " + r + " at " + timeoutTime);
+            setBroadcastTimeoutLocked(timeoutTime);
+        }
 
-            final BroadcastOptions brOptions = r.options;
-            final Object nextReceiver = r.receivers.get(recIdx);
+        final BroadcastOptions brOptions = r.options;
+        final Object nextReceiver = r.receivers.get(recIdx);
 
-            if (nextReceiver instanceof BroadcastFilter) {
-                // Simple case: this is a registered receiver who gets
-                // a direct call.
-                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
-                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                        "Delivering ordered ["
-                        + mQueueName + "] to registered "
-                        + filter + ": " + r);
-                deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
-                if (r.receiver == null || !r.ordered) {
-                    // The receiver has already finished, so schedule to
-                    // process the next one.
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
-                            + mQueueName + "]: ordered="
-                            + r.ordered + " receiver=" + r.receiver);
-                    r.state = BroadcastRecord.IDLE;
-                    scheduleBroadcastsLocked();
-                } else {
-                    if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
-                        scheduleTempWhitelistLocked(filter.owningUid,
-                                brOptions.getTemporaryAppWhitelistDuration(), r);
-                    }
+        if (nextReceiver instanceof BroadcastFilter) {
+            // Simple case: this is a registered receiver who gets
+            // a direct call.
+            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
+            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                    "Delivering ordered ["
+                    + mQueueName + "] to registered "
+                    + filter + ": " + r);
+            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
+            if (r.receiver == null || !r.ordered) {
+                // The receiver has already finished, so schedule to
+                // process the next one.
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
+                        + mQueueName + "]: ordered="
+                        + r.ordered + " receiver=" + r.receiver);
+                r.state = BroadcastRecord.IDLE;
+                scheduleBroadcastsLocked();
+            } else {
+                if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
+                    scheduleTempWhitelistLocked(filter.owningUid,
+                            brOptions.getTemporaryAppWhitelistDuration(), r);
                 }
-                return;
             }
+            return;
+        }
+
+        // Hard case: need to instantiate the receiver, possibly
+        // starting its application process to host it.
 
-            // Hard case: need to instantiate the receiver, possibly
-            // starting its application process to host it.
-
-            ResolveInfo info =
-                (ResolveInfo)nextReceiver;
-            ComponentName component = new ComponentName(
-                    info.activityInfo.applicationInfo.packageName,
-                    info.activityInfo.name);
-
-            boolean skip = false;
-            if (brOptions != null &&
-                    (info.activityInfo.applicationInfo.targetSdkVersion
-                            < brOptions.getMinManifestReceiverApiLevel() ||
-                    info.activityInfo.applicationInfo.targetSdkVersion
-                            > brOptions.getMaxManifestReceiverApiLevel())) {
+        ResolveInfo info =
+            (ResolveInfo)nextReceiver;
+        ComponentName component = new ComponentName(
+                info.activityInfo.applicationInfo.packageName,
+                info.activityInfo.name);
+
+        boolean skip = false;
+        if (brOptions != null &&
+                (info.activityInfo.applicationInfo.targetSdkVersion
+                        < brOptions.getMinManifestReceiverApiLevel() ||
+                info.activityInfo.applicationInfo.targetSdkVersion
+                        > brOptions.getMaxManifestReceiverApiLevel())) {
+            skip = true;
+        }
+        int perm = mService.checkComponentPermission(info.activityInfo.permission,
+                r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
+                info.activityInfo.exported);
+        if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
+            if (!info.activityInfo.exported) {
+                Slog.w(TAG, "Permission Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid=" + r.callingPid
+                        + ", uid=" + r.callingUid + ")"
+                        + " is not exported from uid " + info.activityInfo.applicationInfo.uid
+                        + " due to receiver " + component.flattenToShortString());
+            } else {
+                Slog.w(TAG, "Permission Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid=" + r.callingPid
+                        + ", uid=" + r.callingUid + ")"
+                        + " requires " + info.activityInfo.permission
+                        + " due to receiver " + component.flattenToShortString());
+            }
+            skip = true;
+        } else if (!skip && info.activityInfo.permission != null) {
+            final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
+            if (opCode != AppOpsManager.OP_NONE
+                    && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+                            r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+                Slog.w(TAG, "Appop Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid="
+                        + r.callingPid + ", uid=" + r.callingUid + ")"
+                        + " requires appop " + AppOpsManager.permissionToOp(
+                                info.activityInfo.permission)
+                        + " due to registered receiver "
+                        + component.flattenToShortString());
                 skip = true;
             }
-            int perm = mService.checkComponentPermission(info.activityInfo.permission,
-                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
-                    info.activityInfo.exported);
-            if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
-                if (!info.activityInfo.exported) {
-                    Slog.w(TAG, "Permission Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid=" + r.callingPid
-                            + ", uid=" + r.callingUid + ")"
-                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
-                            + " due to receiver " + component.flattenToShortString());
-                } else {
-                    Slog.w(TAG, "Permission Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid=" + r.callingPid
-                            + ", uid=" + r.callingUid + ")"
-                            + " requires " + info.activityInfo.permission
-                            + " due to receiver " + component.flattenToShortString());
+        }
+        if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
+            r.requiredPermissions != null && r.requiredPermissions.length > 0) {
+            for (int i = 0; i < r.requiredPermissions.length; i++) {
+                String requiredPermission = r.requiredPermissions[i];
+                try {
+                    perm = AppGlobals.getPackageManager().
+                            checkPermission(requiredPermission,
+                                    info.activityInfo.applicationInfo.packageName,
+                                    UserHandle
+                                            .getUserId(info.activityInfo.applicationInfo.uid));
+                } catch (RemoteException e) {
+                    perm = PackageManager.PERMISSION_DENIED;
                 }
-                skip = true;
-            } else if (!skip && info.activityInfo.permission != null) {
-                final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
-                if (opCode != AppOpsManager.OP_NONE
-                        && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
-                                r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
-                    Slog.w(TAG, "Appop Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid="
-                            + r.callingPid + ", uid=" + r.callingUid + ")"
-                            + " requires appop " + AppOpsManager.permissionToOp(
-                                    info.activityInfo.permission)
-                            + " due to registered receiver "
-                            + component.flattenToShortString());
+                if (perm != PackageManager.PERMISSION_GRANTED) {
+                    Slog.w(TAG, "Permission Denial: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString()
+                            + " requires " + requiredPermission
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
                     skip = true;
+                    break;
                 }
-            }
-            if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
-                r.requiredPermissions != null && r.requiredPermissions.length > 0) {
-                for (int i = 0; i < r.requiredPermissions.length; i++) {
-                    String requiredPermission = r.requiredPermissions[i];
-                    try {
-                        perm = AppGlobals.getPackageManager().
-                                checkPermission(requiredPermission,
-                                        info.activityInfo.applicationInfo.packageName,
-                                        UserHandle
-                                                .getUserId(info.activityInfo.applicationInfo.uid));
-                    } catch (RemoteException e) {
-                        perm = PackageManager.PERMISSION_DENIED;
-                    }
-                    if (perm != PackageManager.PERMISSION_GRANTED) {
-                        Slog.w(TAG, "Permission Denial: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString()
-                                + " requires " + requiredPermission
-                                + " due to sender " + r.callerPackage
-                                + " (uid " + r.callingUid + ")");
-                        skip = true;
-                        break;
-                    }
-                    int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
-                    if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
-                            && mService.mAppOpsService.noteOperation(appOp,
-                            info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
-                            != AppOpsManager.MODE_ALLOWED) {
-                        Slog.w(TAG, "Appop Denial: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString()
-                                + " requires appop " + AppOpsManager.permissionToOp(
-                                requiredPermission)
-                                + " due to sender " + r.callerPackage
-                                + " (uid " + r.callingUid + ")");
-                        skip = true;
-                        break;
-                    }
+                int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
+                if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
+                        && mService.mAppOpsService.noteOperation(appOp,
+                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                        != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString()
+                            + " requires appop " + AppOpsManager.permissionToOp(
+                            requiredPermission)
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
+                    skip = true;
+                    break;
                 }
             }
-            if (!skip && r.appOp != AppOpsManager.OP_NONE
-                    && mService.mAppOpsService.noteOperation(r.appOp,
-                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
-                    != AppOpsManager.MODE_ALLOWED) {
-                Slog.w(TAG, "Appop Denial: receiving "
-                        + r.intent + " to "
-                        + component.flattenToShortString()
-                        + " requires appop " + AppOpsManager.opToName(r.appOp)
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")");
+        }
+        if (!skip && r.appOp != AppOpsManager.OP_NONE
+                && mService.mAppOpsService.noteOperation(r.appOp,
+                info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                != AppOpsManager.MODE_ALLOWED) {
+            Slog.w(TAG, "Appop Denial: receiving "
+                    + r.intent + " to "
+                    + component.flattenToShortString()
+                    + " requires appop " + AppOpsManager.opToName(r.appOp)
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")");
+            skip = true;
+        }
+        if (!skip) {
+            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+                    r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
+        }
+        boolean isSingleton = false;
+        try {
+            isSingleton = mService.isSingleton(info.activityInfo.processName,
+                    info.activityInfo.applicationInfo,
+                    info.activityInfo.name, info.activityInfo.flags);
+        } catch (SecurityException e) {
+            Slog.w(TAG, e.getMessage());
+            skip = true;
+        }
+        if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
+            if (ActivityManager.checkUidPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS,
+                    info.activityInfo.applicationInfo.uid)
+                            != PackageManager.PERMISSION_GRANTED) {
+                Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
+                        + " requests FLAG_SINGLE_USER, but app does not hold "
+                        + android.Manifest.permission.INTERACT_ACROSS_USERS);
                 skip = true;
             }
-            if (!skip) {
-                skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
-                        r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
-            }
-            boolean isSingleton = false;
+        }
+        if (!skip && info.activityInfo.applicationInfo.isInstantApp()
+                && r.callingUid != info.activityInfo.applicationInfo.uid) {
+            Slog.w(TAG, "Instant App Denial: receiving "
+                    + r.intent
+                    + " to " + component.flattenToShortString()
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")"
+                    + " Instant Apps do not support manifest receivers");
+            skip = true;
+        }
+        if (!skip && r.callerInstantApp
+                && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
+                && r.callingUid != info.activityInfo.applicationInfo.uid) {
+            Slog.w(TAG, "Instant App Denial: receiving "
+                    + r.intent
+                    + " to " + component.flattenToShortString()
+                    + " requires receiver have visibleToInstantApps set"
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")");
+            skip = true;
+        }
+        if (r.curApp != null && r.curApp.crashing) {
+            // If the target process is crashing, just skip it.
+            Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
+                    + " to " + r.curApp + ": process crashing");
+            skip = true;
+        }
+        if (!skip) {
+            boolean isAvailable = false;
             try {
-                isSingleton = mService.isSingleton(info.activityInfo.processName,
-                        info.activityInfo.applicationInfo,
-                        info.activityInfo.name, info.activityInfo.flags);
-            } catch (SecurityException e) {
-                Slog.w(TAG, e.getMessage());
-                skip = true;
-            }
-            if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
-                if (ActivityManager.checkUidPermission(
-                        android.Manifest.permission.INTERACT_ACROSS_USERS,
-                        info.activityInfo.applicationInfo.uid)
-                                != PackageManager.PERMISSION_GRANTED) {
-                    Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
-                            + " requests FLAG_SINGLE_USER, but app does not hold "
-                            + android.Manifest.permission.INTERACT_ACROSS_USERS);
-                    skip = true;
-                }
-            }
-            if (!skip && info.activityInfo.applicationInfo.isInstantApp()
-                    && r.callingUid != info.activityInfo.applicationInfo.uid) {
-                Slog.w(TAG, "Instant App Denial: receiving "
-                        + r.intent
-                        + " to " + component.flattenToShortString()
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")"
-                        + " Instant Apps do not support manifest receivers");
-                skip = true;
+                isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
+                        info.activityInfo.packageName,
+                        UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
+            } catch (Exception e) {
+                // all such failures mean we skip this receiver
+                Slog.w(TAG, "Exception getting recipient info for "
+                        + info.activityInfo.packageName, e);
             }
-            if (!skip && r.callerInstantApp
-                    && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
-                    && r.callingUid != info.activityInfo.applicationInfo.uid) {
-                Slog.w(TAG, "Instant App Denial: receiving "
-                        + r.intent
-                        + " to " + component.flattenToShortString()
-                        + " requires receiver have visibleToInstantApps set"
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")");
+            if (!isAvailable) {
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
+                        "Skipping delivery to " + info.activityInfo.packageName + " / "
+                        + info.activityInfo.applicationInfo.uid
+                        + " : package no longer available");
                 skip = true;
             }
-            if (r.curApp != null && r.curApp.crashing) {
-                // If the target process is crashing, just skip it.
-                Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
-                        + " to " + r.curApp + ": process crashing");
+        }
+
+        // If permissions need a review before any of the app components can run, we drop
+        // the broadcast and if the calling app is in the foreground and the broadcast is
+        // explicit we launch the review UI passing it a pending intent to send the skipped
+        // broadcast.
+        if (mService.mPermissionReviewRequired && !skip) {
+            if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
+                    info.activityInfo.packageName, UserHandle.getUserId(
+                            info.activityInfo.applicationInfo.uid))) {
                 skip = true;
             }
-            if (!skip) {
-                boolean isAvailable = false;
-                try {
-                    isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
-                            info.activityInfo.packageName,
-                            UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
-                } catch (Exception e) {
-                    // all such failures mean we skip this receiver
-                    Slog.w(TAG, "Exception getting recipient info for "
-                            + info.activityInfo.packageName, e);
-                }
-                if (!isAvailable) {
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
-                            "Skipping delivery to " + info.activityInfo.packageName + " / "
-                            + info.activityInfo.applicationInfo.uid
-                            + " : package no longer available");
-                    skip = true;
-                }
-            }
+        }
 
-            // If permissions need a review before any of the app components can run, we drop
-            // the broadcast and if the calling app is in the foreground and the broadcast is
-            // explicit we launch the review UI passing it a pending intent to send the skipped
-            // broadcast.
-            if (mService.mPermissionReviewRequired && !skip) {
-                if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
-                        info.activityInfo.packageName, UserHandle.getUserId(
-                                info.activityInfo.applicationInfo.uid))) {
+        // This is safe to do even if we are skipping the broadcast, and we need
+        // this information now to evaluate whether it is going to be allowed to run.
+        final int receiverUid = info.activityInfo.applicationInfo.uid;
+        // If it's a singleton, it needs to be the same app or a special app
+        if (r.callingUid != Process.SYSTEM_UID && isSingleton
+                && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
+            info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
+        }
+        String targetProcess = info.activityInfo.processName;
+        ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
+                info.activityInfo.applicationInfo.uid, false);
+
+        if (!skip) {
+            final int allowed = mService.getAppStartModeLocked(
+                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
+                    info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
+            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
+                // We won't allow this receiver to be launched if the app has been
+                // completely disabled from launches, or it was not explicitly sent
+                // to it and the app is in a state that should not receive it
+                // (depending on how getAppStartModeLocked has determined that).
+                if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
+                    Slog.w(TAG, "Background execution disabled: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString());
+                    skip = true;
+                } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
+                        || (r.intent.getComponent() == null
+                            && r.intent.getPackage() == null
+                            && ((r.intent.getFlags()
+                                    & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
+                            && !isSignaturePerm(r.requiredPermissions))) {
+                    mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
+                            component.getPackageName());
+                    Slog.w(TAG, "Background execution not allowed: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString());
                     skip = true;
                 }
             }
+        }
 
-            // This is safe to do even if we are skipping the broadcast, and we need
-            // this information now to evaluate whether it is going to be allowed to run.
-            final int receiverUid = info.activityInfo.applicationInfo.uid;
-            // If it's a singleton, it needs to be the same app or a special app
-            if (r.callingUid != Process.SYSTEM_UID && isSingleton
-                    && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
-                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
-            }
-            String targetProcess = info.activityInfo.processName;
-            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
-                    info.activityInfo.applicationInfo.uid, false);
-
-            if (!skip) {
-                final int allowed = mService.getAppStartModeLocked(
-                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
-                        info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
-                if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
-                    // We won't allow this receiver to be launched if the app has been
-                    // completely disabled from launches, or it was not explicitly sent
-                    // to it and the app is in a state that should not receive it
-                    // (depending on how getAppStartModeLocked has determined that).
-                    if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
-                        Slog.w(TAG, "Background execution disabled: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString());
-                        skip = true;
-                    } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
-                            || (r.intent.getComponent() == null
-                                && r.intent.getPackage() == null
-                                && ((r.intent.getFlags()
-                                        & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
-                                && !isSignaturePerm(r.requiredPermissions))) {
-                        mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
-                                component.getPackageName());
-                        Slog.w(TAG, "Background execution not allowed: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString());
-                        skip = true;
-                    }
-                }
-            }
+        if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
+                && !mService.mUserController
+                .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
+                        0 /* flags */)) {
+            skip = true;
+            Slog.w(TAG,
+                    "Skipping delivery to " + info.activityInfo.packageName + " / "
+                            + info.activityInfo.applicationInfo.uid + " : user is not running");
+        }
 
-            if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
-                    && !mService.mUserController
-                    .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
-                            0 /* flags */)) {
-                skip = true;
-                Slog.w(TAG,
-                        "Skipping delivery to " + info.activityInfo.packageName + " / "
-                                + info.activityInfo.applicationInfo.uid + " : user is not running");
-            }
+        if (skip) {
+            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                    "Skipping delivery of ordered [" + mQueueName + "] "
+                    + r + " for whatever reason");
+            r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
+            r.receiver = null;
+            r.curFilter = null;
+            r.state = BroadcastRecord.IDLE;
+            r.manifestSkipCount++;
+            scheduleBroadcastsLocked();
+            return;
+        }
+        r.manifestCount++;
 
-            if (skip) {
-                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                        "Skipping delivery of ordered [" + mQueueName + "] "
-                        + r + " for whatever reason");
-                r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
-                r.receiver = null;
-                r.curFilter = null;
-                r.state = BroadcastRecord.IDLE;
-                r.manifestSkipCount++;
-                scheduleBroadcastsLocked();
-                return;
-            }
-            r.manifestCount++;
-
-            r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
-            r.state = BroadcastRecord.APP_RECEIVE;
-            r.curComponent = component;
-            r.curReceiver = info.activityInfo;
-            if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
-                Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
-                        + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
-                        + receiverUid);
-            }
+        r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
+        r.state = BroadcastRecord.APP_RECEIVE;
+        r.curComponent = component;
+        r.curReceiver = info.activityInfo;
+        if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
+            Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
+                    + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
+                    + receiverUid);
+        }
 
-            if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
-                scheduleTempWhitelistLocked(receiverUid,
-                        brOptions.getTemporaryAppWhitelistDuration(), r);
-            }
+        if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
+            scheduleTempWhitelistLocked(receiverUid,
+                    brOptions.getTemporaryAppWhitelistDuration(), r);
+        }
+
+        // Broadcast is being executed, its package can't be stopped.
+        try {
+            AppGlobals.getPackageManager().setPackageStoppedState(
+                    r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
+        } catch (RemoteException e) {
+        } catch (IllegalArgumentException e) {
+            Slog.w(TAG, "Failed trying to unstop package "
+                    + r.curComponent.getPackageName() + ": " + e);
+        }
 
-            // Broadcast is being executed, its package can't be stopped.
+        // Is this receiver's application already running?
+        if (app != null && app.thread != null && !app.killed) {
             try {
-                AppGlobals.getPackageManager().setPackageStoppedState(
-                        r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
+                app.addPackage(info.activityInfo.packageName,
+                        info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
+                processCurBroadcastLocked(r, app, skipOomAdj);
+                return;
             } catch (RemoteException e) {
-            } catch (IllegalArgumentException e) {
-                Slog.w(TAG, "Failed trying to unstop package "
-                        + r.curComponent.getPackageName() + ": " + e);
-            }
-
-            // Is this receiver's application already running?
-            if (app != null && app.thread != null && !app.killed) {
-                try {
-                    app.addPackage(info.activityInfo.packageName,
-                            info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
-                    processCurBroadcastLocked(r, app);
-                    return;
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception when sending broadcast to "
-                          + r.curComponent, e);
-                } catch (RuntimeException e) {
-                    Slog.wtf(TAG, "Failed sending broadcast to "
-                            + r.curComponent + " with " + r.intent, e);
-                    // If some unexpected exception happened, just skip
-                    // this broadcast.  At this point we are not in the call
-                    // from a client, so throwing an exception out from here
-                    // will crash the entire system instead of just whoever
-                    // sent the broadcast.
-                    logBroadcastReceiverDiscardLocked(r);
-                    finishReceiverLocked(r, r.resultCode, r.resultData,
-                            r.resultExtras, r.resultAbort, false);
-                    scheduleBroadcastsLocked();
-                    // We need to reset the state if we failed to start the receiver.
-                    r.state = BroadcastRecord.IDLE;
-                    return;
-                }
-
-                // If a dead object exception was thrown -- fall through to
-                // restart the application.
-            }
-
-            // Not running -- get it started, to be executed when the app comes up.
-            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                    "Need to start app ["
-                    + mQueueName + "] " + targetProcess + " for broadcast " + r);
-            if ((r.curApp=mService.startProcessLocked(targetProcess,
-                    info.activityInfo.applicationInfo, true,
-                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
-                    "broadcast", r.curComponent,
-                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
-                            == null) {
-                // Ah, this recipient is unavailable.  Finish it if necessary,
-                // and mark the broadcast record as ready for the next.
-                Slog.w(TAG, "Unable to launch app "
-                        + info.activityInfo.applicationInfo.packageName + "/"
-                        + receiverUid + " for broadcast "
-                        + r.intent + ": process is bad");
+                Slog.w(TAG, "Exception when sending broadcast to "
+                      + r.curComponent, e);
+            } catch (RuntimeException e) {
+                Slog.wtf(TAG, "Failed sending broadcast to "
+                        + r.curComponent + " with " + r.intent, e);
+                // If some unexpected exception happened, just skip
+                // this broadcast.  At this point we are not in the call
+                // from a client, so throwing an exception out from here
+                // will crash the entire system instead of just whoever
+                // sent the broadcast.
                 logBroadcastReceiverDiscardLocked(r);
                 finishReceiverLocked(r, r.resultCode, r.resultData,
                         r.resultExtras, r.resultAbort, false);
                 scheduleBroadcastsLocked();
+                // We need to reset the state if we failed to start the receiver.
                 r.state = BroadcastRecord.IDLE;
                 return;
             }
 
-            mPendingBroadcast = r;
-            mPendingBroadcastRecvIndex = recIdx;
+            // If a dead object exception was thrown -- fall through to
+            // restart the application.
         }
+
+        // Not running -- get it started, to be executed when the app comes up.
+        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                "Need to start app ["
+                + mQueueName + "] " + targetProcess + " for broadcast " + r);
+        if ((r.curApp=mService.startProcessLocked(targetProcess,
+                info.activityInfo.applicationInfo, true,
+                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
+                "broadcast", r.curComponent,
+                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
+                        == null) {
+            // Ah, this recipient is unavailable.  Finish it if necessary,
+            // and mark the broadcast record as ready for the next.
+            Slog.w(TAG, "Unable to launch app "
+                    + info.activityInfo.applicationInfo.packageName + "/"
+                    + receiverUid + " for broadcast "
+                    + r.intent + ": process is bad");
+            logBroadcastReceiverDiscardLocked(r);
+            finishReceiverLocked(r, r.resultCode, r.resultData,
+                    r.resultExtras, r.resultAbort, false);
+            scheduleBroadcastsLocked();
+            r.state = BroadcastRecord.IDLE;
+            return;
+        }
+
+        mPendingBroadcast = r;
+        mPendingBroadcastRecvIndex = recIdx;
     }
 
     final void setBroadcastTimeoutLocked(long timeoutTime) {