BroadcastQueue.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import java.io.FileDescriptor;
20import java.io.PrintWriter;
21import java.util.ArrayList;
22
23import android.app.ActivityManager;
24import android.app.AppGlobals;
25import android.app.AppOpsManager;
26import android.content.ComponentName;
27import android.content.IIntentReceiver;
28import android.content.Intent;
29import android.content.pm.ActivityInfo;
30import android.content.pm.PackageInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.ResolveInfo;
33import android.os.Bundle;
34import android.os.Handler;
35import android.os.IBinder;
36import android.os.Message;
37import android.os.Process;
38import android.os.RemoteException;
39import android.os.SystemClock;
40import android.os.UserHandle;
41import android.util.EventLog;
42import android.util.Log;
43import android.util.Slog;
44
45/**
46 * BROADCASTS
47 *
48 * We keep two broadcast queues and associated bookkeeping, one for those at
49 * foreground priority, and one for normal (background-priority) broadcasts.
50 */
51public final class BroadcastQueue {
52    static final String TAG = "BroadcastQueue";
53    static final String TAG_MU = ActivityManagerService.TAG_MU;
54    static final boolean DEBUG_BROADCAST = ActivityManagerService.DEBUG_BROADCAST;
55    static final boolean DEBUG_BROADCAST_LIGHT = ActivityManagerService.DEBUG_BROADCAST_LIGHT;
56    static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
57
58    static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 50;
59    static final int MAX_BROADCAST_SUMMARY_HISTORY
60            = ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
61
62    final ActivityManagerService mService;
63
64    /**
65     * Recognizable moniker for this queue
66     */
67    final String mQueueName;
68
69    /**
70     * Timeout period for this queue's broadcasts
71     */
72    final long mTimeoutPeriod;
73
74    /**
75     * If true, we can delay broadcasts while waiting services to finish in the previous
76     * receiver's process.
77     */
78    final boolean mDelayBehindServices;
79
80    /**
81     * Lists of all active broadcasts that are to be executed immediately
82     * (without waiting for another broadcast to finish).  Currently this only
83     * contains broadcasts to registered receivers, to avoid spinning up
84     * a bunch of processes to execute IntentReceiver components.  Background-
85     * and foreground-priority broadcasts are queued separately.
86     */
87    final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>();
88
89    /**
90     * List of all active broadcasts that are to be executed one at a time.
91     * The object at the top of the list is the currently activity broadcasts;
92     * those after it are waiting for the top to finish.  As with parallel
93     * broadcasts, separate background- and foreground-priority queues are
94     * maintained.
95     */
96    final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>();
97
98    /**
99     * Historical data of past broadcasts, for debugging.
100     */
101    final BroadcastRecord[] mBroadcastHistory = new BroadcastRecord[MAX_BROADCAST_HISTORY];
102
103    /**
104     * Summary of historical data of past broadcasts, for debugging.
105     */
106    final Intent[] mBroadcastSummaryHistory = new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
107
108    /**
109     * Set when we current have a BROADCAST_INTENT_MSG in flight.
110     */
111    boolean mBroadcastsScheduled = false;
112
113    /**
114     * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
115     */
116    boolean mPendingBroadcastTimeoutMessage;
117
118    /**
119     * Intent broadcasts that we have tried to start, but are
120     * waiting for the application's process to be created.  We only
121     * need one per scheduling class (instead of a list) because we always
122     * process broadcasts one at a time, so no others can be started while
123     * waiting for this one.
124     */
125    BroadcastRecord mPendingBroadcast = null;
126
127    /**
128     * The receiver index that is pending, to restart the broadcast if needed.
129     */
130    int mPendingBroadcastRecvIndex;
131
132    static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
133    static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
134
135    final Handler mHandler = new Handler() {
136        public void handleMessage(Message msg) {
137            switch (msg.what) {
138                case BROADCAST_INTENT_MSG: {
139                    if (DEBUG_BROADCAST) Slog.v(
140                            TAG, "Received BROADCAST_INTENT_MSG");
141                    processNextBroadcast(true);
142                } break;
143                case BROADCAST_TIMEOUT_MSG: {
144                    synchronized (mService) {
145                        broadcastTimeoutLocked(true);
146                    }
147                } break;
148            }
149        }
150    };
151
152    private final class AppNotResponding implements Runnable {
153        private final ProcessRecord mApp;
154        private final String mAnnotation;
155
156        public AppNotResponding(ProcessRecord app, String annotation) {
157            mApp = app;
158            mAnnotation = annotation;
159        }
160
161        @Override
162        public void run() {
163            mService.appNotResponding(mApp, null, null, false, mAnnotation);
164        }
165    }
166
167    BroadcastQueue(ActivityManagerService service, String name, long timeoutPeriod,
168            boolean allowDelayBehindServices) {
169        mService = service;
170        mQueueName = name;
171        mTimeoutPeriod = timeoutPeriod;
172        mDelayBehindServices = allowDelayBehindServices;
173    }
174
175    public boolean isPendingBroadcastProcessLocked(int pid) {
176        return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
177    }
178
179    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
180        mParallelBroadcasts.add(r);
181    }
182
183    public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
184        mOrderedBroadcasts.add(r);
185    }
186
187    public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
188        for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
189            if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
190                if (DEBUG_BROADCAST) Slog.v(TAG,
191                        "***** DROPPING PARALLEL ["
192                + mQueueName + "]: " + r.intent);
193                mParallelBroadcasts.set(i, r);
194                return true;
195            }
196        }
197        return false;
198    }
199
200    public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
201        for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
202            if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
203                if (DEBUG_BROADCAST) Slog.v(TAG,
204                        "***** DROPPING ORDERED ["
205                        + mQueueName + "]: " + r.intent);
206                mOrderedBroadcasts.set(i, r);
207                return true;
208            }
209        }
210        return false;
211    }
212
213    private final void processCurBroadcastLocked(BroadcastRecord r,
214            ProcessRecord app) throws RemoteException {
215        if (DEBUG_BROADCAST)  Slog.v(TAG,
216                "Process cur broadcast " + r + " for app " + app);
217        if (app.thread == null) {
218            throw new RemoteException();
219        }
220        r.receiver = app.thread.asBinder();
221        r.curApp = app;
222        app.curReceiver = r;
223        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
224        mService.updateLruProcessLocked(app, false, null);
225        mService.updateOomAdjLocked();
226
227        // Tell the application to launch this receiver.
228        r.intent.setComponent(r.curComponent);
229
230        boolean started = false;
231        try {
232            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
233                    "Delivering to component " + r.curComponent
234                    + ": " + r);
235            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
236            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
237                    mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
238                    r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
239                    app.repProcState);
240            if (DEBUG_BROADCAST)  Slog.v(TAG,
241                    "Process cur broadcast " + r + " DELIVERED for app " + app);
242            started = true;
243        } finally {
244            if (!started) {
245                if (DEBUG_BROADCAST)  Slog.v(TAG,
246                        "Process cur broadcast " + r + ": NOT STARTED!");
247                r.receiver = null;
248                r.curApp = null;
249                app.curReceiver = null;
250            }
251        }
252    }
253
254    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
255        boolean didSomething = false;
256        final BroadcastRecord br = mPendingBroadcast;
257        if (br != null && br.curApp.pid == app.pid) {
258            try {
259                mPendingBroadcast = null;
260                processCurBroadcastLocked(br, app);
261                didSomething = true;
262            } catch (Exception e) {
263                Slog.w(TAG, "Exception in new application when starting receiver "
264                        + br.curComponent.flattenToShortString(), e);
265                logBroadcastReceiverDiscardLocked(br);
266                finishReceiverLocked(br, br.resultCode, br.resultData,
267                        br.resultExtras, br.resultAbort, false);
268                scheduleBroadcastsLocked();
269                // We need to reset the state if we failed to start the receiver.
270                br.state = BroadcastRecord.IDLE;
271                throw new RuntimeException(e.getMessage());
272            }
273        }
274        return didSomething;
275    }
276
277    public void skipPendingBroadcastLocked(int pid) {
278        final BroadcastRecord br = mPendingBroadcast;
279        if (br != null && br.curApp.pid == pid) {
280            br.state = BroadcastRecord.IDLE;
281            br.nextReceiver = mPendingBroadcastRecvIndex;
282            mPendingBroadcast = null;
283            scheduleBroadcastsLocked();
284        }
285    }
286
287    public void skipCurrentReceiverLocked(ProcessRecord app) {
288        boolean reschedule = false;
289        BroadcastRecord r = app.curReceiver;
290        if (r != null) {
291            // The current broadcast is waiting for this app's receiver
292            // to be finished.  Looks like that's not going to happen, so
293            // let the broadcast continue.
294            logBroadcastReceiverDiscardLocked(r);
295            finishReceiverLocked(r, r.resultCode, r.resultData,
296                    r.resultExtras, r.resultAbort, false);
297            reschedule = true;
298        }
299
300        r = mPendingBroadcast;
301        if (r != null && r.curApp == app) {
302            if (DEBUG_BROADCAST) Slog.v(TAG,
303                    "[" + mQueueName + "] skip & discard pending app " + r);
304            logBroadcastReceiverDiscardLocked(r);
305            finishReceiverLocked(r, r.resultCode, r.resultData,
306                    r.resultExtras, r.resultAbort, false);
307            reschedule = true;
308        }
309        if (reschedule) {
310            scheduleBroadcastsLocked();
311        }
312    }
313
314    public void scheduleBroadcastsLocked() {
315        if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
316                + mQueueName + "]: current="
317                + mBroadcastsScheduled);
318
319        if (mBroadcastsScheduled) {
320            return;
321        }
322        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
323        mBroadcastsScheduled = true;
324    }
325
326    public BroadcastRecord getMatchingOrderedReceiver(IBinder receiver) {
327        if (mOrderedBroadcasts.size() > 0) {
328            final BroadcastRecord r = mOrderedBroadcasts.get(0);
329            if (r != null && r.receiver == receiver) {
330                return r;
331            }
332        }
333        return null;
334    }
335
336    public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
337            String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
338        final int state = r.state;
339        final ActivityInfo receiver = r.curReceiver;
340        r.state = BroadcastRecord.IDLE;
341        if (state == BroadcastRecord.IDLE) {
342            Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
343        }
344        r.receiver = null;
345        r.intent.setComponent(null);
346        if (r.curApp != null) {
347            r.curApp.curReceiver = null;
348        }
349        if (r.curFilter != null) {
350            r.curFilter.receiverList.curBroadcast = null;
351        }
352        r.curFilter = null;
353        r.curReceiver = null;
354        r.curApp = null;
355        mPendingBroadcast = null;
356
357        r.resultCode = resultCode;
358        r.resultData = resultData;
359        r.resultExtras = resultExtras;
360        if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
361            r.resultAbort = resultAbort;
362        } else {
363            r.resultAbort = false;
364        }
365
366        if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
367                && r.queue.mOrderedBroadcasts.size() > 0
368                && r.queue.mOrderedBroadcasts.get(0) == r) {
369            ActivityInfo nextReceiver;
370            if (r.nextReceiver < r.receivers.size()) {
371                Object obj = r.receivers.get(r.nextReceiver);
372                nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
373            } else {
374                nextReceiver = null;
375            }
376            // Don't do this if the next receive is in the same process as the current one.
377            if (receiver == null || nextReceiver == null
378                    || receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
379                    || !receiver.processName.equals(nextReceiver.processName)) {
380                // In this case, we are ready to process the next receiver for the current broadcast,
381                // but are on a queue that would like to wait for services to finish before moving
382                // on.  If there are background services currently starting, then we will go into a
383                // special state where we hold off on continuing this broadcast until they are done.
384                if (mService.mServices.hasBackgroundServices(r.userId)) {
385                    Slog.i(ActivityManagerService.TAG, "Delay finish: "
386                            + r.curComponent.flattenToShortString());
387                    r.state = BroadcastRecord.WAITING_SERVICES;
388                    return false;
389                }
390            }
391        }
392
393        r.curComponent = null;
394
395        // We will process the next receiver right now if this is finishing
396        // an app receiver (which is always asynchronous) or after we have
397        // come back from calling a receiver.
398        return state == BroadcastRecord.APP_RECEIVE
399                || state == BroadcastRecord.CALL_DONE_RECEIVE;
400    }
401
402    public void backgroundServicesFinishedLocked(int userId) {
403        if (mOrderedBroadcasts.size() > 0) {
404            BroadcastRecord br = mOrderedBroadcasts.get(0);
405            if (br.userId == userId && br.state == BroadcastRecord.WAITING_SERVICES) {
406                Slog.i(ActivityManagerService.TAG, "Resuming delayed broadcast");
407                br.curComponent = null;
408                br.state = BroadcastRecord.IDLE;
409                processNextBroadcast(false);
410            }
411        }
412    }
413
414    private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
415            Intent intent, int resultCode, String data, Bundle extras,
416            boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
417        // Send the intent to the receiver asynchronously using one-way binder calls.
418        if (app != null && app.thread != null) {
419            // If we have an app thread, do the call through that so it is
420            // correctly ordered with other one-way calls.
421            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
422                    data, extras, ordered, sticky, sendingUser, app.repProcState);
423        } else {
424            receiver.performReceive(intent, resultCode, data, extras, ordered,
425                    sticky, sendingUser);
426        }
427    }
428
429    private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
430            BroadcastFilter filter, boolean ordered) {
431        boolean skip = false;
432        if (filter.requiredPermission != null) {
433            int perm = mService.checkComponentPermission(filter.requiredPermission,
434                    r.callingPid, r.callingUid, -1, true);
435            if (perm != PackageManager.PERMISSION_GRANTED) {
436                Slog.w(TAG, "Permission Denial: broadcasting "
437                        + r.intent.toString()
438                        + " from " + r.callerPackage + " (pid="
439                        + r.callingPid + ", uid=" + r.callingUid + ")"
440                        + " requires " + filter.requiredPermission
441                        + " due to registered receiver " + filter);
442                skip = true;
443            }
444        }
445        if (!skip && r.requiredPermission != null) {
446            int perm = mService.checkComponentPermission(r.requiredPermission,
447                    filter.receiverList.pid, filter.receiverList.uid, -1, true);
448            if (perm != PackageManager.PERMISSION_GRANTED) {
449                Slog.w(TAG, "Permission Denial: receiving "
450                        + r.intent.toString()
451                        + " to " + filter.receiverList.app
452                        + " (pid=" + filter.receiverList.pid
453                        + ", uid=" + filter.receiverList.uid + ")"
454                        + " requires " + r.requiredPermission
455                        + " due to sender " + r.callerPackage
456                        + " (uid " + r.callingUid + ")");
457                skip = true;
458            }
459        }
460        if (r.appOp != AppOpsManager.OP_NONE) {
461            int mode = mService.mAppOpsService.noteOperation(r.appOp,
462                    filter.receiverList.uid, filter.packageName);
463            if (mode != AppOpsManager.MODE_ALLOWED) {
464                if (DEBUG_BROADCAST)  Slog.v(TAG,
465                        "App op " + r.appOp + " not allowed for broadcast to uid "
466                        + filter.receiverList.uid + " pkg " + filter.packageName);
467                skip = true;
468            }
469        }
470        if (!skip) {
471            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
472                    r.callingPid, r.resolvedType, filter.receiverList.uid);
473        }
474
475        if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
476            Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
477                    + " to " + filter.receiverList + ": process crashing");
478            skip = true;
479        }
480
481        if (!skip) {
482            // If this is not being sent as an ordered broadcast, then we
483            // don't want to touch the fields that keep track of the current
484            // state of ordered broadcasts.
485            if (ordered) {
486                r.receiver = filter.receiverList.receiver.asBinder();
487                r.curFilter = filter;
488                filter.receiverList.curBroadcast = r;
489                r.state = BroadcastRecord.CALL_IN_RECEIVE;
490                if (filter.receiverList.app != null) {
491                    // Bump hosting application to no longer be in background
492                    // scheduling class.  Note that we can't do that if there
493                    // isn't an app...  but we can only be in that case for
494                    // things that directly call the IActivityManager API, which
495                    // are already core system stuff so don't matter for this.
496                    r.curApp = filter.receiverList.app;
497                    filter.receiverList.app.curReceiver = r;
498                    mService.updateOomAdjLocked(r.curApp, true);
499                }
500            }
501            try {
502                if (DEBUG_BROADCAST_LIGHT) {
503                    int seq = r.intent.getIntExtra("seq", -1);
504                    Slog.i(TAG, "Delivering to " + filter
505                            + " (seq=" + seq + "): " + r);
506                }
507                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
508                    new Intent(r.intent), r.resultCode, r.resultData,
509                    r.resultExtras, r.ordered, r.initialSticky, r.userId);
510                if (ordered) {
511                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
512                }
513            } catch (RemoteException e) {
514                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
515                if (ordered) {
516                    r.receiver = null;
517                    r.curFilter = null;
518                    filter.receiverList.curBroadcast = null;
519                    if (filter.receiverList.app != null) {
520                        filter.receiverList.app.curReceiver = null;
521                    }
522                }
523            }
524        }
525    }
526
527    final void processNextBroadcast(boolean fromMsg) {
528        synchronized(mService) {
529            BroadcastRecord r;
530
531            if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast ["
532                    + mQueueName + "]: "
533                    + mParallelBroadcasts.size() + " broadcasts, "
534                    + mOrderedBroadcasts.size() + " ordered broadcasts");
535
536            mService.updateCpuStats();
537
538            if (fromMsg) {
539                mBroadcastsScheduled = false;
540            }
541
542            // First, deliver any non-serialized broadcasts right away.
543            while (mParallelBroadcasts.size() > 0) {
544                r = mParallelBroadcasts.remove(0);
545                r.dispatchTime = SystemClock.uptimeMillis();
546                r.dispatchClockTime = System.currentTimeMillis();
547                final int N = r.receivers.size();
548                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
549                        + mQueueName + "] " + r);
550                for (int i=0; i<N; i++) {
551                    Object target = r.receivers.get(i);
552                    if (DEBUG_BROADCAST)  Slog.v(TAG,
553                            "Delivering non-ordered on [" + mQueueName + "] to registered "
554                            + target + ": " + r);
555                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
556                }
557                addBroadcastToHistoryLocked(r);
558                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
559                        + mQueueName + "] " + r);
560            }
561
562            // Now take care of the next serialized one...
563
564            // If we are waiting for a process to come up to handle the next
565            // broadcast, then do nothing at this point.  Just in case, we
566            // check that the process we're waiting for still exists.
567            if (mPendingBroadcast != null) {
568                if (DEBUG_BROADCAST_LIGHT) {
569                    Slog.v(TAG, "processNextBroadcast ["
570                            + mQueueName + "]: waiting for "
571                            + mPendingBroadcast.curApp);
572                }
573
574                boolean isDead;
575                synchronized (mService.mPidsSelfLocked) {
576                    ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
577                    isDead = proc == null || proc.crashing;
578                }
579                if (!isDead) {
580                    // It's still alive, so keep waiting
581                    return;
582                } else {
583                    Slog.w(TAG, "pending app  ["
584                            + mQueueName + "]" + mPendingBroadcast.curApp
585                            + " died before responding to broadcast");
586                    mPendingBroadcast.state = BroadcastRecord.IDLE;
587                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
588                    mPendingBroadcast = null;
589                }
590            }
591
592            boolean looped = false;
593
594            do {
595                if (mOrderedBroadcasts.size() == 0) {
596                    // No more broadcasts pending, so all done!
597                    mService.scheduleAppGcsLocked();
598                    if (looped) {
599                        // If we had finished the last ordered broadcast, then
600                        // make sure all processes have correct oom and sched
601                        // adjustments.
602                        mService.updateOomAdjLocked();
603                    }
604                    return;
605                }
606                r = mOrderedBroadcasts.get(0);
607                boolean forceReceive = false;
608
609                // Ensure that even if something goes awry with the timeout
610                // detection, we catch "hung" broadcasts here, discard them,
611                // and continue to make progress.
612                //
613                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
614                // receivers don't get executed with timeouts. They're intended for
615                // one time heavy lifting after system upgrades and can take
616                // significant amounts of time.
617                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
618                if (mService.mProcessesReady && r.dispatchTime > 0) {
619                    long now = SystemClock.uptimeMillis();
620                    if ((numReceivers > 0) &&
621                            (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
622                        Slog.w(TAG, "Hung broadcast ["
623                                + mQueueName + "] discarded after timeout failure:"
624                                + " now=" + now
625                                + " dispatchTime=" + r.dispatchTime
626                                + " startTime=" + r.receiverTime
627                                + " intent=" + r.intent
628                                + " numReceivers=" + numReceivers
629                                + " nextReceiver=" + r.nextReceiver
630                                + " state=" + r.state);
631                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
632                        forceReceive = true;
633                        r.state = BroadcastRecord.IDLE;
634                    }
635                }
636
637                if (r.state != BroadcastRecord.IDLE) {
638                    if (DEBUG_BROADCAST) Slog.d(TAG,
639                            "processNextBroadcast("
640                            + mQueueName + ") called when not idle (state="
641                            + r.state + ")");
642                    return;
643                }
644
645                if (r.receivers == null || r.nextReceiver >= numReceivers
646                        || r.resultAbort || forceReceive) {
647                    // No more receivers for this broadcast!  Send the final
648                    // result if requested...
649                    if (r.resultTo != null) {
650                        try {
651                            if (DEBUG_BROADCAST) {
652                                int seq = r.intent.getIntExtra("seq", -1);
653                                Slog.i(TAG, "Finishing broadcast ["
654                                        + mQueueName + "] " + r.intent.getAction()
655                                        + " seq=" + seq + " app=" + r.callerApp);
656                            }
657                            performReceiveLocked(r.callerApp, r.resultTo,
658                                new Intent(r.intent), r.resultCode,
659                                r.resultData, r.resultExtras, false, false, r.userId);
660                            // Set this to null so that the reference
661                            // (local and remote) isn't kept in the mBroadcastHistory.
662                            r.resultTo = null;
663                        } catch (RemoteException e) {
664                            Slog.w(TAG, "Failure ["
665                                    + mQueueName + "] sending broadcast result of "
666                                    + r.intent, e);
667                        }
668                    }
669
670                    if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
671                    cancelBroadcastTimeoutLocked();
672
673                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
674                            + r);
675
676                    // ... and on to the next...
677                    addBroadcastToHistoryLocked(r);
678                    mOrderedBroadcasts.remove(0);
679                    r = null;
680                    looped = true;
681                    continue;
682                }
683            } while (r == null);
684
685            // Get the next receiver...
686            int recIdx = r.nextReceiver++;
687
688            // Keep track of when this receiver started, and make sure there
689            // is a timeout message pending to kill it if need be.
690            r.receiverTime = SystemClock.uptimeMillis();
691            if (recIdx == 0) {
692                r.dispatchTime = r.receiverTime;
693                r.dispatchClockTime = System.currentTimeMillis();
694                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
695                        + mQueueName + "] " + r);
696            }
697            if (! mPendingBroadcastTimeoutMessage) {
698                long timeoutTime = r.receiverTime + mTimeoutPeriod;
699                if (DEBUG_BROADCAST) Slog.v(TAG,
700                        "Submitting BROADCAST_TIMEOUT_MSG ["
701                        + mQueueName + "] for " + r + " at " + timeoutTime);
702                setBroadcastTimeoutLocked(timeoutTime);
703            }
704
705            Object nextReceiver = r.receivers.get(recIdx);
706            if (nextReceiver instanceof BroadcastFilter) {
707                // Simple case: this is a registered receiver who gets
708                // a direct call.
709                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
710                if (DEBUG_BROADCAST)  Slog.v(TAG,
711                        "Delivering ordered ["
712                        + mQueueName + "] to registered "
713                        + filter + ": " + r);
714                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
715                if (r.receiver == null || !r.ordered) {
716                    // The receiver has already finished, so schedule to
717                    // process the next one.
718                    if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
719                            + mQueueName + "]: ordered="
720                            + r.ordered + " receiver=" + r.receiver);
721                    r.state = BroadcastRecord.IDLE;
722                    scheduleBroadcastsLocked();
723                }
724                return;
725            }
726
727            // Hard case: need to instantiate the receiver, possibly
728            // starting its application process to host it.
729
730            ResolveInfo info =
731                (ResolveInfo)nextReceiver;
732            ComponentName component = new ComponentName(
733                    info.activityInfo.applicationInfo.packageName,
734                    info.activityInfo.name);
735
736            boolean skip = false;
737            int perm = mService.checkComponentPermission(info.activityInfo.permission,
738                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
739                    info.activityInfo.exported);
740            if (perm != PackageManager.PERMISSION_GRANTED) {
741                if (!info.activityInfo.exported) {
742                    Slog.w(TAG, "Permission Denial: broadcasting "
743                            + r.intent.toString()
744                            + " from " + r.callerPackage + " (pid=" + r.callingPid
745                            + ", uid=" + r.callingUid + ")"
746                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
747                            + " due to receiver " + component.flattenToShortString());
748                } else {
749                    Slog.w(TAG, "Permission Denial: broadcasting "
750                            + r.intent.toString()
751                            + " from " + r.callerPackage + " (pid=" + r.callingPid
752                            + ", uid=" + r.callingUid + ")"
753                            + " requires " + info.activityInfo.permission
754                            + " due to receiver " + component.flattenToShortString());
755                }
756                skip = true;
757            }
758            if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
759                r.requiredPermission != null) {
760                try {
761                    perm = AppGlobals.getPackageManager().
762                            checkPermission(r.requiredPermission,
763                                    info.activityInfo.applicationInfo.packageName);
764                } catch (RemoteException e) {
765                    perm = PackageManager.PERMISSION_DENIED;
766                }
767                if (perm != PackageManager.PERMISSION_GRANTED) {
768                    Slog.w(TAG, "Permission Denial: receiving "
769                            + r.intent + " to "
770                            + component.flattenToShortString()
771                            + " requires " + r.requiredPermission
772                            + " due to sender " + r.callerPackage
773                            + " (uid " + r.callingUid + ")");
774                    skip = true;
775                }
776            }
777            if (r.appOp != AppOpsManager.OP_NONE) {
778                int mode = mService.mAppOpsService.noteOperation(r.appOp,
779                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
780                if (mode != AppOpsManager.MODE_ALLOWED) {
781                    if (DEBUG_BROADCAST)  Slog.v(TAG,
782                            "App op " + r.appOp + " not allowed for broadcast to uid "
783                            + info.activityInfo.applicationInfo.uid + " pkg "
784                            + info.activityInfo.packageName);
785                    skip = true;
786                }
787            }
788            if (!skip) {
789                skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
790                        r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
791            }
792            boolean isSingleton = false;
793            try {
794                isSingleton = mService.isSingleton(info.activityInfo.processName,
795                        info.activityInfo.applicationInfo,
796                        info.activityInfo.name, info.activityInfo.flags);
797            } catch (SecurityException e) {
798                Slog.w(TAG, e.getMessage());
799                skip = true;
800            }
801            if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
802                if (ActivityManager.checkUidPermission(
803                        android.Manifest.permission.INTERACT_ACROSS_USERS,
804                        info.activityInfo.applicationInfo.uid)
805                                != PackageManager.PERMISSION_GRANTED) {
806                    Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
807                            + " requests FLAG_SINGLE_USER, but app does not hold "
808                            + android.Manifest.permission.INTERACT_ACROSS_USERS);
809                    skip = true;
810                }
811            }
812            if (r.curApp != null && r.curApp.crashing) {
813                // If the target process is crashing, just skip it.
814                Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
815                        + " to " + r.curApp + ": process crashing");
816                skip = true;
817            }
818            if (!skip) {
819                boolean isAvailable = false;
820                try {
821                    isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
822                            info.activityInfo.packageName,
823                            UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
824                } catch (Exception e) {
825                    // all such failures mean we skip this receiver
826                    Slog.w(TAG, "Exception getting recipient info for "
827                            + info.activityInfo.packageName, e);
828                }
829                if (!isAvailable) {
830                    if (DEBUG_BROADCAST) {
831                        Slog.v(TAG, "Skipping delivery to " + info.activityInfo.packageName
832                                + " / " + info.activityInfo.applicationInfo.uid
833                                + " : package no longer available");
834                    }
835                    skip = true;
836                }
837            }
838
839            if (skip) {
840                if (DEBUG_BROADCAST)  Slog.v(TAG,
841                        "Skipping delivery of ordered ["
842                        + mQueueName + "] " + r + " for whatever reason");
843                r.receiver = null;
844                r.curFilter = null;
845                r.state = BroadcastRecord.IDLE;
846                scheduleBroadcastsLocked();
847                return;
848            }
849
850            r.state = BroadcastRecord.APP_RECEIVE;
851            String targetProcess = info.activityInfo.processName;
852            r.curComponent = component;
853            if (r.callingUid != Process.SYSTEM_UID && isSingleton) {
854                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
855            }
856            r.curReceiver = info.activityInfo;
857            if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
858                Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
859                        + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
860                        + info.activityInfo.applicationInfo.uid);
861            }
862
863            // Broadcast is being executed, its package can't be stopped.
864            try {
865                AppGlobals.getPackageManager().setPackageStoppedState(
866                        r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
867            } catch (RemoteException e) {
868            } catch (IllegalArgumentException e) {
869                Slog.w(TAG, "Failed trying to unstop package "
870                        + r.curComponent.getPackageName() + ": " + e);
871            }
872
873            // Is this receiver's application already running?
874            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
875                    info.activityInfo.applicationInfo.uid, false);
876            if (app != null && app.thread != null) {
877                try {
878                    app.addPackage(info.activityInfo.packageName, mService.mProcessStats);
879                    processCurBroadcastLocked(r, app);
880                    return;
881                } catch (RemoteException e) {
882                    Slog.w(TAG, "Exception when sending broadcast to "
883                          + r.curComponent, e);
884                } catch (RuntimeException e) {
885                    Log.wtf(TAG, "Failed sending broadcast to "
886                            + r.curComponent + " with " + r.intent, e);
887                    // If some unexpected exception happened, just skip
888                    // this broadcast.  At this point we are not in the call
889                    // from a client, so throwing an exception out from here
890                    // will crash the entire system instead of just whoever
891                    // sent the broadcast.
892                    logBroadcastReceiverDiscardLocked(r);
893                    finishReceiverLocked(r, r.resultCode, r.resultData,
894                            r.resultExtras, r.resultAbort, false);
895                    scheduleBroadcastsLocked();
896                    // We need to reset the state if we failed to start the receiver.
897                    r.state = BroadcastRecord.IDLE;
898                    return;
899                }
900
901                // If a dead object exception was thrown -- fall through to
902                // restart the application.
903            }
904
905            // Not running -- get it started, to be executed when the app comes up.
906            if (DEBUG_BROADCAST)  Slog.v(TAG,
907                    "Need to start app ["
908                    + mQueueName + "] " + targetProcess + " for broadcast " + r);
909            if ((r.curApp=mService.startProcessLocked(targetProcess,
910                    info.activityInfo.applicationInfo, true,
911                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
912                    "broadcast", r.curComponent,
913                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
914                            == null) {
915                // Ah, this recipient is unavailable.  Finish it if necessary,
916                // and mark the broadcast record as ready for the next.
917                Slog.w(TAG, "Unable to launch app "
918                        + info.activityInfo.applicationInfo.packageName + "/"
919                        + info.activityInfo.applicationInfo.uid + " for broadcast "
920                        + r.intent + ": process is bad");
921                logBroadcastReceiverDiscardLocked(r);
922                finishReceiverLocked(r, r.resultCode, r.resultData,
923                        r.resultExtras, r.resultAbort, false);
924                scheduleBroadcastsLocked();
925                r.state = BroadcastRecord.IDLE;
926                return;
927            }
928
929            mPendingBroadcast = r;
930            mPendingBroadcastRecvIndex = recIdx;
931        }
932    }
933
934    final void setBroadcastTimeoutLocked(long timeoutTime) {
935        if (! mPendingBroadcastTimeoutMessage) {
936            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
937            mHandler.sendMessageAtTime(msg, timeoutTime);
938            mPendingBroadcastTimeoutMessage = true;
939        }
940    }
941
942    final void cancelBroadcastTimeoutLocked() {
943        if (mPendingBroadcastTimeoutMessage) {
944            mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
945            mPendingBroadcastTimeoutMessage = false;
946        }
947    }
948
949    final void broadcastTimeoutLocked(boolean fromMsg) {
950        if (fromMsg) {
951            mPendingBroadcastTimeoutMessage = false;
952        }
953
954        if (mOrderedBroadcasts.size() == 0) {
955            return;
956        }
957
958        long now = SystemClock.uptimeMillis();
959        BroadcastRecord r = mOrderedBroadcasts.get(0);
960        if (fromMsg) {
961            if (mService.mDidDexOpt) {
962                // Delay timeouts until dexopt finishes.
963                mService.mDidDexOpt = false;
964                long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
965                setBroadcastTimeoutLocked(timeoutTime);
966                return;
967            }
968            if (!mService.mProcessesReady) {
969                // Only process broadcast timeouts if the system is ready. That way
970                // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
971                // to do heavy lifting for system up.
972                return;
973            }
974
975            long timeoutTime = r.receiverTime + mTimeoutPeriod;
976            if (timeoutTime > now) {
977                // We can observe premature timeouts because we do not cancel and reset the
978                // broadcast timeout message after each receiver finishes.  Instead, we set up
979                // an initial timeout then kick it down the road a little further as needed
980                // when it expires.
981                if (DEBUG_BROADCAST) Slog.v(TAG,
982                        "Premature timeout ["
983                        + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
984                        + timeoutTime);
985                setBroadcastTimeoutLocked(timeoutTime);
986                return;
987            }
988        }
989
990        BroadcastRecord br = mOrderedBroadcasts.get(0);
991        if (br.state == BroadcastRecord.WAITING_SERVICES) {
992            // In this case the broadcast had already finished, but we had decided to wait
993            // for started services to finish as well before going on.  So if we have actually
994            // waited long enough time timeout the broadcast, let's give up on the whole thing
995            // and just move on to the next.
996            Slog.i(ActivityManagerService.TAG, "Waited long enough for: " + (br.curComponent != null
997                    ? br.curComponent.flattenToShortString() : "(null)"));
998            br.curComponent = null;
999            br.state = BroadcastRecord.IDLE;
1000            processNextBroadcast(false);
1001            return;
1002        }
1003
1004        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r. receiver
1005                + ", started " + (now - r.receiverTime) + "ms ago");
1006        r.receiverTime = now;
1007        r.anrCount++;
1008
1009        // Current receiver has passed its expiration date.
1010        if (r.nextReceiver <= 0) {
1011            Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
1012            return;
1013        }
1014
1015        ProcessRecord app = null;
1016        String anrMessage = null;
1017
1018        Object curReceiver = r.receivers.get(r.nextReceiver-1);
1019        Slog.w(TAG, "Receiver during timeout: " + curReceiver);
1020        logBroadcastReceiverDiscardLocked(r);
1021        if (curReceiver instanceof BroadcastFilter) {
1022            BroadcastFilter bf = (BroadcastFilter)curReceiver;
1023            if (bf.receiverList.pid != 0
1024                    && bf.receiverList.pid != ActivityManagerService.MY_PID) {
1025                synchronized (mService.mPidsSelfLocked) {
1026                    app = mService.mPidsSelfLocked.get(
1027                            bf.receiverList.pid);
1028                }
1029            }
1030        } else {
1031            app = r.curApp;
1032        }
1033
1034        if (app != null) {
1035            anrMessage = "Broadcast of " + r.intent.toString();
1036        }
1037
1038        if (mPendingBroadcast == r) {
1039            mPendingBroadcast = null;
1040        }
1041
1042        // Move on to the next receiver.
1043        finishReceiverLocked(r, r.resultCode, r.resultData,
1044                r.resultExtras, r.resultAbort, false);
1045        scheduleBroadcastsLocked();
1046
1047        if (anrMessage != null) {
1048            // Post the ANR to the handler since we do not want to process ANRs while
1049            // potentially holding our lock.
1050            mHandler.post(new AppNotResponding(app, anrMessage));
1051        }
1052    }
1053
1054    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
1055        if (r.callingUid < 0) {
1056            // This was from a registerReceiver() call; ignore it.
1057            return;
1058        }
1059        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
1060                MAX_BROADCAST_HISTORY-1);
1061        r.finishTime = SystemClock.uptimeMillis();
1062        mBroadcastHistory[0] = r;
1063        System.arraycopy(mBroadcastSummaryHistory, 0, mBroadcastSummaryHistory, 1,
1064                MAX_BROADCAST_SUMMARY_HISTORY-1);
1065        mBroadcastSummaryHistory[0] = r.intent;
1066    }
1067
1068    final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
1069        if (r.nextReceiver > 0) {
1070            Object curReceiver = r.receivers.get(r.nextReceiver-1);
1071            if (curReceiver instanceof BroadcastFilter) {
1072                BroadcastFilter bf = (BroadcastFilter) curReceiver;
1073                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
1074                        bf.owningUserId, System.identityHashCode(r),
1075                        r.intent.getAction(),
1076                        r.nextReceiver - 1,
1077                        System.identityHashCode(bf));
1078            } else {
1079                ResolveInfo ri = (ResolveInfo)curReceiver;
1080                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1081                        UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
1082                        System.identityHashCode(r), r.intent.getAction(),
1083                        r.nextReceiver - 1, ri.toString());
1084            }
1085        } else {
1086            Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
1087                    + r);
1088            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1089                    -1, System.identityHashCode(r),
1090                    r.intent.getAction(),
1091                    r.nextReceiver,
1092                    "NONE");
1093        }
1094    }
1095
1096    final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
1097            int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
1098        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
1099                || mPendingBroadcast != null) {
1100            boolean printed = false;
1101            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
1102                BroadcastRecord br = mParallelBroadcasts.get(i);
1103                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1104                    continue;
1105                }
1106                if (!printed) {
1107                    if (needSep) {
1108                        pw.println();
1109                    }
1110                    needSep = true;
1111                    printed = true;
1112                    pw.println("  Active broadcasts [" + mQueueName + "]:");
1113                }
1114                pw.println("  Active Broadcast " + mQueueName + " #" + i + ":");
1115                br.dump(pw, "    ");
1116            }
1117            printed = false;
1118            needSep = true;
1119            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
1120                BroadcastRecord br = mOrderedBroadcasts.get(i);
1121                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1122                    continue;
1123                }
1124                if (!printed) {
1125                    if (needSep) {
1126                        pw.println();
1127                    }
1128                    needSep = true;
1129                    printed = true;
1130                    pw.println("  Active ordered broadcasts [" + mQueueName + "]:");
1131                }
1132                pw.println("  Active Ordered Broadcast " + mQueueName + " #" + i + ":");
1133                mOrderedBroadcasts.get(i).dump(pw, "    ");
1134            }
1135            if (dumpPackage == null || (mPendingBroadcast != null
1136                    && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
1137                if (needSep) {
1138                    pw.println();
1139                }
1140                pw.println("  Pending broadcast [" + mQueueName + "]:");
1141                if (mPendingBroadcast != null) {
1142                    mPendingBroadcast.dump(pw, "    ");
1143                } else {
1144                    pw.println("    (null)");
1145                }
1146                needSep = true;
1147            }
1148        }
1149
1150        int i;
1151        boolean printed = false;
1152        for (i=0; i<MAX_BROADCAST_HISTORY; i++) {
1153            BroadcastRecord r = mBroadcastHistory[i];
1154            if (r == null) {
1155                break;
1156            }
1157            if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
1158                continue;
1159            }
1160            if (!printed) {
1161                if (needSep) {
1162                    pw.println();
1163                }
1164                needSep = true;
1165                pw.println("  Historical broadcasts [" + mQueueName + "]:");
1166                printed = true;
1167            }
1168            if (dumpAll) {
1169                pw.print("  Historical Broadcast " + mQueueName + " #");
1170                        pw.print(i); pw.println(":");
1171                r.dump(pw, "    ");
1172            } else {
1173                pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
1174                pw.print("    ");
1175                pw.println(r.intent.toShortString(false, true, true, false));
1176                if (r.targetComp != null && r.targetComp != r.intent.getComponent()) {
1177                    pw.print("    targetComp: "); pw.println(r.targetComp.toShortString());
1178                }
1179                Bundle bundle = r.intent.getExtras();
1180                if (bundle != null) {
1181                    pw.print("    extras: "); pw.println(bundle.toString());
1182                }
1183            }
1184        }
1185
1186        if (dumpPackage == null) {
1187            if (dumpAll) {
1188                i = 0;
1189                printed = false;
1190            }
1191            for (; i<MAX_BROADCAST_SUMMARY_HISTORY; i++) {
1192                Intent intent = mBroadcastSummaryHistory[i];
1193                if (intent == null) {
1194                    break;
1195                }
1196                if (!printed) {
1197                    if (needSep) {
1198                        pw.println();
1199                    }
1200                    needSep = true;
1201                    pw.println("  Historical broadcasts summary [" + mQueueName + "]:");
1202                    printed = true;
1203                }
1204                if (!dumpAll && i >= 50) {
1205                    pw.println("  ...");
1206                    break;
1207                }
1208                pw.print("  #"); pw.print(i); pw.print(": ");
1209                pw.println(intent.toShortString(false, true, true, false));
1210                Bundle bundle = intent.getExtras();
1211                if (bundle != null) {
1212                    pw.print("    extras: "); pw.println(bundle.toString());
1213                }
1214            }
1215        }
1216
1217        return needSep;
1218    }
1219}
1220