blob: 254a21938e60690102d5042999e9ac97763ce211 [file] [log] [blame]
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001/*
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
Dianne Hackborn7d19e022012-08-07 19:12:33 -070023import android.app.ActivityManager;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080024import android.app.AppGlobals;
Dianne Hackbornf51f6122013-02-04 18:23:34 -080025import android.app.AppOpsManager;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080026import android.content.ComponentName;
27import android.content.IIntentReceiver;
28import android.content.Intent;
Dianne Hackborn7d19e022012-08-07 19:12:33 -070029import android.content.pm.ActivityInfo;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080030import android.content.pm.PackageManager;
31import android.content.pm.ResolveInfo;
32import android.os.Bundle;
33import android.os.Handler;
34import android.os.IBinder;
35import android.os.Message;
36import android.os.Process;
37import android.os.RemoteException;
38import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070039import android.os.UserHandle;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080040import android.util.EventLog;
Dianne Hackborn6c5406a2012-11-29 16:18:01 -080041import android.util.Log;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080042import android.util.Slog;
43
44/**
45 * BROADCASTS
46 *
47 * We keep two broadcast queues and associated bookkeeping, one for those at
48 * foreground priority, and one for normal (background-priority) broadcasts.
49 */
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070050public final class BroadcastQueue {
Dianne Hackborn40c8db52012-02-10 18:59:48 -080051 static final String TAG = "BroadcastQueue";
52 static final String TAG_MU = ActivityManagerService.TAG_MU;
53 static final boolean DEBUG_BROADCAST = ActivityManagerService.DEBUG_BROADCAST;
54 static final boolean DEBUG_BROADCAST_LIGHT = ActivityManagerService.DEBUG_BROADCAST_LIGHT;
55 static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
56
57 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070058 static final int MAX_BROADCAST_SUMMARY_HISTORY = 100;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080059
60 final ActivityManagerService mService;
61
62 /**
63 * Recognizable moniker for this queue
64 */
65 final String mQueueName;
66
67 /**
68 * Timeout period for this queue's broadcasts
69 */
70 final long mTimeoutPeriod;
71
72 /**
73 * Lists of all active broadcasts that are to be executed immediately
74 * (without waiting for another broadcast to finish). Currently this only
75 * contains broadcasts to registered receivers, to avoid spinning up
76 * a bunch of processes to execute IntentReceiver components. Background-
77 * and foreground-priority broadcasts are queued separately.
78 */
79 final ArrayList<BroadcastRecord> mParallelBroadcasts
80 = new ArrayList<BroadcastRecord>();
81 /**
82 * List of all active broadcasts that are to be executed one at a time.
83 * The object at the top of the list is the currently activity broadcasts;
84 * those after it are waiting for the top to finish. As with parallel
85 * broadcasts, separate background- and foreground-priority queues are
86 * maintained.
87 */
88 final ArrayList<BroadcastRecord> mOrderedBroadcasts
89 = new ArrayList<BroadcastRecord>();
90
91 /**
92 * Historical data of past broadcasts, for debugging.
93 */
94 final BroadcastRecord[] mBroadcastHistory
95 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
96
97 /**
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070098 * Summary of historical data of past broadcasts, for debugging.
99 */
100 final Intent[] mBroadcastSummaryHistory
101 = new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
102
103 /**
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800104 * Set when we current have a BROADCAST_INTENT_MSG in flight.
105 */
106 boolean mBroadcastsScheduled = false;
107
108 /**
109 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
110 */
111 boolean mPendingBroadcastTimeoutMessage;
112
113 /**
114 * Intent broadcasts that we have tried to start, but are
115 * waiting for the application's process to be created. We only
116 * need one per scheduling class (instead of a list) because we always
117 * process broadcasts one at a time, so no others can be started while
118 * waiting for this one.
119 */
120 BroadcastRecord mPendingBroadcast = null;
121
122 /**
123 * The receiver index that is pending, to restart the broadcast if needed.
124 */
125 int mPendingBroadcastRecvIndex;
126
127 static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
128 static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
129
130 final Handler mHandler = new Handler() {
131 //public Handler() {
132 // if (localLOGV) Slog.v(TAG, "Handler started!");
133 //}
134
135 public void handleMessage(Message msg) {
136 switch (msg.what) {
137 case BROADCAST_INTENT_MSG: {
138 if (DEBUG_BROADCAST) Slog.v(
139 TAG, "Received BROADCAST_INTENT_MSG");
140 processNextBroadcast(true);
141 } break;
142 case BROADCAST_TIMEOUT_MSG: {
143 synchronized (mService) {
144 broadcastTimeoutLocked(true);
145 }
146 } break;
147 }
148 }
149 };
150
151 private final class AppNotResponding implements Runnable {
152 private final ProcessRecord mApp;
153 private final String mAnnotation;
154
155 public AppNotResponding(ProcessRecord app, String annotation) {
156 mApp = app;
157 mAnnotation = annotation;
158 }
159
160 @Override
161 public void run() {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700162 mService.appNotResponding(mApp, null, null, false, mAnnotation);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800163 }
164 }
165
166 BroadcastQueue(ActivityManagerService service, String name, long timeoutPeriod) {
167 mService = service;
168 mQueueName = name;
169 mTimeoutPeriod = timeoutPeriod;
170 }
171
172 public boolean isPendingBroadcastProcessLocked(int pid) {
173 return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
174 }
175
176 public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
177 mParallelBroadcasts.add(r);
178 }
179
180 public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
181 mOrderedBroadcasts.add(r);
182 }
183
184 public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
185 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
186 if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
187 if (DEBUG_BROADCAST) Slog.v(TAG,
188 "***** DROPPING PARALLEL ["
189 + mQueueName + "]: " + r.intent);
190 mParallelBroadcasts.set(i, r);
191 return true;
192 }
193 }
194 return false;
195 }
196
197 public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
198 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
199 if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
200 if (DEBUG_BROADCAST) Slog.v(TAG,
201 "***** DROPPING ORDERED ["
202 + mQueueName + "]: " + r.intent);
203 mOrderedBroadcasts.set(i, r);
204 return true;
205 }
206 }
207 return false;
208 }
209
210 private final void processCurBroadcastLocked(BroadcastRecord r,
211 ProcessRecord app) throws RemoteException {
212 if (DEBUG_BROADCAST) Slog.v(TAG,
213 "Process cur broadcast " + r + " for app " + app);
214 if (app.thread == null) {
215 throw new RemoteException();
216 }
217 r.receiver = app.thread.asBinder();
218 r.curApp = app;
219 app.curReceiver = r;
Dianne Hackborna413dc02013-07-12 12:02:55 -0700220 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700221 mService.updateLruProcessLocked(app, true);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800222
223 // Tell the application to launch this receiver.
224 r.intent.setComponent(r.curComponent);
225
226 boolean started = false;
227 try {
228 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
229 "Delivering to component " + r.curComponent
230 + ": " + r);
231 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
232 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
233 mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
Dianne Hackborna413dc02013-07-12 12:02:55 -0700234 r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
235 app.repProcState);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800236 if (DEBUG_BROADCAST) Slog.v(TAG,
237 "Process cur broadcast " + r + " DELIVERED for app " + app);
238 started = true;
239 } finally {
240 if (!started) {
241 if (DEBUG_BROADCAST) Slog.v(TAG,
242 "Process cur broadcast " + r + ": NOT STARTED!");
243 r.receiver = null;
244 r.curApp = null;
245 app.curReceiver = null;
246 }
247 }
248 }
249
250 public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
251 boolean didSomething = false;
252 final BroadcastRecord br = mPendingBroadcast;
253 if (br != null && br.curApp.pid == app.pid) {
254 try {
255 mPendingBroadcast = null;
256 processCurBroadcastLocked(br, app);
257 didSomething = true;
258 } catch (Exception e) {
259 Slog.w(TAG, "Exception in new application when starting receiver "
260 + br.curComponent.flattenToShortString(), e);
261 logBroadcastReceiverDiscardLocked(br);
262 finishReceiverLocked(br, br.resultCode, br.resultData,
263 br.resultExtras, br.resultAbort, true);
264 scheduleBroadcastsLocked();
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700265 // We need to reset the state if we failed to start the receiver.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800266 br.state = BroadcastRecord.IDLE;
267 throw new RuntimeException(e.getMessage());
268 }
269 }
270 return didSomething;
271 }
272
273 public void skipPendingBroadcastLocked(int pid) {
274 final BroadcastRecord br = mPendingBroadcast;
275 if (br != null && br.curApp.pid == pid) {
276 br.state = BroadcastRecord.IDLE;
277 br.nextReceiver = mPendingBroadcastRecvIndex;
278 mPendingBroadcast = null;
279 scheduleBroadcastsLocked();
280 }
281 }
282
283 public void skipCurrentReceiverLocked(ProcessRecord app) {
284 boolean reschedule = false;
285 BroadcastRecord r = app.curReceiver;
286 if (r != null) {
287 // The current broadcast is waiting for this app's receiver
288 // to be finished. Looks like that's not going to happen, so
289 // let the broadcast continue.
290 logBroadcastReceiverDiscardLocked(r);
291 finishReceiverLocked(r, r.resultCode, r.resultData,
292 r.resultExtras, r.resultAbort, true);
293 reschedule = true;
294 }
295
296 r = mPendingBroadcast;
297 if (r != null && r.curApp == app) {
298 if (DEBUG_BROADCAST) Slog.v(TAG,
299 "[" + mQueueName + "] skip & discard pending app " + r);
300 logBroadcastReceiverDiscardLocked(r);
301 finishReceiverLocked(r, r.resultCode, r.resultData,
302 r.resultExtras, r.resultAbort, true);
303 reschedule = true;
304 }
305 if (reschedule) {
306 scheduleBroadcastsLocked();
307 }
308 }
309
310 public void scheduleBroadcastsLocked() {
311 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
312 + mQueueName + "]: current="
313 + mBroadcastsScheduled);
314
315 if (mBroadcastsScheduled) {
316 return;
317 }
318 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
319 mBroadcastsScheduled = true;
320 }
321
322 public BroadcastRecord getMatchingOrderedReceiver(IBinder receiver) {
323 if (mOrderedBroadcasts.size() > 0) {
324 final BroadcastRecord r = mOrderedBroadcasts.get(0);
325 if (r != null && r.receiver == receiver) {
326 return r;
327 }
328 }
329 return null;
330 }
331
332 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
333 String resultData, Bundle resultExtras, boolean resultAbort,
334 boolean explicit) {
335 int state = r.state;
336 r.state = BroadcastRecord.IDLE;
337 if (state == BroadcastRecord.IDLE) {
338 if (explicit) {
339 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
340 }
341 }
342 r.receiver = null;
343 r.intent.setComponent(null);
344 if (r.curApp != null) {
345 r.curApp.curReceiver = null;
346 }
347 if (r.curFilter != null) {
348 r.curFilter.receiverList.curBroadcast = null;
349 }
350 r.curFilter = null;
351 r.curApp = null;
352 r.curComponent = null;
353 r.curReceiver = null;
354 mPendingBroadcast = null;
355
356 r.resultCode = resultCode;
357 r.resultData = resultData;
358 r.resultExtras = resultExtras;
359 r.resultAbort = resultAbort;
360
361 // We will process the next receiver right now if this is finishing
362 // an app receiver (which is always asynchronous) or after we have
363 // come back from calling a receiver.
364 return state == BroadcastRecord.APP_RECEIVE
365 || state == BroadcastRecord.CALL_DONE_RECEIVE;
366 }
367
368 private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
369 Intent intent, int resultCode, String data, Bundle extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700370 boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800371 // Send the intent to the receiver asynchronously using one-way binder calls.
372 if (app != null && app.thread != null) {
373 // If we have an app thread, do the call through that so it is
374 // correctly ordered with other one-way calls.
375 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborna413dc02013-07-12 12:02:55 -0700376 data, extras, ordered, sticky, sendingUser, app.repProcState);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800377 } else {
Dianne Hackborn20e80982012-08-31 19:00:44 -0700378 receiver.performReceive(intent, resultCode, data, extras, ordered,
379 sticky, sendingUser);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800380 }
381 }
382
383 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
384 BroadcastFilter filter, boolean ordered) {
385 boolean skip = false;
Amith Yamasani8bf06ed2012-08-27 19:30:30 -0700386 if (filter.requiredPermission != null) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800387 int perm = mService.checkComponentPermission(filter.requiredPermission,
388 r.callingPid, r.callingUid, -1, true);
389 if (perm != PackageManager.PERMISSION_GRANTED) {
390 Slog.w(TAG, "Permission Denial: broadcasting "
391 + r.intent.toString()
392 + " from " + r.callerPackage + " (pid="
393 + r.callingPid + ", uid=" + r.callingUid + ")"
394 + " requires " + filter.requiredPermission
395 + " due to registered receiver " + filter);
396 skip = true;
397 }
398 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -0700399 if (!skip && r.requiredPermission != null) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800400 int perm = mService.checkComponentPermission(r.requiredPermission,
401 filter.receiverList.pid, filter.receiverList.uid, -1, true);
402 if (perm != PackageManager.PERMISSION_GRANTED) {
403 Slog.w(TAG, "Permission Denial: receiving "
404 + r.intent.toString()
405 + " to " + filter.receiverList.app
406 + " (pid=" + filter.receiverList.pid
407 + ", uid=" + filter.receiverList.uid + ")"
408 + " requires " + r.requiredPermission
409 + " due to sender " + r.callerPackage
410 + " (uid " + r.callingUid + ")");
411 skip = true;
412 }
413 }
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800414 if (r.appOp != AppOpsManager.OP_NONE) {
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700415 int mode = mService.mAppOpsService.noteOperation(r.appOp,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800416 filter.receiverList.uid, filter.packageName);
417 if (mode != AppOpsManager.MODE_ALLOWED) {
418 if (DEBUG_BROADCAST) Slog.v(TAG,
419 "App op " + r.appOp + " not allowed for broadcast to uid "
420 + filter.receiverList.uid + " pkg " + filter.packageName);
421 skip = true;
422 }
423 }
Ben Gruver49660c72013-08-06 19:54:08 -0700424 if (!skip) {
425 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
426 r.callingPid, r.resolvedType, filter.receiverList.uid);
427 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800428
429 if (!skip) {
430 // If this is not being sent as an ordered broadcast, then we
431 // don't want to touch the fields that keep track of the current
432 // state of ordered broadcasts.
433 if (ordered) {
434 r.receiver = filter.receiverList.receiver.asBinder();
435 r.curFilter = filter;
436 filter.receiverList.curBroadcast = r;
437 r.state = BroadcastRecord.CALL_IN_RECEIVE;
438 if (filter.receiverList.app != null) {
439 // Bump hosting application to no longer be in background
440 // scheduling class. Note that we can't do that if there
441 // isn't an app... but we can only be in that case for
442 // things that directly call the IActivityManager API, which
443 // are already core system stuff so don't matter for this.
444 r.curApp = filter.receiverList.app;
445 filter.receiverList.app.curReceiver = r;
Dianne Hackborna413dc02013-07-12 12:02:55 -0700446 mService.updateOomAdjLocked(r.curApp, true);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800447 }
448 }
449 try {
450 if (DEBUG_BROADCAST_LIGHT) {
451 int seq = r.intent.getIntExtra("seq", -1);
452 Slog.i(TAG, "Delivering to " + filter
453 + " (seq=" + seq + "): " + r);
454 }
455 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700456 new Intent(r.intent), r.resultCode, r.resultData,
457 r.resultExtras, r.ordered, r.initialSticky, r.userId);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800458 if (ordered) {
459 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
460 }
461 } catch (RemoteException e) {
462 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
463 if (ordered) {
464 r.receiver = null;
465 r.curFilter = null;
466 filter.receiverList.curBroadcast = null;
467 if (filter.receiverList.app != null) {
468 filter.receiverList.app.curReceiver = null;
469 }
470 }
471 }
472 }
473 }
474
475 final void processNextBroadcast(boolean fromMsg) {
476 synchronized(mService) {
477 BroadcastRecord r;
478
479 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast ["
480 + mQueueName + "]: "
481 + mParallelBroadcasts.size() + " broadcasts, "
482 + mOrderedBroadcasts.size() + " ordered broadcasts");
483
484 mService.updateCpuStats();
485
486 if (fromMsg) {
487 mBroadcastsScheduled = false;
488 }
489
490 // First, deliver any non-serialized broadcasts right away.
491 while (mParallelBroadcasts.size() > 0) {
492 r = mParallelBroadcasts.remove(0);
493 r.dispatchTime = SystemClock.uptimeMillis();
494 r.dispatchClockTime = System.currentTimeMillis();
495 final int N = r.receivers.size();
496 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
497 + mQueueName + "] " + r);
498 for (int i=0; i<N; i++) {
499 Object target = r.receivers.get(i);
500 if (DEBUG_BROADCAST) Slog.v(TAG,
501 "Delivering non-ordered on [" + mQueueName + "] to registered "
502 + target + ": " + r);
503 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
504 }
505 addBroadcastToHistoryLocked(r);
506 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
507 + mQueueName + "] " + r);
508 }
509
510 // Now take care of the next serialized one...
511
512 // If we are waiting for a process to come up to handle the next
513 // broadcast, then do nothing at this point. Just in case, we
514 // check that the process we're waiting for still exists.
515 if (mPendingBroadcast != null) {
516 if (DEBUG_BROADCAST_LIGHT) {
517 Slog.v(TAG, "processNextBroadcast ["
518 + mQueueName + "]: waiting for "
519 + mPendingBroadcast.curApp);
520 }
521
522 boolean isDead;
523 synchronized (mService.mPidsSelfLocked) {
524 isDead = (mService.mPidsSelfLocked.get(
525 mPendingBroadcast.curApp.pid) == null);
526 }
527 if (!isDead) {
528 // It's still alive, so keep waiting
529 return;
530 } else {
531 Slog.w(TAG, "pending app ["
532 + mQueueName + "]" + mPendingBroadcast.curApp
533 + " died before responding to broadcast");
534 mPendingBroadcast.state = BroadcastRecord.IDLE;
535 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
536 mPendingBroadcast = null;
537 }
538 }
539
540 boolean looped = false;
541
542 do {
543 if (mOrderedBroadcasts.size() == 0) {
544 // No more broadcasts pending, so all done!
545 mService.scheduleAppGcsLocked();
546 if (looped) {
547 // If we had finished the last ordered broadcast, then
548 // make sure all processes have correct oom and sched
549 // adjustments.
550 mService.updateOomAdjLocked();
551 }
552 return;
553 }
554 r = mOrderedBroadcasts.get(0);
555 boolean forceReceive = false;
556
557 // Ensure that even if something goes awry with the timeout
558 // detection, we catch "hung" broadcasts here, discard them,
559 // and continue to make progress.
560 //
561 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
562 // receivers don't get executed with timeouts. They're intended for
563 // one time heavy lifting after system upgrades and can take
564 // significant amounts of time.
565 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
566 if (mService.mProcessesReady && r.dispatchTime > 0) {
567 long now = SystemClock.uptimeMillis();
568 if ((numReceivers > 0) &&
569 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
570 Slog.w(TAG, "Hung broadcast ["
571 + mQueueName + "] discarded after timeout failure:"
572 + " now=" + now
573 + " dispatchTime=" + r.dispatchTime
574 + " startTime=" + r.receiverTime
575 + " intent=" + r.intent
576 + " numReceivers=" + numReceivers
577 + " nextReceiver=" + r.nextReceiver
578 + " state=" + r.state);
579 broadcastTimeoutLocked(false); // forcibly finish this broadcast
580 forceReceive = true;
581 r.state = BroadcastRecord.IDLE;
582 }
583 }
584
585 if (r.state != BroadcastRecord.IDLE) {
586 if (DEBUG_BROADCAST) Slog.d(TAG,
587 "processNextBroadcast("
588 + mQueueName + ") called when not idle (state="
589 + r.state + ")");
590 return;
591 }
592
593 if (r.receivers == null || r.nextReceiver >= numReceivers
594 || r.resultAbort || forceReceive) {
595 // No more receivers for this broadcast! Send the final
596 // result if requested...
597 if (r.resultTo != null) {
598 try {
599 if (DEBUG_BROADCAST) {
600 int seq = r.intent.getIntExtra("seq", -1);
601 Slog.i(TAG, "Finishing broadcast ["
602 + mQueueName + "] " + r.intent.getAction()
603 + " seq=" + seq + " app=" + r.callerApp);
604 }
605 performReceiveLocked(r.callerApp, r.resultTo,
606 new Intent(r.intent), r.resultCode,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700607 r.resultData, r.resultExtras, false, false, r.userId);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800608 // Set this to null so that the reference
609 // (local and remote) isnt kept in the mBroadcastHistory.
610 r.resultTo = null;
611 } catch (RemoteException e) {
612 Slog.w(TAG, "Failure ["
613 + mQueueName + "] sending broadcast result of "
614 + r.intent, e);
615 }
616 }
617
618 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
619 cancelBroadcastTimeoutLocked();
620
621 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
622 + r);
623
624 // ... and on to the next...
625 addBroadcastToHistoryLocked(r);
626 mOrderedBroadcasts.remove(0);
627 r = null;
628 looped = true;
629 continue;
630 }
631 } while (r == null);
632
633 // Get the next receiver...
634 int recIdx = r.nextReceiver++;
635
636 // Keep track of when this receiver started, and make sure there
637 // is a timeout message pending to kill it if need be.
638 r.receiverTime = SystemClock.uptimeMillis();
639 if (recIdx == 0) {
640 r.dispatchTime = r.receiverTime;
641 r.dispatchClockTime = System.currentTimeMillis();
642 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
643 + mQueueName + "] " + r);
644 }
645 if (! mPendingBroadcastTimeoutMessage) {
646 long timeoutTime = r.receiverTime + mTimeoutPeriod;
647 if (DEBUG_BROADCAST) Slog.v(TAG,
648 "Submitting BROADCAST_TIMEOUT_MSG ["
649 + mQueueName + "] for " + r + " at " + timeoutTime);
650 setBroadcastTimeoutLocked(timeoutTime);
651 }
652
653 Object nextReceiver = r.receivers.get(recIdx);
654 if (nextReceiver instanceof BroadcastFilter) {
655 // Simple case: this is a registered receiver who gets
656 // a direct call.
657 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
658 if (DEBUG_BROADCAST) Slog.v(TAG,
659 "Delivering ordered ["
660 + mQueueName + "] to registered "
661 + filter + ": " + r);
662 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
663 if (r.receiver == null || !r.ordered) {
664 // The receiver has already finished, so schedule to
665 // process the next one.
666 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
667 + mQueueName + "]: ordered="
668 + r.ordered + " receiver=" + r.receiver);
669 r.state = BroadcastRecord.IDLE;
670 scheduleBroadcastsLocked();
671 }
672 return;
673 }
674
675 // Hard case: need to instantiate the receiver, possibly
676 // starting its application process to host it.
677
678 ResolveInfo info =
679 (ResolveInfo)nextReceiver;
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700680 ComponentName component = new ComponentName(
681 info.activityInfo.applicationInfo.packageName,
682 info.activityInfo.name);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800683
684 boolean skip = false;
685 int perm = mService.checkComponentPermission(info.activityInfo.permission,
686 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
687 info.activityInfo.exported);
688 if (perm != PackageManager.PERMISSION_GRANTED) {
689 if (!info.activityInfo.exported) {
690 Slog.w(TAG, "Permission Denial: broadcasting "
691 + r.intent.toString()
692 + " from " + r.callerPackage + " (pid=" + r.callingPid
693 + ", uid=" + r.callingUid + ")"
694 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700695 + " due to receiver " + component.flattenToShortString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800696 } else {
697 Slog.w(TAG, "Permission Denial: broadcasting "
698 + r.intent.toString()
699 + " from " + r.callerPackage + " (pid=" + r.callingPid
700 + ", uid=" + r.callingUid + ")"
701 + " requires " + info.activityInfo.permission
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700702 + " due to receiver " + component.flattenToShortString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800703 }
704 skip = true;
705 }
706 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
707 r.requiredPermission != null) {
708 try {
709 perm = AppGlobals.getPackageManager().
710 checkPermission(r.requiredPermission,
711 info.activityInfo.applicationInfo.packageName);
712 } catch (RemoteException e) {
713 perm = PackageManager.PERMISSION_DENIED;
714 }
715 if (perm != PackageManager.PERMISSION_GRANTED) {
716 Slog.w(TAG, "Permission Denial: receiving "
717 + r.intent + " to "
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700718 + component.flattenToShortString()
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800719 + " requires " + r.requiredPermission
720 + " due to sender " + r.callerPackage
721 + " (uid " + r.callingUid + ")");
722 skip = true;
723 }
724 }
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800725 if (r.appOp != AppOpsManager.OP_NONE) {
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700726 int mode = mService.mAppOpsService.noteOperation(r.appOp,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800727 info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
728 if (mode != AppOpsManager.MODE_ALLOWED) {
729 if (DEBUG_BROADCAST) Slog.v(TAG,
730 "App op " + r.appOp + " not allowed for broadcast to uid "
731 + info.activityInfo.applicationInfo.uid + " pkg "
732 + info.activityInfo.packageName);
733 skip = true;
734 }
735 }
Ben Gruver49660c72013-08-06 19:54:08 -0700736 if (!skip) {
737 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
738 r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
739 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700740 boolean isSingleton = false;
741 try {
742 isSingleton = mService.isSingleton(info.activityInfo.processName,
743 info.activityInfo.applicationInfo,
744 info.activityInfo.name, info.activityInfo.flags);
745 } catch (SecurityException e) {
746 Slog.w(TAG, e.getMessage());
747 skip = true;
748 }
749 if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
750 if (ActivityManager.checkUidPermission(
751 android.Manifest.permission.INTERACT_ACROSS_USERS,
752 info.activityInfo.applicationInfo.uid)
753 != PackageManager.PERMISSION_GRANTED) {
754 Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
755 + " requests FLAG_SINGLE_USER, but app does not hold "
756 + android.Manifest.permission.INTERACT_ACROSS_USERS);
757 skip = true;
758 }
759 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800760 if (r.curApp != null && r.curApp.crashing) {
761 // If the target process is crashing, just skip it.
762 if (DEBUG_BROADCAST) Slog.v(TAG,
763 "Skipping deliver ordered ["
764 + mQueueName + "] " + r + " to " + r.curApp
765 + ": process crashing");
766 skip = true;
767 }
768
769 if (skip) {
770 if (DEBUG_BROADCAST) Slog.v(TAG,
771 "Skipping delivery of ordered ["
772 + mQueueName + "] " + r + " for whatever reason");
773 r.receiver = null;
774 r.curFilter = null;
775 r.state = BroadcastRecord.IDLE;
776 scheduleBroadcastsLocked();
777 return;
778 }
779
780 r.state = BroadcastRecord.APP_RECEIVE;
781 String targetProcess = info.activityInfo.processName;
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700782 r.curComponent = component;
783 if (r.callingUid != Process.SYSTEM_UID && isSingleton) {
784 info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800785 }
786 r.curReceiver = info.activityInfo;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700787 if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800788 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
789 + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
790 + info.activityInfo.applicationInfo.uid);
791 }
792
793 // Broadcast is being executed, its package can't be stopped.
794 try {
795 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700796 r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800797 } catch (RemoteException e) {
798 } catch (IllegalArgumentException e) {
799 Slog.w(TAG, "Failed trying to unstop package "
800 + r.curComponent.getPackageName() + ": " + e);
801 }
802
803 // Is this receiver's application already running?
804 ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
805 info.activityInfo.applicationInfo.uid);
806 if (app != null && app.thread != null) {
807 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700808 app.addPackage(info.activityInfo.packageName, mService.mProcessStats);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800809 processCurBroadcastLocked(r, app);
810 return;
811 } catch (RemoteException e) {
812 Slog.w(TAG, "Exception when sending broadcast to "
813 + r.curComponent, e);
Dianne Hackborn6c5406a2012-11-29 16:18:01 -0800814 } catch (RuntimeException e) {
815 Log.wtf(TAG, "Failed sending broadcast to "
816 + r.curComponent + " with " + r.intent, e);
817 // If some unexpected exception happened, just skip
818 // this broadcast. At this point we are not in the call
819 // from a client, so throwing an exception out from here
820 // will crash the entire system instead of just whoever
821 // sent the broadcast.
822 logBroadcastReceiverDiscardLocked(r);
823 finishReceiverLocked(r, r.resultCode, r.resultData,
824 r.resultExtras, r.resultAbort, true);
825 scheduleBroadcastsLocked();
826 // We need to reset the state if we failed to start the receiver.
827 r.state = BroadcastRecord.IDLE;
828 return;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800829 }
830
831 // If a dead object exception was thrown -- fall through to
832 // restart the application.
833 }
834
835 // Not running -- get it started, to be executed when the app comes up.
836 if (DEBUG_BROADCAST) Slog.v(TAG,
837 "Need to start app ["
838 + mQueueName + "] " + targetProcess + " for broadcast " + r);
839 if ((r.curApp=mService.startProcessLocked(targetProcess,
840 info.activityInfo.applicationInfo, true,
841 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
842 "broadcast", r.curComponent,
843 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false))
844 == null) {
845 // Ah, this recipient is unavailable. Finish it if necessary,
846 // and mark the broadcast record as ready for the next.
847 Slog.w(TAG, "Unable to launch app "
848 + info.activityInfo.applicationInfo.packageName + "/"
849 + info.activityInfo.applicationInfo.uid + " for broadcast "
850 + r.intent + ": process is bad");
851 logBroadcastReceiverDiscardLocked(r);
852 finishReceiverLocked(r, r.resultCode, r.resultData,
853 r.resultExtras, r.resultAbort, true);
854 scheduleBroadcastsLocked();
855 r.state = BroadcastRecord.IDLE;
856 return;
857 }
858
859 mPendingBroadcast = r;
860 mPendingBroadcastRecvIndex = recIdx;
861 }
862 }
863
864 final void setBroadcastTimeoutLocked(long timeoutTime) {
865 if (! mPendingBroadcastTimeoutMessage) {
866 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
867 mHandler.sendMessageAtTime(msg, timeoutTime);
868 mPendingBroadcastTimeoutMessage = true;
869 }
870 }
871
872 final void cancelBroadcastTimeoutLocked() {
873 if (mPendingBroadcastTimeoutMessage) {
874 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
875 mPendingBroadcastTimeoutMessage = false;
876 }
877 }
878
879 final void broadcastTimeoutLocked(boolean fromMsg) {
880 if (fromMsg) {
881 mPendingBroadcastTimeoutMessage = false;
882 }
883
884 if (mOrderedBroadcasts.size() == 0) {
885 return;
886 }
887
888 long now = SystemClock.uptimeMillis();
889 BroadcastRecord r = mOrderedBroadcasts.get(0);
890 if (fromMsg) {
891 if (mService.mDidDexOpt) {
892 // Delay timeouts until dexopt finishes.
893 mService.mDidDexOpt = false;
894 long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
895 setBroadcastTimeoutLocked(timeoutTime);
896 return;
897 }
898 if (!mService.mProcessesReady) {
899 // Only process broadcast timeouts if the system is ready. That way
900 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
901 // to do heavy lifting for system up.
902 return;
903 }
904
905 long timeoutTime = r.receiverTime + mTimeoutPeriod;
906 if (timeoutTime > now) {
907 // We can observe premature timeouts because we do not cancel and reset the
908 // broadcast timeout message after each receiver finishes. Instead, we set up
909 // an initial timeout then kick it down the road a little further as needed
910 // when it expires.
911 if (DEBUG_BROADCAST) Slog.v(TAG,
912 "Premature timeout ["
913 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
914 + timeoutTime);
915 setBroadcastTimeoutLocked(timeoutTime);
916 return;
917 }
918 }
919
920 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
921 + ", started " + (now - r.receiverTime) + "ms ago");
922 r.receiverTime = now;
923 r.anrCount++;
924
925 // Current receiver has passed its expiration date.
926 if (r.nextReceiver <= 0) {
927 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
928 return;
929 }
930
931 ProcessRecord app = null;
932 String anrMessage = null;
933
934 Object curReceiver = r.receivers.get(r.nextReceiver-1);
935 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
936 logBroadcastReceiverDiscardLocked(r);
937 if (curReceiver instanceof BroadcastFilter) {
938 BroadcastFilter bf = (BroadcastFilter)curReceiver;
939 if (bf.receiverList.pid != 0
940 && bf.receiverList.pid != ActivityManagerService.MY_PID) {
941 synchronized (mService.mPidsSelfLocked) {
942 app = mService.mPidsSelfLocked.get(
943 bf.receiverList.pid);
944 }
945 }
946 } else {
947 app = r.curApp;
948 }
949
950 if (app != null) {
951 anrMessage = "Broadcast of " + r.intent.toString();
952 }
953
954 if (mPendingBroadcast == r) {
955 mPendingBroadcast = null;
956 }
957
958 // Move on to the next receiver.
959 finishReceiverLocked(r, r.resultCode, r.resultData,
960 r.resultExtras, r.resultAbort, true);
961 scheduleBroadcastsLocked();
962
963 if (anrMessage != null) {
964 // Post the ANR to the handler since we do not want to process ANRs while
965 // potentially holding our lock.
966 mHandler.post(new AppNotResponding(app, anrMessage));
967 }
968 }
969
970 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
971 if (r.callingUid < 0) {
972 // This was from a registerReceiver() call; ignore it.
973 return;
974 }
975 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
976 MAX_BROADCAST_HISTORY-1);
977 r.finishTime = SystemClock.uptimeMillis();
978 mBroadcastHistory[0] = r;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700979 System.arraycopy(mBroadcastSummaryHistory, 0, mBroadcastSummaryHistory, 1,
980 MAX_BROADCAST_SUMMARY_HISTORY-1);
981 mBroadcastSummaryHistory[0] = r.intent;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800982 }
983
984 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
985 if (r.nextReceiver > 0) {
986 Object curReceiver = r.receivers.get(r.nextReceiver-1);
987 if (curReceiver instanceof BroadcastFilter) {
988 BroadcastFilter bf = (BroadcastFilter) curReceiver;
989 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700990 bf.owningUserId, System.identityHashCode(r),
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800991 r.intent.getAction(),
992 r.nextReceiver - 1,
993 System.identityHashCode(bf));
994 } else {
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700995 ResolveInfo ri = (ResolveInfo)curReceiver;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800996 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700997 UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
998 System.identityHashCode(r), r.intent.getAction(),
999 r.nextReceiver - 1, ri.toString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001000 }
1001 } else {
1002 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
1003 + r);
1004 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001005 -1, System.identityHashCode(r),
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001006 r.intent.getAction(),
1007 r.nextReceiver,
1008 "NONE");
1009 }
1010 }
1011
1012 final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
1013 int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
1014 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
1015 || mPendingBroadcast != null) {
1016 boolean printed = false;
1017 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
1018 BroadcastRecord br = mParallelBroadcasts.get(i);
1019 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1020 continue;
1021 }
1022 if (!printed) {
1023 if (needSep) {
1024 pw.println();
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001025 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001026 needSep = true;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001027 printed = true;
1028 pw.println(" Active broadcasts [" + mQueueName + "]:");
1029 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001030 pw.println(" Active Broadcast " + mQueueName + " #" + i + ":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001031 br.dump(pw, " ");
1032 }
1033 printed = false;
1034 needSep = true;
1035 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
1036 BroadcastRecord br = mOrderedBroadcasts.get(i);
1037 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1038 continue;
1039 }
1040 if (!printed) {
1041 if (needSep) {
1042 pw.println();
1043 }
1044 needSep = true;
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001045 printed = true;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001046 pw.println(" Active ordered broadcasts [" + mQueueName + "]:");
1047 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001048 pw.println(" Active Ordered Broadcast " + mQueueName + " #" + i + ":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001049 mOrderedBroadcasts.get(i).dump(pw, " ");
1050 }
1051 if (dumpPackage == null || (mPendingBroadcast != null
1052 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
1053 if (needSep) {
1054 pw.println();
1055 }
1056 pw.println(" Pending broadcast [" + mQueueName + "]:");
1057 if (mPendingBroadcast != null) {
1058 mPendingBroadcast.dump(pw, " ");
1059 } else {
1060 pw.println(" (null)");
1061 }
1062 needSep = true;
1063 }
1064 }
1065
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001066 int i;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001067 boolean printed = false;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001068 for (i=0; i<MAX_BROADCAST_HISTORY; i++) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001069 BroadcastRecord r = mBroadcastHistory[i];
1070 if (r == null) {
1071 break;
1072 }
1073 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
1074 continue;
1075 }
1076 if (!printed) {
1077 if (needSep) {
1078 pw.println();
1079 }
1080 needSep = true;
1081 pw.println(" Historical broadcasts [" + mQueueName + "]:");
1082 printed = true;
1083 }
1084 if (dumpAll) {
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001085 pw.print(" Historical Broadcast " + mQueueName + " #");
1086 pw.print(i); pw.println(":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001087 r.dump(pw, " ");
1088 } else {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001089 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
1090 pw.print(" ");
1091 pw.println(r.intent.toShortString(false, true, true, false));
Dianne Hackborna40cfeb2013-03-25 17:49:36 -07001092 if (r.targetComp != null && r.targetComp != r.intent.getComponent()) {
1093 pw.print(" targetComp: "); pw.println(r.targetComp.toShortString());
1094 }
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001095 Bundle bundle = r.intent.getExtras();
1096 if (bundle != null) {
1097 pw.print(" extras: "); pw.println(bundle.toString());
1098 }
1099 }
1100 }
1101
1102 if (dumpPackage == null) {
1103 if (dumpAll) {
1104 i = 0;
1105 printed = false;
1106 }
1107 for (; i<MAX_BROADCAST_SUMMARY_HISTORY; i++) {
1108 Intent intent = mBroadcastSummaryHistory[i];
1109 if (intent == null) {
1110 break;
1111 }
1112 if (!printed) {
1113 if (needSep) {
1114 pw.println();
1115 }
1116 needSep = true;
1117 pw.println(" Historical broadcasts summary [" + mQueueName + "]:");
1118 printed = true;
1119 }
1120 if (!dumpAll && i >= 50) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001121 pw.println(" ...");
1122 break;
1123 }
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001124 pw.print(" #"); pw.print(i); pw.print(": ");
1125 pw.println(intent.toShortString(false, true, true, false));
1126 Bundle bundle = intent.getExtras();
1127 if (bundle != null) {
1128 pw.print(" extras: "); pw.println(bundle.toString());
1129 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001130 }
1131 }
1132
1133 return needSep;
1134 }
1135}