android之基础学习攻克

广播相关学习-processNextBroadcast逻辑

2018-12-19  本文已影响0人  weiinter105

下面梳理下processNextBroadcast的相关逻辑

BroadcastQueue#processNextBroadcast

854    //add arg parallelOnce if true, process one broadcast
855    void processNextBroadcast(boolean fromMsg) { 
856        processNextBrBroadcastQueue#processNextBroadcast
854    //add arg parallelOnce if true, process one broadcast
855    void processNextBroadcast(boolean fromMsg) { 
856        processNextBroadcast(fromMsg, false);
857    }
858
859    void processNextBroadcast(boolean fromMsg, boolean parallelOnce) {
860        synchronized (mService) {
861            processNextBroadcastLocked(fromMsg, false, parallelOnce);
862        }
863    }
864
865    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
866        processNextBroadcastLocked(fromMsg, skipOomAdj, false);
867    }
868
869    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj, boolean parallelOnce) {
870   
871        BroadcastRecord r;
872
873        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
874                + mQueueName + "]: "
875                + mParallelBroadcasts.size() + " parallel broadcasts, "
876                + mOrderedBroadcasts.size() + " ordered broadcasts");
877
878        mService.updateCpuStats();
879
880        if (fromMsg) {
881            mBroadcastsScheduled = false; //当这个消息还在队列中时,mBroadcastsScheduled为true;
                  //当消息开始执行时,这个值为false;那么就又可以发送消息BROADCAST_INTENT_MSG了;等到这个消息执行完了,就又会取出下面的消息依次执行
882        }
883
884        // First, deliver any non-serialized broadcasts right away.
             //首先处理并行广播
885        while (mParallelBroadcasts.size() > 0) {
886            r = mParallelBroadcasts.remove(0);
887            r.dispatchTime = SystemClock.uptimeMillis(); //对于串行广播的dispatchTime,就是
888            r.dispatchClockTime = System.currentTimeMillis();//记录广播的分发时间(分发时间-入队时间 = BROADCAST_INTENT_MSG消息的等待时间)
889
890            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
891                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
892                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
893                    System.identityHashCode(r));
894                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
895                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
896                    System.identityHashCode(r));
897            }
898
899            final int N = r.receivers.size();
900            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
901                    + mQueueName + "] " + r);
902            for (int i=0; i<N; i++) {
903                Object target = r.receivers.get(i);
904                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
905                        "Delivering non-ordered on [" + mQueueName + "] to registered "
906                        + target + ": " + r);
907                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i); //对并行广播的每个动态接收者,调用deliverToRegisteredReceiverLocked
908            }
909            addBroadcastToHistoryLocked(r); //将处理过的broadcast加入到历史记录中
910            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
911                    + mQueueName + "] " + r);
919        }
920
921        // Now take care of the next serialized one...
922
923        // If we are waiting for a process to come up to handle the next
924        // broadcast, then do nothing at this point.  Just in case, we
925        // check that the process we're waiting for still exists.
            //开始处理有序广播或者静态注册的receiver
             // 对于有序或静态广播而言,需要依次向每个BroadcastReceiver发送广播,前一个处理完毕后才能发送下一个广播
            // 如果BroadcastReceiver对应的进程还未启动,则需要等待
            // mPendingBroadcast就是用于保存,因为对应进程还未启动,而处于等待状态的BroadcastRecord
926        if (mPendingBroadcast != null) {
927            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
928                    "processNextBroadcast [" + mQueueName + "]: waiting for "
929                    + mPendingBroadcast.curApp);
930
931            boolean isDead;
932            if (mPendingBroadcast.curApp.pid > 0) {
       //通过AMS得到对应进程的信息
        //BroadRecord对应多个BroadcastReceiver,即对应多个进程
        //此处curApp保存当前正在等待的进程
933                synchronized (mService.mPidsSelfLocked) {
934                    ProcessRecord proc = mService.mPidsSelfLocked.get(
935                            mPendingBroadcast.curApp.pid);
936                    isDead = proc == null || proc.crashing;
937                }
938            } else {
939                final ProcessRecord proc = mService.mProcessNames.get(
940                        mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
941                isDead = proc == null || !proc.pendingStart;
942            }
943            if (!isDead) {
944                // It's still alive, so keep waiting
         // 注意到有序和静态广播必须依次处理
        // 因此,若前一个BroadcastRecord对应的某个进程启动较慢,不仅会影响该BroadcastRecord中后续进程接收广播
        // 还会影响到后续所有BroadcastRecord对应进程接收广播
945                return;
946            } else {
947                Slog.w(TAG, "pending app  ["
948                        + mQueueName + "]" + mPendingBroadcast.curApp
949                        + " died before responding to broadcast");
950                mPendingBroadcast.state = BroadcastRecord.IDLE;
951                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
952                mPendingBroadcast = null;
953            }
954        }
955
956        boolean looped = false;
957
958        do {
959            if (mOrderedBroadcasts.size() == 0) {
                     //没有串行广播等待处理了,那么就可以return了
960                // No more broadcasts pending, so all done!
961                mService.scheduleAppGcsLocked();
962                if (looped) {
963                    // If we had finished the last ordered broadcast, then
964                    // make sure all processes have correct oom and sched
965                    // adjustments.
                        // 因为静态广播和有序广播,可能拉起进程
                       // 因此这些广播处理完毕后,AMS需要释放掉一些不需要的进程
966                    mService.updateOomAdjLocked();
967                }
968                return;
969            }
970            r = mOrderedBroadcasts.get(0); //取出串行队列中的第一个broadcastRecord
971            boolean forceReceive = false;
972
973            // Ensure that even if something goes awry with the timeout
974            // detection, we catch "hung" broadcasts here, discard them,
975            // and continue to make progress.
976            //
977            // This is only done if the system is ready so that PRE_BOOT_COMPLETED
978            // receivers don't get executed with timeouts. They're intended for
979            // one time heavy lifting after system upgrades and can take
980            // significant amounts of time.
981            int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
                 // 这里用于判断此广播是否处理超时
    // 仅在系统启动完毕后,才进行该判断,因为PRE_BOOT_COMPLETED广播可能由于系统升级需要等待较长时间
982            if (mService.mProcessesReady && r.dispatchTime > 0) {
983                long now = SystemClock.uptimeMillis();
984                if ((numReceivers > 0) &&
985                        (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
                         //单个广播处理的超时时间,定义为2 * 每个接收者处理的最长时间(10s)* 接收者的数量
986                    Slog.w(TAG, "Hung broadcast ["
987                            + mQueueName + "] discarded after timeout failure:"
988                            + " now=" + now
989                            + " dispatchTime=" + r.dispatchTime
990                            + " startTime=" + r.receiverTime
991                            + " intent=" + r.intent
992                            + " numReceivers=" + numReceivers
993                            + " nextReceiver=" + r.nextReceiver
994                            + " state=" + r.state);
                         
995                    broadcastTimeoutLocked(false); // forcibly finish this broadcast  //直接调用broadcastTimeoutLocked时,参数为false
996                    forceReceive = true; 
997                    r.state = BroadcastRecord.IDLE; //强制结束这条广播
                          //BroadcastRecord状态为idle时代表当前receiver或者整个BroadcastRecord处理完了,可以处理下一个了
998                }
999            }
1000
1001            if (r.state != BroadcastRecord.IDLE) {
1002                if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
1003                        "processNextBroadcast("
1004                        + mQueueName + ") called when not idle (state="
1005                        + r.state + ")");
1006                return;
1007            }
1008
1009            if (r.receivers == null || r.nextReceiver >= numReceivers
1010                    || r.resultAbort || forceReceive) {
                        //receiver处理完了,或者broadcastRecord强制结束,都代表该broadcast处理完了
1011                // No more receivers for this broadcast!  Send the final
1012                // result if requested...
1013                if (r.resultTo != null) {
                            //当广播执行完或者强制取消的时候,将结果返回给r.resultTo
1014                    try {
1015                        if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
1016                                "Finishing broadcast [" + mQueueName + "] "
1017                                + r.intent.getAction() + " app=" + r.callerApp);
1018                        performReceiveLocked(r.callerApp, r.resultTo,
1019                            new Intent(r.intent), r.resultCode,
1020                            r.resultData, r.resultExtras, false, false, r.userId);
1021                        // Set this to null so that the reference
1022                        // (local and remote) isn't kept in the mBroadcastHistory.
1023                        r.resultTo = null;
1024                    } catch (RemoteException e) {
1025                        r.resultTo = null;
1026                        Slog.w(TAG, "Failure ["
1027                                + mQueueName + "] sending broadcast result of "
1028                                + r.intent, e);
1029
1030                    }
1031                }
1032
1033                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
1034                cancelBroadcastTimeoutLocked(); //广播确实执行完了,或者强制结束了,那么就cancelBroadcastTimeoutLocked;但如果是因为超时被强制执行的,当时的receiver进程的app process已经ANR了,这个其实没用
1035
1036                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
1037                        "Finished with ordered broadcast " + r);
1038
1039                // ... and on to the next...
1040                addBroadcastToHistoryLocked(r);
1041                if (r.intent.getComponent() == null && r.intent.getPackage() == null
1042                        && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
1043                    // This was an implicit broadcast... let's record it for posterity.
1044                    mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
1045                            r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
1046                }
1047                mOrderedBroadcasts.remove(0);
1048                r = null;
1049                looped = true; //将r置为null,looped置为true;进行以下轮循环,取出下一个串行队列中的广播
1050                continue;
1051            }
1052        } while (r == null);
1053
               //上面的流程是找到串行队列中第一个BroadcastRecord,下面处理其中的receiver
1054        // Get the next receiver...
1055        int recIdx = r.nextReceiver++;  
1056
1057        // Keep track of when this receiver started, and make sure there
1058        // is a timeout message pending to kill it if need be.
1059        r.receiverTime = SystemClock.uptimeMillis(); //对于串行广播而言,每当传递到一个新的receiver时都更新下receiverTime
1060        if (recIdx == 0) {
1061            r.dispatchTime = r.receiverTime; //取出广播的第一个receiver时,就是广播的BroadcastRecord相应的dispatchTime
1062            r.dispatchClockTime = System.currentTimeMillis();
1063            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
1064                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1065                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
1066                    System.identityHashCode(r));
1067                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1068                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
1069                    System.identityHashCode(r));
1070            }
1071            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
1072                    + mQueueName + "] " + r);
1073        }
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        }
1081
1082        final BroadcastOptions brOptions = r.options;
1083        final Object nextReceiver = r.receivers.get(recIdx); //得到待处理的receiver
1084
1085        if (nextReceiver instanceof BroadcastFilter) {   
                    //receiver是动态注册的
1086            // Simple case: this is a registered receiver who gets
1087            // a direct call.
1088            BroadcastFilter filter = (BroadcastFilter)nextReceiver; 
1089            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
1090                    "Delivering ordered ["
1091                    + mQueueName + "] to registered "
1092                    + filter + ": " + r);
1093            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx); //调用deliverToRegisteredReceiverLocked处理该动态注册receiver
1094            if (r.receiver == null || !r.ordered) {
1095                // The receiver has already finished, so schedule to
1096                // process the next one. //在处理广播的过程performReceiveLocked中,如果receiver所在进程被kill,则会将r.receiver = null; r.curFilter = null;
1097                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
1098                        + mQueueName + "]: ordered="
1099                        + r.ordered + " receiver=" + r.receiver);
1100                r.state = BroadcastRecord.IDLE; //将当前的状态置为IDLE
1101                scheduleBroadcastsLocked(); //触发下一轮处理过程
1102            } else {
                       //处理特殊的选项
                       //向DeviceIdleController发送消息,赋予白名单内的应用,
                        //在Doze模式的激活窗口中,额外的可以访问网络和持锁的时间(后续再调研)
1103                if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { //参考BroadcastOptions
1104                    scheduleTempWhitelistLocked(filter.owningUid,
1105                            brOptions.getTemporaryAppWhitelistDuration(), r);
1106                }
1107            }
1108            return;
1109        }
1110
1111        // Hard case: need to instantiate the receiver, possibly
1112        // starting its application process to host it.
1113
1114        ResolveInfo info =
1115            (ResolveInfo)nextReceiver;
1116        ComponentName component = new ComponentName(
1117                info.activityInfo.applicationInfo.packageName,
1118                info.activityInfo.name); //静态注册广播的处理
1119
1120        boolean skip = false;
1121        if (brOptions != null &&
1122                (info.activityInfo.applicationInfo.targetSdkVersion
1123                        < brOptions.getMinManifestReceiverApiLevel() ||
1124                info.activityInfo.applicationInfo.targetSdkVersion
1125                        > brOptions.getMaxManifestReceiverApiLevel())) {
1126            skip = true;
1127        }
1128        int perm = mService.checkComponentPermission(info.activityInfo.permission,
1129                r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
1130                info.activityInfo.exported);
1131        if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
1132            if (!info.activityInfo.exported) {
1133                Slog.w(TAG, "Permission Denial: broadcasting "
1134                        + r.intent.toString()
1135                        + " from " + r.callerPackage + " (pid=" + r.callingPid
1136                        + ", uid=" + r.callingUid + ")"
1137                        + " is not exported from uid " + info.activityInfo.applicationInfo.uid
1138                        + " due to receiver " + component.flattenToShortString());
1139            } else {
1140                Slog.w(TAG, "Permission Denial: broadcasting "
1141                        + r.intent.toString()
1142                        + " from " + r.callerPackage + " (pid=" + r.callingPid
1143                        + ", uid=" + r.callingUid + ")"
1144                        + " requires " + info.activityInfo.permission
1145                        + " due to receiver " + component.flattenToShortString());
1146            }
1147            skip = true;
1148        } else if (!skip && info.activityInfo.permission != null) {
1149            final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
1150            if (opCode != AppOpsManager.OP_NONE
1151                    && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
1152                            r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
1153                Slog.w(TAG, "Appop Denial: broadcasting "
1154                        + r.intent.toString()
1155                        + " from " + r.callerPackage + " (pid="
1156                        + r.callingPid + ", uid=" + r.callingUid + ")"
1157                        + " requires appop " + AppOpsManager.permissionToOp(
1158                                info.activityInfo.permission)
1159                        + " due to registered receiver "
1160                        + component.flattenToShortString());
1161                skip = true;
1162            }
1163        }
1164        if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
1165            r.requiredPermissions != null && r.requiredPermissions.length > 0) {
1166            for (int i = 0; i < r.requiredPermissions.length; i++) {
1167                String requiredPermission = r.requiredPermissions[i];
1168                try {
1169                    perm = AppGlobals.getPackageManager().
1170                            checkPermission(requiredPermission,
1171                                    info.activityInfo.applicationInfo.packageName,
1172                                    UserHandle
1173                                            .getUserId(info.activityInfo.applicationInfo.uid));
1174                } catch (RemoteException e) {
1175                    perm = PackageManager.PERMISSION_DENIED;
1176                }
1177                if (perm != PackageManager.PERMISSION_GRANTED) {
1178                    Slog.w(TAG, "Permission Denial: receiving "
1179                            + r.intent + " to "
1180                            + component.flattenToShortString()
1181                            + " requires " + requiredPermission
1182                            + " due to sender " + r.callerPackage
1183                            + " (uid " + r.callingUid + ")");
1184                    skip = true;
1185                    break;
1186                }
1187                int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
1188                if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
1192                        && mService.mAppOpsService.checkOperation(appOp,
1193                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
1195                        != AppOpsManager.MODE_ALLOWED) {
1196                    Slog.w(TAG, "Appop Denial: receiving "
1197                            + r.intent + " to "
1198                            + component.flattenToShortString()
1199                            + " requires appop " + AppOpsManager.permissionToOp(
1200                            requiredPermission)
1201                            + " due to sender " + r.callerPackage
1202                            + " (uid " + r.callingUid + ")");
1203                    skip = true;
1204                    break;
1205                }
1206            }
1207        }
1208        if (!skip && r.appOp != AppOpsManager.OP_NONE
1215                != AppOpsManager.MODE_ALLOWED) {
1216            Slog.w(TAG, "Appop Denial: receiving "
1217                    + r.intent + " to "
1218                    + component.flattenToShortString()
1219                    + " requires appop " + AppOpsManager.opToName(r.appOp)
1220                    + " due to sender " + r.callerPackage
1221                    + " (uid " + r.callingUid + ")");
1222            skip = true;
1223        }
1229        if (!skip) {
1230            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
1231                    r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
1232        }
1233        boolean isSingleton = false;
1234        try {
1235            isSingleton = mService.isSingleton(info.activityInfo.processName,
1236                    info.activityInfo.applicationInfo,
1237                    info.activityInfo.name, info.activityInfo.flags);
1238        } catch (SecurityException e) {
1239            Slog.w(TAG, e.getMessage());
1240            skip = true;
1241        }
1242        if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
1243            if (ActivityManager.checkUidPermission(
1244                    android.Manifest.permission.INTERACT_ACROSS_USERS,
1245                    info.activityInfo.applicationInfo.uid)
1246                            != PackageManager.PERMISSION_GRANTED) {
1247                Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
1248                        + " requests FLAG_SINGLE_USER, but app does not hold "
1249                        + android.Manifest.permission.INTERACT_ACROSS_USERS);
1250                skip = true;
1251            }
1252        }
1253        if (!skip && info.activityInfo.applicationInfo.isInstantApp()
1254                && r.callingUid != info.activityInfo.applicationInfo.uid) {
1255            Slog.w(TAG, "Instant App Denial: receiving "
1256                    + r.intent
1257                    + " to " + component.flattenToShortString()
1258                    + " due to sender " + r.callerPackage
1259                    + " (uid " + r.callingUid + ")"
1260                    + " Instant Apps do not support manifest receivers");
1261            skip = true;
1262        }
1263        if (!skip && r.callerInstantApp
1264                && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
1265                && r.callingUid != info.activityInfo.applicationInfo.uid) {
1266            Slog.w(TAG, "Instant App Denial: receiving "
1267                    + r.intent
1268                    + " to " + component.flattenToShortString()
1269                    + " requires receiver have visibleToInstantApps set"
1270                    + " due to sender " + r.callerPackage
1271                    + " (uid " + r.callingUid + ")");
1272            skip = true;
1273        }
1274        if (r.curApp != null && r.curApp.crashing) {
1275            // If the target process is crashing, just skip it.
1276            Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
1277                    + " to " + r.curApp + ": process crashing");
1278            skip = true;
1279        }
1280        if (!skip) {
1281            boolean isAvailable = false;
1282            try {
1283                isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
1284                        info.activityInfo.packageName,
1285                        UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
1286            } catch (Exception e) {
1287                // all such failures mean we skip this receiver
1288                Slog.w(TAG, "Exception getting recipient info for "
1289                        + info.activityInfo.packageName, e);
1290            }
1291            if (!isAvailable) {
1292                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
1293                        "Skipping delivery to " + info.activityInfo.packageName + " / "
1294                        + info.activityInfo.applicationInfo.uid
1295                        + " : package no longer available");
1296                skip = true;
1297            }
1298        }
1299
1300        // If permissions need a review before any of the app components can run, we drop
1301        // the broadcast and if the calling app is in the foreground and the broadcast is
1302        // explicit we launch the review UI passing it a pending intent to send the skipped
1303        // broadcast.
1304        if (mService.mPermissionReviewRequired && !skip) {
1305            if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
1306                    info.activityInfo.packageName, UserHandle.getUserId(
1307                            info.activityInfo.applicationInfo.uid))) {
1308                skip = true;
1309            }
1310        }
1311
1312        // This is safe to do even if we are skipping the broadcast, and we need
1313        // this information now to evaluate whether it is going to be allowed to run.
1314        final int receiverUid = info.activityInfo.applicationInfo.uid;
1315        // If it's a singleton, it needs to be the same app or a special app
1316        if (r.callingUid != Process.SYSTEM_UID && isSingleton
1317                && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
1318            info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
1319        }
               //上面都是一些权限校验,暂时不详述了(和deliverToRegisteredReceiverLocked一样,前面也要做一些权限检查)
1320        String targetProcess = info.activityInfo.processName;
1321        ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
1322                info.activityInfo.applicationInfo.uid, false);
1323       
        // 这里也是权限的校验,但是这里比较重要,因为Android新版本的限制越来越多在此处判断
        // getAppStartModeLocked中会根据idle白名单,tmp名单,targetSdkVersion,appops权限等一些列校验
        // 随着Android版本变化,此处的校验也越来越严格
1324        if (!skip) {
1325            final int allowed = mService.getAppStartModeLocked(
1326                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
1329                    info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false, r.callerPackage); //r.callerPackage // who sent this 发送广播的进程
1330            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
1331                // We won't allow this receiver to be launched if the app has been
1332                // completely disabled from launches, or it was not explicitly sent
1333                // to it and the app is in a state that should not receive it
1334                // (depending on how getAppStartModeLocked has determined that).
1335                if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
1336                    Slog.w(TAG, "Background execution disabled: receiving "
1337                            + r.intent + " to "
1338                            + component.flattenToShortString());
1339                    skip = true;
                        // 在Android O上对后台app不允许接收广播的管控
1340                } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
 /**
5808     * If set, the broadcast will never go to manifest receivers in background (cached
5809     * or not running) apps, regardless of whether that would be done by default.  By
5810     * default they will receive broadcasts if the broadcast has specified an
5811     * explicit component or package name.
5812     * @hide
5813    
5814    public static final int FLAG_RECEIVER_EXCLUDE_BACKGROUND = 0x00800000;
 */
1341                        || (r.intent.getComponent() == null
1342                            && r.intent.getPackage() == null
1343                            && ((r.intent.getFlags()
1344                                    & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)

 /**
5796     * If set, the broadcast will always go to manifest receivers in background (cached
5797     * or not running) apps, regardless of whether that would be done by default.  By
5798     * default they will only receive broadcasts if the broadcast has specified an
5799     * explicit component or package name.
5800     *
5801     * NOTE: dumpstate uses this flag numerically, so when its value is changed
5802     * the broadcast code there must also be changed to match.
5803     *
5804     * @hide
5805    
5806    public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
 */
1345                            && !isSignaturePerm(r.requiredPermissions))) {
1346                    mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
1347                            component.getPackageName());
1348                    Slog.w(TAG, "Background execution not allowed: receiving "
1349                            + r.intent + " to "
1350                            + component.flattenToShortString());
1351                    skip = true;
1352                }
1353            }
1354        }
1355
1356        if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
1357                && !mService.mUserController
1358                .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
1359                        0 /* flags */)) {
1360            skip = true;
1361            Slog.w(TAG,
1362                    "Skipping delivery to " + info.activityInfo.packageName + " / "
1363                            + info.activityInfo.applicationInfo.uid + " : user is not running"); //user is not running,且广播不输ACTION_SHUTDOWN的情况下,肯定要skip receiver
1364        }
1365
1366        if (skip) {
1367            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
1368                    "Skipping delivery of ordered [" + mQueueName + "] "
1369                    + r + " for whatever reason");
1370            r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
1371            r.receiver = null;
1372            r.curFilter = null;
1373            r.state = BroadcastRecord.IDLE;
1374            r.manifestSkipCount++;
                    //如果要跳过当前的receiver(skip = true),对BroadcastRecord做一些清理工作
1375            scheduleBroadcastsLocked(); //触发下一轮
1376            return;
1377        }
1378        r.manifestCount++;
1379
1380        r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
1381        r.state = BroadcastRecord.APP_RECEIVE; //将BroadcastRecord的状态设为APP_RECEIVE
1382        r.curComponent = component;
1383        r.curReceiver = info.activityInfo;
1384        if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
1385            Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
1386                    + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
1387                    + receiverUid);
1388        }
1389
1390        if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
1391            scheduleTempWhitelistLocked(receiverUid,
1392                    brOptions.getTemporaryAppWhitelistDuration(), r);
1393        }
1394
1395        // Broadcast is being executed, its package can't be stopped.
1396        try {
                      // 因为广播在派发,设置package不能被stop
1397            AppGlobals.getPackageManager().setPackageStoppedState(
1398                    r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
1399        } catch (RemoteException e) {
1400        } catch (IllegalArgumentException e) {
1401            Slog.w(TAG, "Failed trying to unstop package "
1402                    + r.curComponent.getPackageName() + ": " + e);
1403        }
1404
1405        // Is this receiver's application already running?
1406        if (app != null && app.thread != null && !app.killed) {
                // 此处判断这个receiver的进程是否存在,如果存在,那么在processCurBroadcastLocked派发
1407            try {
1408                app.addPackage(info.activityInfo.packageName,
1409                        info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
1410                processCurBroadcastLocked(r, app, skipOomAdj);
1411                return;
1412            } catch (RemoteException e) {
1413                Slog.w(TAG, "Exception when sending broadcast to "
1414                      + r.curComponent, e);
1415            } catch (RuntimeException e) {
1416                Slog.wtf(TAG, "Failed sending broadcast to "
1417                        + r.curComponent + " with " + r.intent, e);
1418                // If some unexpected exception happened, just skip
1419                // this broadcast.  At this point we are not in the call
1420                // from a client, so throwing an exception out from here
1421                // will crash the entire system instead of just whoever
1422                // sent the broadcast.
1423                logBroadcastReceiverDiscardLocked(r);
1424                finishReceiverLocked(r, r.resultCode, r.resultData,
1425                        r.resultExtras, r.resultAbort, false); //主要是做一些清理工作
1426                scheduleBroadcastsLocked(); //主动触发处理下一个receiver或者BroadcastRecord的流程;processNextBroadcast
1427                // We need to reset the state if we failed to start the receiver.
1428                r.state = BroadcastRecord.IDLE;
1429                return;
1430            }
1431
1432            // If a dead object exception was thrown -- fall through to
1433            // restart the application.
1434        }
1435
1436        // Not running -- get it started, to be executed when the app comes up.
1437        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
1438                "Need to start app ["
1439                + mQueueName + "] " + targetProcess + " for broadcast " + r);
1440
1446       // 如果进程不在,启动新的进程
1447        if ((r.curApp=mService.startProcessLocked(targetProcess,
1448                info.activityInfo.applicationInfo, true,
1449                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
1450                "broadcast", r.curComponent,
1454                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false,
1455                        r.callerPackage)) == null) {
1457            // Ah, this recipient is unavailable.  Finish it if necessary,
1458            // and mark the broadcast record as ready for the next.
1459            Slog.w(TAG, "Unable to launch app "
1460                    + info.activityInfo.applicationInfo.packageName + "/"
1461                    + receiverUid + " for broadcast "
1462                    + r.intent + ": process is bad");
1463            logBroadcastReceiverDiscardLocked(r);
1464            finishReceiverLocked(r, r.resultCode, r.resultData,
1465                    r.resultExtras, r.resultAbort, false);
1466            scheduleBroadcastsLocked();
1467            r.state = BroadcastRecord.IDLE;
1468            return;
1469        }
1470
1471        mPendingBroadcast = r; //将进程放到 mPendingBroadcast 中,记录待处理的广播;在进程启动之后,进程attach到system server的时候处理
1472        mPendingBroadcastRecvIndex = recIdx;
1473    }
1474

BroadcastQueue#deliverToRegisteredReceiverLocked(广播传递给动态注册的接收者)
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    }

总结上面的逻辑而言,大体分为以下4步:
1.处理并行队列中所有的并行广播;
2.处理等待中的mPendingBroadcast,正常情况下这个值为null,进程启动后attach到system_server就会处理;
大致处理逻辑如下:
attachApplicationLocked->sendPendingBroadcastsLocked-> processCurBroadcastLocked

322    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
323        boolean didSomething = false;
324        final BroadcastRecord br = mPendingBroadcast;
325        if (br != null && br.curApp.pid > 0 && br.curApp.pid == app.pid) {
326            if (br.curApp != app) {
327                Slog.e(TAG, "App mismatch when sending pending broadcast to "
328                        + app.processName + ", intended target is " + br.curApp.processName);
329                return false;
330            }
331            try {
332                mPendingBroadcast = null;
333                processCurBroadcastLocked(br, app, false);
334                didSomething = true;
335            } catch (Exception e) {
336                Slog.w(TAG, "Exception in new application when starting receiver "
337                        + br.curComponent.flattenToShortString(), e);
338                logBroadcastReceiverDiscardLocked(br);
339                finishReceiverLocked(br, br.resultCode, br.resultData,
340                        br.resultExtras, br.resultAbort, false);
341                scheduleBroadcastsLocked();
342                // We need to reset the state if we failed to start the receiver.
343                br.state = BroadcastRecord.IDLE;
344                throw new RuntimeException(e.getMessage());
345            }
346        }
347        return didSomething;
348    }

3.对于串行广播,找到当前串行队列队头的BroadcastRecord;对Broadcast是否已经传递结束或者超时;这种情况下处理BroadcastRecord指定的resultTo,再将该广播从串行队列中移除;
4.找到串行广播本次要处理的receiver;区分是动态注册的还是静态注册的;

send Broadcast.png
上一篇下一篇

猜你喜欢

热点阅读