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.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.app.ActivityManager; 23 import android.app.ActivityThread; 24 import android.app.IActivityManager; 25 import android.app.QueuedWork; 26 import android.compat.annotation.UnsupportedAppUsage; 27 import android.os.Build; 28 import android.os.Bundle; 29 import android.os.IBinder; 30 import android.os.Process; 31 import android.os.RemoteException; 32 import android.os.Trace; 33 import android.os.UserHandle; 34 import android.util.Log; 35 import android.util.Slog; 36 37 /** 38 * Base class for code that receives and handles broadcast intents sent by 39 * {@link android.content.Context#sendBroadcast(Intent)}. 40 * 41 * <p>You can either dynamically register an instance of this class with 42 * {@link Context#registerReceiver Context.registerReceiver()} 43 * or statically declare an implementation with the 44 * {@link android.R.styleable#AndroidManifestReceiver <receiver>} 45 * tag in your <code>AndroidManifest.xml</code>. 46 * 47 * <div class="special reference"> 48 * <h3>Developer Guides</h3> 49 * <p>For more information about using BroadcastReceiver, read the 50 * <a href="{@docRoot}guide/components/broadcasts.html">Broadcasts</a> developer guide.</p></div> 51 * 52 */ 53 public abstract class BroadcastReceiver { 54 @UnsupportedAppUsage 55 private PendingResult mPendingResult; 56 private boolean mDebugUnregister; 57 58 /** 59 * State for a result that is pending for a broadcast receiver. Returned 60 * by {@link BroadcastReceiver#goAsync() goAsync()} 61 * while in {@link BroadcastReceiver#onReceive BroadcastReceiver.onReceive()}. 62 * This allows you to return from onReceive() without having the broadcast 63 * terminate; you must call {@link #finish()} once you are done with the 64 * broadcast. This allows you to process the broadcast off of the main 65 * thread of your app. 66 * 67 * <p>Note on threading: the state inside of this class is not itself 68 * thread-safe. However, you can use it from any thread if you make 69 * sure that you do not have races. Typically this means you will hand 70 * the entire object to another thread, which will be solely responsible 71 * for setting any results and finally calling {@link #finish()}. 72 */ 73 public static class PendingResult { 74 /** @hide */ 75 public static final int TYPE_COMPONENT = 0; 76 /** @hide */ 77 public static final int TYPE_REGISTERED = 1; 78 /** @hide */ 79 public static final int TYPE_UNREGISTERED = 2; 80 81 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 82 final int mType; 83 @UnsupportedAppUsage 84 final boolean mOrderedHint; 85 @UnsupportedAppUsage 86 final boolean mInitialStickyHint; 87 final boolean mAssumeDeliveredHint; 88 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 89 final IBinder mToken; 90 @UnsupportedAppUsage 91 final int mSendingUser; 92 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 93 final int mFlags; 94 95 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 96 int mResultCode; 97 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 98 String mResultData; 99 @UnsupportedAppUsage 100 Bundle mResultExtras; 101 @UnsupportedAppUsage 102 boolean mAbortBroadcast; 103 @UnsupportedAppUsage 104 boolean mFinished; 105 String mReceiverClassName; 106 final int mSentFromUid; 107 final String mSentFromPackage; 108 109 /** @hide */ 110 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, boolean ordered, boolean sticky, IBinder token, int userId, int flags)111 public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, 112 boolean ordered, boolean sticky, IBinder token, int userId, int flags) { 113 this(resultCode, resultData, resultExtras, type, ordered, sticky, 114 guessAssumeDelivered(type, ordered), token, userId, flags, 115 Process.INVALID_UID, null); 116 } 117 118 /** @hide */ PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, boolean ordered, boolean sticky, boolean assumeDelivered, IBinder token, int userId, int flags, int sentFromUid, String sentFromPackage)119 public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, 120 boolean ordered, boolean sticky, boolean assumeDelivered, IBinder token, 121 int userId, int flags, int sentFromUid, String sentFromPackage) { 122 mResultCode = resultCode; 123 mResultData = resultData; 124 mResultExtras = resultExtras; 125 mType = type; 126 mOrderedHint = ordered; 127 mInitialStickyHint = sticky; 128 mAssumeDeliveredHint = assumeDelivered; 129 mToken = token; 130 mSendingUser = userId; 131 mFlags = flags; 132 mSentFromUid = sentFromUid; 133 mSentFromPackage = sentFromPackage; 134 } 135 136 /** @hide */ guessAssumeDelivered(int type, boolean ordered)137 public static boolean guessAssumeDelivered(int type, boolean ordered) { 138 // When a caller didn't provide a concrete way of knowing if we need 139 // to report delivery, make a best-effort guess 140 if (type == TYPE_COMPONENT) { 141 return false; 142 } else if (ordered && type != TYPE_UNREGISTERED) { 143 return false; 144 } 145 return true; 146 } 147 148 /** 149 * Version of {@link BroadcastReceiver#setResultCode(int) 150 * BroadcastReceiver.setResultCode(int)} for 151 * asynchronous broadcast handling. 152 */ setResultCode(int code)153 public final void setResultCode(int code) { 154 checkSynchronousHint(); 155 mResultCode = code; 156 } 157 158 /** 159 * Version of {@link BroadcastReceiver#getResultCode() 160 * BroadcastReceiver.getResultCode()} for 161 * asynchronous broadcast handling. 162 */ getResultCode()163 public final int getResultCode() { 164 return mResultCode; 165 } 166 167 /** 168 * Version of {@link BroadcastReceiver#setResultData(String) 169 * BroadcastReceiver.setResultData(String)} for 170 * asynchronous broadcast handling. 171 */ setResultData(String data)172 public final void setResultData(String data) { 173 checkSynchronousHint(); 174 mResultData = data; 175 } 176 177 /** 178 * Version of {@link BroadcastReceiver#getResultData() 179 * BroadcastReceiver.getResultData()} for 180 * asynchronous broadcast handling. 181 */ getResultData()182 public final String getResultData() { 183 return mResultData; 184 } 185 186 /** 187 * Version of {@link BroadcastReceiver#setResultExtras(Bundle) 188 * BroadcastReceiver.setResultExtras(Bundle)} for 189 * asynchronous broadcast handling. 190 */ setResultExtras(Bundle extras)191 public final void setResultExtras(Bundle extras) { 192 checkSynchronousHint(); 193 mResultExtras = extras; 194 } 195 196 /** 197 * Version of {@link BroadcastReceiver#getResultExtras(boolean) 198 * BroadcastReceiver.getResultExtras(boolean)} for 199 * asynchronous broadcast handling. 200 */ getResultExtras(boolean makeMap)201 public final Bundle getResultExtras(boolean makeMap) { 202 Bundle e = mResultExtras; 203 if (!makeMap) return e; 204 if (e == null) mResultExtras = e = new Bundle(); 205 return e; 206 } 207 208 /** 209 * Version of {@link BroadcastReceiver#setResult(int, String, Bundle) 210 * BroadcastReceiver.setResult(int, String, Bundle)} for 211 * asynchronous broadcast handling. 212 */ setResult(int code, String data, Bundle extras)213 public final void setResult(int code, String data, Bundle extras) { 214 checkSynchronousHint(); 215 mResultCode = code; 216 mResultData = data; 217 mResultExtras = extras; 218 } 219 220 /** 221 * Version of {@link BroadcastReceiver#getAbortBroadcast() 222 * BroadcastReceiver.getAbortBroadcast()} for 223 * asynchronous broadcast handling. 224 */ getAbortBroadcast()225 public final boolean getAbortBroadcast() { 226 return mAbortBroadcast; 227 } 228 229 /** 230 * Version of {@link BroadcastReceiver#abortBroadcast() 231 * BroadcastReceiver.abortBroadcast()} for 232 * asynchronous broadcast handling. 233 */ abortBroadcast()234 public final void abortBroadcast() { 235 checkSynchronousHint(); 236 mAbortBroadcast = true; 237 } 238 239 /** 240 * Version of {@link BroadcastReceiver#clearAbortBroadcast() 241 * BroadcastReceiver.clearAbortBroadcast()} for 242 * asynchronous broadcast handling. 243 */ clearAbortBroadcast()244 public final void clearAbortBroadcast() { 245 mAbortBroadcast = false; 246 } 247 248 /** 249 * Finish the broadcast. The current result will be sent and the 250 * next broadcast will proceed. 251 */ finish()252 public final void finish() { 253 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { 254 Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER, 255 "PendingResult#finish#ClassName:" + mReceiverClassName, 256 1); 257 } 258 259 if (mType == TYPE_COMPONENT) { 260 final IActivityManager mgr = ActivityManager.getService(); 261 if (QueuedWork.hasPendingWork()) { 262 // If this is a broadcast component, we need to make sure any 263 // queued work is complete before telling AM we are done, so 264 // we don't have our process killed before that. We now know 265 // there is pending work; put another piece of work at the end 266 // of the list to finish the broadcast, so we don't block this 267 // thread (which may be the main thread) to have it finished. 268 // 269 // Note that we don't need to use QueuedWork.addFinisher() with the 270 // runnable, since we know the AM is waiting for us until the 271 // executor gets to it. 272 QueuedWork.queue(new Runnable() { 273 @Override public void run() { 274 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 275 "Finishing broadcast after work to component " + mToken); 276 sendFinished(mgr); 277 } 278 }, false); 279 } else { 280 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 281 "Finishing broadcast to component " + mToken); 282 sendFinished(mgr); 283 } 284 } else { 285 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 286 "Finishing broadcast to " + mToken); 287 final IActivityManager mgr = ActivityManager.getService(); 288 sendFinished(mgr); 289 } 290 } 291 292 /** @hide */ setExtrasClassLoader(ClassLoader cl)293 public void setExtrasClassLoader(ClassLoader cl) { 294 if (mResultExtras != null) { 295 mResultExtras.setClassLoader(cl); 296 } 297 } 298 299 /** @hide */ sendFinished(IActivityManager am)300 public void sendFinished(IActivityManager am) { 301 synchronized (this) { 302 if (mFinished) { 303 throw new IllegalStateException("Broadcast already finished"); 304 } 305 mFinished = true; 306 307 try { 308 if (mResultExtras != null) { 309 mResultExtras.setAllowFds(false); 310 } 311 312 // When the OS didn't assume delivery, we need to inform 313 // it that we've actually finished the delivery 314 if (!mAssumeDeliveredHint) { 315 if (mOrderedHint) { 316 am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, 317 mAbortBroadcast, mFlags); 318 } else { 319 am.finishReceiver(mToken, 0, null, null, false, mFlags); 320 } 321 } 322 } catch (RemoteException ex) { 323 } 324 } 325 } 326 327 /** @hide */ getSendingUserId()328 public int getSendingUserId() { 329 return mSendingUser; 330 } 331 332 /** @hide */ getSentFromUid()333 public int getSentFromUid() { 334 return mSentFromUid; 335 } 336 337 /** @hide */ getSentFromPackage()338 public String getSentFromPackage() { 339 return mSentFromPackage; 340 } 341 checkSynchronousHint()342 void checkSynchronousHint() { 343 // Note that we don't assert when receiving the initial sticky value, 344 // since that may have come from an ordered broadcast. We'll catch 345 // them later when the real broadcast happens again. 346 if (mOrderedHint || mInitialStickyHint) { 347 return; 348 } 349 RuntimeException e = new RuntimeException( 350 "BroadcastReceiver trying to return result during a non-ordered broadcast"); 351 e.fillInStackTrace(); 352 Log.e("BroadcastReceiver", e.getMessage(), e); 353 } 354 } 355 BroadcastReceiver()356 public BroadcastReceiver() { 357 } 358 359 /** 360 * This method is called when the BroadcastReceiver is receiving an Intent 361 * broadcast. During this time you can use the other methods on 362 * BroadcastReceiver to view/modify the current result values. This method 363 * is always called within the main thread of its process, unless you 364 * explicitly asked for it to be scheduled on a different thread using 365 * {@link android.content.Context#registerReceiver(BroadcastReceiver, 366 * IntentFilter, String, android.os.Handler)}. When it runs on the main 367 * thread you should 368 * never perform long-running operations in it (there is a timeout of 369 * 10 seconds that the system allows before considering the receiver to 370 * be blocked and a candidate to be killed). You cannot launch a popup dialog 371 * in your implementation of onReceive(). 372 * 373 * <p><b>If this BroadcastReceiver was launched through a <receiver> tag, 374 * then the object is no longer alive after returning from this 375 * function.</b> This means you should not perform any operations that 376 * return a result to you asynchronously. If you need to perform any follow up 377 * background work, schedule a {@link android.app.job.JobService} with 378 * {@link android.app.job.JobScheduler}. 379 * 380 * If you wish to interact with a service that is already running and previously 381 * bound using {@link android.content.Context#bindService(Intent, ServiceConnection, int) bindService()}, 382 * you can use {@link #peekService}. 383 * 384 * <p>The Intent filters used in {@link android.content.Context#registerReceiver} 385 * and in application manifests are <em>not</em> guaranteed to be exclusive. They 386 * are hints to the operating system about how to find suitable recipients. It is 387 * possible for senders to force delivery to specific recipients, bypassing filter 388 * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()} 389 * implementations should respond only to known actions, ignoring any unexpected 390 * Intents that they may receive. 391 * 392 * @param context The Context in which the receiver is running. 393 * @param intent The Intent being received. 394 */ onReceive(Context context, Intent intent)395 public abstract void onReceive(Context context, Intent intent); 396 397 /** 398 * This can be called by an application in {@link #onReceive} to allow 399 * it to keep the broadcast active after returning from that function. 400 * This does <em>not</em> change the expectation of being relatively 401 * responsive to the broadcast, but does allow 402 * the implementation to move work related to it over to another thread 403 * to avoid glitching the main UI thread due to disk IO. 404 * 405 * <p>As a general rule, broadcast receivers are allowed to run for up to 10 seconds 406 * before the system will consider them non-responsive and ANR the app. Since these usually 407 * execute on the app's main thread, they are already bound by the ~5 second time limit 408 * of various operations that can happen there (not to mention just avoiding UI jank), so 409 * the receive limit is generally not of concern. However, once you use {@code goAsync}, though 410 * able to be off the main thread, the broadcast execution limit still applies, and that 411 * includes the time spent between calling this method and ultimately 412 * {@link PendingResult#finish() PendingResult.finish()}.</p> 413 * 414 * <p>If you are taking advantage of this method to have more time to execute, it is useful 415 * to know that the available time can be longer in certain situations. In particular, if 416 * the broadcast you are receiving is not a foreground broadcast (that is, the sender has not 417 * used {@link Intent#FLAG_RECEIVER_FOREGROUND}), then more time is allowed for the receivers 418 * to run, allowing them to execute for 30 seconds or even a bit more. This is something that 419 * receivers should rarely take advantage of (long work should be punted to another system 420 * facility such as {@link android.app.job.JobScheduler}, {@link android.app.Service}, or 421 * see especially {@link androidx.core.app.JobIntentService}), but can be useful in 422 * certain rare cases where it is necessary to do some work as soon as the broadcast is 423 * delivered. Keep in mind that the work you do here will block further broadcasts until 424 * it completes, so taking advantage of this at all excessively can be counter-productive 425 * and cause later events to be received more slowly.</p> 426 * 427 * @return Returns a {@link PendingResult} representing the result of 428 * the active broadcast. The BroadcastRecord itself is no longer active; 429 * all data and other interaction must go through {@link PendingResult} 430 * APIs. The {@link PendingResult#finish PendingResult.finish()} method 431 * must be called once processing of the broadcast is done. 432 */ goAsync()433 public final PendingResult goAsync() { 434 PendingResult res = mPendingResult; 435 mPendingResult = null; 436 437 if (res != null && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { 438 res.mReceiverClassName = getClass().getName(); 439 Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER, 440 "BroadcastReceiver#goAsync#ClassName:" + res.mReceiverClassName, 441 1); 442 } 443 444 return res; 445 } 446 447 /** 448 * Provide a binder to an already-bound service. This method is synchronous 449 * and will not start the target service if it is not present, so it is safe 450 * to call from {@link #onReceive}. 451 * 452 * For peekService() to return a non null {@link android.os.IBinder} interface 453 * the service must have published it before. In other words some component 454 * must have called {@link android.content.Context#bindService(Intent, ServiceConnection, int)} on it. 455 * 456 * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)} 457 * @param service Identifies the already-bound service you wish to use. See 458 * {@link android.content.Context#bindService(Intent, ServiceConnection, int)} 459 * for more information. 460 */ peekService(Context myContext, Intent service)461 public IBinder peekService(Context myContext, Intent service) { 462 IActivityManager am = ActivityManager.getService(); 463 IBinder binder = null; 464 try { 465 service.prepareToLeaveProcess(myContext); 466 binder = am.peekService(service, service.resolveTypeIfNeeded( 467 myContext.getContentResolver()), myContext.getOpPackageName()); 468 } catch (RemoteException e) { 469 } 470 return binder; 471 } 472 473 /** 474 * Change the current result code of this broadcast; only works with 475 * broadcasts sent through 476 * {@link Context#sendOrderedBroadcast(Intent, String) 477 * Context.sendOrderedBroadcast}. Often uses the 478 * Activity {@link android.app.Activity#RESULT_CANCELED} and 479 * {@link android.app.Activity#RESULT_OK} constants, though the 480 * actual meaning of this value is ultimately up to the broadcaster. 481 * 482 * <p class="note">This method does not work with non-ordered broadcasts such 483 * as those sent with {@link Context#sendBroadcast(Intent) 484 * Context.sendBroadcast}</p> 485 * 486 * @param code The new result code. 487 * 488 * @see #setResult(int, String, Bundle) 489 */ setResultCode(int code)490 public final void setResultCode(int code) { 491 checkSynchronousHint(); 492 mPendingResult.mResultCode = code; 493 } 494 495 /** 496 * Retrieve the current result code, as set by the previous receiver. 497 * 498 * @return int The current result code. 499 */ getResultCode()500 public final int getResultCode() { 501 return mPendingResult != null ? mPendingResult.mResultCode : 0; 502 } 503 504 /** 505 * Change the current result data of this broadcast; only works with 506 * broadcasts sent through 507 * {@link Context#sendOrderedBroadcast(Intent, String) 508 * Context.sendOrderedBroadcast}. This is an arbitrary 509 * string whose interpretation is up to the broadcaster. 510 * 511 * <p><strong>This method does not work with non-ordered broadcasts such 512 * as those sent with {@link Context#sendBroadcast(Intent) 513 * Context.sendBroadcast}</strong></p> 514 * 515 * @param data The new result data; may be null. 516 * 517 * @see #setResult(int, String, Bundle) 518 */ setResultData(String data)519 public final void setResultData(String data) { 520 checkSynchronousHint(); 521 mPendingResult.mResultData = data; 522 } 523 524 /** 525 * Retrieve the current result data, as set by the previous receiver. 526 * Often this is null. 527 * 528 * @return String The current result data; may be null. 529 */ getResultData()530 public final String getResultData() { 531 return mPendingResult != null ? mPendingResult.mResultData : null; 532 } 533 534 /** 535 * Change the current result extras of this broadcast; only works with 536 * broadcasts sent through 537 * {@link Context#sendOrderedBroadcast(Intent, String) 538 * Context.sendOrderedBroadcast}. This is a Bundle 539 * holding arbitrary data, whose interpretation is up to the 540 * broadcaster. Can be set to null. Calling this method completely 541 * replaces the current map (if any). 542 * 543 * <p><strong>This method does not work with non-ordered broadcasts such 544 * as those sent with {@link Context#sendBroadcast(Intent) 545 * Context.sendBroadcast}</strong></p> 546 * 547 * @param extras The new extra data map; may be null. 548 * 549 * @see #setResult(int, String, Bundle) 550 */ setResultExtras(Bundle extras)551 public final void setResultExtras(Bundle extras) { 552 checkSynchronousHint(); 553 mPendingResult.mResultExtras = extras; 554 } 555 556 /** 557 * Retrieve the current result extra data, as set by the previous receiver. 558 * Any changes you make to the returned Map will be propagated to the next 559 * receiver. 560 * 561 * @param makeMap If true then a new empty Map will be made for you if the 562 * current Map is null; if false you should be prepared to 563 * receive a null Map. 564 * 565 * @return Map The current extras map. 566 */ getResultExtras(boolean makeMap)567 public final Bundle getResultExtras(boolean makeMap) { 568 if (mPendingResult == null) { 569 return null; 570 } 571 Bundle e = mPendingResult.mResultExtras; 572 if (!makeMap) return e; 573 if (e == null) mPendingResult.mResultExtras = e = new Bundle(); 574 return e; 575 } 576 577 /** 578 * Change all of the result data returned from this broadcasts; only works 579 * with broadcasts sent through 580 * {@link Context#sendOrderedBroadcast(Intent, String) 581 * Context.sendOrderedBroadcast}. All current result data is replaced 582 * by the value given to this method. 583 * 584 * <p><strong>This method does not work with non-ordered broadcasts such 585 * as those sent with {@link Context#sendBroadcast(Intent) 586 * Context.sendBroadcast}</strong></p> 587 * 588 * @param code The new result code. Often uses the 589 * Activity {@link android.app.Activity#RESULT_CANCELED} and 590 * {@link android.app.Activity#RESULT_OK} constants, though the 591 * actual meaning of this value is ultimately up to the broadcaster. 592 * @param data The new result data. This is an arbitrary 593 * string whose interpretation is up to the broadcaster; may be null. 594 * @param extras The new extra data map. This is a Bundle 595 * holding arbitrary data, whose interpretation is up to the 596 * broadcaster. Can be set to null. This completely 597 * replaces the current map (if any). 598 */ setResult(int code, String data, Bundle extras)599 public final void setResult(int code, String data, Bundle extras) { 600 checkSynchronousHint(); 601 mPendingResult.mResultCode = code; 602 mPendingResult.mResultData = data; 603 mPendingResult.mResultExtras = extras; 604 } 605 606 /** 607 * Returns the flag indicating whether or not this receiver should 608 * abort the current broadcast. 609 * 610 * @return True if the broadcast should be aborted. 611 */ getAbortBroadcast()612 public final boolean getAbortBroadcast() { 613 return mPendingResult != null ? mPendingResult.mAbortBroadcast : false; 614 } 615 616 /** 617 * Sets the flag indicating that this receiver should abort the 618 * current broadcast; only works with broadcasts sent through 619 * {@link Context#sendOrderedBroadcast(Intent, String) 620 * Context.sendOrderedBroadcast}. This will prevent 621 * any other broadcast receivers from receiving the broadcast. It will still 622 * call {@link #onReceive} of the BroadcastReceiver that the caller of 623 * {@link Context#sendOrderedBroadcast(Intent, String) 624 * Context.sendOrderedBroadcast} passed in. 625 * 626 * <p><strong>This method does not work with non-ordered broadcasts such 627 * as those sent with {@link Context#sendBroadcast(Intent) 628 * Context.sendBroadcast}</strong></p> 629 */ abortBroadcast()630 public final void abortBroadcast() { 631 checkSynchronousHint(); 632 mPendingResult.mAbortBroadcast = true; 633 } 634 635 /** 636 * Clears the flag indicating that this receiver should abort the current 637 * broadcast. 638 */ clearAbortBroadcast()639 public final void clearAbortBroadcast() { 640 if (mPendingResult != null) { 641 mPendingResult.mAbortBroadcast = false; 642 } 643 } 644 645 /** 646 * Returns true if the receiver is currently processing an ordered 647 * broadcast. 648 */ isOrderedBroadcast()649 public final boolean isOrderedBroadcast() { 650 return mPendingResult != null ? mPendingResult.mOrderedHint : false; 651 } 652 653 /** 654 * Returns true if the receiver is currently processing the initial 655 * value of a sticky broadcast -- that is, the value that was last 656 * broadcast and is currently held in the sticky cache, so this is 657 * not directly the result of a broadcast right now. 658 */ isInitialStickyBroadcast()659 public final boolean isInitialStickyBroadcast() { 660 return mPendingResult != null ? mPendingResult.mInitialStickyHint : false; 661 } 662 663 /** 664 * For internal use, sets the hint about whether this BroadcastReceiver is 665 * running in ordered mode. 666 */ setOrderedHint(boolean isOrdered)667 public final void setOrderedHint(boolean isOrdered) { 668 // Accidentally left in the SDK. 669 } 670 671 /** 672 * For internal use to set the result data that is active. @hide 673 */ 674 @UnsupportedAppUsage setPendingResult(PendingResult result)675 public final void setPendingResult(PendingResult result) { 676 mPendingResult = result; 677 } 678 679 /** 680 * For internal use to set the result data that is active. @hide 681 */ 682 @UnsupportedAppUsage getPendingResult()683 public final PendingResult getPendingResult() { 684 return mPendingResult; 685 } 686 687 /** 688 * Returns the user that the broadcast was sent to. 689 * 690 * <p>It can be used in a receiver registered by 691 * {@link Context#registerReceiverForAllUsers Context.registerReceiverForAllUsers()} 692 * to determine on which user the broadcast was sent. 693 * 694 * @hide 695 */ 696 @SystemApi getSendingUser()697 public final @NonNull UserHandle getSendingUser() { 698 return UserHandle.of(getSendingUserId()); 699 } 700 701 /** @hide */ getSendingUserId()702 public int getSendingUserId() { 703 return mPendingResult.mSendingUser; 704 } 705 706 /** 707 * Returns the uid of the app that initially sent this broadcast. 708 * 709 * @return the uid of the broadcasting app or {@link Process#INVALID_UID} if the current 710 * receiver cannot access the identity of the broadcasting app 711 */ getSentFromUid()712 public int getSentFromUid() { 713 return mPendingResult != null ? mPendingResult.mSentFromUid : Process.INVALID_UID; 714 } 715 716 /** 717 * Returns the package name of the app that initially sent this broadcast. 718 * 719 * @return the package name of the broadcasting app or {@code null} if the current 720 * receiver cannot access the identity of the broadcasting app 721 */ getSentFromPackage()722 public @Nullable String getSentFromPackage() { 723 return mPendingResult != null ? mPendingResult.mSentFromPackage : null; 724 } 725 726 /** 727 * Control inclusion of debugging help for mismatched 728 * calls to {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) 729 * Context.registerReceiver()}. 730 * If called with true, before given to registerReceiver(), then the 731 * callstack of the following {@link Context#unregisterReceiver(BroadcastReceiver) 732 * Context.unregisterReceiver()} call is retained, to be printed if a later 733 * incorrect unregister call is made. Note that doing this requires retaining 734 * information about the BroadcastReceiver for the lifetime of the app, 735 * resulting in a leak -- this should only be used for debugging. 736 */ setDebugUnregister(boolean debug)737 public final void setDebugUnregister(boolean debug) { 738 mDebugUnregister = debug; 739 } 740 741 /** 742 * Return the last value given to {@link #setDebugUnregister}. 743 */ getDebugUnregister()744 public final boolean getDebugUnregister() { 745 return mDebugUnregister; 746 } 747 checkSynchronousHint()748 void checkSynchronousHint() { 749 if (mPendingResult == null) { 750 throw new IllegalStateException("Call while result is not pending"); 751 } 752 753 // Note that we don't assert when receiving the initial sticky value, 754 // since that may have come from an ordered broadcast. We'll catch 755 // them later when the real broadcast happens again. 756 if (mPendingResult.mOrderedHint || mPendingResult.mInitialStickyHint) { 757 return; 758 } 759 RuntimeException e = new RuntimeException( 760 "BroadcastReceiver trying to return result during a non-ordered broadcast"); 761 e.fillInStackTrace(); 762 Log.e("BroadcastReceiver", e.getMessage(), e); 763 } 764 } 765 766