动态注册广播相关的
app端
LoadedApk#ReceiverDispatcher
1203 static final class ReceiverDispatcher {
1204
1205 final static class InnerReceiver extends IIntentReceiver.Stub {
1206 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1207 final LoadedApk.ReceiverDispatcher mStrongRef;
1208
1209 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1210 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1211 mStrongRef = strong ? rd : null;
1212 }
1213
1214 @Override
1215 public void performReceive(Intent intent, int resultCode, String data,
1216 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1217 final LoadedApk.ReceiverDispatcher rd;
1218 if (intent == null) {
1219 Log.wtf(TAG, "Null intent received");
1220 rd = null;
1221 } else {
1222 rd = mDispatcher.get();
1223 }
1224 if (ActivityThread.DEBUG_BROADCAST) {
1225 int seq = intent.getIntExtra("seq", -1);
1226 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1227 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
1228 }
1229 if (rd != null) {
1230 rd.performReceive(intent, resultCode, data, extras,
1231 ordered, sticky, sendingUser);
1232 } else {
1233 // The activity manager dispatched a broadcast to a registered
1234 // receiver in this process, but before it could be delivered the
1235 // receiver was unregistered. Acknowledge the broadcast on its
1236 // behalf so that the system's broadcast sequence can continue.
1237 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1238 "Finishing broadcast to unregistered receiver");
1239 IActivityManager mgr = ActivityManager.getService();
1240 try {
1241 if (extras != null) {
1242 extras.setAllowFds(false);
1243 }
1244 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
1245 } catch (RemoteException e) {
1246 throw e.rethrowFromSystemServer();
1247 }
1248 }
1249 }
1250 }
1251
1252 final IIntentReceiver.Stub mIIntentReceiver;
1253 final BroadcastReceiver mReceiver;
1254 final Context mContext;
1255 final Handler mActivityThread;
1256 final Instrumentation mInstrumentation;
1257 final boolean mRegistered;
1258 final IntentReceiverLeaked mLocation;
1259 RuntimeException mUnregisterLocation;
1260 boolean mForgotten;
1261
1262 final class Args extends BroadcastReceiver.PendingResult {
1263 private Intent mCurIntent;
1264 private final boolean mOrdered;
1265 private boolean mDispatched;
1266 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
1267
1268 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
1269 boolean ordered, boolean sticky, int sendingUser) {
1270 super(resultCode, resultData, resultExtras,
1271 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1272 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
1273 mCurIntent = intent;
1274 mOrdered = ordered;
1275 }
1276
1277 public final Runnable getRunnable() {
1278 return () -> {
1279 final BroadcastReceiver receiver = mReceiver;
1280 final boolean ordered = mOrdered;
1281
1282 if (ActivityThread.DEBUG_BROADCAST) {
1283 int seq = mCurIntent.getIntExtra("seq", -1);
1284 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1285 + " seq=" + seq + " to " + mReceiver);
1286 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1287 + " mOrderedHint=" + ordered);
1288 }
1289
1290 final IActivityManager mgr = ActivityManager.getService();
1291 final Intent intent = mCurIntent;
1292 if (intent == null) {
1293 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1294 + ": run() previously called at "
1295 + Log.getStackTraceString(mPreviousRunStacktrace));
1296 }
1297
1298 mCurIntent = null;
1299 mDispatched = true;
1300 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1301 if (receiver == null || intent == null || mForgotten) {
1302 if (mRegistered && ordered) {
1303 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1304 "Finishing null broadcast to " + mReceiver);
1305 sendFinished(mgr);
1306 }
1307 return;
1308 }
1309
1310 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1312 long startTime = SystemClock.uptimeMillis();
1313 try {
1314 ClassLoader cl = mReceiver.getClass().getClassLoader();
1315 intent.setExtrasClassLoader(cl);
1316 intent.prepareToEnterProcess();
1317 setExtrasClassLoader(cl);
1318 receiver.setPendingResult(this);
1319 receiver.onReceive(mContext, intent);
1320 } catch (Exception e) {
1321 if (mRegistered && ordered) {
1322 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1323 "Finishing failed broadcast to " + mReceiver);
1324 sendFinished(mgr);
1325 }
1326 if (mInstrumentation == null ||
1327 !mInstrumentation.onException(mReceiver, e)) {
1328 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1329 throw new RuntimeException(
1330 "Error receiving broadcast " + intent
1331 + " in " + mReceiver, e);
1332 }
1333 }
1334
1335 if (receiver.getPendingResult() != null) {
1336 finish();
1337 }
1340 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1341 };
1342 }
1343 }
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1424 Handler activityThread, Instrumentation instrumentation,
1425 boolean registered) {
1426 if (activityThread == null) {
1427 throw new NullPointerException("Handler must not be null");
1428 }
1429
1430 mIIntentReceiver = new InnerReceiver(this, !registered);
1431 mReceiver = receiver;
1432 mContext = context;
1433 mActivityThread = activityThread;
1434 mInstrumentation = instrumentation;
1435 mRegistered = registered;
1436 mLocation = new IntentReceiverLeaked(null);
1437 mLocation.fillInStackTrace();
1438 }
1439
1440 void validate(Context context, Handler activityThread) {
1441 if (mContext != context) {
1442 throw new IllegalStateException(
1443 "Receiver " + mReceiver +
1444 " registered with differing Context (was " +
1445 mContext + " now " + context + ")");
1446 }
1447 if (mActivityThread != activityThread) {
1448 throw new IllegalStateException(
1449 "Receiver " + mReceiver +
1450 " registered with differing handler (was " +
1451 mActivityThread + " now " + activityThread + ")");
1452 }
1453 }
1454
1455 IntentReceiverLeaked getLocation() {
1456 return mLocation;
1457 }
1458
1459 BroadcastReceiver getIntentReceiver() {
1460 return mReceiver;
1461 }
1462
1463 IIntentReceiver getIIntentReceiver() {
1464 return mIIntentReceiver;
1465 }
1466
1467 void setUnregisterLocation(RuntimeException ex) {
1468 mUnregisterLocation = ex;
1469 }
1470
1471 RuntimeException getUnregisterLocation() {
1472 return mUnregisterLocation;
1473 }
1474
1475 public void performReceive(Intent intent, int resultCode, String data,
1476 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1477 final Args args = new Args(intent, resultCode, data, extras, ordered,
1478 sticky, sendingUser);
1479 if (intent == null) {
1480 Log.wtf(TAG, "Null intent received");
1481 } else {
1482 if (ActivityThread.DEBUG_BROADCAST) {
1483 int seq = intent.getIntExtra("seq", -1);
1484 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1485 + " seq=" + seq + " to " + mReceiver);
1486 }
1487 }
1488 if (intent == null || !mActivityThread.post(args.getRunnable())) {
1489 if (mRegistered && ordered) {
1490 IActivityManager mgr = ActivityManager.getService();
1491 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1492 "Finishing sync broadcast to " + mReceiver);
1493 args.sendFinished(mgr);
1494 }
1495 }
1496 }
1497
1498 }
system_server端
ReceiverList
32final class ReceiverList extends ArrayList<BroadcastFilter>
33 implements IBinder.DeathRecipient {
34 final ActivityManagerService owner;
35 public final IIntentReceiver receiver;
36 public final ProcessRecord app;
37 public final int pid;
38 public final int uid;
39 public final int userId;
40 BroadcastRecord curBroadcast = null;
41 boolean linkedToDeath = false;
42
43 String stringName;
44
BroadcastFilter
25final class BroadcastFilter extends IntentFilter {
26 // Back-pointer to the list this filter is in.
27 final ReceiverList receiverList;
28 final String packageName;
29 final String requiredPermission;
30 final int owningUid;
31 final int owningUserId;
32 final boolean instantApp;
33 final boolean visibleToInstantApp;
34
一个ReceiverList可以包含多个BroadcastFilter ,及一个BoradcastReceiver对象可以见多个IntentFilter,这也是正常的
broadcast_register_s.jpg
InnerReceiver为IIntentReceiver对象,用于AMS binder call到客户端(oneway),最终调用客户端的onReceive
发送广播相关的另加
BroadcastQueue
68 private static final String TAG = "BroadcastQueue";
69 private static final String TAG_MU = TAG + POSTFIX_MU;
70 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
71
72 static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 50;
73 static final int MAX_BROADCAST_SUMMARY_HISTORY
74 = ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
75
76 final ActivityManagerService mService;
77
78 /**
79 * Recognizable moniker for this queue
80 */
81 final String mQueueName;
82
83 /**
84 * Timeout period for this queue's broadcasts
85 */
86 final long mTimeoutPeriod;
87
88 /**
89 * If true, we can delay broadcasts while waiting services to finish in the previous
90 * receiver's process.
91 */
92 final boolean mDelayBehindServices;
93
94 /**
95 * Lists of all active broadcasts that are to be executed immediately
96 * (without waiting for another broadcast to finish). Currently this only
97 * contains broadcasts to registered receivers, to avoid spinning up
98 * a bunch of processes to execute IntentReceiver components. Background-
99 * and foreground-priority broadcasts are queued separately.
100 */
101 final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
102
103 /**
104 * List of all active broadcasts that are to be executed one at a time.
105 * The object at the top of the list is the currently activity broadcasts;
106 * those after it are waiting for the top to finish. As with parallel
107 * broadcasts, separate background- and foreground-priority queues are
108 * maintained.
109 */
110 final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
111
112 /**
113 * Historical data of past broadcasts, for debugging. This is a ring buffer
114 * whose last element is at mHistoryNext.
115 */
116 final BroadcastRecord[] mBroadcastHistory = new BroadcastRecord[MAX_BROADCAST_HISTORY];
117 int mHistoryNext = 0;
118
119 /**
120 * Summary of historical data of past broadcasts, for debugging. This is a
121 * ring buffer whose last element is at mSummaryHistoryNext.
122 */
123 final Intent[] mBroadcastSummaryHistory = new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
124 int mSummaryHistoryNext = 0;
125
126 /**
127 * Various milestone timestamps of entries in the mBroadcastSummaryHistory ring
128 * buffer, also tracked via the mSummaryHistoryNext index. These are all in wall
129 * clock time, not elapsed.
130 */
131 final long[] mSummaryHistoryEnqueueTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
132 final long[] mSummaryHistoryDispatchTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
133 final long[] mSummaryHistoryFinishTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
134
135 /**
136 * Set when we current have a BROADCAST_INTENT_MSG in flight.
137 */
138 boolean mBroadcastsScheduled = false;
139
140 /**
141 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
142 */
143 boolean mPendingBroadcastTimeoutMessage;
144
145 /**
146 * Intent broadcasts that we have tried to start, but are
147 * waiting for the application's process to be created. We only
148 * need one per scheduling class (instead of a list) because we always
149 * process broadcasts one at a time, so no others can be started while
150 * waiting for this one.
151 */
152 BroadcastRecord mPendingBroadcast = null;
153
154 /**
155 * The receiver index that is pending, to restart the broadcast if needed.
156 */
157 int mPendingBroadcastRecvIndex;
158
159 static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
160 static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
161
162 final BroadcastHandler mHandler;
163
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 }
BroadcastRecord
45final class BroadcastRecord extends Binder {
46 final Intent intent; // the original intent that generated us
47 final ComponentName targetComp; // original component name set on the intent
48 final ProcessRecord callerApp; // process that sent this
49 final String callerPackage; // who sent this
50 final int callingPid; // the pid of who sent this
51 final int callingUid; // the uid of who sent this
52 final boolean callerInstantApp; // caller is an Instant App?
53 final boolean ordered; // serialize the send to receivers?
54 final boolean sticky; // originated from existing sticky data?
55 final boolean initialSticky; // initial broadcast from register to sticky?
56 final int userId; // user id this broadcast was for
57 final String resolvedType; // the resolved data type
58 final String[] requiredPermissions; // permissions the caller has required
59 final int appOp; // an app op that is associated with this broadcast
60 final BroadcastOptions options; // BroadcastOptions supplied by caller
61 final List receivers; // contains BroadcastFilter and ResolveInfo
62 final int[] delivery; // delivery state of each receiver
63 IIntentReceiver resultTo; // who receives final result if non-null
64 long enqueueClockTime; // the clock time the broadcast was enqueued
65 long dispatchTime; // when dispatch started on this set of receivers
66 long dispatchClockTime; // the clock time the dispatch started
67 long receiverTime; // when current receiver started for timeouts.
68 long finishTime; // when we finished the broadcast.
69 int resultCode; // current result code value.
70 String resultData; // current result data value.
71 Bundle resultExtras; // current result extra data values.
72 boolean resultAbort; // current result abortBroadcast value.
73 int nextReceiver; // next receiver to be executed.
74 IBinder receiver; // who is currently running, null if none.
75 int state;
76 int anrCount; // has this broadcast record hit any ANRs?
77 int manifestCount; // number of manifest receivers dispatched.
78 int manifestSkipCount; // number of manifest receivers skipped.
79 BroadcastQueue queue; // the outbound queue handling this broadcast
broadcast_send_dispatch.jpg
参考从源码角度看广播
网友评论