1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content; 18 19 import android.app.ActivityManagerNative; 20 import android.app.ActivityThread; 21 import android.app.IActivityManager; 22 import android.app.QueuedWork; 23 import android.os.Bundle; 24 import android.os.IBinder; 25 import android.os.RemoteException; 26 import android.util.Log; 27 import android.util.Slog; 28 29 /** 30 * Base class for code that will receive intents sent by sendBroadcast(). 31 * 32 * <p>If you don't need to send broadcasts across applications, consider using 33 * this class with {@link android.support.v4.content.LocalBroadcastManager} instead 34 * of the more general facilities described below. This will give you a much 35 * more efficient implementation (no cross-process communication needed) and allow 36 * you to avoid thinking about any security issues related to other applications 37 * being able to receive or send your broadcasts. 38 * 39 * <p>You can either dynamically register an instance of this class with 40 * {@link Context#registerReceiver Context.registerReceiver()} 41 * or statically publish an implementation through the 42 * {@link android.R.styleable#AndroidManifestReceiver <receiver>} 43 * tag in your <code>AndroidManifest.xml</code>. 44 * 45 * <p><em><strong>Note:</strong></em> 46 * If registering a receiver in your 47 * {@link android.app.Activity#onResume() Activity.onResume()} 48 * implementation, you should unregister it in 49 * {@link android.app.Activity#onPause() Activity.onPause()}. 50 * (You won't receive intents when paused, 51 * and this will cut down on unnecessary system overhead). Do not unregister in 52 * {@link android.app.Activity#onSaveInstanceState(android.os.Bundle) Activity.onSaveInstanceState()}, 53 * because this won't be called if the user moves back in the history 54 * stack. 55 * 56 * <p>There are two major classes of broadcasts that can be received:</p> 57 * <ul> 58 * <li> <b>Normal broadcasts</b> (sent with {@link Context#sendBroadcast(Intent) 59 * Context.sendBroadcast}) are completely asynchronous. All receivers of the 60 * broadcast are run in an undefined order, often at the same time. This is 61 * more efficient, but means that receivers cannot use the result or abort 62 * APIs included here. 63 * <li> <b>Ordered broadcasts</b> (sent with {@link Context#sendOrderedBroadcast(Intent, String) 64 * Context.sendOrderedBroadcast}) are delivered to one receiver at a time. 65 * As each receiver executes in turn, it can propagate a result to the next 66 * receiver, or it can completely abort the broadcast so that it won't be passed 67 * to other receivers. The order receivers run in can be controlled with the 68 * {@link android.R.styleable#AndroidManifestIntentFilter_priority 69 * android:priority} attribute of the matching intent-filter; receivers with 70 * the same priority will be run in an arbitrary order. 71 * </ul> 72 * 73 * <p>Even in the case of normal broadcasts, the system may in some 74 * situations revert to delivering the broadcast one receiver at a time. In 75 * particular, for receivers that may require the creation of a process, only 76 * one will be run at a time to avoid overloading the system with new processes. 77 * In this situation, however, the non-ordered semantics hold: these receivers still 78 * cannot return results or abort their broadcast.</p> 79 * 80 * <p>Note that, although the Intent class is used for sending and receiving 81 * these broadcasts, the Intent broadcast mechanism here is completely separate 82 * from Intents that are used to start Activities with 83 * {@link Context#startActivity Context.startActivity()}. 84 * There is no way for a BroadcastReceiver 85 * to see or capture Intents used with startActivity(); likewise, when 86 * you broadcast an Intent, you will never find or start an Activity. 87 * These two operations are semantically very different: starting an 88 * Activity with an Intent is a foreground operation that modifies what the 89 * user is currently interacting with; broadcasting an Intent is a background 90 * operation that the user is not normally aware of. 91 * 92 * <p>The BroadcastReceiver class (when launched as a component through 93 * a manifest's {@link android.R.styleable#AndroidManifestReceiver <receiver>} 94 * tag) is an important part of an 95 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">application's overall lifecycle</a>.</p> 96 * 97 * <p>Topics covered here: 98 * <ol> 99 * <li><a href="#Security">Security</a> 100 * <li><a href="#ReceiverLifecycle">Receiver Lifecycle</a> 101 * <li><a href="#ProcessLifecycle">Process Lifecycle</a> 102 * </ol> 103 * 104 * <div class="special reference"> 105 * <h3>Developer Guides</h3> 106 * <p>For information about how to use this class to receive and resolve intents, read the 107 * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a> 108 * developer guide.</p> 109 * </div> 110 * 111 * <a name="Security"></a> 112 * <h3>Security</h3> 113 * 114 * <p>Receivers used with the {@link Context} APIs are by their nature a 115 * cross-application facility, so you must consider how other applications 116 * may be able to abuse your use of them. Some things to consider are: 117 * 118 * <ul> 119 * <li><p>The Intent namespace is global. Make sure that Intent action names and 120 * other strings are written in a namespace you own, or else you may inadvertently 121 * conflict with other applications. 122 * <li><p>When you use {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}, 123 * <em>any</em> application may send broadcasts to that registered receiver. You can 124 * control who can send broadcasts to it through permissions described below. 125 * <li><p>When you publish a receiver in your application's manifest and specify 126 * intent-filters for it, any other application can send broadcasts to it regardless 127 * of the filters you specify. To prevent others from sending to it, make it 128 * unavailable to them with <code>android:exported="false"</code>. 129 * <li><p>When you use {@link Context#sendBroadcast(Intent)} or related methods, 130 * normally any other application can receive these broadcasts. You can control who 131 * can receive such broadcasts through permissions described below. Alternatively, 132 * starting with {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}, you 133 * can also safely restrict the broadcast to a single application with 134 * {@link Intent#setPackage(String) Intent.setPackage} 135 * </ul> 136 * 137 * <p>None of these issues exist when using 138 * {@link android.support.v4.content.LocalBroadcastManager}, since intents 139 * broadcast it never go outside of the current process. 140 * 141 * <p>Access permissions can be enforced by either the sender or receiver 142 * of a broadcast. 143 * 144 * <p>To enforce a permission when sending, you supply a non-null 145 * <var>permission</var> argument to 146 * {@link Context#sendBroadcast(Intent, String)} or 147 * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)}. 148 * Only receivers who have been granted this permission 149 * (by requesting it with the 150 * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 151 * tag in their <code>AndroidManifest.xml</code>) will be able to receive 152 * the broadcast. 153 * 154 * <p>To enforce a permission when receiving, you supply a non-null 155 * <var>permission</var> when registering your receiver -- either when calling 156 * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)} 157 * or in the static 158 * {@link android.R.styleable#AndroidManifestReceiver <receiver>} 159 * tag in your <code>AndroidManifest.xml</code>. Only broadcasters who have 160 * been granted this permission (by requesting it with the 161 * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 162 * tag in their <code>AndroidManifest.xml</code>) will be able to send an 163 * Intent to the receiver. 164 * 165 * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> 166 * document for more information on permissions and security in general. 167 * 168 * <a name="ReceiverLifecycle"></a> 169 * <h3>Receiver Lifecycle</h3> 170 * 171 * <p>A BroadcastReceiver object is only valid for the duration of the call 172 * to {@link #onReceive}. Once your code returns from this function, 173 * the system considers the object to be finished and no longer active. 174 * 175 * <p>This has important repercussions to what you can do in an 176 * {@link #onReceive} implementation: anything that requires asynchronous 177 * operation is not available, because you will need to return from the 178 * function to handle the asynchronous operation, but at that point the 179 * BroadcastReceiver is no longer active and thus the system is free to kill 180 * its process before the asynchronous operation completes. 181 * 182 * <p>In particular, you may <i>not</i> show a dialog or bind to a service from 183 * within a BroadcastReceiver. For the former, you should instead use the 184 * {@link android.app.NotificationManager} API. For the latter, you can 185 * use {@link android.content.Context#startService Context.startService()} to 186 * send a command to the service. 187 * 188 * <a name="ProcessLifecycle"></a> 189 * <h3>Process Lifecycle</h3> 190 * 191 * <p>A process that is currently executing a BroadcastReceiver (that is, 192 * currently running the code in its {@link #onReceive} method) is 193 * considered to be a foreground process and will be kept running by the 194 * system except under cases of extreme memory pressure. 195 * 196 * <p>Once you return from onReceive(), the BroadcastReceiver is no longer 197 * active, and its hosting process is only as important as any other application 198 * components that are running in it. This is especially important because if 199 * that process was only hosting the BroadcastReceiver (a common case for 200 * applications that the user has never or not recently interacted with), then 201 * upon returning from onReceive() the system will consider its process 202 * to be empty and aggressively kill it so that resources are available for other 203 * more important processes. 204 * 205 * <p>This means that for longer-running operations you will often use 206 * a {@link android.app.Service} in conjunction with a BroadcastReceiver to keep 207 * the containing process active for the entire time of your operation. 208 */ 209 public abstract class BroadcastReceiver { 210 private PendingResult mPendingResult; 211 private boolean mDebugUnregister; 212 213 /** 214 * State for a result that is pending for a broadcast receiver. Returned 215 * by {@link BroadcastReceiver#goAsync() goAsync()} 216 * while in {@link BroadcastReceiver#onReceive BroadcastReceiver.onReceive()}. 217 * This allows you to return from onReceive() without having the broadcast 218 * terminate; you must call {@link #finish()} once you are done with the 219 * broadcast. This allows you to process the broadcast off of the main 220 * thread of your app. 221 * 222 * <p>Note on threading: the state inside of this class is not itself 223 * thread-safe, however you can use it from any thread if you properly 224 * sure that you do not have races. Typically this means you will hand 225 * the entire object to another thread, which will be solely responsible 226 * for setting any results and finally calling {@link #finish()}. 227 */ 228 public static class PendingResult { 229 /** @hide */ 230 public static final int TYPE_COMPONENT = 0; 231 /** @hide */ 232 public static final int TYPE_REGISTERED = 1; 233 /** @hide */ 234 public static final int TYPE_UNREGISTERED = 2; 235 236 final int mType; 237 final boolean mOrderedHint; 238 final boolean mInitialStickyHint; 239 final IBinder mToken; 240 final int mSendingUser; 241 242 int mResultCode; 243 String mResultData; 244 Bundle mResultExtras; 245 boolean mAbortBroadcast; 246 boolean mFinished; 247 248 /** @hide */ PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, boolean ordered, boolean sticky, IBinder token, int userId)249 public PendingResult(int resultCode, String resultData, Bundle resultExtras, 250 int type, boolean ordered, boolean sticky, IBinder token, int userId) { 251 mResultCode = resultCode; 252 mResultData = resultData; 253 mResultExtras = resultExtras; 254 mType = type; 255 mOrderedHint = ordered; 256 mInitialStickyHint = sticky; 257 mToken = token; 258 mSendingUser = userId; 259 } 260 261 /** 262 * Version of {@link BroadcastReceiver#setResultCode(int) 263 * BroadcastReceiver.setResultCode(int)} for 264 * asynchronous broadcast handling. 265 */ setResultCode(int code)266 public final void setResultCode(int code) { 267 checkSynchronousHint(); 268 mResultCode = code; 269 } 270 271 /** 272 * Version of {@link BroadcastReceiver#getResultCode() 273 * BroadcastReceiver.getResultCode()} for 274 * asynchronous broadcast handling. 275 */ getResultCode()276 public final int getResultCode() { 277 return mResultCode; 278 } 279 280 /** 281 * Version of {@link BroadcastReceiver#setResultData(String) 282 * BroadcastReceiver.setResultData(String)} for 283 * asynchronous broadcast handling. 284 */ setResultData(String data)285 public final void setResultData(String data) { 286 checkSynchronousHint(); 287 mResultData = data; 288 } 289 290 /** 291 * Version of {@link BroadcastReceiver#getResultData() 292 * BroadcastReceiver.getResultData()} for 293 * asynchronous broadcast handling. 294 */ getResultData()295 public final String getResultData() { 296 return mResultData; 297 } 298 299 /** 300 * Version of {@link BroadcastReceiver#setResultExtras(Bundle) 301 * BroadcastReceiver.setResultExtras(Bundle)} for 302 * asynchronous broadcast handling. 303 */ setResultExtras(Bundle extras)304 public final void setResultExtras(Bundle extras) { 305 checkSynchronousHint(); 306 mResultExtras = extras; 307 } 308 309 /** 310 * Version of {@link BroadcastReceiver#getResultExtras(boolean) 311 * BroadcastReceiver.getResultExtras(boolean)} for 312 * asynchronous broadcast handling. 313 */ getResultExtras(boolean makeMap)314 public final Bundle getResultExtras(boolean makeMap) { 315 Bundle e = mResultExtras; 316 if (!makeMap) return e; 317 if (e == null) mResultExtras = e = new Bundle(); 318 return e; 319 } 320 321 /** 322 * Version of {@link BroadcastReceiver#setResult(int, String, Bundle) 323 * BroadcastReceiver.setResult(int, String, Bundle)} for 324 * asynchronous broadcast handling. 325 */ setResult(int code, String data, Bundle extras)326 public final void setResult(int code, String data, Bundle extras) { 327 checkSynchronousHint(); 328 mResultCode = code; 329 mResultData = data; 330 mResultExtras = extras; 331 } 332 333 /** 334 * Version of {@link BroadcastReceiver#getAbortBroadcast() 335 * BroadcastReceiver.getAbortBroadcast()} for 336 * asynchronous broadcast handling. 337 */ getAbortBroadcast()338 public final boolean getAbortBroadcast() { 339 return mAbortBroadcast; 340 } 341 342 /** 343 * Version of {@link BroadcastReceiver#abortBroadcast() 344 * BroadcastReceiver.abortBroadcast()} for 345 * asynchronous broadcast handling. 346 */ abortBroadcast()347 public final void abortBroadcast() { 348 checkSynchronousHint(); 349 mAbortBroadcast = true; 350 } 351 352 /** 353 * Version of {@link BroadcastReceiver#clearAbortBroadcast() 354 * BroadcastReceiver.clearAbortBroadcast()} for 355 * asynchronous broadcast handling. 356 */ clearAbortBroadcast()357 public final void clearAbortBroadcast() { 358 mAbortBroadcast = false; 359 } 360 361 /** 362 * Finish the broadcast. The current result will be sent and the 363 * next broadcast will proceed. 364 */ finish()365 public final void finish() { 366 if (mType == TYPE_COMPONENT) { 367 final IActivityManager mgr = ActivityManagerNative.getDefault(); 368 if (QueuedWork.hasPendingWork()) { 369 // If this is a broadcast component, we need to make sure any 370 // queued work is complete before telling AM we are done, so 371 // we don't have our process killed before that. We now know 372 // there is pending work; put another piece of work at the end 373 // of the list to finish the broadcast, so we don't block this 374 // thread (which may be the main thread) to have it finished. 375 // 376 // Note that we don't need to use QueuedWork.add() with the 377 // runnable, since we know the AM is waiting for us until the 378 // executor gets to it. 379 QueuedWork.singleThreadExecutor().execute( new Runnable() { 380 @Override public void run() { 381 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 382 "Finishing broadcast after work to component " + mToken); 383 sendFinished(mgr); 384 } 385 }); 386 } else { 387 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 388 "Finishing broadcast to component " + mToken); 389 sendFinished(mgr); 390 } 391 } else if (mOrderedHint && mType != TYPE_UNREGISTERED) { 392 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 393 "Finishing broadcast to " + mToken); 394 final IActivityManager mgr = ActivityManagerNative.getDefault(); 395 sendFinished(mgr); 396 } 397 } 398 399 /** @hide */ setExtrasClassLoader(ClassLoader cl)400 public void setExtrasClassLoader(ClassLoader cl) { 401 if (mResultExtras != null) { 402 mResultExtras.setClassLoader(cl); 403 } 404 } 405 406 /** @hide */ sendFinished(IActivityManager am)407 public void sendFinished(IActivityManager am) { 408 synchronized (this) { 409 if (mFinished) { 410 throw new IllegalStateException("Broadcast already finished"); 411 } 412 mFinished = true; 413 414 try { 415 if (mResultExtras != null) { 416 mResultExtras.setAllowFds(false); 417 } 418 if (mOrderedHint) { 419 am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, 420 mAbortBroadcast); 421 } else { 422 // This broadcast was sent to a component; it is not ordered, 423 // but we still need to tell the activity manager we are done. 424 am.finishReceiver(mToken, 0, null, null, false); 425 } 426 } catch (RemoteException ex) { 427 } 428 } 429 } 430 431 /** @hide */ getSendingUserId()432 public int getSendingUserId() { 433 return mSendingUser; 434 } 435 checkSynchronousHint()436 void checkSynchronousHint() { 437 // Note that we don't assert when receiving the initial sticky value, 438 // since that may have come from an ordered broadcast. We'll catch 439 // them later when the real broadcast happens again. 440 if (mOrderedHint || mInitialStickyHint) { 441 return; 442 } 443 RuntimeException e = new RuntimeException( 444 "BroadcastReceiver trying to return result during a non-ordered broadcast"); 445 e.fillInStackTrace(); 446 Log.e("BroadcastReceiver", e.getMessage(), e); 447 } 448 } 449 BroadcastReceiver()450 public BroadcastReceiver() { 451 } 452 453 /** 454 * This method is called when the BroadcastReceiver is receiving an Intent 455 * broadcast. During this time you can use the other methods on 456 * BroadcastReceiver to view/modify the current result values. This method 457 * is always called within the main thread of its process, unless you 458 * explicitly asked for it to be scheduled on a different thread using 459 * {@link android.content.Context#registerReceiver(BroadcastReceiver, 460 * IntentFilter, String, android.os.Handler)}. When it runs on the main 461 * thread you should 462 * never perform long-running operations in it (there is a timeout of 463 * 10 seconds that the system allows before considering the receiver to 464 * be blocked and a candidate to be killed). You cannot launch a popup dialog 465 * in your implementation of onReceive(). 466 * 467 * <p><b>If this BroadcastReceiver was launched through a <receiver> tag, 468 * then the object is no longer alive after returning from this 469 * function.</b> This means you should not perform any operations that 470 * return a result to you asynchronously -- in particular, for interacting 471 * with services, you should use 472 * {@link Context#startService(Intent)} instead of 473 * {@link Context#bindService(Intent, ServiceConnection, int)}. If you wish 474 * to interact with a service that is already running, you can use 475 * {@link #peekService}. 476 * 477 * <p>The Intent filters used in {@link android.content.Context#registerReceiver} 478 * and in application manifests are <em>not</em> guaranteed to be exclusive. They 479 * are hints to the operating system about how to find suitable recipients. It is 480 * possible for senders to force delivery to specific recipients, bypassing filter 481 * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()} 482 * implementations should respond only to known actions, ignoring any unexpected 483 * Intents that they may receive. 484 * 485 * @param context The Context in which the receiver is running. 486 * @param intent The Intent being received. 487 */ onReceive(Context context, Intent intent)488 public abstract void onReceive(Context context, Intent intent); 489 490 /** 491 * This can be called by an application in {@link #onReceive} to allow 492 * it to keep the broadcast active after returning from that function. 493 * This does <em>not</em> change the expectation of being relatively 494 * responsive to the broadcast (finishing it within 10s), but does allow 495 * the implementation to move work related to it over to another thread 496 * to avoid glitching the main UI thread due to disk IO. 497 * 498 * @return Returns a {@link PendingResult} representing the result of 499 * the active broadcast. The BroadcastRecord itself is no longer active; 500 * all data and other interaction must go through {@link PendingResult} 501 * APIs. The {@link PendingResult#finish PendingResult.finish()} method 502 * must be called once processing of the broadcast is done. 503 */ goAsync()504 public final PendingResult goAsync() { 505 PendingResult res = mPendingResult; 506 mPendingResult = null; 507 return res; 508 } 509 510 /** 511 * Provide a binder to an already-running service. This method is synchronous 512 * and will not start the target service if it is not present, so it is safe 513 * to call from {@link #onReceive}. 514 * 515 * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)} 516 * @param service The Intent indicating the service you wish to use. See {@link 517 * Context#startService(Intent)} for more information. 518 */ peekService(Context myContext, Intent service)519 public IBinder peekService(Context myContext, Intent service) { 520 IActivityManager am = ActivityManagerNative.getDefault(); 521 IBinder binder = null; 522 try { 523 service.prepareToLeaveProcess(); 524 binder = am.peekService(service, service.resolveTypeIfNeeded( 525 myContext.getContentResolver())); 526 } catch (RemoteException e) { 527 } 528 return binder; 529 } 530 531 /** 532 * Change the current result code of this broadcast; only works with 533 * broadcasts sent through 534 * {@link Context#sendOrderedBroadcast(Intent, String) 535 * Context.sendOrderedBroadcast}. Often uses the 536 * Activity {@link android.app.Activity#RESULT_CANCELED} and 537 * {@link android.app.Activity#RESULT_OK} constants, though the 538 * actual meaning of this value is ultimately up to the broadcaster. 539 * 540 * <p class="note">This method does not work with non-ordered broadcasts such 541 * as those sent with {@link Context#sendBroadcast(Intent) 542 * Context.sendBroadcast}</p> 543 * 544 * @param code The new result code. 545 * 546 * @see #setResult(int, String, Bundle) 547 */ setResultCode(int code)548 public final void setResultCode(int code) { 549 checkSynchronousHint(); 550 mPendingResult.mResultCode = code; 551 } 552 553 /** 554 * Retrieve the current result code, as set by the previous receiver. 555 * 556 * @return int The current result code. 557 */ getResultCode()558 public final int getResultCode() { 559 return mPendingResult != null ? mPendingResult.mResultCode : 0; 560 } 561 562 /** 563 * Change the current result data of this broadcast; only works with 564 * broadcasts sent through 565 * {@link Context#sendOrderedBroadcast(Intent, String) 566 * Context.sendOrderedBroadcast}. This is an arbitrary 567 * string whose interpretation is up to the broadcaster. 568 * 569 * <p><strong>This method does not work with non-ordered broadcasts such 570 * as those sent with {@link Context#sendBroadcast(Intent) 571 * Context.sendBroadcast}</strong></p> 572 * 573 * @param data The new result data; may be null. 574 * 575 * @see #setResult(int, String, Bundle) 576 */ setResultData(String data)577 public final void setResultData(String data) { 578 checkSynchronousHint(); 579 mPendingResult.mResultData = data; 580 } 581 582 /** 583 * Retrieve the current result data, as set by the previous receiver. 584 * Often this is null. 585 * 586 * @return String The current result data; may be null. 587 */ getResultData()588 public final String getResultData() { 589 return mPendingResult != null ? mPendingResult.mResultData : null; 590 } 591 592 /** 593 * Change the current result extras of this broadcast; only works with 594 * broadcasts sent through 595 * {@link Context#sendOrderedBroadcast(Intent, String) 596 * Context.sendOrderedBroadcast}. This is a Bundle 597 * holding arbitrary data, whose interpretation is up to the 598 * broadcaster. Can be set to null. Calling this method completely 599 * replaces the current map (if any). 600 * 601 * <p><strong>This method does not work with non-ordered broadcasts such 602 * as those sent with {@link Context#sendBroadcast(Intent) 603 * Context.sendBroadcast}</strong></p> 604 * 605 * @param extras The new extra data map; may be null. 606 * 607 * @see #setResult(int, String, Bundle) 608 */ setResultExtras(Bundle extras)609 public final void setResultExtras(Bundle extras) { 610 checkSynchronousHint(); 611 mPendingResult.mResultExtras = extras; 612 } 613 614 /** 615 * Retrieve the current result extra data, as set by the previous receiver. 616 * Any changes you make to the returned Map will be propagated to the next 617 * receiver. 618 * 619 * @param makeMap If true then a new empty Map will be made for you if the 620 * current Map is null; if false you should be prepared to 621 * receive a null Map. 622 * 623 * @return Map The current extras map. 624 */ getResultExtras(boolean makeMap)625 public final Bundle getResultExtras(boolean makeMap) { 626 if (mPendingResult == null) { 627 return null; 628 } 629 Bundle e = mPendingResult.mResultExtras; 630 if (!makeMap) return e; 631 if (e == null) mPendingResult.mResultExtras = e = new Bundle(); 632 return e; 633 } 634 635 /** 636 * Change all of the result data returned from this broadcasts; only works 637 * with broadcasts sent through 638 * {@link Context#sendOrderedBroadcast(Intent, String) 639 * Context.sendOrderedBroadcast}. All current result data is replaced 640 * by the value given to this method. 641 * 642 * <p><strong>This method does not work with non-ordered broadcasts such 643 * as those sent with {@link Context#sendBroadcast(Intent) 644 * Context.sendBroadcast}</strong></p> 645 * 646 * @param code The new result code. Often uses the 647 * Activity {@link android.app.Activity#RESULT_CANCELED} and 648 * {@link android.app.Activity#RESULT_OK} constants, though the 649 * actual meaning of this value is ultimately up to the broadcaster. 650 * @param data The new result data. This is an arbitrary 651 * string whose interpretation is up to the broadcaster; may be null. 652 * @param extras The new extra data map. This is a Bundle 653 * holding arbitrary data, whose interpretation is up to the 654 * broadcaster. Can be set to null. This completely 655 * replaces the current map (if any). 656 */ setResult(int code, String data, Bundle extras)657 public final void setResult(int code, String data, Bundle extras) { 658 checkSynchronousHint(); 659 mPendingResult.mResultCode = code; 660 mPendingResult.mResultData = data; 661 mPendingResult.mResultExtras = extras; 662 } 663 664 /** 665 * Returns the flag indicating whether or not this receiver should 666 * abort the current broadcast. 667 * 668 * @return True if the broadcast should be aborted. 669 */ getAbortBroadcast()670 public final boolean getAbortBroadcast() { 671 return mPendingResult != null ? mPendingResult.mAbortBroadcast : false; 672 } 673 674 /** 675 * Sets the flag indicating that this receiver should abort the 676 * current broadcast; only works with broadcasts sent through 677 * {@link Context#sendOrderedBroadcast(Intent, String) 678 * Context.sendOrderedBroadcast}. This will prevent 679 * any other broadcast receivers from receiving the broadcast. It will still 680 * call {@link #onReceive} of the BroadcastReceiver that the caller of 681 * {@link Context#sendOrderedBroadcast(Intent, String) 682 * Context.sendOrderedBroadcast} passed in. 683 * 684 * <p><strong>This method does not work with non-ordered broadcasts such 685 * as those sent with {@link Context#sendBroadcast(Intent) 686 * Context.sendBroadcast}</strong></p> 687 */ abortBroadcast()688 public final void abortBroadcast() { 689 checkSynchronousHint(); 690 mPendingResult.mAbortBroadcast = true; 691 } 692 693 /** 694 * Clears the flag indicating that this receiver should abort the current 695 * broadcast. 696 */ clearAbortBroadcast()697 public final void clearAbortBroadcast() { 698 if (mPendingResult != null) { 699 mPendingResult.mAbortBroadcast = false; 700 } 701 } 702 703 /** 704 * Returns true if the receiver is currently processing an ordered 705 * broadcast. 706 */ isOrderedBroadcast()707 public final boolean isOrderedBroadcast() { 708 return mPendingResult != null ? mPendingResult.mOrderedHint : false; 709 } 710 711 /** 712 * Returns true if the receiver is currently processing the initial 713 * value of a sticky broadcast -- that is, the value that was last 714 * broadcast and is currently held in the sticky cache, so this is 715 * not directly the result of a broadcast right now. 716 */ isInitialStickyBroadcast()717 public final boolean isInitialStickyBroadcast() { 718 return mPendingResult != null ? mPendingResult.mInitialStickyHint : false; 719 } 720 721 /** 722 * For internal use, sets the hint about whether this BroadcastReceiver is 723 * running in ordered mode. 724 */ setOrderedHint(boolean isOrdered)725 public final void setOrderedHint(boolean isOrdered) { 726 // Accidentally left in the SDK. 727 } 728 729 /** 730 * For internal use to set the result data that is active. @hide 731 */ setPendingResult(PendingResult result)732 public final void setPendingResult(PendingResult result) { 733 mPendingResult = result; 734 } 735 736 /** 737 * For internal use to set the result data that is active. @hide 738 */ getPendingResult()739 public final PendingResult getPendingResult() { 740 return mPendingResult; 741 } 742 743 /** @hide */ getSendingUserId()744 public int getSendingUserId() { 745 return mPendingResult.mSendingUser; 746 } 747 748 /** 749 * Control inclusion of debugging help for mismatched 750 * calls to {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) 751 * Context.registerReceiver()}. 752 * If called with true, before given to registerReceiver(), then the 753 * callstack of the following {@link Context#unregisterReceiver(BroadcastReceiver) 754 * Context.unregisterReceiver()} call is retained, to be printed if a later 755 * incorrect unregister call is made. Note that doing this requires retaining 756 * information about the BroadcastReceiver for the lifetime of the app, 757 * resulting in a leak -- this should only be used for debugging. 758 */ setDebugUnregister(boolean debug)759 public final void setDebugUnregister(boolean debug) { 760 mDebugUnregister = debug; 761 } 762 763 /** 764 * Return the last value given to {@link #setDebugUnregister}. 765 */ getDebugUnregister()766 public final boolean getDebugUnregister() { 767 return mDebugUnregister; 768 } 769 checkSynchronousHint()770 void checkSynchronousHint() { 771 if (mPendingResult == null) { 772 throw new IllegalStateException("Call while result is not pending"); 773 } 774 775 // Note that we don't assert when receiving the initial sticky value, 776 // since that may have come from an ordered broadcast. We'll catch 777 // them later when the real broadcast happens again. 778 if (mPendingResult.mOrderedHint || mPendingResult.mInitialStickyHint) { 779 return; 780 } 781 RuntimeException e = new RuntimeException( 782 "BroadcastReceiver trying to return result during a non-ordered broadcast"); 783 e.fillInStackTrace(); 784 Log.e("BroadcastReceiver", e.getMessage(), e); 785 } 786 } 787 788