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 &lt;receiver&gt;}
43  * tag in your <code>AndroidManifest.xml</code>.
44  *
45  * <p><em><strong>Note:</strong></em>
46  * &nbsp;&nbsp;&nbsp;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 &lt;receiver&gt;}
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 &lt;uses-permission&gt;}
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 &lt;receiver&gt;}
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 &lt;uses-permission&gt;}
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 &lt;receiver&gt; 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