BroadcastQueue#addBroadcastToHistoryLocked
1528 private final void addBroadcastToHistoryLocked(BroadcastRecord original) {
1529 if (original.callingUid < 0) {
1530 // This was from a registerReceiver() call; ignore it.
1531 return;
1532 }
//注意这里为BroadcastRecord的finishTime赋值了
1533 original.finishTime = SystemClock.uptimeMillis();
1534
1535 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
1536 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1537 createBroadcastTraceTitle(original, BroadcastRecord.DELIVERY_DELIVERED),
1538 System.identityHashCode(original));
1539 }
1540
1541 // Note sometimes (only for sticky broadcasts?) we reuse BroadcastRecords,
1542 // So don't change the incoming record directly.
1543 final BroadcastRecord historyRecord = original.maybeStripForHistory();
1544
1545 mBroadcastHistory[mHistoryNext] = historyRecord;
1546 mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
1547
1548 mBroadcastSummaryHistory[mSummaryHistoryNext] = historyRecord.intent;
1549 mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = historyRecord.enqueueClockTime;
1550 mSummaryHistoryDispatchTime[mSummaryHistoryNext] = historyRecord.dispatchClockTime;
1551 mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis();
1552 mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
1553 }
这个方用的调用处有两处
对于并行广播:
843 // First, deliver any non-serialized broadcasts right away.
844 while (mParallelBroadcasts.size() > 0) {
845 r = mParallelBroadcasts.remove(0);
846 r.dispatchTime = SystemClock.uptimeMillis();
847 r.dispatchClockTime = System.currentTimeMillis();
848
849 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
850 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
851 createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
852 System.identityHashCode(r));
853 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
854 createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
855 System.identityHashCode(r));
856 }
857
858 final int N = r.receivers.size();
859 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
860 + mQueueName + "] " + r);
861 for (int i=0; i<N; i++) {
862 Object target = r.receivers.get(i);
863 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
864 "Delivering non-ordered on [" + mQueueName + "] to registered "
865 + target + ": " + r);
866 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
867 }
868 addBroadcastToHistoryLocked(r);
869 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
870 + mQueueName + "] " + r);
871 }
对于串行广播:
910 do {
911 if (mOrderedBroadcasts.size() == 0) {
912 // No more broadcasts pending, so all done!
913 mService.scheduleAppGcsLocked();
914 if (looped) {
915 // If we had finished the last ordered broadcast, then
916 // make sure all processes have correct oom and sched
917 // adjustments.
918 mService.updateOomAdjLocked();
919 }
920 return;
921 }
922 r = mOrderedBroadcasts.get(0);
923 boolean forceReceive = false;
924
925 // Ensure that even if something goes awry with the timeout
926 // detection, we catch "hung" broadcasts here, discard them,
927 // and continue to make progress.
928 //
929 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
930 // receivers don't get executed with timeouts. They're intended for
931 // one time heavy lifting after system upgrades and can take
932 // significant amounts of time.
933 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
934 if (mService.mProcessesReady && r.dispatchTime > 0) {
935 long now = SystemClock.uptimeMillis();
936 if ((numReceivers > 0) &&
937 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
938 Slog.w(TAG, "Hung broadcast ["
939 + mQueueName + "] discarded after timeout failure:"
940 + " now=" + now
941 + " dispatchTime=" + r.dispatchTime
942 + " startTime=" + r.receiverTime
943 + " intent=" + r.intent
944 + " numReceivers=" + numReceivers
945 + " nextReceiver=" + r.nextReceiver
946 + " state=" + r.state);
947 broadcastTimeoutLocked(false); // forcibly finish this broadcast
948 forceReceive = true;
949 r.state = BroadcastRecord.IDLE;
950 }
951 }
952
953 if (r.state != BroadcastRecord.IDLE) {
954 if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
955 "processNextBroadcast("
956 + mQueueName + ") called when not idle (state="
957 + r.state + ")");
958 return;
959 }
960
961 if (r.receivers == null || r.nextReceiver >= numReceivers
962 || r.resultAbort || forceReceive) {
963 // No more receivers for this broadcast! Send the final
964 // result if requested...
965 if (r.resultTo != null) {
966 try {
967 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
968 "Finishing broadcast [" + mQueueName + "] "
969 + r.intent.getAction() + " app=" + r.callerApp);
970 performReceiveLocked(r.callerApp, r.resultTo,
971 new Intent(r.intent), r.resultCode,
972 r.resultData, r.resultExtras, false, false, r.userId);
973 // Set this to null so that the reference
974 // (local and remote) isn't kept in the mBroadcastHistory.
975 r.resultTo = null;
976 } catch (RemoteException e) {
977 r.resultTo = null;
978 Slog.w(TAG, "Failure ["
979 + mQueueName + "] sending broadcast result of "
980 + r.intent, e);
981
982 }
983 }
984
985 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
986 cancelBroadcastTimeoutLocked();
987
988 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
989 "Finished with ordered broadcast " + r);
990
991 // ... and on to the next...
992 addBroadcastToHistoryLocked(r);
993 if (r.intent.getComponent() == null && r.intent.getPackage() == null
994 && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
995 // This was an implicit broadcast... let's record it for posterity.
996 mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
997 r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
998 }
999 mOrderedBroadcasts.remove(0);
1000 r = null;
1001 looped = true;
1002 continue;
1003 }
1004 } while (r == null);
因此,Broadcast的finishTime属于当一个BroadcastRecord中所有receiver执行完成,或者超时强制终止时,作为BroadcastRecord的finishTime
BroadcastQueue#skipReceiverLocked
主动跳过一个receiver,触发下一次处理流程
389 private void skipReceiverLocked(BroadcastRecord r) {
390 logBroadcastReceiverDiscardLocked(r);
391 finishReceiverLocked(r, r.resultCode, r.resultData,
392 r.resultExtras, r.resultAbort, false);
393 scheduleBroadcastsLocked(); //用于触发进行nextReceiver的处理
394 }
BroadcastQueue#logBroadcastReceiverDiscardLocked
将BroadcastRecord当前receiver放弃了,打印event log
1651 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
1652 final int logIndex = r.nextReceiver - 1;
1653 if (logIndex >= 0 && logIndex < r.receivers.size()) {
1654 Object curReceiver = r.receivers.get(logIndex);
1655 if (curReceiver instanceof BroadcastFilter) {
1656 BroadcastFilter bf = (BroadcastFilter) curReceiver;
1657 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
1658 bf.owningUserId, System.identityHashCode(r),
1659 r.intent.getAction(), logIndex, System.identityHashCode(bf));
1660 } else {
1661 ResolveInfo ri = (ResolveInfo) curReceiver;
1662 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1663 UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
1664 System.identityHashCode(r), r.intent.getAction(), logIndex, ri.toString());
1665 }
1666 } else {
1667 if (logIndex < 0) Slog.w(TAG,
1668 "Discarding broadcast before first receiver is invoked: " + r);
1669 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
1670 -1, System.identityHashCode(r),
1671 r.intent.getAction(),
1672 r.nextReceiver,
1673 "NONE");
1674 }
1675 }
BroadcastQueue#finishReceiverLocked
418 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
419 String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
420 final int state = r.state;
421 final ActivityInfo receiver = r.curReceiver;
422 r.state = BroadcastRecord.IDLE;
423 if (state == BroadcastRecord.IDLE) {
424 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
425 }
426 r.receiver = null;
427 r.intent.setComponent(null);
428 if (r.curApp != null && r.curApp.curReceivers.contains(r)) {
429 r.curApp.curReceivers.remove(r);
430 }
431 if (r.curFilter != null) {
432 r.curFilter.receiverList.curBroadcast = null;
433 }
434 r.curFilter = null;
435 r.curReceiver = null;
436 r.curApp = null;
437 mPendingBroadcast = null;
//置空操作
//将当前BroadcastRecord中的一些值置空
438
439 r.resultCode = resultCode;
440 r.resultData = resultData;
441 r.resultExtras = resultExtras;
442 if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
443 r.resultAbort = resultAbort;
444 } else {
445 r.resultAbort = false;
446 }
447 //waitForServices的特殊情况
448 if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
449 && r.queue.mOrderedBroadcasts.size() > 0
450 && r.queue.mOrderedBroadcasts.get(0) == r) {
451 ActivityInfo nextReceiver;
452 if (r.nextReceiver < r.receivers.size()) {
453 Object obj = r.receivers.get(r.nextReceiver);
454 nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
455 } else {
456 nextReceiver = null;
457 }
458 // Don't do this if the next receive is in the same process as the current one.
459 if (receiver == null || nextReceiver == null
460 || receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
461 || !receiver.processName.equals(nextReceiver.processName)) {
462 // In this case, we are ready to process the next receiver for the current broadcast,
463 // but are on a queue that would like to wait for services to finish before moving
464 // on. If there are background services currently starting, then we will go into a
465 // special state where we hold off on continuing this broadcast until they are done.
466 if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
467 Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString());
468 r.state = BroadcastRecord.WAITING_SERVICES; //Broadcast已经执行完了,要等当前user的后台服务执行完才继续下一个broadcast;或者是当我们切换用户时或者进程时,我们需要把当前用户的后台服务执行完,才执行下一个BroadcastRecord或者BroadcastReceiver
469 return false; //返回false,代表暂时不执行下一个broadcast
470 }
471 }
472 }
473
474 r.curComponent = null;
475
476 // We will process the next receiver right now if this is finishing
477 // an app receiver (which is always asynchronous) or after we have
478 // come back from calling a receiver.
479 return state == BroadcastRecord.APP_RECEIVE
480 || state == BroadcastRecord.CALL_DONE_RECEIVE;
//CALL_DONE_RECEIVE 串行广播+动态注册receiver:执行完performReceiveLocked后,将BroadcastRecord的state置为CALL_DONE_RECEIVE
//APP_RECEIVE 串行广播+静态注册receiver:执行processCurBroadcastLocked之前就将状态置为APP_RECEIVE
//总之是针对串行广播的,这个返回值会在finishReceiver中被用到,返回true则自动调用processNextBroadcastLocked,进行BroadcastRecord的下一个receiver的处理
481 }
BroadcastQueue#scheduleBroadcastsLocked
通过BROADCAST_INTENT_MSG消息触发下一个receiver的处理
396 public void scheduleBroadcastsLocked() {
397 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
398 + mQueueName + "]: current="
399 + mBroadcastsScheduled);
400
401 if (mBroadcastsScheduled) {
402 return;
403 }
404 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
405 mBroadcastsScheduled = true;
406 }
ActivityManagerService#finishReceiver
如调用BroadcastReceiver实例的onReceive函数过程中,如果receiver所在进程死了;最终会调用到
22570 public void finishReceiver(IBinder who, int resultCode, String resultData,
22571 Bundle resultExtras, boolean resultAbort, int flags) {
22572 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22573
22574 // Refuse possible leaked file descriptors
22575 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22576 throw new IllegalArgumentException("File descriptors passed in Bundle");
22577 }
22578
22579 final long origId = Binder.clearCallingIdentity();
22580 try {
22581 boolean doNext = false;
22582 BroadcastRecord r;
22583
22584 synchronized(this) {
22585 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22586 ? mFgBroadcastQueue : mBgBroadcastQueue;
22587 r = queue.getMatchingOrderedReceiver(who);
22588 if (r != null) {
22589 doNext = r.queue.finishReceiverLocked(r, resultCode,
22590 resultData, resultExtras, resultAbort, true); //处理当前BroadcastRecord状态,并返回一个结果,用于判断是否要触发下一个processNextBroadcastLocked
22591 }
22592 if (doNext) {
22593 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
//所以processNextBroadcastLocked中的next不是BroadcastRecord这个粒度的,而是BroadcatReceiver这个粒度的(针对串行广播)
//对于并行广播而言,每执行一次都会将并行队列中的Broadcast全部处理完毕
22594 }
22595 // updateOomAdjLocked() will be done here
22596 trimApplicationsLocked();
22597 }
22598
22599 } finally {
22600 Binder.restoreCallingIdentity(origId);
22601 }
22602 }
超时发生ANR的相关逻辑
每个receiver都会尝试发送,但是只有mPendingBroadcastTimeoutMessage为false是才会真正发送;每次取出BroadcastRecord中的一个receiver准备执行时,就会先尝试发送一个broadcast的timeout消息
1074 if (! mPendingBroadcastTimeoutMessage) { //mPendingBroadcastTimeoutMessage = true代表当前已经有BROADCAST_TIMEOUT_MSG消息了,无需再重复发送了
1075 long timeoutTime = r.receiverTime + mTimeoutPeriod;
1076 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
1077 "Submitting BROADCAST_TIMEOUT_MSG ["
1078 + mQueueName + "] for " + r + " at " + timeoutTime);
1079 setBroadcastTimeoutLocked(timeoutTime); //针对BroadcastReceiver发送超时消息
1080 }
BroadcastQueue#setBroadcastTimeoutLocked
1475 final void setBroadcastTimeoutLocked(long timeoutTime) {
1476 if (! mPendingBroadcastTimeoutMessage) {
1477 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
1478 mHandler.sendMessageAtTime(msg, timeoutTime);
1479 mPendingBroadcastTimeoutMessage = true;
1480 }
1481 }
那么比如我有4个receiver,每个3s,那么会在第四个的时候进行broadcastTimeoutLocked的处理(如果相关线程不繁忙的话)
166 final class BroadcastHandler extends Handler {
167 public BroadcastHandler(Looper looper) {
168 super(looper, null, true);
169 }
170
171 @Override
172 public void handleMessage(Message msg) {
173 switch (msg.what) {
174 case BROADCAST_INTENT_MSG: {
175 if (DEBUG_BROADCAST) Slog.v(
176 TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
177 processNextBroadcast(true);
178 } break;
179 case BROADCAST_TIMEOUT_MSG: {
180 synchronized (mService) {
181 broadcastTimeoutLocked(true);
182 }
183 } break;
184 }
185 }
186 }
BroadcastQueue#broadcastTimeoutLocked
发生超时时,当前BroadcastReceiver所在进程ANR
1490 final void broadcastTimeoutLocked(boolean fromMsg) {
1491 if (fromMsg) {
1492 mPendingBroadcastTimeoutMessage = false; //调到这以后mPendingBroadcastTimeoutMessage 置为false,就可以重新发送超时消息了
1493 }
1494
1495 if (mOrderedBroadcasts.size() == 0) {
1496 return;
1497 }
1498
1499 long now = SystemClock.uptimeMillis();
1500 BroadcastRecord r = mOrderedBroadcasts.get(0);
1501 if (fromMsg) {
1502 if (!mService.mProcessesReady) {
1503 // Only process broadcast timeouts if the system is ready. That way
1504 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
1505 // to do heavy lifting for system up.
1506 return;
1507 }
1508
1509 long timeoutTime = r.receiverTime + mTimeoutPeriod;
1510 if (timeoutTime > now) {
1511 // We can observe premature timeouts because we do not cancel and reset the
1512 // broadcast timeout message after each receiver finishes. Instead, we set up
1513 // an initial timeout then kick it down the road a little further as needed
1514 // when it expires.
1515 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
1516 "Premature timeout ["
1517 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
1518 + timeoutTime);
1519 setBroadcastTimeoutLocked(timeoutTime); //重新发送BROADCAST_TIMEOUT_MSG消息并直接返回
1520 return;
1521 }
1522 }
1523
1524 BroadcastRecord br = mOrderedBroadcasts.get(0);
1525 if (br.state == BroadcastRecord.WAITING_SERVICES) {
1526 // In this case the broadcast had already finished, but we had decided to wait
1527 // for started services to finish as well before going on. So if we have actually
1528 // waited long enough time timeout the broadcast, let's give up on the whole thing
1529 // and just move on to the next.
1530 Slog.i(TAG, "Waited long enough for: " + (br.curComponent != null
1531 ? br.curComponent.flattenToShortString() : "(null)"));
1532 br.curComponent = null;
1533 br.state = BroadcastRecord.IDLE;
1534 processNextBroadcast(false);
1535 return;
1536 }
1537
//确定超时了,将r.receiverTime改为当前时间(这样就不会因为这个broadcast超时影响下一个receiver所在进程也ANR了),然后finish当前Receiver,重新触发下一轮流程
1538 // If the receiver app is being debugged we quietly ignore unresponsiveness, just
1539 // tidying up and moving on to the next broadcast without crashing or ANRing this
1540 // app just because it's stopped at a breakpoint.
1541 final boolean debugging = (r.curApp != null && r.curApp.debugging);
1542
1543 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
1544 + ", started " + (now - r.receiverTime) + "ms ago");
1545 r.receiverTime = now;
1546 if (!debugging) {
1547 r.anrCount++;
1548 }
1549
1550 ProcessRecord app = null;
1551 String anrMessage = null;
1552
1553 Object curReceiver;
1554 if (r.nextReceiver > 0) {
1555 curReceiver = r.receivers.get(r.nextReceiver-1);
1556 r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
1557 } else {
1558 curReceiver = r.curReceiver;
1559 }
1560 Slog.w(TAG, "Receiver during timeout of " + r + " : " + curReceiver);
1561 logBroadcastReceiverDiscardLocked(r);
1562 if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
1563 BroadcastFilter bf = (BroadcastFilter)curReceiver;
1564 if (bf.receiverList.pid != 0
1565 && bf.receiverList.pid != ActivityManagerService.MY_PID) {
1566 synchronized (mService.mPidsSelfLocked) {
1567 app = mService.mPidsSelfLocked.get(
1568 bf.receiverList.pid);
1569 }
1570 }
1571 } else {
1572 app = r.curApp;
1573 }
1574
1575 if (app != null) {
1576 anrMessage = "Broadcast of " + r.intent.toString();
1577 }
1578
1579 if (mPendingBroadcast == r) {
1580 mPendingBroadcast = null;
1581 }
1582
1583 // Move on to the next receiver.
1584 finishReceiverLocked(r, r.resultCode, r.resultData,
1585 r.resultExtras, r.resultAbort, false);
1586 scheduleBroadcastsLocked();
1587
1588 if (!debugging && anrMessage != null) {
1589 // Post the ANR to the handler since we do not want to process ANRs while
1590 // potentially holding our lock.
1591 mHandler.post(new AppNotResponding(app, anrMessage));
1592 }
1593 }
BroadcastQueue#cancelBroadcastTimeoutLocked
只有当串行广播所有的BroadcastReceiver时,或者当广播强制被结束时,才会调用cancelBroadcastTimeoutLocked,取消队列中BROADCAST_TIMEOUT_MSG消息
1409 final void cancelBroadcastTimeoutLocked() {
1410 if (mPendingBroadcastTimeoutMessage) {
1411 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this); //BROADCAST_TIMEOUT_MSG消息从队列中移除
1412 mPendingBroadcastTimeoutMessage = false;
1413 }
1414 }
下面举例说明下,已前台广播为例:
1.一个broadcast有4个receiver,分别是3,3,3,3
时间轴
0 3 6 9 10(耗时操作消息被取出执行执行了,此时dispatch time = 9,9+10 = 19)12 此时整个Broadcast执行完了,会cancel超时小心;因此整个并没有耗时
2.一个broadcast有2个receiver,分别是1,13
0 1 10(耗时操作消息被取出执行执行了,此时dispatch time = 1,1+10 = 11) 11(此时超时了,receiver所在进程发生ANR),然后进入下一轮流程,进入下一个broadcast
3.一个broadcast有3个receiver,分别是1,13,2
0 1 10(耗时操作消息被取出执行执行了,此时dispatch time = 1,1+10 = 11) 11(此时超时了,receiver所在进程发生ANR),然后进入下一轮流程,进入下一个receiver,发送超时消息(时间为11+10 = 21),13(该Broadcast执行完成,取消超时消息);进入下一个Broadcast
4.一个broadcast有3个receiver,分别是5,等待7s才进入下一轮,5,2
0 5 10 (下一轮timeout = 15) 12(取出开始执行) 15(ANR,当前receiver执行超时),(下一轮timeout = 25),17(此时结束,取消超时消息,触发一个BroadcastRecord)
总结
用这种方式能查出两个receiver处理之间的耗时超过timeout就会ANR(本次receiver处理的相关Message,BROADCAST_INTENT_MSG等待取出时间+执行时间 >= timeout),且不会连带影响下一个receiver(看起来system_server中的ActivityMananger线程耗时以及receiver所在进程的主线程耗时,来回binder call耗时,都可能会造成相关receiver广播超时)
deliverToRegisteredReceiverLocked
处理动态注册的receiver
首先检查相关权限,然后调用performReceiveLocked进行相关处理
530 private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
531 BroadcastFilter filter, boolean ordered, int index) {
532 boolean skip = false;
//检查广播发送方是否有BroadcastReceiver指定的权限
533 if (filter.requiredPermission != null) {
534 int perm = mService.checkComponentPermission(filter.requiredPermission,
535 r.callingPid, r.callingUid, -1, true);
536 if (perm != PackageManager.PERMISSION_GRANTED) {
537 Slog.w(TAG, "Permission Denial: broadcasting "
538 + r.intent.toString()
539 + " from " + r.callerPackage + " (pid="
540 + r.callingPid + ", uid=" + r.callingUid + ")"
541 + " requires " + filter.requiredPermission
542 + " due to registered receiver " + filter);
543 skip = true;
544 } else {
545 final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);
546 if (opCode != AppOpsManager.OP_NONE
547 && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
548 r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
549 Slog.w(TAG, "Appop Denial: broadcasting "
550 + r.intent.toString()
551 + " from " + r.callerPackage + " (pid="
552 + r.callingPid + ", uid=" + r.callingUid + ")"
553 + " requires appop " + AppOpsManager.permissionToOp(
554 filter.requiredPermission)
555 + " due to registered receiver " + filter);
556 skip = true;
557 }
558 }
559 }
560 if (!skip && r.requiredPermissions != null && r.requiredPermissions.length > 0) {
561 for (int i = 0; i < r.requiredPermissions.length; i++) {
562 String requiredPermission = r.requiredPermissions[i];
563 int perm = mService.checkComponentPermission(requiredPermission,
564 filter.receiverList.pid, filter.receiverList.uid, -1, true);
565 if (perm != PackageManager.PERMISSION_GRANTED) {
566 Slog.w(TAG, "Permission Denial: receiving "
567 + r.intent.toString()
568 + " to " + filter.receiverList.app
569 + " (pid=" + filter.receiverList.pid
570 + ", uid=" + filter.receiverList.uid + ")"
571 + " requires " + requiredPermission
572 + " due to sender " + r.callerPackage
573 + " (uid " + r.callingUid + ")");
574 skip = true;
575 break;
576 }
577 int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
578 if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
//检查BroadcastReceiver是否有Broadcast要求的权限
581 && mService.mAppOpsService.checkOperation(appOp,
582 filter.receiverList.uid, filter.packageName)
583 != AppOpsManager.MODE_ALLOWED) {
584 Slog.w(TAG, "Appop Denial: receiving "
585 + r.intent.toString()
586 + " to " + filter.receiverList.app
587 + " (pid=" + filter.receiverList.pid
588 + ", uid=" + filter.receiverList.uid + ")"
589 + " requires appop " + AppOpsManager.permissionToOp(
590 requiredPermission)
591 + " due to sender " + r.callerPackage
592 + " (uid " + r.callingUid + ")");
593 skip = true;
594 break;
595 }
596 }
597 }
598 if (!skip && (r.requiredPermissions == null || r.requiredPermissions.length == 0)) {
599 int perm = mService.checkComponentPermission(null,
600 filter.receiverList.pid, filter.receiverList.uid, -1, true);
601 if (perm != PackageManager.PERMISSION_GRANTED) {
602 Slog.w(TAG, "Permission Denial: security check failed when receiving "
603 + r.intent.toString()
604 + " to " + filter.receiverList.app
605 + " (pid=" + filter.receiverList.pid
606 + ", uid=" + filter.receiverList.uid + ")"
607 + " due to sender " + r.callerPackage
608 + " (uid " + r.callingUid + ")");
609 skip = true;
610 }
611 }
612 if (!skip && r.appOp != AppOpsManager.OP_NONE
613
614 && mService.mAppOpsService.noteOperation(r.appOp,
615 filter.receiverList.uid, filter.packageName)
619 != AppOpsManager.MODE_ALLOWED) {
620 Slog.w(TAG, "Appop Denial: receiving "
621 + r.intent.toString()
622 + " to " + filter.receiverList.app
623 + " (pid=" + filter.receiverList.pid
624 + ", uid=" + filter.receiverList.uid + ")"
625 + " requires appop " + AppOpsManager.opToName(r.appOp)
626 + " due to sender " + r.callerPackage
627 + " (uid " + r.callingUid + ")");
628 skip = true;
629 }
630
636
637 if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
638 r.callingPid, r.resolvedType, filter.receiverList.uid)) {
639 skip = true;
640 }
641
642 if (!skip && (filter.receiverList.app == null || filter.receiverList.app.killed
643 || filter.receiverList.app.crashing)) {
644 Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
645 + " to " + filter.receiverList + ": process gone or crashing");
646 skip = true;
647 }
648
649 // Ensure that broadcasts are only sent to other Instant Apps if they are marked as
650 // visible to Instant Apps.
651 final boolean visibleToInstantApps =
652 (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
653
654 if (!skip && !visibleToInstantApps && filter.instantApp
655 && filter.receiverList.uid != r.callingUid) {
656 Slog.w(TAG, "Instant App Denial: receiving "
657 + r.intent.toString()
658 + " to " + filter.receiverList.app
659 + " (pid=" + filter.receiverList.pid
660 + ", uid=" + filter.receiverList.uid + ")"
661 + " due to sender " + r.callerPackage
662 + " (uid " + r.callingUid + ")"
663 + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
664 skip = true;
665 }
666
667 if (!skip && !filter.visibleToInstantApp && r.callerInstantApp
668 && filter.receiverList.uid != r.callingUid) {
669 Slog.w(TAG, "Instant App Denial: receiving "
670 + r.intent.toString()
671 + " to " + filter.receiverList.app
672 + " (pid=" + filter.receiverList.pid
673 + ", uid=" + filter.receiverList.uid + ")"
674 + " requires receiver be visible to instant apps"
675 + " due to sender " + r.callerPackage
676 + " (uid " + r.callingUid + ")");
677 skip = true;
678 }
679
680 if (skip) {
//不满足发送条件的话,标记一下,结束发送
681 r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
682 return;
683 }
684
685 // If permissions need a review before any of the app components can run, we drop
686 // the broadcast and if the calling app is in the foreground and the broadcast is
687 // explicit we launch the review UI passing it a pending intent to send the skipped
688 // broadcast.
//特殊情况,还需要再次检查权限,中断广播发送
//再次满足发送条件后,会重新进入到后续的发送流程
689 if (mService.mPermissionReviewRequired) {
690 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, filter.packageName,
691 filter.owningUserId)) {
692 r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
693 return;
694 }
695 }
696
697 r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;//可以发送了,标记一下
698
699 // If this is not being sent as an ordered broadcast, then we
700 // don't want to touch the fields that keep track of the current
701 // state of ordered broadcasts.
702 if (ordered) { //针对串行广播,保存BroadRecord,BroadcastFilter中的结构,代表串行广播走到哪了
703 r.receiver = filter.receiverList.receiver.asBinder();
704 r.curFilter = filter;
705 filter.receiverList.curBroadcast = r;
706 r.state = BroadcastRecord.CALL_IN_RECEIVE; //当前Broadcast的状态
707 if (filter.receiverList.app != null) {
708 // Bump hosting application to no longer be in background
709 // scheduling class. Note that we can't do that if there
710 // isn't an app... but we can only be in that case for
711 // things that directly call the IActivityManager API, which
712 // are already core system stuff so don't matter for this.
713 r.curApp = filter.receiverList.app;
714 filter.receiverList.app.curReceivers.add(r);
715 mService.updateOomAdjLocked(r.curApp, true);
716 }
717 }
723 try {
724 if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
725 "Delivering to " + filter + " : " + r);
726 if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
//若BroadcastReceiver对应的进程处于fullBackup状态(备份和恢复),则不发送广播
727 // Skip delivery if full backup in progress
728 // If it's an ordered broadcast, we need to continue to the next receiver.
729 if (ordered) {
//有序广播必须处理完一个,才能处理下一个,因此这里主动触发一下
730 skipReceiverLocked(r);
731 }
732 } else {
//执行发送工作
733 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
734 new Intent(r.intent), r.resultCode, r.resultData,
735 r.resultExtras, r.ordered, r.initialSticky, r.userId);
736 }
737 if (ordered) {
738 r.state = BroadcastRecord.CALL_DONE_RECEIVE; //将BroadcastRecord的state设为CALL_DONE_RECEIVE
//从字面上理解,似乎取已经通过performReceiveLocked来调用BroadcastRecord实例中的onReceive了
739 }
740 } catch (RemoteException e) {
741 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
742 if (ordered) {
743 r.receiver = null;
744 r.curFilter = null;
745 filter.receiverList.curBroadcast = null;
746 if (filter.receiverList.app != null) {
747 filter.receiverList.app.curReceivers.remove(r);
748 }
749 }
750 }
751 }
BroadcastQueue#performReceiveLocked
495 void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
496 Intent intent, int resultCode, String data, Bundle extras,
497 boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
498 // Send the intent to the receiver asynchronously using one-way binder calls.
499 if (app != null) { //app:receiver所在进程
500 if (app.thread != null) {
501 // If we have an app thread, do the call through that so it is
502 // correctly ordered with other one-way calls.
503 try {
504 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
505 data, extras, ordered, sticky, sendingUser, app.repProcState);
//app进程中的一个binder线程响应(binder call都是binder线程响应的),在其中会调用mActivityThread.post来发送消息,最终调用onReceive函数;mActivityThread默认为null
506 // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
507 // DeadObjectException when the process isn't actually dead.
508 //} catch (DeadObjectException ex) {
509 // Failed to call into the process. It's dying so just let it die and move on.
510 // throw ex;
511 } catch (RemoteException ex) {
512 // Failed to call into the process. It's either dying or wedged. Kill it gently.
513 synchronized (mService) {
514 Slog.w(TAG, "Can't deliver broadcast to " + app.processName
515 + " (pid " + app.pid + "). Crashing it.");
516 app.scheduleCrash("can't deliver broadcast");
517 }
518 throw ex;
519 }
520 } else {
521 // Application has died. Receiver doesn't exist.
522 throw new RemoteException("app.thread must not be null");
523 }
524 } else {
//如果动态接收者的所在进程已死亡,则IIntentReceiver中弱引用的LoadedApk.ReceiverDispatcher为null
//则调用AMS的finishReceiver
525 receiver.performReceive(intent, resultCode, data, extras, ordered,
526 sticky, sendingUser);
527 }
528 }
BroadcastQueue#processCurBroadcastLocked
处理静态广播(此时所在进程已唤起)
273 private final void processCurBroadcastLocked(BroadcastRecord r,
274 ProcessRecord app, boolean skipOomAdj) throws RemoteException {
275 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
276 "Process cur broadcast " + r + " for app " + app);
277 if (app.thread == null) {
278 throw new RemoteException();
279 }
280 if (app.inFullBackup) {
281 skipReceiverLocked(r);
282 return;
283 }
284
285 r.receiver = app.thread.asBinder();
286 r.curApp = app;
287 app.curReceivers.add(r);
288 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
289 mService.updateLruProcessLocked(app, false, null);
// 要派发之前,调整这个进程的优先级
// 所以app在receiver执行的过程中优先级是很高的
290 if (!skipOomAdj) {
291 mService.updateOomAdjLocked();
292 }
293
294 // Tell the application to launch this receiver.
295 r.intent.setComponent(r.curComponent);
296
297 boolean started = false;
298 try {
299 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
300 "Delivering to component " + r.curComponent
301 + ": " + r);
302 mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
303 PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
// binder call到app进程 调用onReceive
304 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
305 mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
306 r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
307 app.repProcState);
308 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
309 "Process cur broadcast " + r + " DELIVERED for app " + app);
310 started = true;
311 } finally {
312 if (!started) {
313 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
314 "Process cur broadcast " + r + ": NOT STARTED!");
315 r.receiver = null;
316 r.curApp = null;
317 app.curReceivers.remove(r);
318 }
319 }
320 }
ActivityThread#scheduleReceiver
776 public final void scheduleReceiver(Intent intent, ActivityInfo info,
777 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
778 boolean sync, int sendingUser, int processState) {
779 updateProcessState(processState, false);
780 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
781 sync, false, mAppThread.asBinder(), sendingUser);
782 r.info = info;
783 r.compatInfo = compatInfo;
784 sendMessage(H.RECEIVER, r);
785 }
1660 case RECEIVER:
1661 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1662 handleReceiver((ReceiverData)msg.obj);
1663 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1664 break;
ActivityThread#handleReceiver
private void handleReceiver(ReceiverData data) {
3334 // If we are getting ready to gc after going to the background, well
3335 // we are back active so skip it.
3336 unscheduleGcIdler();
3337
3338 String component = data.intent.getComponent().getClassName();
3339
3340 LoadedApk packageInfo = getPackageInfoNoCheck(
3341 data.info.applicationInfo, data.compatInfo);
3342
3343 IActivityManager mgr = ActivityManager.getService();
3344
3345 Application app;
3346 BroadcastReceiver receiver;
3347 ContextImpl context;
3348 try {
3349 app = packageInfo.makeApplication(false, mInstrumentation);
3350 context = (ContextImpl) app.getBaseContext();
3351 if (data.info.splitName != null) {
3352 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
3353 }
3354 java.lang.ClassLoader cl = context.getClassLoader();
3355 data.intent.setExtrasClassLoader(cl);
3356 data.intent.prepareToEnterProcess();
3357 data.setExtrasClassLoader(cl);
3358 receiver = packageInfo.getAppFactory()
3359 .instantiateReceiver(cl, data.info.name, data.intent);
//对于静态广播而言,启动进程后就调用scheduleReceiver函数处理广播
//BroadcastReceiver的实例还没有创建,因此需要在此进行反射初始化
3360 } catch (Exception e) {
3361 if (DEBUG_BROADCAST) Slog.i(TAG,
3362 "Finishing failed broadcast to " + data.intent.getComponent());
//静态广播创建出问题,需要通知AMS,调用AMS的finishReceiver
3363 data.sendFinished(mgr);
3364 throw new RuntimeException(
3365 "Unable to instantiate receiver " + component
3366 + ": " + e.toString(), e);
3367 }
3368
3369 try {
3370 if (localLOGV) Slog.v(
3371 TAG, "Performing receive of " + data.intent
3372 + ": app=" + app
3373 + ", appName=" + app.getPackageName()
3374 + ", pkg=" + packageInfo.getPackageName()
3375 + ", comp=" + data.intent.getComponent().toShortString()
3376 + ", dir=" + packageInfo.getAppDir());
3377
3378 sCurrentBroadcastIntent.set(data.intent);
3379 receiver.setPendingResult(data);
3380 receiver.onReceive(context.getReceiverRestrictedContext(),
3381 data.intent);
3382 } catch (Exception e) {
3383 if (DEBUG_BROADCAST) Slog.i(TAG,
3384 "Finishing failed broadcast to " + data.intent.getComponent());
//静态广播调用onReceive时出问题,如所在进程已被销毁,需要通知AMS,调用AMS的finishReceiver
3385 data.sendFinished(mgr);
3386 if (!mInstrumentation.onException(receiver, e)) {
3387 throw new RuntimeException(
3388 "Unable to start receiver " + component
3389 + ": " + e.toString(), e);
3390 }
3391 } finally {
3392 sCurrentBroadcastIntent.set(null);
3393 }
3394
3395 if (receiver.getPendingResult() != null) {
3396 data.finish();
3397 }
3398 }
send Broadcast.png
网友评论