• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         final int mFlags;
242 
243         int mResultCode;
244         String mResultData;
245         Bundle mResultExtras;
246         boolean mAbortBroadcast;
247         boolean mFinished;
248 
249         /** @hide */
PendingResult(int resultCode, String resultData, Bundle resultExtras, int type, boolean ordered, boolean sticky, IBinder token, int userId, int flags)250         public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type,
251                 boolean ordered, boolean sticky, IBinder token, int userId, int flags) {
252             mResultCode = resultCode;
253             mResultData = resultData;
254             mResultExtras = resultExtras;
255             mType = type;
256             mOrderedHint = ordered;
257             mInitialStickyHint = sticky;
258             mToken = token;
259             mSendingUser = userId;
260             mFlags = flags;
261         }
262 
263         /**
264          * Version of {@link BroadcastReceiver#setResultCode(int)
265          * BroadcastReceiver.setResultCode(int)} for
266          * asynchronous broadcast handling.
267          */
setResultCode(int code)268         public final void setResultCode(int code) {
269             checkSynchronousHint();
270             mResultCode = code;
271         }
272 
273         /**
274          * Version of {@link BroadcastReceiver#getResultCode()
275          * BroadcastReceiver.getResultCode()} for
276          * asynchronous broadcast handling.
277          */
getResultCode()278         public final int getResultCode() {
279             return mResultCode;
280         }
281 
282         /**
283          * Version of {@link BroadcastReceiver#setResultData(String)
284          * BroadcastReceiver.setResultData(String)} for
285          * asynchronous broadcast handling.
286          */
setResultData(String data)287         public final void setResultData(String data) {
288             checkSynchronousHint();
289             mResultData = data;
290         }
291 
292         /**
293          * Version of {@link BroadcastReceiver#getResultData()
294          * BroadcastReceiver.getResultData()} for
295          * asynchronous broadcast handling.
296          */
getResultData()297         public final String getResultData() {
298             return mResultData;
299         }
300 
301         /**
302          * Version of {@link BroadcastReceiver#setResultExtras(Bundle)
303          * BroadcastReceiver.setResultExtras(Bundle)} for
304          * asynchronous broadcast handling.
305          */
setResultExtras(Bundle extras)306         public final void setResultExtras(Bundle extras) {
307             checkSynchronousHint();
308             mResultExtras = extras;
309         }
310 
311         /**
312          * Version of {@link BroadcastReceiver#getResultExtras(boolean)
313          * BroadcastReceiver.getResultExtras(boolean)} for
314          * asynchronous broadcast handling.
315          */
getResultExtras(boolean makeMap)316         public final Bundle getResultExtras(boolean makeMap) {
317             Bundle e = mResultExtras;
318             if (!makeMap) return e;
319             if (e == null) mResultExtras = e = new Bundle();
320             return e;
321         }
322 
323         /**
324          * Version of {@link BroadcastReceiver#setResult(int, String, Bundle)
325          * BroadcastReceiver.setResult(int, String, Bundle)} for
326          * asynchronous broadcast handling.
327          */
setResult(int code, String data, Bundle extras)328         public final void setResult(int code, String data, Bundle extras) {
329             checkSynchronousHint();
330             mResultCode = code;
331             mResultData = data;
332             mResultExtras = extras;
333         }
334 
335         /**
336          * Version of {@link BroadcastReceiver#getAbortBroadcast()
337          * BroadcastReceiver.getAbortBroadcast()} for
338          * asynchronous broadcast handling.
339          */
getAbortBroadcast()340         public final boolean getAbortBroadcast() {
341             return mAbortBroadcast;
342         }
343 
344         /**
345          * Version of {@link BroadcastReceiver#abortBroadcast()
346          * BroadcastReceiver.abortBroadcast()} for
347          * asynchronous broadcast handling.
348          */
abortBroadcast()349         public final void abortBroadcast() {
350             checkSynchronousHint();
351             mAbortBroadcast = true;
352         }
353 
354         /**
355          * Version of {@link BroadcastReceiver#clearAbortBroadcast()
356          * BroadcastReceiver.clearAbortBroadcast()} for
357          * asynchronous broadcast handling.
358          */
clearAbortBroadcast()359         public final void clearAbortBroadcast() {
360             mAbortBroadcast = false;
361         }
362 
363         /**
364          * Finish the broadcast.  The current result will be sent and the
365          * next broadcast will proceed.
366          */
finish()367         public final void finish() {
368             if (mType == TYPE_COMPONENT) {
369                 final IActivityManager mgr = ActivityManagerNative.getDefault();
370                 if (QueuedWork.hasPendingWork()) {
371                     // If this is a broadcast component, we need to make sure any
372                     // queued work is complete before telling AM we are done, so
373                     // we don't have our process killed before that.  We now know
374                     // there is pending work; put another piece of work at the end
375                     // of the list to finish the broadcast, so we don't block this
376                     // thread (which may be the main thread) to have it finished.
377                     //
378                     // Note that we don't need to use QueuedWork.add() with the
379                     // runnable, since we know the AM is waiting for us until the
380                     // executor gets to it.
381                     QueuedWork.singleThreadExecutor().execute( new Runnable() {
382                         @Override public void run() {
383                             if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
384                                     "Finishing broadcast after work to component " + mToken);
385                             sendFinished(mgr);
386                         }
387                     });
388                 } else {
389                     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
390                             "Finishing broadcast to component " + mToken);
391                     sendFinished(mgr);
392                 }
393             } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
394                 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
395                         "Finishing broadcast to " + mToken);
396                 final IActivityManager mgr = ActivityManagerNative.getDefault();
397                 sendFinished(mgr);
398             }
399         }
400 
401         /** @hide */
setExtrasClassLoader(ClassLoader cl)402         public void setExtrasClassLoader(ClassLoader cl) {
403             if (mResultExtras != null) {
404                 mResultExtras.setClassLoader(cl);
405             }
406         }
407 
408         /** @hide */
sendFinished(IActivityManager am)409         public void sendFinished(IActivityManager am) {
410             synchronized (this) {
411                 if (mFinished) {
412                     throw new IllegalStateException("Broadcast already finished");
413                 }
414                 mFinished = true;
415 
416                 try {
417                     if (mResultExtras != null) {
418                         mResultExtras.setAllowFds(false);
419                     }
420                     if (mOrderedHint) {
421                         am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
422                                 mAbortBroadcast, mFlags);
423                     } else {
424                         // This broadcast was sent to a component; it is not ordered,
425                         // but we still need to tell the activity manager we are done.
426                         am.finishReceiver(mToken, 0, null, null, false, mFlags);
427                     }
428                 } catch (RemoteException ex) {
429                 }
430             }
431         }
432 
433         /** @hide */
getSendingUserId()434         public int getSendingUserId() {
435             return mSendingUser;
436         }
437 
checkSynchronousHint()438         void checkSynchronousHint() {
439             // Note that we don't assert when receiving the initial sticky value,
440             // since that may have come from an ordered broadcast.  We'll catch
441             // them later when the real broadcast happens again.
442             if (mOrderedHint || mInitialStickyHint) {
443                 return;
444             }
445             RuntimeException e = new RuntimeException(
446                     "BroadcastReceiver trying to return result during a non-ordered broadcast");
447             e.fillInStackTrace();
448             Log.e("BroadcastReceiver", e.getMessage(), e);
449         }
450     }
451 
BroadcastReceiver()452     public BroadcastReceiver() {
453     }
454 
455     /**
456      * This method is called when the BroadcastReceiver is receiving an Intent
457      * broadcast.  During this time you can use the other methods on
458      * BroadcastReceiver to view/modify the current result values.  This method
459      * is always called within the main thread of its process, unless you
460      * explicitly asked for it to be scheduled on a different thread using
461      * {@link android.content.Context#registerReceiver(BroadcastReceiver,
462      * IntentFilter, String, android.os.Handler)}. When it runs on the main
463      * thread you should
464      * never perform long-running operations in it (there is a timeout of
465      * 10 seconds that the system allows before considering the receiver to
466      * be blocked and a candidate to be killed). You cannot launch a popup dialog
467      * in your implementation of onReceive().
468      *
469      * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
470      * then the object is no longer alive after returning from this
471      * function.</b>  This means you should not perform any operations that
472      * return a result to you asynchronously -- in particular, for interacting
473      * with services, you should use
474      * {@link Context#startService(Intent)} instead of
475      * {@link Context#bindService(Intent, ServiceConnection, int)}.  If you wish
476      * to interact with a service that is already running, you can use
477      * {@link #peekService}.
478      *
479      * <p>The Intent filters used in {@link android.content.Context#registerReceiver}
480      * and in application manifests are <em>not</em> guaranteed to be exclusive. They
481      * are hints to the operating system about how to find suitable recipients. It is
482      * possible for senders to force delivery to specific recipients, bypassing filter
483      * resolution.  For this reason, {@link #onReceive(Context, Intent) onReceive()}
484      * implementations should respond only to known actions, ignoring any unexpected
485      * Intents that they may receive.
486      *
487      * @param context The Context in which the receiver is running.
488      * @param intent The Intent being received.
489      */
onReceive(Context context, Intent intent)490     public abstract void onReceive(Context context, Intent intent);
491 
492     /**
493      * This can be called by an application in {@link #onReceive} to allow
494      * it to keep the broadcast active after returning from that function.
495      * This does <em>not</em> change the expectation of being relatively
496      * responsive to the broadcast (finishing it within 10s), but does allow
497      * the implementation to move work related to it over to another thread
498      * to avoid glitching the main UI thread due to disk IO.
499      *
500      * @return Returns a {@link PendingResult} representing the result of
501      * the active broadcast.  The BroadcastRecord itself is no longer active;
502      * all data and other interaction must go through {@link PendingResult}
503      * APIs.  The {@link PendingResult#finish PendingResult.finish()} method
504      * must be called once processing of the broadcast is done.
505      */
goAsync()506     public final PendingResult goAsync() {
507         PendingResult res = mPendingResult;
508         mPendingResult = null;
509         return res;
510     }
511 
512     /**
513      * Provide a binder to an already-running service.  This method is synchronous
514      * and will not start the target service if it is not present, so it is safe
515      * to call from {@link #onReceive}.
516      *
517      * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)}
518      * @param service The Intent indicating the service you wish to use.  See {@link
519      * Context#startService(Intent)} for more information.
520      */
peekService(Context myContext, Intent service)521     public IBinder peekService(Context myContext, Intent service) {
522         IActivityManager am = ActivityManagerNative.getDefault();
523         IBinder binder = null;
524         try {
525             service.prepareToLeaveProcess(myContext);
526             binder = am.peekService(service, service.resolveTypeIfNeeded(
527                     myContext.getContentResolver()), myContext.getOpPackageName());
528         } catch (RemoteException e) {
529         }
530         return binder;
531     }
532 
533     /**
534      * Change the current result code of this broadcast; only works with
535      * broadcasts sent through
536      * {@link Context#sendOrderedBroadcast(Intent, String)
537      * Context.sendOrderedBroadcast}.  Often uses the
538      * Activity {@link android.app.Activity#RESULT_CANCELED} and
539      * {@link android.app.Activity#RESULT_OK} constants, though the
540      * actual meaning of this value is ultimately up to the broadcaster.
541      *
542      * <p class="note">This method does not work with non-ordered broadcasts such
543      * as those sent with {@link Context#sendBroadcast(Intent)
544      * Context.sendBroadcast}</p>
545      *
546      * @param code The new result code.
547      *
548      * @see #setResult(int, String, Bundle)
549      */
setResultCode(int code)550     public final void setResultCode(int code) {
551         checkSynchronousHint();
552         mPendingResult.mResultCode = code;
553     }
554 
555     /**
556      * Retrieve the current result code, as set by the previous receiver.
557      *
558      * @return int The current result code.
559      */
getResultCode()560     public final int getResultCode() {
561         return mPendingResult != null ? mPendingResult.mResultCode : 0;
562     }
563 
564     /**
565      * Change the current result data of this broadcast; only works with
566      * broadcasts sent through
567      * {@link Context#sendOrderedBroadcast(Intent, String)
568      * Context.sendOrderedBroadcast}.  This is an arbitrary
569      * string whose interpretation is up to the broadcaster.
570      *
571      * <p><strong>This method does not work with non-ordered broadcasts such
572      * as those sent with {@link Context#sendBroadcast(Intent)
573      * Context.sendBroadcast}</strong></p>
574      *
575      * @param data The new result data; may be null.
576      *
577      * @see #setResult(int, String, Bundle)
578      */
setResultData(String data)579     public final void setResultData(String data) {
580         checkSynchronousHint();
581         mPendingResult.mResultData = data;
582     }
583 
584     /**
585      * Retrieve the current result data, as set by the previous receiver.
586      * Often this is null.
587      *
588      * @return String The current result data; may be null.
589      */
getResultData()590     public final String getResultData() {
591         return mPendingResult != null ? mPendingResult.mResultData : null;
592     }
593 
594     /**
595      * Change the current result extras of this broadcast; only works with
596      * broadcasts sent through
597      * {@link Context#sendOrderedBroadcast(Intent, String)
598      * Context.sendOrderedBroadcast}.  This is a Bundle
599      * holding arbitrary data, whose interpretation is up to the
600      * broadcaster.  Can be set to null.  Calling this method completely
601      * replaces the current map (if any).
602      *
603      * <p><strong>This method does not work with non-ordered broadcasts such
604      * as those sent with {@link Context#sendBroadcast(Intent)
605      * Context.sendBroadcast}</strong></p>
606      *
607      * @param extras The new extra data map; may be null.
608      *
609      * @see #setResult(int, String, Bundle)
610      */
setResultExtras(Bundle extras)611     public final void setResultExtras(Bundle extras) {
612         checkSynchronousHint();
613         mPendingResult.mResultExtras = extras;
614     }
615 
616     /**
617      * Retrieve the current result extra data, as set by the previous receiver.
618      * Any changes you make to the returned Map will be propagated to the next
619      * receiver.
620      *
621      * @param makeMap If true then a new empty Map will be made for you if the
622      *                current Map is null; if false you should be prepared to
623      *                receive a null Map.
624      *
625      * @return Map The current extras map.
626      */
getResultExtras(boolean makeMap)627     public final Bundle getResultExtras(boolean makeMap) {
628         if (mPendingResult == null) {
629             return null;
630         }
631         Bundle e = mPendingResult.mResultExtras;
632         if (!makeMap) return e;
633         if (e == null) mPendingResult.mResultExtras = e = new Bundle();
634         return e;
635     }
636 
637     /**
638      * Change all of the result data returned from this broadcasts; only works
639      * with broadcasts sent through
640      * {@link Context#sendOrderedBroadcast(Intent, String)
641      * Context.sendOrderedBroadcast}.  All current result data is replaced
642      * by the value given to this method.
643      *
644      * <p><strong>This method does not work with non-ordered broadcasts such
645      * as those sent with {@link Context#sendBroadcast(Intent)
646      * Context.sendBroadcast}</strong></p>
647      *
648      * @param code The new result code.  Often uses the
649      * Activity {@link android.app.Activity#RESULT_CANCELED} and
650      * {@link android.app.Activity#RESULT_OK} constants, though the
651      * actual meaning of this value is ultimately up to the broadcaster.
652      * @param data The new result data.  This is an arbitrary
653      * string whose interpretation is up to the broadcaster; may be null.
654      * @param extras The new extra data map.  This is a Bundle
655      * holding arbitrary data, whose interpretation is up to the
656      * broadcaster.  Can be set to null.  This completely
657      * replaces the current map (if any).
658      */
setResult(int code, String data, Bundle extras)659     public final void setResult(int code, String data, Bundle extras) {
660         checkSynchronousHint();
661         mPendingResult.mResultCode = code;
662         mPendingResult.mResultData = data;
663         mPendingResult.mResultExtras = extras;
664     }
665 
666     /**
667      * Returns the flag indicating whether or not this receiver should
668      * abort the current broadcast.
669      *
670      * @return True if the broadcast should be aborted.
671      */
getAbortBroadcast()672     public final boolean getAbortBroadcast() {
673         return mPendingResult != null ? mPendingResult.mAbortBroadcast : false;
674     }
675 
676     /**
677      * Sets the flag indicating that this receiver should abort the
678      * current broadcast; only works with broadcasts sent through
679      * {@link Context#sendOrderedBroadcast(Intent, String)
680      * Context.sendOrderedBroadcast}.  This will prevent
681      * any other broadcast receivers from receiving the broadcast. It will still
682      * call {@link #onReceive} of the BroadcastReceiver that the caller of
683      * {@link Context#sendOrderedBroadcast(Intent, String)
684      * Context.sendOrderedBroadcast} passed in.
685      *
686      * <p><strong>This method does not work with non-ordered broadcasts such
687      * as those sent with {@link Context#sendBroadcast(Intent)
688      * Context.sendBroadcast}</strong></p>
689      */
abortBroadcast()690     public final void abortBroadcast() {
691         checkSynchronousHint();
692         mPendingResult.mAbortBroadcast = true;
693     }
694 
695     /**
696      * Clears the flag indicating that this receiver should abort the current
697      * broadcast.
698      */
clearAbortBroadcast()699     public final void clearAbortBroadcast() {
700         if (mPendingResult != null) {
701             mPendingResult.mAbortBroadcast = false;
702         }
703     }
704 
705     /**
706      * Returns true if the receiver is currently processing an ordered
707      * broadcast.
708      */
isOrderedBroadcast()709     public final boolean isOrderedBroadcast() {
710         return mPendingResult != null ? mPendingResult.mOrderedHint : false;
711     }
712 
713     /**
714      * Returns true if the receiver is currently processing the initial
715      * value of a sticky broadcast -- that is, the value that was last
716      * broadcast and is currently held in the sticky cache, so this is
717      * not directly the result of a broadcast right now.
718      */
isInitialStickyBroadcast()719     public final boolean isInitialStickyBroadcast() {
720         return mPendingResult != null ? mPendingResult.mInitialStickyHint : false;
721     }
722 
723     /**
724      * For internal use, sets the hint about whether this BroadcastReceiver is
725      * running in ordered mode.
726      */
setOrderedHint(boolean isOrdered)727     public final void setOrderedHint(boolean isOrdered) {
728         // Accidentally left in the SDK.
729     }
730 
731     /**
732      * For internal use to set the result data that is active. @hide
733      */
setPendingResult(PendingResult result)734     public final void setPendingResult(PendingResult result) {
735         mPendingResult = result;
736     }
737 
738     /**
739      * For internal use to set the result data that is active. @hide
740      */
getPendingResult()741     public final PendingResult getPendingResult() {
742         return mPendingResult;
743     }
744 
745     /** @hide */
getSendingUserId()746     public int getSendingUserId() {
747         return mPendingResult.mSendingUser;
748     }
749 
750     /**
751      * Control inclusion of debugging help for mismatched
752      * calls to {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
753      * Context.registerReceiver()}.
754      * If called with true, before given to registerReceiver(), then the
755      * callstack of the following {@link Context#unregisterReceiver(BroadcastReceiver)
756      * Context.unregisterReceiver()} call is retained, to be printed if a later
757      * incorrect unregister call is made.  Note that doing this requires retaining
758      * information about the BroadcastReceiver for the lifetime of the app,
759      * resulting in a leak -- this should only be used for debugging.
760      */
setDebugUnregister(boolean debug)761     public final void setDebugUnregister(boolean debug) {
762         mDebugUnregister = debug;
763     }
764 
765     /**
766      * Return the last value given to {@link #setDebugUnregister}.
767      */
getDebugUnregister()768     public final boolean getDebugUnregister() {
769         return mDebugUnregister;
770     }
771 
checkSynchronousHint()772     void checkSynchronousHint() {
773         if (mPendingResult == null) {
774             throw new IllegalStateException("Call while result is not pending");
775         }
776 
777         // Note that we don't assert when receiving the initial sticky value,
778         // since that may have come from an ordered broadcast.  We'll catch
779         // them later when the real broadcast happens again.
780         if (mPendingResult.mOrderedHint || mPendingResult.mInitialStickyHint) {
781             return;
782         }
783         RuntimeException e = new RuntimeException(
784                 "BroadcastReceiver trying to return result during a non-ordered broadcast");
785         e.fillInStackTrace();
786         Log.e("BroadcastReceiver", e.getMessage(), e);
787     }
788 }
789 
790