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