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      * Retrieve a PendingIntent that will start a new activity, like calling
246      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
247      * Note that the activity will be started outside of the context of an
248      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
249      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
250      *
251      * <p class="note">For security reasons, the {@link android.content.Intent}
252      * you supply here should almost always be an <em>explicit intent</em>,
253      * that is specify an explicit component to be delivered to through
254      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
255      *
256      * @param context The Context in which this PendingIntent should start
257      * the activity.
258      * @param requestCode Private request code for the sender
259      * @param intent Intent of the activity to be launched.
260      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
261      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
262      * or any of the flags as supported by
263      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
264      * of the intent that can be supplied when the actual send happens.
265      *
266      * @return Returns an existing or new PendingIntent matching the given
267      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
268      * supplied.
269      */
getActivity(Context context, int requestCode, Intent intent, @Flags int flags)270     public static PendingIntent getActivity(Context context, int requestCode,
271             Intent intent, @Flags int flags) {
272         return getActivity(context, requestCode, intent, flags, null);
273     }
274 
275     /**
276      * Retrieve a PendingIntent that will start a new activity, like calling
277      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
278      * Note that the activity will be started outside of the context of an
279      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
280      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
281      *
282      * <p class="note">For security reasons, the {@link android.content.Intent}
283      * you supply here should almost always be an <em>explicit intent</em>,
284      * that is specify an explicit component to be delivered to through
285      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
286      *
287      * @param context The Context in which this PendingIntent should start
288      * the activity.
289      * @param requestCode Private request code for the sender
290      * @param intent Intent of the activity to be launched.
291      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
292      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
293      * or any of the flags as supported by
294      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
295      * of the intent that can be supplied when the actual send happens.
296      * @param options Additional options for how the Activity should be started.
297      * May be null if there are no options.
298      *
299      * @return Returns an existing or new PendingIntent matching the given
300      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
301      * supplied.
302      */
getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)303     public static PendingIntent getActivity(Context context, int requestCode,
304             @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
305         String packageName = context.getPackageName();
306         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
307                 context.getContentResolver()) : null;
308         try {
309             intent.migrateExtraStreamToClipData();
310             intent.prepareToLeaveProcess();
311             IIntentSender target =
312                 ActivityManagerNative.getDefault().getIntentSender(
313                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
314                     null, null, requestCode, new Intent[] { intent },
315                     resolvedType != null ? new String[] { resolvedType } : null,
316                     flags, options, UserHandle.myUserId());
317             return target != null ? new PendingIntent(target) : null;
318         } catch (RemoteException e) {
319         }
320         return null;
321     }
322 
323     /**
324      * @hide
325      * Note that UserHandle.CURRENT will be interpreted at the time the
326      * activity is started, not when the pending intent is created.
327      */
getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)328     public static PendingIntent getActivityAsUser(Context context, int requestCode,
329             @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
330         String packageName = context.getPackageName();
331         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
332                 context.getContentResolver()) : null;
333         try {
334             intent.migrateExtraStreamToClipData();
335             intent.prepareToLeaveProcess();
336             IIntentSender target =
337                 ActivityManagerNative.getDefault().getIntentSender(
338                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
339                     null, null, requestCode, new Intent[] { intent },
340                     resolvedType != null ? new String[] { resolvedType } : null,
341                     flags, options, user.getIdentifier());
342             return target != null ? new PendingIntent(target) : null;
343         } catch (RemoteException e) {
344         }
345         return null;
346     }
347 
348     /**
349      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
350      * array of Intents to be supplied.  The last Intent in the array is
351      * taken as the primary key for the PendingIntent, like the single Intent
352      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
353      * the resulting PendingIntent, all of the Intents are started in the same
354      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
355      *
356      * <p class="note">
357      * The <em>first</em> intent in the array will be started outside of the context of an
358      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
359      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
360      * the first in the array are started in the context of the previous activity
361      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
362      * </p>
363      *
364      * <p class="note">
365      * The <em>last</em> intent in the array represents the key for the
366      * PendingIntent.  In other words, it is the significant element for matching
367      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
368      * its content will be the subject of replacement by
369      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
370      * This is because it is the most specific of the supplied intents, and the
371      * UI the user actually sees when the intents are started.
372      * </p>
373      *
374      * <p class="note">For security reasons, the {@link android.content.Intent} objects
375      * you supply here should almost always be <em>explicit intents</em>,
376      * that is specify an explicit component to be delivered to through
377      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
378      *
379      * @param context The Context in which this PendingIntent should start
380      * the activity.
381      * @param requestCode Private request code for the sender
382      * @param intents Array of Intents of the activities to be launched.
383      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
384      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
385      * or any of the flags as supported by
386      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
387      * of the intent that can be supplied when the actual send happens.
388      *
389      * @return Returns an existing or new PendingIntent matching the given
390      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
391      * supplied.
392      */
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)393     public static PendingIntent getActivities(Context context, int requestCode,
394             @NonNull Intent[] intents, @Flags int flags) {
395         return getActivities(context, requestCode, intents, flags, null);
396     }
397 
398     /**
399      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
400      * array of Intents to be supplied.  The last Intent in the array is
401      * taken as the primary key for the PendingIntent, like the single Intent
402      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
403      * the resulting PendingIntent, all of the Intents are started in the same
404      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
405      *
406      * <p class="note">
407      * The <em>first</em> intent in the array will be started outside of the context of an
408      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
409      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
410      * the first in the array are started in the context of the previous activity
411      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
412      * </p>
413      *
414      * <p class="note">
415      * The <em>last</em> intent in the array represents the key for the
416      * PendingIntent.  In other words, it is the significant element for matching
417      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
418      * its content will be the subject of replacement by
419      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
420      * This is because it is the most specific of the supplied intents, and the
421      * UI the user actually sees when the intents are started.
422      * </p>
423      *
424      * <p class="note">For security reasons, the {@link android.content.Intent} objects
425      * you supply here should almost always be <em>explicit intents</em>,
426      * that is specify an explicit component to be delivered to through
427      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
428      *
429      * @param context The Context in which this PendingIntent should start
430      * the activity.
431      * @param requestCode Private request code for the sender
432      * @param intents Array of Intents of the activities to be launched.
433      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
434      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
435      * or any of the flags as supported by
436      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
437      * of the intent that can be supplied when the actual send happens.
438      *
439      * @return Returns an existing or new PendingIntent matching the given
440      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
441      * supplied.
442      */
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)443     public static PendingIntent getActivities(Context context, int requestCode,
444             @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
445         String packageName = context.getPackageName();
446         String[] resolvedTypes = new String[intents.length];
447         for (int i=0; i<intents.length; i++) {
448             intents[i].migrateExtraStreamToClipData();
449             intents[i].prepareToLeaveProcess();
450             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
451         }
452         try {
453             IIntentSender target =
454                 ActivityManagerNative.getDefault().getIntentSender(
455                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
456                     null, null, requestCode, intents, resolvedTypes, flags, options,
457                     UserHandle.myUserId());
458             return target != null ? new PendingIntent(target) : null;
459         } catch (RemoteException e) {
460         }
461         return null;
462     }
463 
464     /**
465      * @hide
466      * Note that UserHandle.CURRENT will be interpreted at the time the
467      * activity is started, not when the pending intent is created.
468      */
getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)469     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
470             @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
471         String packageName = context.getPackageName();
472         String[] resolvedTypes = new String[intents.length];
473         for (int i=0; i<intents.length; i++) {
474             intents[i].migrateExtraStreamToClipData();
475             intents[i].prepareToLeaveProcess();
476             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
477         }
478         try {
479             IIntentSender target =
480                 ActivityManagerNative.getDefault().getIntentSender(
481                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
482                     null, null, requestCode, intents, resolvedTypes,
483                     flags, options, user.getIdentifier());
484             return target != null ? new PendingIntent(target) : null;
485         } catch (RemoteException e) {
486         }
487         return null;
488     }
489 
490     /**
491      * Retrieve a PendingIntent that will perform a broadcast, like calling
492      * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
493      *
494      * <p class="note">For security reasons, the {@link android.content.Intent}
495      * you supply here should almost always be an <em>explicit intent</em>,
496      * that is specify an explicit component to be delivered to through
497      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
498      *
499      * @param context The Context in which this PendingIntent should perform
500      * the broadcast.
501      * @param requestCode Private request code for the sender
502      * @param intent The Intent to be broadcast.
503      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
504      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
505      * or any of the flags as supported by
506      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
507      * of the intent that can be supplied when the actual send happens.
508      *
509      * @return Returns an existing or new PendingIntent matching the given
510      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
511      * supplied.
512      */
getBroadcast(Context context, int requestCode, Intent intent, @Flags int flags)513     public static PendingIntent getBroadcast(Context context, int requestCode,
514             Intent intent, @Flags int flags) {
515         return getBroadcastAsUser(context, requestCode, intent, flags,
516                 new UserHandle(UserHandle.myUserId()));
517     }
518 
519     /**
520      * @hide
521      * Note that UserHandle.CURRENT will be interpreted at the time the
522      * broadcast is sent, not when the pending intent is created.
523      */
getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)524     public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
525             Intent intent, int flags, UserHandle userHandle) {
526         String packageName = context.getPackageName();
527         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
528                 context.getContentResolver()) : null;
529         try {
530             intent.prepareToLeaveProcess();
531             IIntentSender target =
532                 ActivityManagerNative.getDefault().getIntentSender(
533                     ActivityManager.INTENT_SENDER_BROADCAST, packageName,
534                     null, null, requestCode, new Intent[] { intent },
535                     resolvedType != null ? new String[] { resolvedType } : null,
536                     flags, null, userHandle.getIdentifier());
537             return target != null ? new PendingIntent(target) : null;
538         } catch (RemoteException e) {
539         }
540         return null;
541     }
542 
543     /**
544      * Retrieve a PendingIntent that will start a service, like calling
545      * {@link Context#startService Context.startService()}.  The start
546      * arguments given to the service will come from the extras of the Intent.
547      *
548      * <p class="note">For security reasons, the {@link android.content.Intent}
549      * you supply here should almost always be an <em>explicit intent</em>,
550      * that is specify an explicit component to be delivered to through
551      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
552      *
553      * @param context The Context in which this PendingIntent should start
554      * the service.
555      * @param requestCode Private request code for the sender
556      * @param intent An Intent describing the service to be started.
557      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
558      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
559      * or any of the flags as supported by
560      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
561      * of the intent that can be supplied when the actual send happens.
562      *
563      * @return Returns an existing or new PendingIntent matching the given
564      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
565      * supplied.
566      */
getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)567     public static PendingIntent getService(Context context, int requestCode,
568             @NonNull Intent intent, @Flags int flags) {
569         String packageName = context.getPackageName();
570         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
571                 context.getContentResolver()) : null;
572         try {
573             intent.prepareToLeaveProcess();
574             IIntentSender target =
575                 ActivityManagerNative.getDefault().getIntentSender(
576                     ActivityManager.INTENT_SENDER_SERVICE, packageName,
577                     null, null, requestCode, new Intent[] { intent },
578                     resolvedType != null ? new String[] { resolvedType } : null,
579                     flags, null, UserHandle.myUserId());
580             return target != null ? new PendingIntent(target) : null;
581         } catch (RemoteException e) {
582         }
583         return null;
584     }
585 
586     /**
587      * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
588      *
589      * @return Returns a IntentSender object that wraps the sender of PendingIntent
590      *
591      */
getIntentSender()592     public IntentSender getIntentSender() {
593         return new IntentSender(mTarget);
594     }
595 
596     /**
597      * Cancel a currently active PendingIntent.  Only the original application
598      * owning a PendingIntent can cancel it.
599      */
cancel()600     public void cancel() {
601         try {
602             ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
603         } catch (RemoteException e) {
604         }
605     }
606 
607     /**
608      * Perform the operation associated with this PendingIntent.
609      *
610      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
611      *
612      * @throws CanceledException Throws CanceledException if the PendingIntent
613      * is no longer allowing more intents to be sent through it.
614      */
send()615     public void send() throws CanceledException {
616         send(null, 0, null, null, null, null, null);
617     }
618 
619     /**
620      * Perform the operation associated with this PendingIntent.
621      *
622      * @param code Result code to supply back to the PendingIntent's target.
623      *
624      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
625      *
626      * @throws CanceledException Throws CanceledException if the PendingIntent
627      * is no longer allowing more intents to be sent through it.
628      */
send(int code)629     public void send(int code) throws CanceledException {
630         send(null, code, null, null, null, null, null);
631     }
632 
633     /**
634      * Perform the operation associated with this PendingIntent, allowing the
635      * caller to specify information about the Intent to use.
636      *
637      * @param context The Context of the caller.
638      * @param code Result code to supply back to the PendingIntent's target.
639      * @param intent Additional Intent data.  See {@link Intent#fillIn
640      * Intent.fillIn()} for information on how this is applied to the
641      * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this
642      * pending intent was created, this argument will be ignored.
643      *
644      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
645      *
646      * @throws CanceledException Throws CanceledException if the PendingIntent
647      * is no longer allowing more intents to be sent through it.
648      */
send(Context context, int code, @Nullable Intent intent)649     public void send(Context context, int code, @Nullable Intent intent)
650             throws CanceledException {
651         send(context, code, intent, null, null, null, null);
652     }
653 
654     /**
655      * Perform the operation associated with this PendingIntent, allowing the
656      * caller to be notified when the send has completed.
657      *
658      * @param code Result code to supply back to the PendingIntent's target.
659      * @param onFinished The object to call back on when the send has
660      * completed, or null for no callback.
661      * @param handler Handler identifying the thread on which the callback
662      * should happen.  If null, the callback will happen from the thread
663      * pool of the process.
664      *
665      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
666      *
667      * @throws CanceledException Throws CanceledException if the PendingIntent
668      * is no longer allowing more intents to be sent through it.
669      */
send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)670     public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)
671             throws CanceledException {
672         send(null, code, null, onFinished, handler, null, null);
673     }
674 
675     /**
676      * Perform the operation associated with this PendingIntent, allowing the
677      * caller to specify information about the Intent to use and be notified
678      * when the send has completed.
679      *
680      * <p>For the intent parameter, a PendingIntent
681      * often has restrictions on which fields can be supplied here, based on
682      * how the PendingIntent was retrieved in {@link #getActivity},
683      * {@link #getBroadcast}, or {@link #getService}.
684      *
685      * @param context The Context of the caller.  This may be null if
686      * <var>intent</var> is also null.
687      * @param code Result code to supply back to the PendingIntent's target.
688      * @param intent Additional Intent data.  See {@link Intent#fillIn
689      * Intent.fillIn()} for information on how this is applied to the
690      * original Intent.  Use null to not modify the original Intent.
691      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
692      * created, this argument will be ignored.
693      * @param onFinished The object to call back on when the send has
694      * completed, or null for no callback.
695      * @param handler Handler identifying the thread on which the callback
696      * should happen.  If null, the callback will happen from the thread
697      * pool of the process.
698      *
699      * @see #send()
700      * @see #send(int)
701      * @see #send(Context, int, Intent)
702      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
703      * @see #send(Context, int, Intent, OnFinished, Handler, String)
704      *
705      * @throws CanceledException Throws CanceledException if the PendingIntent
706      * is no longer allowing more intents to be sent through it.
707      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)708     public void send(Context context, int code, @Nullable Intent intent,
709             @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException {
710         send(context, code, intent, onFinished, handler, null, null);
711     }
712 
713     /**
714      * Perform the operation associated with this PendingIntent, allowing the
715      * caller to specify information about the Intent to use and be notified
716      * when the send has completed.
717      *
718      * <p>For the intent parameter, a PendingIntent
719      * often has restrictions on which fields can be supplied here, based on
720      * how the PendingIntent was retrieved in {@link #getActivity},
721      * {@link #getBroadcast}, or {@link #getService}.
722      *
723      * @param context The Context of the caller.  This may be null if
724      * <var>intent</var> is also null.
725      * @param code Result code to supply back to the PendingIntent's target.
726      * @param intent Additional Intent data.  See {@link Intent#fillIn
727      * Intent.fillIn()} for information on how this is applied to the
728      * original Intent.  Use null to not modify the original Intent.
729      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
730      * created, this argument will be ignored.
731      * @param onFinished The object to call back on when the send has
732      * completed, or null for no callback.
733      * @param handler Handler identifying the thread on which the callback
734      * should happen.  If null, the callback will happen from the thread
735      * pool of the process.
736      * @param requiredPermission Name of permission that a recipient of the PendingIntent
737      * is required to hold.  This is only valid for broadcast intents, and
738      * corresponds to the permission argument in
739      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
740      * If null, no permission is required.
741      *
742      * @see #send()
743      * @see #send(int)
744      * @see #send(Context, int, Intent)
745      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
746      * @see #send(Context, int, Intent, OnFinished, Handler)
747      *
748      * @throws CanceledException Throws CanceledException if the PendingIntent
749      * is no longer allowing more intents to be sent through it.
750      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)751     public void send(Context context, int code, @Nullable Intent intent,
752             @Nullable OnFinished onFinished, @Nullable Handler handler,
753             @Nullable String requiredPermission)
754             throws CanceledException {
755         send(context, code, intent, onFinished, handler, requiredPermission, null);
756     }
757 
758     /**
759      * Perform the operation associated with this PendingIntent, allowing the
760      * caller to specify information about the Intent to use and be notified
761      * when the send has completed.
762      *
763      * <p>For the intent parameter, a PendingIntent
764      * often has restrictions on which fields can be supplied here, based on
765      * how the PendingIntent was retrieved in {@link #getActivity},
766      * {@link #getBroadcast}, or {@link #getService}.
767      *
768      * @param context The Context of the caller.  This may be null if
769      * <var>intent</var> is also null.
770      * @param code Result code to supply back to the PendingIntent's target.
771      * @param intent Additional Intent data.  See {@link Intent#fillIn
772      * Intent.fillIn()} for information on how this is applied to the
773      * original Intent.  Use null to not modify the original Intent.
774      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
775      * created, this argument will be ignored.
776      * @param onFinished The object to call back on when the send has
777      * completed, or null for no callback.
778      * @param handler Handler identifying the thread on which the callback
779      * should happen.  If null, the callback will happen from the thread
780      * pool of the process.
781      * @param requiredPermission Name of permission that a recipient of the PendingIntent
782      * is required to hold.  This is only valid for broadcast intents, and
783      * corresponds to the permission argument in
784      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
785      * If null, no permission is required.
786      * @param options Additional options the caller would like to provide to modify the sending
787      * behavior.  May be built from an {@link ActivityOptions} to apply to an activity start.
788      *
789      * @see #send()
790      * @see #send(int)
791      * @see #send(Context, int, Intent)
792      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
793      * @see #send(Context, int, Intent, OnFinished, Handler)
794      *
795      * @throws CanceledException Throws CanceledException if the PendingIntent
796      * is no longer allowing more intents to be sent through it.
797      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)798     public void send(Context context, int code, @Nullable Intent intent,
799             @Nullable OnFinished onFinished, @Nullable Handler handler,
800             @Nullable String requiredPermission, @Nullable Bundle options)
801             throws CanceledException {
802         try {
803             String resolvedType = intent != null ?
804                     intent.resolveTypeIfNeeded(context.getContentResolver())
805                     : null;
806             int res = mTarget.send(code, intent, resolvedType,
807                     onFinished != null
808                             ? new FinishedDispatcher(this, onFinished, handler)
809                             : null,
810                     requiredPermission, options);
811             if (res < 0) {
812                 throw new CanceledException();
813             }
814         } catch (RemoteException e) {
815             throw new CanceledException(e);
816         }
817     }
818 
819     /**
820      * @deprecated Renamed to {@link #getCreatorPackage()}.
821      */
822     @Deprecated
getTargetPackage()823     public String getTargetPackage() {
824         try {
825             return ActivityManagerNative.getDefault()
826                 .getPackageForIntentSender(mTarget);
827         } catch (RemoteException e) {
828             // Should never happen.
829             return null;
830         }
831     }
832 
833     /**
834      * Return the package name of the application that created this
835      * PendingIntent, that is the identity under which you will actually be
836      * sending the Intent.  The returned string is supplied by the system, so
837      * that an application can not spoof its package.
838      *
839      * <p class="note">Be careful about how you use this.  All this tells you is
840      * who created the PendingIntent.  It does <strong>not</strong> tell you who
841      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
842      * passed between applications, so the PendingIntent you receive from an application
843      * could actually be one it received from another application, meaning the result
844      * you get here will identify the original application.  Because of this, you should
845      * only use this information to identify who you expect to be interacting with
846      * through a {@link #send} call, not who gave you the PendingIntent.</p>
847      *
848      * @return The package name of the PendingIntent, or null if there is
849      * none associated with it.
850      */
851     @Nullable
getCreatorPackage()852     public String getCreatorPackage() {
853         try {
854             return ActivityManagerNative.getDefault()
855                 .getPackageForIntentSender(mTarget);
856         } catch (RemoteException e) {
857             // Should never happen.
858             return null;
859         }
860     }
861 
862     /**
863      * Return the uid of the application that created this
864      * PendingIntent, that is the identity under which you will actually be
865      * sending the Intent.  The returned integer is supplied by the system, so
866      * that an application can not spoof its uid.
867      *
868      * <p class="note">Be careful about how you use this.  All this tells you is
869      * who created the PendingIntent.  It does <strong>not</strong> tell you who
870      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
871      * passed between applications, so the PendingIntent you receive from an application
872      * could actually be one it received from another application, meaning the result
873      * you get here will identify the original application.  Because of this, you should
874      * only use this information to identify who you expect to be interacting with
875      * through a {@link #send} call, not who gave you the PendingIntent.</p>
876      *
877      * @return The uid of the PendingIntent, or -1 if there is
878      * none associated with it.
879      */
getCreatorUid()880     public int getCreatorUid() {
881         try {
882             return ActivityManagerNative.getDefault()
883                 .getUidForIntentSender(mTarget);
884         } catch (RemoteException e) {
885             // Should never happen.
886             return -1;
887         }
888     }
889 
890     /**
891      * Return the user handle of the application that created this
892      * PendingIntent, that is the user under which you will actually be
893      * sending the Intent.  The returned UserHandle is supplied by the system, so
894      * that an application can not spoof its user.  See
895      * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
896      * more explanation of user handles.
897      *
898      * <p class="note">Be careful about how you use this.  All this tells you is
899      * who created the PendingIntent.  It does <strong>not</strong> tell you who
900      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
901      * passed between applications, so the PendingIntent you receive from an application
902      * could actually be one it received from another application, meaning the result
903      * you get here will identify the original application.  Because of this, you should
904      * only use this information to identify who you expect to be interacting with
905      * through a {@link #send} call, not who gave you the PendingIntent.</p>
906      *
907      * @return The user handle of the PendingIntent, or null if there is
908      * none associated with it.
909      */
910     @Nullable
getCreatorUserHandle()911     public UserHandle getCreatorUserHandle() {
912         try {
913             int uid = ActivityManagerNative.getDefault()
914                 .getUidForIntentSender(mTarget);
915             return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
916         } catch (RemoteException e) {
917             // Should never happen.
918             return null;
919         }
920     }
921 
922     /**
923      * @hide
924      * Check to verify that this PendingIntent targets a specific package.
925      */
isTargetedToPackage()926     public boolean isTargetedToPackage() {
927         try {
928             return ActivityManagerNative.getDefault()
929                 .isIntentSenderTargetedToPackage(mTarget);
930         } catch (RemoteException e) {
931             // Should never happen.
932             return false;
933         }
934     }
935 
936     /**
937      * @hide
938      * Check whether this PendingIntent will launch an Activity.
939      */
isActivity()940     public boolean isActivity() {
941         try {
942             return ActivityManagerNative.getDefault()
943                 .isIntentSenderAnActivity(mTarget);
944         } catch (RemoteException e) {
945             // Should never happen.
946             return false;
947         }
948     }
949 
950     /**
951      * @hide
952      * Return the Intent of this PendingIntent.
953      */
getIntent()954     public Intent getIntent() {
955         try {
956             return ActivityManagerNative.getDefault()
957                 .getIntentForIntentSender(mTarget);
958         } catch (RemoteException e) {
959             // Should never happen.
960             return null;
961         }
962     }
963 
964     /**
965      * @hide
966      * Return descriptive tag for this PendingIntent.
967      */
getTag(String prefix)968     public String getTag(String prefix) {
969         try {
970             return ActivityManagerNative.getDefault()
971                 .getTagForIntentSender(mTarget, prefix);
972         } catch (RemoteException e) {
973             // Should never happen.
974             return null;
975         }
976     }
977 
978     /**
979      * Comparison operator on two PendingIntent objects, such that true
980      * is returned then they both represent the same operation from the
981      * same package.  This allows you to use {@link #getActivity},
982      * {@link #getBroadcast}, or {@link #getService} multiple times (even
983      * across a process being killed), resulting in different PendingIntent
984      * objects but whose equals() method identifies them as being the same
985      * operation.
986      */
987     @Override
equals(Object otherObj)988     public boolean equals(Object otherObj) {
989         if (otherObj instanceof PendingIntent) {
990             return mTarget.asBinder().equals(((PendingIntent)otherObj)
991                     .mTarget.asBinder());
992         }
993         return false;
994     }
995 
996     @Override
hashCode()997     public int hashCode() {
998         return mTarget.asBinder().hashCode();
999     }
1000 
1001     @Override
toString()1002     public String toString() {
1003         StringBuilder sb = new StringBuilder(128);
1004         sb.append("PendingIntent{");
1005         sb.append(Integer.toHexString(System.identityHashCode(this)));
1006         sb.append(": ");
1007         sb.append(mTarget != null ? mTarget.asBinder() : null);
1008         sb.append('}');
1009         return sb.toString();
1010     }
1011 
describeContents()1012     public int describeContents() {
1013         return 0;
1014     }
1015 
writeToParcel(Parcel out, int flags)1016     public void writeToParcel(Parcel out, int flags) {
1017         out.writeStrongBinder(mTarget.asBinder());
1018     }
1019 
1020     public static final Parcelable.Creator<PendingIntent> CREATOR
1021             = new Parcelable.Creator<PendingIntent>() {
1022         public PendingIntent createFromParcel(Parcel in) {
1023             IBinder target = in.readStrongBinder();
1024             return target != null ? new PendingIntent(target) : null;
1025         }
1026 
1027         public PendingIntent[] newArray(int size) {
1028             return new PendingIntent[size];
1029         }
1030     };
1031 
1032     /**
1033      * Convenience function for writing either a PendingIntent or null pointer to
1034      * a Parcel.  You must use this with {@link #readPendingIntentOrNullFromParcel}
1035      * for later reading it.
1036      *
1037      * @param sender The PendingIntent to write, or null.
1038      * @param out Where to write the PendingIntent.
1039      */
writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)1040     public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
1041             @NonNull Parcel out) {
1042         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
1043                 : null);
1044     }
1045 
1046     /**
1047      * Convenience function for reading either a Messenger or null pointer from
1048      * a Parcel.  You must have previously written the Messenger with
1049      * {@link #writePendingIntentOrNullToParcel}.
1050      *
1051      * @param in The Parcel containing the written Messenger.
1052      *
1053      * @return Returns the Messenger read from the Parcel, or null if null had
1054      * been written.
1055      */
1056     @Nullable
readPendingIntentOrNullFromParcel(@onNull Parcel in)1057     public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
1058         IBinder b = in.readStrongBinder();
1059         return b != null ? new PendingIntent(b) : null;
1060     }
1061 
PendingIntent(IIntentSender target)1062     /*package*/ PendingIntent(IIntentSender target) {
1063         mTarget = target;
1064     }
1065 
PendingIntent(IBinder target)1066     /*package*/ PendingIntent(IBinder target) {
1067         mTarget = IIntentSender.Stub.asInterface(target);
1068     }
1069 
1070     /** @hide */
getTarget()1071     public IIntentSender getTarget() {
1072         return mTarget;
1073     }
1074 }
1075