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