blob: 745cb7e0ff7bbcf711553a72bf11941d9bc1e248 [file] [log] [blame]
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import java.io.FileDescriptor;
20import java.io.PrintWriter;
Christopher Tatef278f122015-04-22 13:12:01 -070021import java.text.SimpleDateFormat;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080022import java.util.ArrayList;
Christopher Tatef278f122015-04-22 13:12:01 -070023import java.util.Date;
Wale Ogunwaleca1c1252015-05-15 12:49:13 -070024import java.util.Set;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080025
Dianne Hackborn7d19e022012-08-07 19:12:33 -070026import android.app.ActivityManager;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080027import android.app.AppGlobals;
Dianne Hackbornf51f6122013-02-04 18:23:34 -080028import android.app.AppOpsManager;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080029import android.content.ComponentName;
30import android.content.IIntentReceiver;
31import android.content.Intent;
Dianne Hackborn7d19e022012-08-07 19:12:33 -070032import android.content.pm.ActivityInfo;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080033import android.content.pm.PackageManager;
34import android.content.pm.ResolveInfo;
35import android.os.Bundle;
36import android.os.Handler;
37import android.os.IBinder;
Jeff Brown6f357d32014-01-15 20:40:55 -080038import android.os.Looper;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080039import android.os.Message;
40import android.os.Process;
41import android.os.RemoteException;
42import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070043import android.os.UserHandle;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080044import android.util.EventLog;
45import android.util.Slog;
46
Wale Ogunwaled57969f2014-11-15 19:37:29 -080047import static com.android.server.am.ActivityManagerDebugConfig.*;
48
Dianne Hackborn40c8db52012-02-10 18:59:48 -080049/**
50 * BROADCASTS
51 *
52 * We keep two broadcast queues and associated bookkeeping, one for those at
53 * foreground priority, and one for normal (background-priority) broadcasts.
54 */
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070055public final class BroadcastQueue {
Wale Ogunwalebfac4682015-04-08 14:33:21 -070056 private static final String TAG = "BroadcastQueue";
Wale Ogunwaled57969f2014-11-15 19:37:29 -080057 private static final String TAG_MU = TAG + POSTFIX_MU;
58 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080059
Dianne Hackborn4c51de42013-10-16 23:34:35 -070060 static final int MAX_BROADCAST_HISTORY = ActivityManager.isLowRamDeviceStatic() ? 10 : 50;
Dianne Hackborn6285a322013-09-18 12:09:47 -070061 static final int MAX_BROADCAST_SUMMARY_HISTORY
Dianne Hackborn4c51de42013-10-16 23:34:35 -070062 = ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
Dianne Hackborn40c8db52012-02-10 18:59:48 -080063
64 final ActivityManagerService mService;
65
66 /**
67 * Recognizable moniker for this queue
68 */
69 final String mQueueName;
70
71 /**
72 * Timeout period for this queue's broadcasts
73 */
74 final long mTimeoutPeriod;
75
76 /**
Dianne Hackborn6285a322013-09-18 12:09:47 -070077 * If true, we can delay broadcasts while waiting services to finish in the previous
78 * receiver's process.
79 */
80 final boolean mDelayBehindServices;
81
82 /**
Dianne Hackborn40c8db52012-02-10 18:59:48 -080083 * Lists of all active broadcasts that are to be executed immediately
84 * (without waiting for another broadcast to finish). Currently this only
85 * contains broadcasts to registered receivers, to avoid spinning up
86 * a bunch of processes to execute IntentReceiver components. Background-
87 * and foreground-priority broadcasts are queued separately.
88 */
Wale Ogunwale540e1232015-05-01 15:35:39 -070089 final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
Dianne Hackborn6285a322013-09-18 12:09:47 -070090
Dianne Hackborn40c8db52012-02-10 18:59:48 -080091 /**
92 * List of all active broadcasts that are to be executed one at a time.
93 * The object at the top of the list is the currently activity broadcasts;
94 * those after it are waiting for the top to finish. As with parallel
95 * broadcasts, separate background- and foreground-priority queues are
96 * maintained.
97 */
Wale Ogunwale540e1232015-05-01 15:35:39 -070098 final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
Dianne Hackborn40c8db52012-02-10 18:59:48 -080099
100 /**
Christopher Tatef278f122015-04-22 13:12:01 -0700101 * Historical data of past broadcasts, for debugging. This is a ring buffer
102 * whose last element is at mHistoryNext.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800103 */
Dianne Hackborn6285a322013-09-18 12:09:47 -0700104 final BroadcastRecord[] mBroadcastHistory = new BroadcastRecord[MAX_BROADCAST_HISTORY];
Christopher Tatef278f122015-04-22 13:12:01 -0700105 int mHistoryNext = 0;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800106
107 /**
Christopher Tatef278f122015-04-22 13:12:01 -0700108 * Summary of historical data of past broadcasts, for debugging. This is a
109 * ring buffer whose last element is at mSummaryHistoryNext.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700110 */
Dianne Hackborn6285a322013-09-18 12:09:47 -0700111 final Intent[] mBroadcastSummaryHistory = new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
Christopher Tatef278f122015-04-22 13:12:01 -0700112 int mSummaryHistoryNext = 0;
113
114 /**
115 * Various milestone timestamps of entries in the mBroadcastSummaryHistory ring
116 * buffer, also tracked via the mSummaryHistoryNext index. These are all in wall
117 * clock time, not elapsed.
118 */
119 final long[] mSummaryHistoryEnqueueTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
120 final long[] mSummaryHistoryDispatchTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
121 final long[] mSummaryHistoryFinishTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700122
123 /**
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800124 * Set when we current have a BROADCAST_INTENT_MSG in flight.
125 */
126 boolean mBroadcastsScheduled = false;
127
128 /**
129 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
130 */
131 boolean mPendingBroadcastTimeoutMessage;
132
133 /**
134 * Intent broadcasts that we have tried to start, but are
135 * waiting for the application's process to be created. We only
136 * need one per scheduling class (instead of a list) because we always
137 * process broadcasts one at a time, so no others can be started while
138 * waiting for this one.
139 */
140 BroadcastRecord mPendingBroadcast = null;
141
142 /**
143 * The receiver index that is pending, to restart the broadcast if needed.
144 */
145 int mPendingBroadcastRecvIndex;
146
147 static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
148 static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
149
Jeff Brown6f357d32014-01-15 20:40:55 -0800150 final BroadcastHandler mHandler;
151
152 private final class BroadcastHandler extends Handler {
153 public BroadcastHandler(Looper looper) {
154 super(looper, null, true);
155 }
156
157 @Override
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800158 public void handleMessage(Message msg) {
159 switch (msg.what) {
160 case BROADCAST_INTENT_MSG: {
161 if (DEBUG_BROADCAST) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800162 TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800163 processNextBroadcast(true);
164 } break;
165 case BROADCAST_TIMEOUT_MSG: {
166 synchronized (mService) {
167 broadcastTimeoutLocked(true);
168 }
169 } break;
170 }
171 }
172 };
173
174 private final class AppNotResponding implements Runnable {
175 private final ProcessRecord mApp;
176 private final String mAnnotation;
177
178 public AppNotResponding(ProcessRecord app, String annotation) {
179 mApp = app;
180 mAnnotation = annotation;
181 }
182
183 @Override
184 public void run() {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700185 mService.appNotResponding(mApp, null, null, false, mAnnotation);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800186 }
187 }
188
Jeff Brown6f357d32014-01-15 20:40:55 -0800189 BroadcastQueue(ActivityManagerService service, Handler handler,
190 String name, long timeoutPeriod, boolean allowDelayBehindServices) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800191 mService = service;
Jeff Brown6f357d32014-01-15 20:40:55 -0800192 mHandler = new BroadcastHandler(handler.getLooper());
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800193 mQueueName = name;
194 mTimeoutPeriod = timeoutPeriod;
Dianne Hackborn6285a322013-09-18 12:09:47 -0700195 mDelayBehindServices = allowDelayBehindServices;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800196 }
197
198 public boolean isPendingBroadcastProcessLocked(int pid) {
199 return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
200 }
201
202 public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
203 mParallelBroadcasts.add(r);
Jeff Brown9fb3fd12014-09-29 15:32:12 -0700204 r.enqueueClockTime = System.currentTimeMillis();
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800205 }
206
207 public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
208 mOrderedBroadcasts.add(r);
Jeff Brown9fb3fd12014-09-29 15:32:12 -0700209 r.enqueueClockTime = System.currentTimeMillis();
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800210 }
211
212 public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
Wale Ogunwaleca1c1252015-05-15 12:49:13 -0700213 for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800214 if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800215 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800216 "***** DROPPING PARALLEL ["
217 + mQueueName + "]: " + r.intent);
218 mParallelBroadcasts.set(i, r);
219 return true;
220 }
221 }
222 return false;
223 }
224
225 public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
Wale Ogunwaleca1c1252015-05-15 12:49:13 -0700226 for (int i = mOrderedBroadcasts.size() - 1; i > 0; i--) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800227 if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800228 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800229 "***** DROPPING ORDERED ["
230 + mQueueName + "]: " + r.intent);
231 mOrderedBroadcasts.set(i, r);
232 return true;
233 }
234 }
235 return false;
236 }
237
238 private final void processCurBroadcastLocked(BroadcastRecord r,
239 ProcessRecord app) throws RemoteException {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800240 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800241 "Process cur broadcast " + r + " for app " + app);
242 if (app.thread == null) {
243 throw new RemoteException();
244 }
245 r.receiver = app.thread.asBinder();
246 r.curApp = app;
247 app.curReceiver = r;
Dianne Hackborna413dc02013-07-12 12:02:55 -0700248 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
Dianne Hackborndb926082013-10-31 16:32:44 -0700249 mService.updateLruProcessLocked(app, false, null);
250 mService.updateOomAdjLocked();
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800251
252 // Tell the application to launch this receiver.
253 r.intent.setComponent(r.curComponent);
254
255 boolean started = false;
256 try {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800257 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800258 "Delivering to component " + r.curComponent
259 + ": " + r);
260 mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
261 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
262 mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
Dianne Hackborna413dc02013-07-12 12:02:55 -0700263 r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
264 app.repProcState);
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800265 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800266 "Process cur broadcast " + r + " DELIVERED for app " + app);
267 started = true;
268 } finally {
269 if (!started) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800270 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800271 "Process cur broadcast " + r + ": NOT STARTED!");
272 r.receiver = null;
273 r.curApp = null;
274 app.curReceiver = null;
275 }
276 }
277 }
278
279 public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
280 boolean didSomething = false;
281 final BroadcastRecord br = mPendingBroadcast;
282 if (br != null && br.curApp.pid == app.pid) {
283 try {
284 mPendingBroadcast = null;
285 processCurBroadcastLocked(br, app);
286 didSomething = true;
287 } catch (Exception e) {
288 Slog.w(TAG, "Exception in new application when starting receiver "
289 + br.curComponent.flattenToShortString(), e);
290 logBroadcastReceiverDiscardLocked(br);
291 finishReceiverLocked(br, br.resultCode, br.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700292 br.resultExtras, br.resultAbort, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800293 scheduleBroadcastsLocked();
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700294 // We need to reset the state if we failed to start the receiver.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800295 br.state = BroadcastRecord.IDLE;
296 throw new RuntimeException(e.getMessage());
297 }
298 }
299 return didSomething;
300 }
301
302 public void skipPendingBroadcastLocked(int pid) {
303 final BroadcastRecord br = mPendingBroadcast;
304 if (br != null && br.curApp.pid == pid) {
305 br.state = BroadcastRecord.IDLE;
306 br.nextReceiver = mPendingBroadcastRecvIndex;
307 mPendingBroadcast = null;
308 scheduleBroadcastsLocked();
309 }
310 }
311
312 public void skipCurrentReceiverLocked(ProcessRecord app) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800313 BroadcastRecord r = app.curReceiver;
Kenji Sugimoto4472fa972014-07-17 14:50:41 +0900314 if (r != null && r.queue == this) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800315 // The current broadcast is waiting for this app's receiver
316 // to be finished. Looks like that's not going to happen, so
317 // let the broadcast continue.
318 logBroadcastReceiverDiscardLocked(r);
319 finishReceiverLocked(r, r.resultCode, r.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700320 r.resultExtras, r.resultAbort, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800321 }
riddle_hsu01eb7fa2015-03-04 17:27:05 +0800322 if (r == null && mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800323 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800324 "[" + mQueueName + "] skip & discard pending app " + r);
riddle_hsu01eb7fa2015-03-04 17:27:05 +0800325 r = mPendingBroadcast;
326 }
327
328 if (r != null) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800329 logBroadcastReceiverDiscardLocked(r);
330 finishReceiverLocked(r, r.resultCode, r.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700331 r.resultExtras, r.resultAbort, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800332 scheduleBroadcastsLocked();
333 }
334 }
335
336 public void scheduleBroadcastsLocked() {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800337 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800338 + mQueueName + "]: current="
339 + mBroadcastsScheduled);
340
341 if (mBroadcastsScheduled) {
342 return;
343 }
344 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
345 mBroadcastsScheduled = true;
346 }
347
348 public BroadcastRecord getMatchingOrderedReceiver(IBinder receiver) {
349 if (mOrderedBroadcasts.size() > 0) {
350 final BroadcastRecord r = mOrderedBroadcasts.get(0);
351 if (r != null && r.receiver == receiver) {
352 return r;
353 }
354 }
355 return null;
356 }
357
358 public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700359 String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
360 final int state = r.state;
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700361 final ActivityInfo receiver = r.curReceiver;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800362 r.state = BroadcastRecord.IDLE;
363 if (state == BroadcastRecord.IDLE) {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700364 Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800365 }
366 r.receiver = null;
367 r.intent.setComponent(null);
Guobin Zhang04d0bb62014-03-07 17:47:10 +0800368 if (r.curApp != null && r.curApp.curReceiver == r) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800369 r.curApp.curReceiver = null;
370 }
371 if (r.curFilter != null) {
372 r.curFilter.receiverList.curBroadcast = null;
373 }
374 r.curFilter = null;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800375 r.curReceiver = null;
Dianne Hackborn6285a322013-09-18 12:09:47 -0700376 r.curApp = null;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800377 mPendingBroadcast = null;
378
379 r.resultCode = resultCode;
380 r.resultData = resultData;
381 r.resultExtras = resultExtras;
Dianne Hackborn6285a322013-09-18 12:09:47 -0700382 if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
383 r.resultAbort = resultAbort;
384 } else {
385 r.resultAbort = false;
386 }
387
388 if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
389 && r.queue.mOrderedBroadcasts.size() > 0
390 && r.queue.mOrderedBroadcasts.get(0) == r) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700391 ActivityInfo nextReceiver;
392 if (r.nextReceiver < r.receivers.size()) {
393 Object obj = r.receivers.get(r.nextReceiver);
394 nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
395 } else {
396 nextReceiver = null;
397 }
398 // Don't do this if the next receive is in the same process as the current one.
399 if (receiver == null || nextReceiver == null
400 || receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
401 || !receiver.processName.equals(nextReceiver.processName)) {
402 // In this case, we are ready to process the next receiver for the current broadcast,
403 // but are on a queue that would like to wait for services to finish before moving
404 // on. If there are background services currently starting, then we will go into a
405 // special state where we hold off on continuing this broadcast until they are done.
406 if (mService.mServices.hasBackgroundServices(r.userId)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800407 Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString());
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700408 r.state = BroadcastRecord.WAITING_SERVICES;
409 return false;
410 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700411 }
412 }
413
414 r.curComponent = null;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800415
416 // We will process the next receiver right now if this is finishing
417 // an app receiver (which is always asynchronous) or after we have
418 // come back from calling a receiver.
419 return state == BroadcastRecord.APP_RECEIVE
420 || state == BroadcastRecord.CALL_DONE_RECEIVE;
421 }
422
Dianne Hackborn6285a322013-09-18 12:09:47 -0700423 public void backgroundServicesFinishedLocked(int userId) {
424 if (mOrderedBroadcasts.size() > 0) {
425 BroadcastRecord br = mOrderedBroadcasts.get(0);
426 if (br.userId == userId && br.state == BroadcastRecord.WAITING_SERVICES) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800427 Slog.i(TAG, "Resuming delayed broadcast");
Dianne Hackborn6285a322013-09-18 12:09:47 -0700428 br.curComponent = null;
429 br.state = BroadcastRecord.IDLE;
430 processNextBroadcast(false);
431 }
432 }
433 }
434
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800435 private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
436 Intent intent, int resultCode, String data, Bundle extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700437 boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800438 // Send the intent to the receiver asynchronously using one-way binder calls.
Craig Mautner38c1a5f2014-07-21 15:36:37 +0000439 if (app != null) {
440 if (app.thread != null) {
441 // If we have an app thread, do the call through that so it is
442 // correctly ordered with other one-way calls.
443 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
444 data, extras, ordered, sticky, sendingUser, app.repProcState);
445 } else {
446 // Application has died. Receiver doesn't exist.
447 throw new RemoteException("app.thread must not be null");
448 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800449 } else {
Dianne Hackborn20e80982012-08-31 19:00:44 -0700450 receiver.performReceive(intent, resultCode, data, extras, ordered,
451 sticky, sendingUser);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800452 }
453 }
454
455 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
456 BroadcastFilter filter, boolean ordered) {
457 boolean skip = false;
Amith Yamasani8bf06ed2012-08-27 19:30:30 -0700458 if (filter.requiredPermission != null) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800459 int perm = mService.checkComponentPermission(filter.requiredPermission,
460 r.callingPid, r.callingUid, -1, true);
461 if (perm != PackageManager.PERMISSION_GRANTED) {
462 Slog.w(TAG, "Permission Denial: broadcasting "
463 + r.intent.toString()
464 + " from " + r.callerPackage + " (pid="
465 + r.callingPid + ", uid=" + r.callingUid + ")"
466 + " requires " + filter.requiredPermission
467 + " due to registered receiver " + filter);
468 skip = true;
469 }
470 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -0700471 if (!skip && r.requiredPermission != null) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800472 int perm = mService.checkComponentPermission(r.requiredPermission,
473 filter.receiverList.pid, filter.receiverList.uid, -1, true);
474 if (perm != PackageManager.PERMISSION_GRANTED) {
475 Slog.w(TAG, "Permission Denial: receiving "
476 + r.intent.toString()
477 + " to " + filter.receiverList.app
478 + " (pid=" + filter.receiverList.pid
479 + ", uid=" + filter.receiverList.uid + ")"
480 + " requires " + r.requiredPermission
481 + " due to sender " + r.callerPackage
482 + " (uid " + r.callingUid + ")");
483 skip = true;
484 }
485 }
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800486 if (r.appOp != AppOpsManager.OP_NONE) {
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700487 int mode = mService.mAppOpsService.noteOperation(r.appOp,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800488 filter.receiverList.uid, filter.packageName);
489 if (mode != AppOpsManager.MODE_ALLOWED) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800490 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800491 "App op " + r.appOp + " not allowed for broadcast to uid "
492 + filter.receiverList.uid + " pkg " + filter.packageName);
493 skip = true;
494 }
495 }
Ben Gruver49660c72013-08-06 19:54:08 -0700496 if (!skip) {
497 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
498 r.callingPid, r.resolvedType, filter.receiverList.uid);
499 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800500
Dianne Hackborn9357b112013-10-03 18:27:48 -0700501 if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
502 Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
503 + " to " + filter.receiverList + ": process crashing");
504 skip = true;
505 }
506
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800507 if (!skip) {
508 // If this is not being sent as an ordered broadcast, then we
509 // don't want to touch the fields that keep track of the current
510 // state of ordered broadcasts.
511 if (ordered) {
512 r.receiver = filter.receiverList.receiver.asBinder();
513 r.curFilter = filter;
514 filter.receiverList.curBroadcast = r;
515 r.state = BroadcastRecord.CALL_IN_RECEIVE;
516 if (filter.receiverList.app != null) {
517 // Bump hosting application to no longer be in background
518 // scheduling class. Note that we can't do that if there
519 // isn't an app... but we can only be in that case for
520 // things that directly call the IActivityManager API, which
521 // are already core system stuff so don't matter for this.
522 r.curApp = filter.receiverList.app;
523 filter.receiverList.app.curReceiver = r;
Dianne Hackborn684bf342014-04-29 17:56:57 -0700524 mService.updateOomAdjLocked(r.curApp);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800525 }
526 }
527 try {
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700528 if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
529 "Delivering to " + filter + " : " + r);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800530 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700531 new Intent(r.intent), r.resultCode, r.resultData,
532 r.resultExtras, r.ordered, r.initialSticky, r.userId);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800533 if (ordered) {
534 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
535 }
536 } catch (RemoteException e) {
537 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
538 if (ordered) {
539 r.receiver = null;
540 r.curFilter = null;
541 filter.receiverList.curBroadcast = null;
542 if (filter.receiverList.app != null) {
543 filter.receiverList.app.curReceiver = null;
544 }
545 }
546 }
547 }
548 }
549
550 final void processNextBroadcast(boolean fromMsg) {
551 synchronized(mService) {
552 BroadcastRecord r;
553
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800554 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800555 + mQueueName + "]: "
556 + mParallelBroadcasts.size() + " broadcasts, "
557 + mOrderedBroadcasts.size() + " ordered broadcasts");
558
559 mService.updateCpuStats();
560
561 if (fromMsg) {
562 mBroadcastsScheduled = false;
563 }
564
565 // First, deliver any non-serialized broadcasts right away.
566 while (mParallelBroadcasts.size() > 0) {
567 r = mParallelBroadcasts.remove(0);
568 r.dispatchTime = SystemClock.uptimeMillis();
569 r.dispatchClockTime = System.currentTimeMillis();
570 final int N = r.receivers.size();
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800571 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800572 + mQueueName + "] " + r);
573 for (int i=0; i<N; i++) {
574 Object target = r.receivers.get(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800575 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800576 "Delivering non-ordered on [" + mQueueName + "] to registered "
577 + target + ": " + r);
578 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
579 }
580 addBroadcastToHistoryLocked(r);
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800581 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800582 + mQueueName + "] " + r);
583 }
584
585 // Now take care of the next serialized one...
586
587 // If we are waiting for a process to come up to handle the next
588 // broadcast, then do nothing at this point. Just in case, we
589 // check that the process we're waiting for still exists.
590 if (mPendingBroadcast != null) {
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700591 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
592 "processNextBroadcast [" + mQueueName + "]: waiting for "
593 + mPendingBroadcast.curApp);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800594
595 boolean isDead;
596 synchronized (mService.mPidsSelfLocked) {
Dianne Hackborn9357b112013-10-03 18:27:48 -0700597 ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
598 isDead = proc == null || proc.crashing;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800599 }
600 if (!isDead) {
601 // It's still alive, so keep waiting
602 return;
603 } else {
604 Slog.w(TAG, "pending app ["
605 + mQueueName + "]" + mPendingBroadcast.curApp
606 + " died before responding to broadcast");
607 mPendingBroadcast.state = BroadcastRecord.IDLE;
608 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
609 mPendingBroadcast = null;
610 }
611 }
612
613 boolean looped = false;
614
615 do {
616 if (mOrderedBroadcasts.size() == 0) {
617 // No more broadcasts pending, so all done!
618 mService.scheduleAppGcsLocked();
619 if (looped) {
620 // If we had finished the last ordered broadcast, then
621 // make sure all processes have correct oom and sched
622 // adjustments.
623 mService.updateOomAdjLocked();
624 }
625 return;
626 }
627 r = mOrderedBroadcasts.get(0);
628 boolean forceReceive = false;
629
630 // Ensure that even if something goes awry with the timeout
631 // detection, we catch "hung" broadcasts here, discard them,
632 // and continue to make progress.
633 //
634 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
635 // receivers don't get executed with timeouts. They're intended for
636 // one time heavy lifting after system upgrades and can take
637 // significant amounts of time.
638 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
639 if (mService.mProcessesReady && r.dispatchTime > 0) {
640 long now = SystemClock.uptimeMillis();
641 if ((numReceivers > 0) &&
642 (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
643 Slog.w(TAG, "Hung broadcast ["
644 + mQueueName + "] discarded after timeout failure:"
645 + " now=" + now
646 + " dispatchTime=" + r.dispatchTime
647 + " startTime=" + r.receiverTime
648 + " intent=" + r.intent
649 + " numReceivers=" + numReceivers
650 + " nextReceiver=" + r.nextReceiver
651 + " state=" + r.state);
652 broadcastTimeoutLocked(false); // forcibly finish this broadcast
653 forceReceive = true;
654 r.state = BroadcastRecord.IDLE;
655 }
656 }
657
658 if (r.state != BroadcastRecord.IDLE) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800659 if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800660 "processNextBroadcast("
661 + mQueueName + ") called when not idle (state="
662 + r.state + ")");
663 return;
664 }
665
666 if (r.receivers == null || r.nextReceiver >= numReceivers
667 || r.resultAbort || forceReceive) {
668 // No more receivers for this broadcast! Send the final
669 // result if requested...
670 if (r.resultTo != null) {
671 try {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800672 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
Todd Kennedyd2f15112015-01-21 15:25:56 -0800673 "Finishing broadcast [" + mQueueName + "] "
674 + r.intent.getAction() + " app=" + r.callerApp);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800675 performReceiveLocked(r.callerApp, r.resultTo,
676 new Intent(r.intent), r.resultCode,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700677 r.resultData, r.resultExtras, false, false, r.userId);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800678 // Set this to null so that the reference
Dianne Hackborn9357b112013-10-03 18:27:48 -0700679 // (local and remote) isn't kept in the mBroadcastHistory.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800680 r.resultTo = null;
681 } catch (RemoteException e) {
Craig Mautner38c1a5f2014-07-21 15:36:37 +0000682 r.resultTo = null;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800683 Slog.w(TAG, "Failure ["
684 + mQueueName + "] sending broadcast result of "
685 + r.intent, e);
686 }
687 }
688
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800689 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800690 cancelBroadcastTimeoutLocked();
691
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700692 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
693 "Finished with ordered broadcast " + r);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800694
695 // ... and on to the next...
696 addBroadcastToHistoryLocked(r);
697 mOrderedBroadcasts.remove(0);
698 r = null;
699 looped = true;
700 continue;
701 }
702 } while (r == null);
703
704 // Get the next receiver...
705 int recIdx = r.nextReceiver++;
706
707 // Keep track of when this receiver started, and make sure there
708 // is a timeout message pending to kill it if need be.
709 r.receiverTime = SystemClock.uptimeMillis();
710 if (recIdx == 0) {
711 r.dispatchTime = r.receiverTime;
712 r.dispatchClockTime = System.currentTimeMillis();
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800713 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800714 + mQueueName + "] " + r);
715 }
716 if (! mPendingBroadcastTimeoutMessage) {
717 long timeoutTime = r.receiverTime + mTimeoutPeriod;
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800718 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800719 "Submitting BROADCAST_TIMEOUT_MSG ["
720 + mQueueName + "] for " + r + " at " + timeoutTime);
721 setBroadcastTimeoutLocked(timeoutTime);
722 }
723
724 Object nextReceiver = r.receivers.get(recIdx);
725 if (nextReceiver instanceof BroadcastFilter) {
726 // Simple case: this is a registered receiver who gets
727 // a direct call.
728 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800729 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800730 "Delivering ordered ["
731 + mQueueName + "] to registered "
732 + filter + ": " + r);
733 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
734 if (r.receiver == null || !r.ordered) {
735 // The receiver has already finished, so schedule to
736 // process the next one.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800737 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800738 + mQueueName + "]: ordered="
739 + r.ordered + " receiver=" + r.receiver);
740 r.state = BroadcastRecord.IDLE;
741 scheduleBroadcastsLocked();
742 }
743 return;
744 }
745
746 // Hard case: need to instantiate the receiver, possibly
747 // starting its application process to host it.
748
749 ResolveInfo info =
750 (ResolveInfo)nextReceiver;
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700751 ComponentName component = new ComponentName(
752 info.activityInfo.applicationInfo.packageName,
753 info.activityInfo.name);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800754
755 boolean skip = false;
756 int perm = mService.checkComponentPermission(info.activityInfo.permission,
757 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
758 info.activityInfo.exported);
759 if (perm != PackageManager.PERMISSION_GRANTED) {
760 if (!info.activityInfo.exported) {
761 Slog.w(TAG, "Permission Denial: broadcasting "
762 + r.intent.toString()
763 + " from " + r.callerPackage + " (pid=" + r.callingPid
764 + ", uid=" + r.callingUid + ")"
765 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700766 + " due to receiver " + component.flattenToShortString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800767 } else {
768 Slog.w(TAG, "Permission Denial: broadcasting "
769 + r.intent.toString()
770 + " from " + r.callerPackage + " (pid=" + r.callingPid
771 + ", uid=" + r.callingUid + ")"
772 + " requires " + info.activityInfo.permission
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700773 + " due to receiver " + component.flattenToShortString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800774 }
775 skip = true;
776 }
777 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
778 r.requiredPermission != null) {
779 try {
780 perm = AppGlobals.getPackageManager().
781 checkPermission(r.requiredPermission,
Svet Ganov4f2dcfd2015-04-22 02:14:47 -0700782 info.activityInfo.applicationInfo.packageName,
783 UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800784 } catch (RemoteException e) {
785 perm = PackageManager.PERMISSION_DENIED;
786 }
787 if (perm != PackageManager.PERMISSION_GRANTED) {
788 Slog.w(TAG, "Permission Denial: receiving "
789 + r.intent + " to "
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700790 + component.flattenToShortString()
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800791 + " requires " + r.requiredPermission
792 + " due to sender " + r.callerPackage
793 + " (uid " + r.callingUid + ")");
794 skip = true;
795 }
796 }
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800797 if (r.appOp != AppOpsManager.OP_NONE) {
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700798 int mode = mService.mAppOpsService.noteOperation(r.appOp,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800799 info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
800 if (mode != AppOpsManager.MODE_ALLOWED) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800801 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800802 "App op " + r.appOp + " not allowed for broadcast to uid "
803 + info.activityInfo.applicationInfo.uid + " pkg "
804 + info.activityInfo.packageName);
805 skip = true;
806 }
807 }
Ben Gruver49660c72013-08-06 19:54:08 -0700808 if (!skip) {
809 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
810 r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
811 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700812 boolean isSingleton = false;
813 try {
814 isSingleton = mService.isSingleton(info.activityInfo.processName,
815 info.activityInfo.applicationInfo,
816 info.activityInfo.name, info.activityInfo.flags);
817 } catch (SecurityException e) {
818 Slog.w(TAG, e.getMessage());
819 skip = true;
820 }
821 if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
822 if (ActivityManager.checkUidPermission(
823 android.Manifest.permission.INTERACT_ACROSS_USERS,
824 info.activityInfo.applicationInfo.uid)
825 != PackageManager.PERMISSION_GRANTED) {
826 Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
827 + " requests FLAG_SINGLE_USER, but app does not hold "
828 + android.Manifest.permission.INTERACT_ACROSS_USERS);
829 skip = true;
830 }
831 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800832 if (r.curApp != null && r.curApp.crashing) {
833 // If the target process is crashing, just skip it.
Dianne Hackborn9357b112013-10-03 18:27:48 -0700834 Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
835 + " to " + r.curApp + ": process crashing");
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800836 skip = true;
837 }
Christopher Tateba629da2013-11-13 17:42:28 -0800838 if (!skip) {
839 boolean isAvailable = false;
840 try {
841 isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
842 info.activityInfo.packageName,
843 UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
844 } catch (Exception e) {
845 // all such failures mean we skip this receiver
846 Slog.w(TAG, "Exception getting recipient info for "
847 + info.activityInfo.packageName, e);
848 }
849 if (!isAvailable) {
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700850 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
851 "Skipping delivery to " + info.activityInfo.packageName + " / "
852 + info.activityInfo.applicationInfo.uid
853 + " : package no longer available");
Christopher Tateba629da2013-11-13 17:42:28 -0800854 skip = true;
855 }
856 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800857
858 if (skip) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800859 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Wale Ogunwale3c36b8e2015-03-09 10:18:51 -0700860 "Skipping delivery of ordered [" + mQueueName + "] "
861 + r + " for whatever reason");
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800862 r.receiver = null;
863 r.curFilter = null;
864 r.state = BroadcastRecord.IDLE;
865 scheduleBroadcastsLocked();
866 return;
867 }
868
869 r.state = BroadcastRecord.APP_RECEIVE;
870 String targetProcess = info.activityInfo.processName;
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700871 r.curComponent = component;
Amith Yamasani4b9d79c2014-05-21 19:14:21 -0700872 final int receiverUid = info.activityInfo.applicationInfo.uid;
873 // If it's a singleton, it needs to be the same app or a special app
874 if (r.callingUid != Process.SYSTEM_UID && isSingleton
875 && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700876 info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800877 }
878 r.curReceiver = info.activityInfo;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700879 if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800880 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
881 + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
882 + info.activityInfo.applicationInfo.uid);
883 }
884
885 // Broadcast is being executed, its package can't be stopped.
886 try {
887 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700888 r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800889 } catch (RemoteException e) {
890 } catch (IllegalArgumentException e) {
891 Slog.w(TAG, "Failed trying to unstop package "
892 + r.curComponent.getPackageName() + ": " + e);
893 }
894
895 // Is this receiver's application already running?
896 ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700897 info.activityInfo.applicationInfo.uid, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800898 if (app != null && app.thread != null) {
899 try {
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700900 app.addPackage(info.activityInfo.packageName,
901 info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800902 processCurBroadcastLocked(r, app);
903 return;
904 } catch (RemoteException e) {
905 Slog.w(TAG, "Exception when sending broadcast to "
906 + r.curComponent, e);
Dianne Hackborn6c5406a2012-11-29 16:18:01 -0800907 } catch (RuntimeException e) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700908 Slog.wtf(TAG, "Failed sending broadcast to "
Dianne Hackborn6c5406a2012-11-29 16:18:01 -0800909 + r.curComponent + " with " + r.intent, e);
910 // If some unexpected exception happened, just skip
911 // this broadcast. At this point we are not in the call
912 // from a client, so throwing an exception out from here
913 // will crash the entire system instead of just whoever
914 // sent the broadcast.
915 logBroadcastReceiverDiscardLocked(r);
916 finishReceiverLocked(r, r.resultCode, r.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700917 r.resultExtras, r.resultAbort, false);
Dianne Hackborn6c5406a2012-11-29 16:18:01 -0800918 scheduleBroadcastsLocked();
919 // We need to reset the state if we failed to start the receiver.
920 r.state = BroadcastRecord.IDLE;
921 return;
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800922 }
923
924 // If a dead object exception was thrown -- fall through to
925 // restart the application.
926 }
927
928 // Not running -- get it started, to be executed when the app comes up.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800929 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800930 "Need to start app ["
931 + mQueueName + "] " + targetProcess + " for broadcast " + r);
932 if ((r.curApp=mService.startProcessLocked(targetProcess,
933 info.activityInfo.applicationInfo, true,
934 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
935 "broadcast", r.curComponent,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700936 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800937 == null) {
938 // Ah, this recipient is unavailable. Finish it if necessary,
939 // and mark the broadcast record as ready for the next.
940 Slog.w(TAG, "Unable to launch app "
941 + info.activityInfo.applicationInfo.packageName + "/"
942 + info.activityInfo.applicationInfo.uid + " for broadcast "
943 + r.intent + ": process is bad");
944 logBroadcastReceiverDiscardLocked(r);
945 finishReceiverLocked(r, r.resultCode, r.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -0700946 r.resultExtras, r.resultAbort, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800947 scheduleBroadcastsLocked();
948 r.state = BroadcastRecord.IDLE;
949 return;
950 }
951
952 mPendingBroadcast = r;
953 mPendingBroadcastRecvIndex = recIdx;
954 }
955 }
956
957 final void setBroadcastTimeoutLocked(long timeoutTime) {
958 if (! mPendingBroadcastTimeoutMessage) {
959 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
960 mHandler.sendMessageAtTime(msg, timeoutTime);
961 mPendingBroadcastTimeoutMessage = true;
962 }
963 }
964
965 final void cancelBroadcastTimeoutLocked() {
966 if (mPendingBroadcastTimeoutMessage) {
967 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG, this);
968 mPendingBroadcastTimeoutMessage = false;
969 }
970 }
971
972 final void broadcastTimeoutLocked(boolean fromMsg) {
973 if (fromMsg) {
974 mPendingBroadcastTimeoutMessage = false;
975 }
976
977 if (mOrderedBroadcasts.size() == 0) {
978 return;
979 }
980
981 long now = SystemClock.uptimeMillis();
982 BroadcastRecord r = mOrderedBroadcasts.get(0);
983 if (fromMsg) {
984 if (mService.mDidDexOpt) {
985 // Delay timeouts until dexopt finishes.
986 mService.mDidDexOpt = false;
987 long timeoutTime = SystemClock.uptimeMillis() + mTimeoutPeriod;
988 setBroadcastTimeoutLocked(timeoutTime);
989 return;
990 }
991 if (!mService.mProcessesReady) {
992 // Only process broadcast timeouts if the system is ready. That way
993 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
994 // to do heavy lifting for system up.
995 return;
996 }
997
998 long timeoutTime = r.receiverTime + mTimeoutPeriod;
999 if (timeoutTime > now) {
1000 // We can observe premature timeouts because we do not cancel and reset the
1001 // broadcast timeout message after each receiver finishes. Instead, we set up
1002 // an initial timeout then kick it down the road a little further as needed
1003 // when it expires.
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001004 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001005 "Premature timeout ["
1006 + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
1007 + timeoutTime);
1008 setBroadcastTimeoutLocked(timeoutTime);
1009 return;
1010 }
1011 }
1012
Dianne Hackborn6285a322013-09-18 12:09:47 -07001013 BroadcastRecord br = mOrderedBroadcasts.get(0);
1014 if (br.state == BroadcastRecord.WAITING_SERVICES) {
1015 // In this case the broadcast had already finished, but we had decided to wait
1016 // for started services to finish as well before going on. So if we have actually
1017 // waited long enough time timeout the broadcast, let's give up on the whole thing
1018 // and just move on to the next.
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001019 Slog.i(TAG, "Waited long enough for: " + (br.curComponent != null
Dianne Hackborn6285a322013-09-18 12:09:47 -07001020 ? br.curComponent.flattenToShortString() : "(null)"));
1021 br.curComponent = null;
1022 br.state = BroadcastRecord.IDLE;
1023 processNextBroadcast(false);
1024 return;
1025 }
1026
1027 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r. receiver
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001028 + ", started " + (now - r.receiverTime) + "ms ago");
1029 r.receiverTime = now;
1030 r.anrCount++;
1031
1032 // Current receiver has passed its expiration date.
1033 if (r.nextReceiver <= 0) {
1034 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
1035 return;
1036 }
1037
1038 ProcessRecord app = null;
1039 String anrMessage = null;
1040
1041 Object curReceiver = r.receivers.get(r.nextReceiver-1);
1042 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
1043 logBroadcastReceiverDiscardLocked(r);
1044 if (curReceiver instanceof BroadcastFilter) {
1045 BroadcastFilter bf = (BroadcastFilter)curReceiver;
1046 if (bf.receiverList.pid != 0
1047 && bf.receiverList.pid != ActivityManagerService.MY_PID) {
1048 synchronized (mService.mPidsSelfLocked) {
1049 app = mService.mPidsSelfLocked.get(
1050 bf.receiverList.pid);
1051 }
1052 }
1053 } else {
1054 app = r.curApp;
1055 }
1056
1057 if (app != null) {
1058 anrMessage = "Broadcast of " + r.intent.toString();
1059 }
1060
1061 if (mPendingBroadcast == r) {
1062 mPendingBroadcast = null;
1063 }
1064
1065 // Move on to the next receiver.
1066 finishReceiverLocked(r, r.resultCode, r.resultData,
Dianne Hackborn6285a322013-09-18 12:09:47 -07001067 r.resultExtras, r.resultAbort, false);
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001068 scheduleBroadcastsLocked();
1069
1070 if (anrMessage != null) {
1071 // Post the ANR to the handler since we do not want to process ANRs while
1072 // potentially holding our lock.
1073 mHandler.post(new AppNotResponding(app, anrMessage));
1074 }
1075 }
1076
Christopher Tatef278f122015-04-22 13:12:01 -07001077 private final int ringAdvance(int x, final int increment, final int ringSize) {
1078 x += increment;
1079 if (x < 0) return (ringSize - 1);
1080 else if (x >= ringSize) return 0;
1081 else return x;
1082 }
1083
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001084 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
1085 if (r.callingUid < 0) {
1086 // This was from a registerReceiver() call; ignore it.
1087 return;
1088 }
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001089 r.finishTime = SystemClock.uptimeMillis();
Christopher Tatef278f122015-04-22 13:12:01 -07001090
1091 mBroadcastHistory[mHistoryNext] = r;
1092 mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
1093
1094 mBroadcastSummaryHistory[mSummaryHistoryNext] = r.intent;
1095 mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = r.enqueueClockTime;
1096 mSummaryHistoryDispatchTime[mSummaryHistoryNext] = r.dispatchClockTime;
1097 mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis();
1098 mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001099 }
1100
Wale Ogunwaleca1c1252015-05-15 12:49:13 -07001101 boolean cleanupDisabledPackageReceiversLocked(
1102 String packageName, Set<String> filterByClasses, int userId, boolean doit) {
1103 boolean didSomething = false;
1104 for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
1105 didSomething |= mParallelBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
1106 packageName, filterByClasses, userId, doit);
1107 if (!doit && didSomething) {
1108 return true;
1109 }
1110 }
1111
1112 for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
1113 didSomething |= mOrderedBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
1114 packageName, filterByClasses, userId, doit);
1115 if (!doit && didSomething) {
1116 return true;
1117 }
1118 }
1119
1120 return didSomething;
1121 }
1122
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001123 final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
1124 if (r.nextReceiver > 0) {
1125 Object curReceiver = r.receivers.get(r.nextReceiver-1);
1126 if (curReceiver instanceof BroadcastFilter) {
1127 BroadcastFilter bf = (BroadcastFilter) curReceiver;
1128 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001129 bf.owningUserId, System.identityHashCode(r),
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001130 r.intent.getAction(),
1131 r.nextReceiver - 1,
1132 System.identityHashCode(bf));
1133 } else {
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001134 ResolveInfo ri = (ResolveInfo)curReceiver;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001135 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001136 UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
1137 System.identityHashCode(r), r.intent.getAction(),
1138 r.nextReceiver - 1, ri.toString());
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001139 }
1140 } else {
1141 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
1142 + r);
1143 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001144 -1, System.identityHashCode(r),
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001145 r.intent.getAction(),
1146 r.nextReceiver,
1147 "NONE");
1148 }
1149 }
1150
1151 final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
1152 int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
1153 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
1154 || mPendingBroadcast != null) {
1155 boolean printed = false;
Wale Ogunwaleca1c1252015-05-15 12:49:13 -07001156 for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001157 BroadcastRecord br = mParallelBroadcasts.get(i);
1158 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1159 continue;
1160 }
1161 if (!printed) {
1162 if (needSep) {
1163 pw.println();
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001164 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001165 needSep = true;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001166 printed = true;
1167 pw.println(" Active broadcasts [" + mQueueName + "]:");
1168 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001169 pw.println(" Active Broadcast " + mQueueName + " #" + i + ":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001170 br.dump(pw, " ");
1171 }
1172 printed = false;
1173 needSep = true;
Wale Ogunwaleca1c1252015-05-15 12:49:13 -07001174 for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001175 BroadcastRecord br = mOrderedBroadcasts.get(i);
1176 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
1177 continue;
1178 }
1179 if (!printed) {
1180 if (needSep) {
1181 pw.println();
1182 }
1183 needSep = true;
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001184 printed = true;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001185 pw.println(" Active ordered broadcasts [" + mQueueName + "]:");
1186 }
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001187 pw.println(" Active Ordered Broadcast " + mQueueName + " #" + i + ":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001188 mOrderedBroadcasts.get(i).dump(pw, " ");
1189 }
1190 if (dumpPackage == null || (mPendingBroadcast != null
1191 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
1192 if (needSep) {
1193 pw.println();
1194 }
1195 pw.println(" Pending broadcast [" + mQueueName + "]:");
1196 if (mPendingBroadcast != null) {
1197 mPendingBroadcast.dump(pw, " ");
1198 } else {
1199 pw.println(" (null)");
1200 }
1201 needSep = true;
1202 }
1203 }
1204
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001205 int i;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001206 boolean printed = false;
Christopher Tatef278f122015-04-22 13:12:01 -07001207
1208 i = -1;
1209 int lastIndex = mHistoryNext;
1210 int ringIndex = lastIndex;
1211 do {
1212 // increasing index = more recent entry, and we want to print the most
1213 // recent first and work backwards, so we roll through the ring backwards.
1214 ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_HISTORY);
1215 BroadcastRecord r = mBroadcastHistory[ringIndex];
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001216 if (r == null) {
Christopher Tatef278f122015-04-22 13:12:01 -07001217 continue;
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001218 }
Christopher Tatef278f122015-04-22 13:12:01 -07001219
1220 i++; // genuine record of some sort even if we're filtering it out
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001221 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
1222 continue;
1223 }
1224 if (!printed) {
1225 if (needSep) {
1226 pw.println();
1227 }
1228 needSep = true;
1229 pw.println(" Historical broadcasts [" + mQueueName + "]:");
1230 printed = true;
1231 }
1232 if (dumpAll) {
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -07001233 pw.print(" Historical Broadcast " + mQueueName + " #");
1234 pw.print(i); pw.println(":");
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001235 r.dump(pw, " ");
1236 } else {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001237 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
1238 pw.print(" ");
1239 pw.println(r.intent.toShortString(false, true, true, false));
Dianne Hackborna40cfeb2013-03-25 17:49:36 -07001240 if (r.targetComp != null && r.targetComp != r.intent.getComponent()) {
1241 pw.print(" targetComp: "); pw.println(r.targetComp.toShortString());
1242 }
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001243 Bundle bundle = r.intent.getExtras();
1244 if (bundle != null) {
1245 pw.print(" extras: "); pw.println(bundle.toString());
1246 }
1247 }
Christopher Tatef278f122015-04-22 13:12:01 -07001248 } while (ringIndex != lastIndex);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001249
1250 if (dumpPackage == null) {
Christopher Tatef278f122015-04-22 13:12:01 -07001251 lastIndex = ringIndex = mSummaryHistoryNext;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001252 if (dumpAll) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001253 printed = false;
Christopher Tatef278f122015-04-22 13:12:01 -07001254 i = -1;
1255 } else {
1256 // roll over the 'i' full dumps that have already been issued
1257 for (int j = i;
1258 j > 0 && ringIndex != lastIndex;) {
1259 ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY);
1260 BroadcastRecord r = mBroadcastHistory[ringIndex];
1261 if (r == null) {
1262 continue;
1263 }
1264 j--;
1265 }
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001266 }
Christopher Tatef278f122015-04-22 13:12:01 -07001267 // done skipping; dump the remainder of the ring. 'i' is still the ordinal within
1268 // the overall broadcast history.
1269 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1270 do {
1271 ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY);
1272 Intent intent = mBroadcastSummaryHistory[ringIndex];
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001273 if (intent == null) {
Christopher Tatef278f122015-04-22 13:12:01 -07001274 continue;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001275 }
1276 if (!printed) {
1277 if (needSep) {
1278 pw.println();
1279 }
1280 needSep = true;
1281 pw.println(" Historical broadcasts summary [" + mQueueName + "]:");
1282 printed = true;
1283 }
1284 if (!dumpAll && i >= 50) {
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001285 pw.println(" ...");
1286 break;
1287 }
Christopher Tatef278f122015-04-22 13:12:01 -07001288 i++;
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001289 pw.print(" #"); pw.print(i); pw.print(": ");
1290 pw.println(intent.toShortString(false, true, true, false));
Christopher Tatef278f122015-04-22 13:12:01 -07001291 pw.print(" enq="); pw.print(sdf.format(new Date(mSummaryHistoryEnqueueTime[ringIndex])));
1292 pw.print(" disp="); pw.print(sdf.format(new Date(mSummaryHistoryDispatchTime[ringIndex])));
1293 pw.print(" fin="); pw.println(sdf.format(new Date(mSummaryHistoryFinishTime[ringIndex])));
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001294 Bundle bundle = intent.getExtras();
1295 if (bundle != null) {
1296 pw.print(" extras: "); pw.println(bundle.toString());
1297 }
Christopher Tatef278f122015-04-22 13:12:01 -07001298 } while (ringIndex != lastIndex);
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001299 }
1300
1301 return needSep;
1302 }
1303}