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 &lt;receiver&gt;}
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 &lt;receiver&gt; 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