• 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.app;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IIntentReceiver;
25 import android.content.IIntentSender;
26 import android.content.IntentSender;
27 import android.os.Bundle;
28 import android.os.Looper;
29 import android.os.RemoteException;
30 import android.os.Handler;
31 import android.os.IBinder;
32 import android.os.Parcel;
33 import android.os.Parcelable;
34 import android.os.Process;
35 import android.os.UserHandle;
36 import android.util.AndroidException;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.RetentionPolicy;
40 
41 /**
42  * A description of an Intent and target action to perform with it.  Instances
43  * of this class are created with {@link #getActivity}, {@link #getActivities},
44  * {@link #getBroadcast}, and {@link #getService}; the returned object can be
45  * handed to other applications so that they can perform the action you
46  * described on your behalf at a later time.
47  *
48  * <p>By giving a PendingIntent to another application,
49  * you are granting it the right to perform the operation you have specified
50  * as if the other application was yourself (with the same permissions and
51  * identity).  As such, you should be careful about how you build the PendingIntent:
52  * almost always, for example, the base Intent you supply should have the component
53  * name explicitly set to one of your own components, to ensure it is ultimately
54  * sent there and nowhere else.
55  *
56  * <p>A PendingIntent itself is simply a reference to a token maintained by
57  * the system describing the original data used to retrieve it.  This means
58  * that, even if its owning application's process is killed, the
59  * PendingIntent itself will remain usable from other processes that
60  * have been given it.  If the creating application later re-retrieves the
61  * same kind of PendingIntent (same operation, same Intent action, data,
62  * categories, and components, and same flags), it will receive a PendingIntent
63  * representing the same token if that is still valid, and can thus call
64  * {@link #cancel} to remove it.
65  *
66  * <p>Because of this behavior, it is important to know when two Intents
67  * are considered to be the same for purposes of retrieving a PendingIntent.
68  * A common mistake people make is to create multiple PendingIntent objects
69  * with Intents that only vary in their "extra" contents, expecting to get
70  * a different PendingIntent each time.  This does <em>not</em> happen.  The
71  * parts of the Intent that are used for matching are the same ones defined
72  * by {@link Intent#filterEquals(Intent) Intent.filterEquals}.  If you use two
73  * Intent objects that are equivalent as per
74  * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get
75  * the same PendingIntent for both of them.
76  *
77  * <p>There are two typical ways to deal with this.
78  *
79  * <p>If you truly need multiple distinct PendingIntent objects active at
80  * the same time (such as to use as two notifications that are both shown
81  * at the same time), then you will need to ensure there is something that
82  * is different about them to associate them with different PendingIntents.
83  * This may be any of the Intent attributes considered by
84  * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different
85  * request code integers supplied to {@link #getActivity}, {@link #getActivities},
86  * {@link #getBroadcast}, or {@link #getService}.
87  *
88  * <p>If you only need one PendingIntent active at a time for any of the
89  * Intents you will use, then you can alternatively use the flags
90  * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either
91  * cancel or modify whatever current PendingIntent is associated with the
92  * Intent you are supplying.
93  */
94 public final class PendingIntent implements Parcelable {
95     private final IIntentSender mTarget;
96 
97     /** @hide */
98     @IntDef(flag = true,
99             value = {
100                     FLAG_ONE_SHOT,
101                     FLAG_NO_CREATE,
102                     FLAG_CANCEL_CURRENT,
103                     FLAG_UPDATE_CURRENT,
104 
105                     Intent.FILL_IN_ACTION,
106                     Intent.FILL_IN_DATA,
107                     Intent.FILL_IN_CATEGORIES,
108                     Intent.FILL_IN_COMPONENT,
109                     Intent.FILL_IN_PACKAGE,
110                     Intent.FILL_IN_SOURCE_BOUNDS,
111                     Intent.FILL_IN_SELECTOR,
112                     Intent.FILL_IN_CLIP_DATA
113             })
114     @Retention(RetentionPolicy.SOURCE)
115     public @interface Flags {}
116 
117     /**
118      * Flag indicating that this PendingIntent can be used only once.
119      * For use with {@link #getActivity}, {@link #getBroadcast}, and
120      * {@link #getService}. <p>If set, after
121      * {@link #send()} is called on it, it will be automatically
122      * canceled for you and any future attempt to send through it will fail.
123      */
124     public static final int FLAG_ONE_SHOT = 1<<30;
125     /**
126      * Flag indicating that if the described PendingIntent does not
127      * already exist, then simply return null instead of creating it.
128      * For use with {@link #getActivity}, {@link #getBroadcast}, and
129      * {@link #getService}.
130      */
131     public static final int FLAG_NO_CREATE = 1<<29;
132     /**
133      * Flag indicating that if the described PendingIntent already exists,
134      * the current one should be canceled before generating a new one.
135      * For use with {@link #getActivity}, {@link #getBroadcast}, and
136      * {@link #getService}. <p>You can use
137      * this to retrieve a new PendingIntent when you are only changing the
138      * extra data in the Intent; by canceling the previous pending intent,
139      * this ensures that only entities given the new data will be able to
140      * launch it.  If this assurance is not an issue, consider
141      * {@link #FLAG_UPDATE_CURRENT}.
142      */
143     public static final int FLAG_CANCEL_CURRENT = 1<<28;
144     /**
145      * Flag indicating that if the described PendingIntent already exists,
146      * then keep it but replace its extra data with what is in this new
147      * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
148      * {@link #getService}. <p>This can be used if you are creating intents where only the
149      * extras change, and don't care that any entities that received your
150      * previous PendingIntent will be able to launch it with your new
151      * extras even if they are not explicitly given to it.
152      */
153     public static final int FLAG_UPDATE_CURRENT = 1<<27;
154 
155     /**
156      * Flag indicating that the created PendingIntent should be immutable.
157      * This means that the additional intent argument passed to the send
158      * methods to fill in unpopulated properties of this intent will be
159      * ignored.
160      */
161     public static final int FLAG_IMMUTABLE = 1<<26;
162 
163     /**
164      * Exception thrown when trying to send through a PendingIntent that
165      * has been canceled or is otherwise no longer able to execute the request.
166      */
167     public static class CanceledException extends AndroidException {
CanceledException()168         public CanceledException() {
169         }
170 
CanceledException(String name)171         public CanceledException(String name) {
172             super(name);
173         }
174 
CanceledException(Exception cause)175         public CanceledException(Exception cause) {
176             super(cause);
177         }
178     }
179 
180     /**
181      * Callback interface for discovering when a send operation has
182      * completed.  Primarily for use with a PendingIntent that is
183      * performing a broadcast, this provides the same information as
184      * calling {@link Context#sendOrderedBroadcast(Intent, String,
185      * android.content.BroadcastReceiver, Handler, int, String, Bundle)
186      * Context.sendBroadcast()} with a final BroadcastReceiver.
187      */
188     public interface OnFinished {
189         /**
190          * Called when a send operation as completed.
191          *
192          * @param pendingIntent The PendingIntent this operation was sent through.
193          * @param intent The original Intent that was sent.
194          * @param resultCode The final result code determined by the send.
195          * @param resultData The final data collected by a broadcast.
196          * @param resultExtras The final extras collected by a broadcast.
197          */
onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)198         void onSendFinished(PendingIntent pendingIntent, Intent intent,
199                 int resultCode, String resultData, Bundle resultExtras);
200     }
201 
202     private static class FinishedDispatcher extends IIntentReceiver.Stub
203             implements Runnable {
204         private final PendingIntent mPendingIntent;
205         private final OnFinished mWho;
206         private final Handler mHandler;
207         private Intent mIntent;
208         private int mResultCode;
209         private String mResultData;
210         private Bundle mResultExtras;
211         private static Handler sDefaultSystemHandler;
FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler)212         FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) {
213             mPendingIntent = pi;
214             mWho = who;
215             if (handler == null && ActivityThread.isSystem()) {
216                 // We assign a default handler for the system process to avoid deadlocks when
217                 // processing receivers in various components that hold global service locks.
218                 if (sDefaultSystemHandler == null) {
219                     sDefaultSystemHandler = new Handler(Looper.getMainLooper());
220                 }
221                 mHandler = sDefaultSystemHandler;
222             } else {
223                 mHandler = handler;
224             }
225         }
performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean serialized, boolean sticky, int sendingUser)226         public void performReceive(Intent intent, int resultCode, String data,
227                 Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
228             mIntent = intent;
229             mResultCode = resultCode;
230             mResultData = data;
231             mResultExtras = extras;
232             if (mHandler == null) {
233                 run();
234             } else {
235                 mHandler.post(this);
236             }
237         }
run()238         public void run() {
239             mWho.onSendFinished(mPendingIntent, mIntent, mResultCode,
240                     mResultData, mResultExtras);
241         }
242     }
243 
244     /**
245      * Listener for observing when pending intents are written to a parcel.
246      *
247      * @hide
248      */
249     public interface OnMarshaledListener {
250         /**
251          * Called when a pending intent is written to a parcel.
252          *
253          * @param intent The pending intent.
254          * @param parcel The parcel to which it was written.
255          * @param flags The parcel flags when it was written.
256          */
onMarshaled(PendingIntent intent, Parcel parcel, int flags)257         void onMarshaled(PendingIntent intent, Parcel parcel, int flags);
258     }
259 
260     private static final ThreadLocal<OnMarshaledListener> sOnMarshaledListener
261             = new ThreadLocal<>();
262 
263     /**
264      * Registers an listener for pending intents being written to a parcel.
265      *
266      * @param listener The listener, null to clear.
267      *
268      * @hide
269      */
setOnMarshaledListener(OnMarshaledListener listener)270     public static void setOnMarshaledListener(OnMarshaledListener listener) {
271         sOnMarshaledListener.set(listener);
272     }
273 
274     /**
275      * Retrieve a PendingIntent that will start a new activity, like calling
276      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
277      * Note that the activity will be started outside of the context of an
278      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
279      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
280      *
281      * <p class="note">For security reasons, the {@link android.content.Intent}
282      * you supply here should almost always be an <em>explicit intent</em>,
283      * that is specify an explicit component to be delivered to through
284      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
285      *
286      * @param context The Context in which this PendingIntent should start
287      * the activity.
288      * @param requestCode Private request code for the sender
289      * @param intent Intent of the activity to be launched.
290      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
291      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
292      * or any of the flags as supported by
293      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
294      * of the intent that can be supplied when the actual send happens.
295      *
296      * @return Returns an existing or new PendingIntent matching the given
297      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
298      * supplied.
299      */
getActivity(Context context, int requestCode, Intent intent, @Flags int flags)300     public static PendingIntent getActivity(Context context, int requestCode,
301             Intent intent, @Flags int flags) {
302         return getActivity(context, requestCode, intent, flags, null);
303     }
304 
305     /**
306      * Retrieve a PendingIntent that will start a new activity, like calling
307      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
308      * Note that the activity will be started outside of the context of an
309      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
310      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
311      *
312      * <p class="note">For security reasons, the {@link android.content.Intent}
313      * you supply here should almost always be an <em>explicit intent</em>,
314      * that is specify an explicit component to be delivered to through
315      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
316      *
317      * @param context The Context in which this PendingIntent should start
318      * the activity.
319      * @param requestCode Private request code for the sender
320      * @param intent Intent of the activity to be launched.
321      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
322      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
323      * or any of the flags as supported by
324      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
325      * of the intent that can be supplied when the actual send happens.
326      * @param options Additional options for how the Activity should be started.
327      * May be null if there are no options.
328      *
329      * @return Returns an existing or new PendingIntent matching the given
330      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
331      * supplied.
332      */
getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)333     public static PendingIntent getActivity(Context context, int requestCode,
334             @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
335         String packageName = context.getPackageName();
336         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
337                 context.getContentResolver()) : null;
338         try {
339             intent.migrateExtraStreamToClipData();
340             intent.prepareToLeaveProcess(context);
341             IIntentSender target =
342                 ActivityManagerNative.getDefault().getIntentSender(
343                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
344                     null, null, requestCode, new Intent[] { intent },
345                     resolvedType != null ? new String[] { resolvedType } : null,
346                     flags, options, UserHandle.myUserId());
347             return target != null ? new PendingIntent(target) : null;
348         } catch (RemoteException e) {
349         }
350         return null;
351     }
352 
353     /**
354      * @hide
355      * Note that UserHandle.CURRENT will be interpreted at the time the
356      * activity is started, not when the pending intent is created.
357      */
getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)358     public static PendingIntent getActivityAsUser(Context context, int requestCode,
359             @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
360         String packageName = context.getPackageName();
361         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
362                 context.getContentResolver()) : null;
363         try {
364             intent.migrateExtraStreamToClipData();
365             intent.prepareToLeaveProcess(context);
366             IIntentSender target =
367                 ActivityManagerNative.getDefault().getIntentSender(
368                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
369                     null, null, requestCode, new Intent[] { intent },
370                     resolvedType != null ? new String[] { resolvedType } : null,
371                     flags, options, user.getIdentifier());
372             return target != null ? new PendingIntent(target) : null;
373         } catch (RemoteException e) {
374         }
375         return null;
376     }
377 
378     /**
379      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
380      * array of Intents to be supplied.  The last Intent in the array is
381      * taken as the primary key for the PendingIntent, like the single Intent
382      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
383      * the resulting PendingIntent, all of the Intents are started in the same
384      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
385      *
386      * <p class="note">
387      * The <em>first</em> intent in the array will be started outside of the context of an
388      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
389      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
390      * the first in the array are started in the context of the previous activity
391      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
392      * </p>
393      *
394      * <p class="note">
395      * The <em>last</em> intent in the array represents the key for the
396      * PendingIntent.  In other words, it is the significant element for matching
397      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
398      * its content will be the subject of replacement by
399      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
400      * This is because it is the most specific of the supplied intents, and the
401      * UI the user actually sees when the intents are started.
402      * </p>
403      *
404      * <p class="note">For security reasons, the {@link android.content.Intent} objects
405      * you supply here should almost always be <em>explicit intents</em>,
406      * that is specify an explicit component to be delivered to through
407      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
408      *
409      * @param context The Context in which this PendingIntent should start
410      * the activity.
411      * @param requestCode Private request code for the sender
412      * @param intents Array of Intents of the activities to be launched.
413      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
414      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
415      * or any of the flags as supported by
416      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
417      * of the intent that can be supplied when the actual send happens.
418      *
419      * @return Returns an existing or new PendingIntent matching the given
420      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
421      * supplied.
422      */
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)423     public static PendingIntent getActivities(Context context, int requestCode,
424             @NonNull Intent[] intents, @Flags int flags) {
425         return getActivities(context, requestCode, intents, flags, null);
426     }
427 
428     /**
429      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
430      * array of Intents to be supplied.  The last Intent in the array is
431      * taken as the primary key for the PendingIntent, like the single Intent
432      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
433      * the resulting PendingIntent, all of the Intents are started in the same
434      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
435      *
436      * <p class="note">
437      * The <em>first</em> intent in the array will be started outside of the context of an
438      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
439      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
440      * the first in the array are started in the context of the previous activity
441      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
442      * </p>
443      *
444      * <p class="note">
445      * The <em>last</em> intent in the array represents the key for the
446      * PendingIntent.  In other words, it is the significant element for matching
447      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
448      * its content will be the subject of replacement by
449      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
450      * This is because it is the most specific of the supplied intents, and the
451      * UI the user actually sees when the intents are started.
452      * </p>
453      *
454      * <p class="note">For security reasons, the {@link android.content.Intent} objects
455      * you supply here should almost always be <em>explicit intents</em>,
456      * that is specify an explicit component to be delivered to through
457      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
458      *
459      * @param context The Context in which this PendingIntent should start
460      * the activity.
461      * @param requestCode Private request code for the sender
462      * @param intents Array of Intents of the activities to be launched.
463      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
464      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
465      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
466      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
467      * of the intent that can be supplied when the actual send happens.
468      *
469      * @return Returns an existing or new PendingIntent matching the given
470      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
471      * supplied.
472      */
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)473     public static PendingIntent getActivities(Context context, int requestCode,
474             @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
475         String packageName = context.getPackageName();
476         String[] resolvedTypes = new String[intents.length];
477         for (int i=0; i<intents.length; i++) {
478             intents[i].migrateExtraStreamToClipData();
479             intents[i].prepareToLeaveProcess(context);
480             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
481         }
482         try {
483             IIntentSender target =
484                 ActivityManagerNative.getDefault().getIntentSender(
485                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
486                     null, null, requestCode, intents, resolvedTypes, flags, options,
487                     UserHandle.myUserId());
488             return target != null ? new PendingIntent(target) : null;
489         } catch (RemoteException e) {
490         }
491         return null;
492     }
493 
494     /**
495      * @hide
496      * Note that UserHandle.CURRENT will be interpreted at the time the
497      * activity is started, not when the pending intent is created.
498      */
getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)499     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
500             @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
501         String packageName = context.getPackageName();
502         String[] resolvedTypes = new String[intents.length];
503         for (int i=0; i<intents.length; i++) {
504             intents[i].migrateExtraStreamToClipData();
505             intents[i].prepareToLeaveProcess(context);
506             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
507         }
508         try {
509             IIntentSender target =
510                 ActivityManagerNative.getDefault().getIntentSender(
511                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
512                     null, null, requestCode, intents, resolvedTypes,
513                     flags, options, user.getIdentifier());
514             return target != null ? new PendingIntent(target) : null;
515         } catch (RemoteException e) {
516         }
517         return null;
518     }
519 
520     /**
521      * Retrieve a PendingIntent that will perform a broadcast, like calling
522      * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
523      *
524      * <p class="note">For security reasons, the {@link android.content.Intent}
525      * you supply here should almost always be an <em>explicit intent</em>,
526      * that is specify an explicit component to be delivered to through
527      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
528      *
529      * @param context The Context in which this PendingIntent should perform
530      * the broadcast.
531      * @param requestCode Private request code for the sender
532      * @param intent The Intent to be broadcast.
533      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
534      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
535      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
536      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
537      * of the intent that can be supplied when the actual send happens.
538      *
539      * @return Returns an existing or new PendingIntent matching the given
540      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
541      * supplied.
542      */
getBroadcast(Context context, int requestCode, Intent intent, @Flags int flags)543     public static PendingIntent getBroadcast(Context context, int requestCode,
544             Intent intent, @Flags int flags) {
545         return getBroadcastAsUser(context, requestCode, intent, flags,
546                 new UserHandle(UserHandle.myUserId()));
547     }
548 
549     /**
550      * @hide
551      * Note that UserHandle.CURRENT will be interpreted at the time the
552      * broadcast is sent, not when the pending intent is created.
553      */
getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)554     public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
555             Intent intent, int flags, UserHandle userHandle) {
556         String packageName = context.getPackageName();
557         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
558                 context.getContentResolver()) : null;
559         try {
560             intent.prepareToLeaveProcess(context);
561             IIntentSender target =
562                 ActivityManagerNative.getDefault().getIntentSender(
563                     ActivityManager.INTENT_SENDER_BROADCAST, packageName,
564                     null, null, requestCode, new Intent[] { intent },
565                     resolvedType != null ? new String[] { resolvedType } : null,
566                     flags, null, userHandle.getIdentifier());
567             return target != null ? new PendingIntent(target) : null;
568         } catch (RemoteException e) {
569         }
570         return null;
571     }
572 
573     /**
574      * Retrieve a PendingIntent that will start a service, like calling
575      * {@link Context#startService Context.startService()}.  The start
576      * arguments given to the service will come from the extras of the Intent.
577      *
578      * <p class="note">For security reasons, the {@link android.content.Intent}
579      * you supply here should almost always be an <em>explicit intent</em>,
580      * that is specify an explicit component to be delivered to through
581      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
582      *
583      * @param context The Context in which this PendingIntent should start
584      * the service.
585      * @param requestCode Private request code for the sender
586      * @param intent An Intent describing the service to be started.
587      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
588      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
589      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
590      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
591      * of the intent that can be supplied when the actual send happens.
592      *
593      * @return Returns an existing or new PendingIntent matching the given
594      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
595      * supplied.
596      */
getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)597     public static PendingIntent getService(Context context, int requestCode,
598             @NonNull Intent intent, @Flags int flags) {
599         String packageName = context.getPackageName();
600         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
601                 context.getContentResolver()) : null;
602         try {
603             intent.prepareToLeaveProcess(context);
604             IIntentSender target =
605                 ActivityManagerNative.getDefault().getIntentSender(
606                     ActivityManager.INTENT_SENDER_SERVICE, packageName,
607                     null, null, requestCode, new Intent[] { intent },
608                     resolvedType != null ? new String[] { resolvedType } : null,
609                     flags, null, UserHandle.myUserId());
610             return target != null ? new PendingIntent(target) : null;
611         } catch (RemoteException e) {
612         }
613         return null;
614     }
615 
616     /**
617      * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
618      *
619      * @return Returns a IntentSender object that wraps the sender of PendingIntent
620      *
621      */
getIntentSender()622     public IntentSender getIntentSender() {
623         return new IntentSender(mTarget);
624     }
625 
626     /**
627      * Cancel a currently active PendingIntent.  Only the original application
628      * owning a PendingIntent can cancel it.
629      */
cancel()630     public void cancel() {
631         try {
632             ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
633         } catch (RemoteException e) {
634         }
635     }
636 
637     /**
638      * Perform the operation associated with this PendingIntent.
639      *
640      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
641      *
642      * @throws CanceledException Throws CanceledException if the PendingIntent
643      * is no longer allowing more intents to be sent through it.
644      */
send()645     public void send() throws CanceledException {
646         send(null, 0, null, null, null, null, null);
647     }
648 
649     /**
650      * Perform the operation associated with this PendingIntent.
651      *
652      * @param code Result code to supply back to the PendingIntent's target.
653      *
654      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
655      *
656      * @throws CanceledException Throws CanceledException if the PendingIntent
657      * is no longer allowing more intents to be sent through it.
658      */
send(int code)659     public void send(int code) throws CanceledException {
660         send(null, code, null, null, null, null, null);
661     }
662 
663     /**
664      * Perform the operation associated with this PendingIntent, allowing the
665      * caller to specify information about the Intent to use.
666      *
667      * @param context The Context of the caller.
668      * @param code Result code to supply back to the PendingIntent's target.
669      * @param intent Additional Intent data.  See {@link Intent#fillIn
670      * Intent.fillIn()} for information on how this is applied to the
671      * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this
672      * pending intent was created, this argument will be ignored.
673      *
674      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
675      *
676      * @throws CanceledException Throws CanceledException if the PendingIntent
677      * is no longer allowing more intents to be sent through it.
678      */
send(Context context, int code, @Nullable Intent intent)679     public void send(Context context, int code, @Nullable Intent intent)
680             throws CanceledException {
681         send(context, code, intent, null, null, null, null);
682     }
683 
684     /**
685      * Perform the operation associated with this PendingIntent, allowing the
686      * caller to be notified when the send has completed.
687      *
688      * @param code Result code to supply back to the PendingIntent's target.
689      * @param onFinished The object to call back on when the send has
690      * completed, or null for no callback.
691      * @param handler Handler identifying the thread on which the callback
692      * should happen.  If null, the callback will happen from the thread
693      * pool of the process.
694      *
695      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
696      *
697      * @throws CanceledException Throws CanceledException if the PendingIntent
698      * is no longer allowing more intents to be sent through it.
699      */
send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)700     public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)
701             throws CanceledException {
702         send(null, code, null, onFinished, handler, null, null);
703     }
704 
705     /**
706      * Perform the operation associated with this PendingIntent, allowing the
707      * caller to specify information about the Intent to use and be notified
708      * when the send has completed.
709      *
710      * <p>For the intent parameter, a PendingIntent
711      * often has restrictions on which fields can be supplied here, based on
712      * how the PendingIntent was retrieved in {@link #getActivity},
713      * {@link #getBroadcast}, or {@link #getService}.
714      *
715      * @param context The Context of the caller.  This may be null if
716      * <var>intent</var> is also null.
717      * @param code Result code to supply back to the PendingIntent's target.
718      * @param intent Additional Intent data.  See {@link Intent#fillIn
719      * Intent.fillIn()} for information on how this is applied to the
720      * original Intent.  Use null to not modify the original Intent.
721      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
722      * created, this argument will be ignored.
723      * @param onFinished The object to call back on when the send has
724      * completed, or null for no callback.
725      * @param handler Handler identifying the thread on which the callback
726      * should happen.  If null, the callback will happen from the thread
727      * pool of the process.
728      *
729      * @see #send()
730      * @see #send(int)
731      * @see #send(Context, int, Intent)
732      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
733      * @see #send(Context, int, Intent, OnFinished, Handler, String)
734      *
735      * @throws CanceledException Throws CanceledException if the PendingIntent
736      * is no longer allowing more intents to be sent through it.
737      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)738     public void send(Context context, int code, @Nullable Intent intent,
739             @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException {
740         send(context, code, intent, onFinished, handler, null, null);
741     }
742 
743     /**
744      * Perform the operation associated with this PendingIntent, allowing the
745      * caller to specify information about the Intent to use and be notified
746      * when the send has completed.
747      *
748      * <p>For the intent parameter, a PendingIntent
749      * often has restrictions on which fields can be supplied here, based on
750      * how the PendingIntent was retrieved in {@link #getActivity},
751      * {@link #getBroadcast}, or {@link #getService}.
752      *
753      * @param context The Context of the caller.  This may be null if
754      * <var>intent</var> is also null.
755      * @param code Result code to supply back to the PendingIntent's target.
756      * @param intent Additional Intent data.  See {@link Intent#fillIn
757      * Intent.fillIn()} for information on how this is applied to the
758      * original Intent.  Use null to not modify the original Intent.
759      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
760      * created, this argument will be ignored.
761      * @param onFinished The object to call back on when the send has
762      * completed, or null for no callback.
763      * @param handler Handler identifying the thread on which the callback
764      * should happen.  If null, the callback will happen from the thread
765      * pool of the process.
766      * @param requiredPermission Name of permission that a recipient of the PendingIntent
767      * is required to hold.  This is only valid for broadcast intents, and
768      * corresponds to the permission argument in
769      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
770      * If null, no permission is required.
771      *
772      * @see #send()
773      * @see #send(int)
774      * @see #send(Context, int, Intent)
775      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
776      * @see #send(Context, int, Intent, OnFinished, Handler)
777      *
778      * @throws CanceledException Throws CanceledException if the PendingIntent
779      * is no longer allowing more intents to be sent through it.
780      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)781     public void send(Context context, int code, @Nullable Intent intent,
782             @Nullable OnFinished onFinished, @Nullable Handler handler,
783             @Nullable String requiredPermission)
784             throws CanceledException {
785         send(context, code, intent, onFinished, handler, requiredPermission, null);
786     }
787 
788     /**
789      * Perform the operation associated with this PendingIntent, allowing the
790      * caller to specify information about the Intent to use and be notified
791      * when the send has completed.
792      *
793      * <p>For the intent parameter, a PendingIntent
794      * often has restrictions on which fields can be supplied here, based on
795      * how the PendingIntent was retrieved in {@link #getActivity},
796      * {@link #getBroadcast}, or {@link #getService}.
797      *
798      * @param context The Context of the caller.  This may be null if
799      * <var>intent</var> is also null.
800      * @param code Result code to supply back to the PendingIntent's target.
801      * @param intent Additional Intent data.  See {@link Intent#fillIn
802      * Intent.fillIn()} for information on how this is applied to the
803      * original Intent.  Use null to not modify the original Intent.
804      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
805      * created, this argument will be ignored.
806      * @param onFinished The object to call back on when the send has
807      * completed, or null for no callback.
808      * @param handler Handler identifying the thread on which the callback
809      * should happen.  If null, the callback will happen from the thread
810      * pool of the process.
811      * @param requiredPermission Name of permission that a recipient of the PendingIntent
812      * is required to hold.  This is only valid for broadcast intents, and
813      * corresponds to the permission argument in
814      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
815      * If null, no permission is required.
816      * @param options Additional options the caller would like to provide to modify the sending
817      * behavior.  May be built from an {@link ActivityOptions} to apply to an activity start.
818      *
819      * @see #send()
820      * @see #send(int)
821      * @see #send(Context, int, Intent)
822      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
823      * @see #send(Context, int, Intent, OnFinished, Handler)
824      *
825      * @throws CanceledException Throws CanceledException if the PendingIntent
826      * is no longer allowing more intents to be sent through it.
827      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)828     public void send(Context context, int code, @Nullable Intent intent,
829             @Nullable OnFinished onFinished, @Nullable Handler handler,
830             @Nullable String requiredPermission, @Nullable Bundle options)
831             throws CanceledException {
832         try {
833             String resolvedType = intent != null ?
834                     intent.resolveTypeIfNeeded(context.getContentResolver())
835                     : null;
836             int res = ActivityManagerNative.getDefault().sendIntentSender(
837                     mTarget, code, intent, resolvedType,
838                     onFinished != null
839                             ? new FinishedDispatcher(this, onFinished, handler)
840                             : null,
841                     requiredPermission, options);
842             if (res < 0) {
843                 throw new CanceledException();
844             }
845         } catch (RemoteException e) {
846             throw new CanceledException(e);
847         }
848     }
849 
850     /**
851      * @deprecated Renamed to {@link #getCreatorPackage()}.
852      */
853     @Deprecated
getTargetPackage()854     public String getTargetPackage() {
855         try {
856             return ActivityManagerNative.getDefault()
857                 .getPackageForIntentSender(mTarget);
858         } catch (RemoteException e) {
859             // Should never happen.
860             return null;
861         }
862     }
863 
864     /**
865      * Return the package name of the application that created this
866      * PendingIntent, that is the identity under which you will actually be
867      * sending the Intent.  The returned string is supplied by the system, so
868      * that an application can not spoof its package.
869      *
870      * <p class="note">Be careful about how you use this.  All this tells you is
871      * who created the PendingIntent.  It does <strong>not</strong> tell you who
872      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
873      * passed between applications, so the PendingIntent you receive from an application
874      * could actually be one it received from another application, meaning the result
875      * you get here will identify the original application.  Because of this, you should
876      * only use this information to identify who you expect to be interacting with
877      * through a {@link #send} call, not who gave you the PendingIntent.</p>
878      *
879      * @return The package name of the PendingIntent, or null if there is
880      * none associated with it.
881      */
882     @Nullable
getCreatorPackage()883     public String getCreatorPackage() {
884         try {
885             return ActivityManagerNative.getDefault()
886                 .getPackageForIntentSender(mTarget);
887         } catch (RemoteException e) {
888             // Should never happen.
889             return null;
890         }
891     }
892 
893     /**
894      * Return the uid of the application that created this
895      * PendingIntent, that is the identity under which you will actually be
896      * sending the Intent.  The returned integer is supplied by the system, so
897      * that an application can not spoof its uid.
898      *
899      * <p class="note">Be careful about how you use this.  All this tells you is
900      * who created the PendingIntent.  It does <strong>not</strong> tell you who
901      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
902      * passed between applications, so the PendingIntent you receive from an application
903      * could actually be one it received from another application, meaning the result
904      * you get here will identify the original application.  Because of this, you should
905      * only use this information to identify who you expect to be interacting with
906      * through a {@link #send} call, not who gave you the PendingIntent.</p>
907      *
908      * @return The uid of the PendingIntent, or -1 if there is
909      * none associated with it.
910      */
getCreatorUid()911     public int getCreatorUid() {
912         try {
913             return ActivityManagerNative.getDefault()
914                 .getUidForIntentSender(mTarget);
915         } catch (RemoteException e) {
916             // Should never happen.
917             return -1;
918         }
919     }
920 
921     /**
922      * Return the user handle of the application that created this
923      * PendingIntent, that is the user under which you will actually be
924      * sending the Intent.  The returned UserHandle is supplied by the system, so
925      * that an application can not spoof its user.  See
926      * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
927      * more explanation of user handles.
928      *
929      * <p class="note">Be careful about how you use this.  All this tells you is
930      * who created the PendingIntent.  It does <strong>not</strong> tell you who
931      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
932      * passed between applications, so the PendingIntent you receive from an application
933      * could actually be one it received from another application, meaning the result
934      * you get here will identify the original application.  Because of this, you should
935      * only use this information to identify who you expect to be interacting with
936      * through a {@link #send} call, not who gave you the PendingIntent.</p>
937      *
938      * @return The user handle of the PendingIntent, or null if there is
939      * none associated with it.
940      */
941     @Nullable
getCreatorUserHandle()942     public UserHandle getCreatorUserHandle() {
943         try {
944             int uid = ActivityManagerNative.getDefault()
945                 .getUidForIntentSender(mTarget);
946             return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
947         } catch (RemoteException e) {
948             // Should never happen.
949             return null;
950         }
951     }
952 
953     /**
954      * @hide
955      * Check to verify that this PendingIntent targets a specific package.
956      */
isTargetedToPackage()957     public boolean isTargetedToPackage() {
958         try {
959             return ActivityManagerNative.getDefault()
960                 .isIntentSenderTargetedToPackage(mTarget);
961         } catch (RemoteException e) {
962             // Should never happen.
963             return false;
964         }
965     }
966 
967     /**
968      * @hide
969      * Check whether this PendingIntent will launch an Activity.
970      */
isActivity()971     public boolean isActivity() {
972         try {
973             return ActivityManagerNative.getDefault()
974                 .isIntentSenderAnActivity(mTarget);
975         } catch (RemoteException e) {
976             // Should never happen.
977             return false;
978         }
979     }
980 
981     /**
982      * @hide
983      * Return the Intent of this PendingIntent.
984      */
getIntent()985     public Intent getIntent() {
986         try {
987             return ActivityManagerNative.getDefault()
988                 .getIntentForIntentSender(mTarget);
989         } catch (RemoteException e) {
990             // Should never happen.
991             return null;
992         }
993     }
994 
995     /**
996      * @hide
997      * Return descriptive tag for this PendingIntent.
998      */
getTag(String prefix)999     public String getTag(String prefix) {
1000         try {
1001             return ActivityManagerNative.getDefault()
1002                 .getTagForIntentSender(mTarget, prefix);
1003         } catch (RemoteException e) {
1004             // Should never happen.
1005             return null;
1006         }
1007     }
1008 
1009     /**
1010      * Comparison operator on two PendingIntent objects, such that true
1011      * is returned then they both represent the same operation from the
1012      * same package.  This allows you to use {@link #getActivity},
1013      * {@link #getBroadcast}, or {@link #getService} multiple times (even
1014      * across a process being killed), resulting in different PendingIntent
1015      * objects but whose equals() method identifies them as being the same
1016      * operation.
1017      */
1018     @Override
equals(Object otherObj)1019     public boolean equals(Object otherObj) {
1020         if (otherObj instanceof PendingIntent) {
1021             return mTarget.asBinder().equals(((PendingIntent)otherObj)
1022                     .mTarget.asBinder());
1023         }
1024         return false;
1025     }
1026 
1027     @Override
hashCode()1028     public int hashCode() {
1029         return mTarget.asBinder().hashCode();
1030     }
1031 
1032     @Override
toString()1033     public String toString() {
1034         StringBuilder sb = new StringBuilder(128);
1035         sb.append("PendingIntent{");
1036         sb.append(Integer.toHexString(System.identityHashCode(this)));
1037         sb.append(": ");
1038         sb.append(mTarget != null ? mTarget.asBinder() : null);
1039         sb.append('}');
1040         return sb.toString();
1041     }
1042 
describeContents()1043     public int describeContents() {
1044         return 0;
1045     }
1046 
writeToParcel(Parcel out, int flags)1047     public void writeToParcel(Parcel out, int flags) {
1048         out.writeStrongBinder(mTarget.asBinder());
1049         OnMarshaledListener listener = sOnMarshaledListener.get();
1050         if (listener != null) {
1051             listener.onMarshaled(this, out, flags);
1052         }
1053 
1054     }
1055 
1056     public static final Parcelable.Creator<PendingIntent> CREATOR
1057             = new Parcelable.Creator<PendingIntent>() {
1058         public PendingIntent createFromParcel(Parcel in) {
1059             IBinder target = in.readStrongBinder();
1060             return target != null ? new PendingIntent(target) : null;
1061         }
1062 
1063         public PendingIntent[] newArray(int size) {
1064             return new PendingIntent[size];
1065         }
1066     };
1067 
1068     /**
1069      * Convenience function for writing either a PendingIntent or null pointer to
1070      * a Parcel.  You must use this with {@link #readPendingIntentOrNullFromParcel}
1071      * for later reading it.
1072      *
1073      * @param sender The PendingIntent to write, or null.
1074      * @param out Where to write the PendingIntent.
1075      */
writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)1076     public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
1077             @NonNull Parcel out) {
1078         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
1079                 : null);
1080     }
1081 
1082     /**
1083      * Convenience function for reading either a Messenger or null pointer from
1084      * a Parcel.  You must have previously written the Messenger with
1085      * {@link #writePendingIntentOrNullToParcel}.
1086      *
1087      * @param in The Parcel containing the written Messenger.
1088      *
1089      * @return Returns the Messenger read from the Parcel, or null if null had
1090      * been written.
1091      */
1092     @Nullable
readPendingIntentOrNullFromParcel(@onNull Parcel in)1093     public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
1094         IBinder b = in.readStrongBinder();
1095         return b != null ? new PendingIntent(b) : null;
1096     }
1097 
PendingIntent(IIntentSender target)1098     /*package*/ PendingIntent(IIntentSender target) {
1099         mTarget = target;
1100     }
1101 
PendingIntent(IBinder target)1102     /*package*/ PendingIntent(IBinder target) {
1103         mTarget = IIntentSender.Stub.asInterface(target);
1104     }
1105 
1106     /** @hide */
getTarget()1107     public IIntentSender getTarget() {
1108         return mTarget;
1109     }
1110 }
1111