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