• 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 static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
20 import static android.app.ActivityManager.INTENT_SENDER_BROADCAST;
21 import static android.app.ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
22 import static android.app.ActivityManager.INTENT_SENDER_SERVICE;
23 
24 import android.Manifest.permission;
25 import android.annotation.IntDef;
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.annotation.RequiresPermission;
29 import android.annotation.SystemApi;
30 import android.annotation.SystemApi.Client;
31 import android.annotation.TestApi;
32 import android.app.ActivityManager.PendingIntentInfo;
33 import android.compat.Compatibility;
34 import android.compat.annotation.ChangeId;
35 import android.compat.annotation.EnabledAfter;
36 import android.compat.annotation.UnsupportedAppUsage;
37 import android.content.Context;
38 import android.content.IIntentReceiver;
39 import android.content.IIntentSender;
40 import android.content.Intent;
41 import android.content.IntentSender;
42 import android.content.pm.PackageManager.ResolveInfoFlags;
43 import android.content.pm.ParceledListSlice;
44 import android.content.pm.ResolveInfo;
45 import android.os.Build;
46 import android.os.Bundle;
47 import android.os.Handler;
48 import android.os.IBinder;
49 import android.os.Looper;
50 import android.os.Parcel;
51 import android.os.Parcelable;
52 import android.os.RemoteException;
53 import android.os.UserHandle;
54 import android.util.AndroidException;
55 import android.util.ArraySet;
56 import android.util.proto.ProtoOutputStream;
57 
58 import com.android.internal.os.IResultReceiver;
59 
60 import java.lang.annotation.Retention;
61 import java.lang.annotation.RetentionPolicy;
62 import java.util.Collections;
63 import java.util.List;
64 import java.util.Objects;
65 
66 /**
67  * A description of an Intent and target action to perform with it.  Instances
68  * of this class are created with {@link #getActivity}, {@link #getActivities},
69  * {@link #getBroadcast}, and {@link #getService}; the returned object can be
70  * handed to other applications so that they can perform the action you
71  * described on your behalf at a later time.
72  *
73  * <p>By giving a PendingIntent to another application,
74  * you are granting it the right to perform the operation you have specified
75  * as if the other application was yourself (with the same permissions and
76  * identity).  As such, you should be careful about how you build the PendingIntent:
77  * almost always, for example, the base Intent you supply should have the component
78  * name explicitly set to one of your own components, to ensure it is ultimately
79  * sent there and nowhere else.
80  *
81  * <p>A PendingIntent itself is simply a reference to a token maintained by
82  * the system describing the original data used to retrieve it.  This means
83  * that, even if its owning application's process is killed, the
84  * PendingIntent itself will remain usable from other processes that
85  * have been given it.  If the creating application later re-retrieves the
86  * same kind of PendingIntent (same operation, same Intent action, data,
87  * categories, and components, and same flags), it will receive a PendingIntent
88  * representing the same token if that is still valid, and can thus call
89  * {@link #cancel} to remove it.
90  *
91  * <p>Because of this behavior, it is important to know when two Intents
92  * are considered to be the same for purposes of retrieving a PendingIntent.
93  * A common mistake people make is to create multiple PendingIntent objects
94  * with Intents that only vary in their "extra" contents, expecting to get
95  * a different PendingIntent each time.  This does <em>not</em> happen.  The
96  * parts of the Intent that are used for matching are the same ones defined
97  * by {@link Intent#filterEquals(Intent) Intent.filterEquals}.  If you use two
98  * Intent objects that are equivalent as per
99  * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get
100  * the same PendingIntent for both of them.
101  *
102  * <p>There are two typical ways to deal with this.
103  *
104  * <p>If you truly need multiple distinct PendingIntent objects active at
105  * the same time (such as to use as two notifications that are both shown
106  * at the same time), then you will need to ensure there is something that
107  * is different about them to associate them with different PendingIntents.
108  * This may be any of the Intent attributes considered by
109  * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different
110  * request code integers supplied to {@link #getActivity}, {@link #getActivities},
111  * {@link #getBroadcast}, or {@link #getService}.
112  *
113  * <p>If you only need one PendingIntent active at a time for any of the
114  * Intents you will use, then you can alternatively use the flags
115  * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either
116  * cancel or modify whatever current PendingIntent is associated with the
117  * Intent you are supplying.
118  *
119  * <p>Also note that flags like {@link #FLAG_ONE_SHOT} or {@link #FLAG_IMMUTABLE} describe the
120  * PendingIntent instance and thus, are used to identify it. Any calls to retrieve or modify a
121  * PendingIntent created with these flags will also require these flags to be supplied in
122  * conjunction with others. E.g. To retrieve an existing PendingIntent created with
123  * FLAG_ONE_SHOT, <b>both</b> FLAG_ONE_SHOT and FLAG_NO_CREATE need to be supplied.
124  */
125 public final class PendingIntent implements Parcelable {
126     private static final String TAG = "PendingIntent";
127     private final IIntentSender mTarget;
128     private IResultReceiver mCancelReceiver;
129     private IBinder mWhitelistToken;
130     private ArraySet<CancelListener> mCancelListeners;
131 
132     // cached pending intent information
133     private @Nullable PendingIntentInfo mCachedInfo;
134 
135     /**
136      * It is now required to specify either {@link #FLAG_IMMUTABLE}
137      * or {@link #FLAG_MUTABLE} when creating a PendingIntent.
138      */
139     @ChangeId
140     @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.R)
141     static final long PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED = 160794467L;
142 
143     /** @hide */
144     @IntDef(flag = true,
145             value = {
146                     FLAG_ONE_SHOT,
147                     FLAG_NO_CREATE,
148                     FLAG_CANCEL_CURRENT,
149                     FLAG_UPDATE_CURRENT,
150                     FLAG_IMMUTABLE,
151                     FLAG_MUTABLE,
152                     FLAG_MUTABLE_UNAUDITED,
153 
154                     Intent.FILL_IN_ACTION,
155                     Intent.FILL_IN_DATA,
156                     Intent.FILL_IN_CATEGORIES,
157                     Intent.FILL_IN_COMPONENT,
158                     Intent.FILL_IN_PACKAGE,
159                     Intent.FILL_IN_SOURCE_BOUNDS,
160                     Intent.FILL_IN_SELECTOR,
161                     Intent.FILL_IN_CLIP_DATA
162             })
163     @Retention(RetentionPolicy.SOURCE)
164     public @interface Flags {}
165 
166     /**
167      * Flag indicating that this PendingIntent can be used only once.
168      * For use with {@link #getActivity}, {@link #getBroadcast}, and
169      * {@link #getService}. <p>If set, after
170      * {@link #send()} is called on it, it will be automatically
171      * canceled for you and any future attempt to send through it will fail.
172      */
173     public static final int FLAG_ONE_SHOT = 1<<30;
174     /**
175      * Flag indicating that if the described PendingIntent does not
176      * already exist, then simply return null instead of creating it.
177      * For use with {@link #getActivity}, {@link #getBroadcast}, and
178      * {@link #getService}.
179      */
180     public static final int FLAG_NO_CREATE = 1<<29;
181     /**
182      * Flag indicating that if the described PendingIntent already exists,
183      * the current one should be canceled before generating a new one.
184      * For use with {@link #getActivity}, {@link #getBroadcast}, and
185      * {@link #getService}. <p>You can use
186      * this to retrieve a new PendingIntent when you are only changing the
187      * extra data in the Intent; by canceling the previous pending intent,
188      * this ensures that only entities given the new data will be able to
189      * launch it.  If this assurance is not an issue, consider
190      * {@link #FLAG_UPDATE_CURRENT}.
191      */
192     public static final int FLAG_CANCEL_CURRENT = 1<<28;
193     /**
194      * Flag indicating that if the described PendingIntent already exists,
195      * then keep it but replace its extra data with what is in this new
196      * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
197      * {@link #getService}. <p>This can be used if you are creating intents where only the
198      * extras change, and don't care that any entities that received your
199      * previous PendingIntent will be able to launch it with your new
200      * extras even if they are not explicitly given to it.
201      *
202      * <p>{@link #FLAG_UPDATE_CURRENT} still works even if {@link
203      * #FLAG_IMMUTABLE} is set - the creator of the PendingIntent can always
204      * update the PendingIntent itself. The IMMUTABLE flag only limits the
205      * ability to alter the semantics of the intent that is sent by {@link
206      * #send} by the invoker of {@link #send}.
207      */
208     public static final int FLAG_UPDATE_CURRENT = 1<<27;
209 
210     /**
211      * Flag indicating that the created PendingIntent should be immutable.
212      * This means that the additional intent argument passed to the send
213      * methods to fill in unpopulated properties of this intent will be
214      * ignored.
215      *
216      * <p>{@link #FLAG_IMMUTABLE} only limits the ability to alter the
217      * semantics of the intent that is sent by {@link #send} by the invoker of
218      * {@link #send}. The creator of the PendingIntent can always update the
219      * PendingIntent itself via {@link #FLAG_UPDATE_CURRENT}.
220      */
221     public static final int FLAG_IMMUTABLE = 1<<26;
222 
223     /**
224      * Flag indicating that the created PendingIntent should be mutable.
225      * This flag cannot be combined with {@link #FLAG_IMMUTABLE}. <p>Up until
226      * {@link android.os.Build.VERSION_CODES#R}, PendingIntents are assumed to
227      * be mutable by default, unless {@link #FLAG_IMMUTABLE} is set. Starting
228      * with {@link android.os.Build.VERSION_CODES#S}, it will be required to
229      * explicitly specify the mutability of PendingIntents on creation with
230      * either (@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE}. It is strongly
231      * recommended to use {@link #FLAG_IMMUTABLE} when creating a
232      * PendingIntent. {@link #FLAG_MUTABLE} should only be used when some
233      * functionality relies on modifying the underlying intent, e.g. any
234      * PendingIntent that needs to be used with inline reply or bubbles.
235      */
236     public static final int FLAG_MUTABLE = 1<<25;
237 
238     /**
239      * @deprecated Use {@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE} instead.
240      * @hide
241      */
242     @Deprecated
243     @TestApi
244     public static final int FLAG_MUTABLE_UNAUDITED = FLAG_MUTABLE;
245 
246     /**
247      * Exception thrown when trying to send through a PendingIntent that
248      * has been canceled or is otherwise no longer able to execute the request.
249      */
250     public static class CanceledException extends AndroidException {
CanceledException()251         public CanceledException() {
252         }
253 
CanceledException(String name)254         public CanceledException(String name) {
255             super(name);
256         }
257 
CanceledException(Exception cause)258         public CanceledException(Exception cause) {
259             super(cause);
260         }
261     }
262 
263     /**
264      * Callback interface for discovering when a send operation has
265      * completed.  Primarily for use with a PendingIntent that is
266      * performing a broadcast, this provides the same information as
267      * calling {@link Context#sendOrderedBroadcast(Intent, String,
268      * android.content.BroadcastReceiver, Handler, int, String, Bundle)
269      * Context.sendBroadcast()} with a final BroadcastReceiver.
270      */
271     public interface OnFinished {
272         /**
273          * Called when a send operation as completed.
274          *
275          * @param pendingIntent The PendingIntent this operation was sent through.
276          * @param intent The original Intent that was sent.
277          * @param resultCode The final result code determined by the send.
278          * @param resultData The final data collected by a broadcast.
279          * @param resultExtras The final extras collected by a broadcast.
280          */
onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)281         void onSendFinished(PendingIntent pendingIntent, Intent intent,
282                 int resultCode, String resultData, Bundle resultExtras);
283     }
284 
285     private static class FinishedDispatcher extends IIntentReceiver.Stub
286             implements Runnable {
287         private final PendingIntent mPendingIntent;
288         private final OnFinished mWho;
289         private final Handler mHandler;
290         private Intent mIntent;
291         private int mResultCode;
292         private String mResultData;
293         private Bundle mResultExtras;
294         private static Handler sDefaultSystemHandler;
FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler)295         FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) {
296             mPendingIntent = pi;
297             mWho = who;
298             if (handler == null && ActivityThread.isSystem()) {
299                 // We assign a default handler for the system process to avoid deadlocks when
300                 // processing receivers in various components that hold global service locks.
301                 if (sDefaultSystemHandler == null) {
302                     sDefaultSystemHandler = new Handler(Looper.getMainLooper());
303                 }
304                 mHandler = sDefaultSystemHandler;
305             } else {
306                 mHandler = handler;
307             }
308         }
performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean serialized, boolean sticky, int sendingUser)309         public void performReceive(Intent intent, int resultCode, String data,
310                 Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
311             mIntent = intent;
312             mResultCode = resultCode;
313             mResultData = data;
314             mResultExtras = extras;
315             if (mHandler == null) {
316                 run();
317             } else {
318                 mHandler.post(this);
319             }
320         }
run()321         public void run() {
322             mWho.onSendFinished(mPendingIntent, mIntent, mResultCode,
323                     mResultData, mResultExtras);
324         }
325     }
326 
327     /**
328      * Listener for observing when pending intents are written to a parcel.
329      *
330      * @hide
331      */
332     public interface OnMarshaledListener {
333         /**
334          * Called when a pending intent is written to a parcel.
335          *
336          * @param intent The pending intent.
337          * @param parcel The parcel to which it was written.
338          * @param flags The parcel flags when it was written.
339          */
onMarshaled(PendingIntent intent, Parcel parcel, int flags)340         void onMarshaled(PendingIntent intent, Parcel parcel, int flags);
341     }
342 
343     private static final ThreadLocal<OnMarshaledListener> sOnMarshaledListener
344             = new ThreadLocal<>();
345 
346     /**
347      * Registers an listener for pending intents being written to a parcel.
348      *
349      * @param listener The listener, null to clear.
350      *
351      * @hide
352      */
353     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setOnMarshaledListener(OnMarshaledListener listener)354     public static void setOnMarshaledListener(OnMarshaledListener listener) {
355         sOnMarshaledListener.set(listener);
356     }
357 
checkFlags(int flags, String packageName)358     private static void checkFlags(int flags, String packageName) {
359         final boolean flagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0;
360         final boolean flagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;
361 
362         if (flagImmutableSet && flagMutableSet) {
363             throw new IllegalArgumentException(
364                 "Cannot set both FLAG_IMMUTABLE and FLAG_MUTABLE for PendingIntent");
365         }
366 
367         if (Compatibility.isChangeEnabled(PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED)
368                 && !flagImmutableSet && !flagMutableSet) {
369             String msg = packageName + ": Targeting S+ (version " + Build.VERSION_CODES.S
370                     + " and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE"
371                     + " be specified when creating a PendingIntent.\nStrongly consider"
372                     + " using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality"
373                     + " depends on the PendingIntent being mutable, e.g. if it needs to"
374                     + " be used with inline replies or bubbles.";
375                 throw new IllegalArgumentException(msg);
376         }
377     }
378 
379     /**
380      * Retrieve a PendingIntent that will start a new activity, like calling
381      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
382      * Note that the activity will be started outside of the context of an
383      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
384      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
385      *
386      * <p class="note">For security reasons, the {@link android.content.Intent}
387      * you supply here should almost always be an <em>explicit intent</em>,
388      * that is specify an explicit component to be delivered to through
389      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
390      *
391      * @param context The Context in which this PendingIntent should start
392      * the activity.
393      * @param requestCode Private request code for the sender
394      * @param intent Intent of the activity to be launched.
395      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
396      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
397      * or any of the flags as supported by
398      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
399      * of the intent that can be supplied when the actual send happens.
400      *
401      * @return Returns an existing or new PendingIntent matching the given
402      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
403      * supplied.
404      */
405     @SuppressWarnings("AndroidFrameworkPendingIntentMutability")
getActivity(Context context, int requestCode, Intent intent, @Flags int flags)406     public static PendingIntent getActivity(Context context, int requestCode,
407             Intent intent, @Flags int flags) {
408         return getActivity(context, requestCode, intent, flags, null);
409     }
410 
411     /**
412      * Retrieve a PendingIntent that will start a new activity, like calling
413      * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
414      * Note that the activity will be started outside of the context of an
415      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
416      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
417      *
418      * <p class="note">For security reasons, the {@link android.content.Intent}
419      * you supply here should almost always be an <em>explicit intent</em>,
420      * that is specify an explicit component to be delivered to through
421      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
422      *
423      * @param context The Context in which this PendingIntent should start
424      * the activity.
425      * @param requestCode Private request code for the sender
426      * @param intent Intent of the activity to be launched.
427      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
428      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
429      * or any of the flags as supported by
430      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
431      * of the intent that can be supplied when the actual send happens.
432      * @param options Additional options for how the Activity should be started.
433      * May be null if there are no options.
434      *
435      * @return Returns an existing or new PendingIntent matching the given
436      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
437      * supplied.
438      */
439     @SuppressWarnings("AndroidFrameworkPendingIntentMutability")
getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)440     public static PendingIntent getActivity(Context context, int requestCode,
441             @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
442         // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null
443         final UserHandle user = context.getUser();
444         return getActivityAsUser(context, requestCode, intent, flags, options,
445                 user != null ? user : UserHandle.of(context.getUserId()));
446     }
447 
448     /**
449      * @hide
450      * Note that UserHandle.CURRENT will be interpreted at the time the
451      * activity is started, not when the pending intent is created.
452      */
453     @UnsupportedAppUsage
getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)454     public static PendingIntent getActivityAsUser(Context context, int requestCode,
455             @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
456         String packageName = context.getPackageName();
457         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
458         checkFlags(flags, packageName);
459         try {
460             intent.migrateExtraStreamToClipData(context);
461             intent.prepareToLeaveProcess(context);
462             IIntentSender target =
463                 ActivityManager.getService().getIntentSenderWithFeature(
464                     INTENT_SENDER_ACTIVITY, packageName,
465                     context.getAttributionTag(), null, null, requestCode, new Intent[] { intent },
466                     resolvedType != null ? new String[] { resolvedType } : null,
467                     flags, options, user.getIdentifier());
468             return target != null ? new PendingIntent(target) : null;
469         } catch (RemoteException e) {
470             throw e.rethrowFromSystemServer();
471         }
472     }
473 
474     /**
475      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
476      * array of Intents to be supplied.  The last Intent in the array is
477      * taken as the primary key for the PendingIntent, like the single Intent
478      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
479      * the resulting PendingIntent, all of the Intents are started in the same
480      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
481      *
482      * <p class="note">
483      * The <em>first</em> intent in the array will be started outside of the context of an
484      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
485      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
486      * the first in the array are started in the context of the previous activity
487      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
488      * </p>
489      *
490      * <p class="note">
491      * The <em>last</em> intent in the array represents the key for the
492      * PendingIntent.  In other words, it is the significant element for matching
493      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
494      * its content will be the subject of replacement by
495      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
496      * This is because it is the most specific of the supplied intents, and the
497      * UI the user actually sees when the intents are started.
498      * </p>
499      *
500      * <p class="note">For security reasons, the {@link android.content.Intent} objects
501      * you supply here should almost always be <em>explicit intents</em>,
502      * that is specify an explicit component to be delivered to through
503      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
504      *
505      * @param context The Context in which this PendingIntent should start
506      * the activity.
507      * @param requestCode Private request code for the sender
508      * @param intents Array of Intents of the activities to be launched.
509      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
510      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
511      * or any of the flags as supported by
512      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
513      * of the intent that can be supplied when the actual send happens.
514      *
515      * @return Returns an existing or new PendingIntent matching the given
516      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
517      * supplied.
518      */
519     @SuppressWarnings("AndroidFrameworkPendingIntentMutability")
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)520     public static PendingIntent getActivities(Context context, int requestCode,
521             @NonNull Intent[] intents, @Flags int flags) {
522         return getActivities(context, requestCode, intents, flags, null);
523     }
524 
525     /**
526      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
527      * array of Intents to be supplied.  The last Intent in the array is
528      * taken as the primary key for the PendingIntent, like the single Intent
529      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
530      * the resulting PendingIntent, all of the Intents are started in the same
531      * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
532      *
533      * <p class="note">
534      * The <em>first</em> intent in the array will be started outside of the context of an
535      * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
536      * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
537      * the first in the array are started in the context of the previous activity
538      * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
539      * </p>
540      *
541      * <p class="note">
542      * The <em>last</em> intent in the array represents the key for the
543      * PendingIntent.  In other words, it is the significant element for matching
544      * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
545      * its content will be the subject of replacement by
546      * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
547      * This is because it is the most specific of the supplied intents, and the
548      * UI the user actually sees when the intents are started.
549      * </p>
550      *
551      * <p class="note">For security reasons, the {@link android.content.Intent} objects
552      * you supply here should almost always be <em>explicit intents</em>,
553      * that is specify an explicit component to be delivered to through
554      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
555      *
556      * @param context The Context in which this PendingIntent should start
557      * the activity.
558      * @param requestCode Private request code for the sender
559      * @param intents Array of Intents of the activities to be launched.
560      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
561      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
562      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
563      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
564      * of the intent that can be supplied when the actual send happens.
565      *
566      * @return Returns an existing or new PendingIntent matching the given
567      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
568      * supplied.
569      */
570     @SuppressWarnings("AndroidFrameworkPendingIntentMutability")
getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)571     public static PendingIntent getActivities(Context context, int requestCode,
572             @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
573         // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null
574         final UserHandle user = context.getUser();
575         return getActivitiesAsUser(context, requestCode, intents, flags, options,
576                 user != null ? user : UserHandle.of(context.getUserId()));
577     }
578 
579     /**
580      * @hide
581      * Note that UserHandle.CURRENT will be interpreted at the time the
582      * activity is started, not when the pending intent is created.
583      */
getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)584     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
585             @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
586         String packageName = context.getPackageName();
587         String[] resolvedTypes = new String[intents.length];
588         for (int i=0; i<intents.length; i++) {
589             intents[i].migrateExtraStreamToClipData(context);
590             intents[i].prepareToLeaveProcess(context);
591             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
592         }
593         checkFlags(flags, packageName);
594         try {
595             IIntentSender target =
596                 ActivityManager.getService().getIntentSenderWithFeature(
597                     INTENT_SENDER_ACTIVITY, packageName,
598                     context.getAttributionTag(), null, null, requestCode, intents, resolvedTypes,
599                     flags, options, user.getIdentifier());
600             return target != null ? new PendingIntent(target) : null;
601         } catch (RemoteException e) {
602             throw e.rethrowFromSystemServer();
603         }
604     }
605 
606     /**
607      * Retrieve a PendingIntent that will perform a broadcast, like calling
608      * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
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 perform
616      * the broadcast.
617      * @param requestCode Private request code for the sender
618      * @param intent The Intent to be broadcast.
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      */
629     @SuppressWarnings("AndroidFrameworkPendingIntentMutability")
getBroadcast(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)630     public static PendingIntent getBroadcast(Context context, int requestCode,
631             @NonNull Intent intent, @Flags int flags) {
632         return getBroadcastAsUser(context, requestCode, intent, flags, context.getUser());
633     }
634 
635     /**
636      * @hide
637      * Note that UserHandle.CURRENT will be interpreted at the time the
638      * broadcast is sent, not when the pending intent is created.
639      */
640     @UnsupportedAppUsage
getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)641     public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
642             Intent intent, int flags, UserHandle userHandle) {
643         String packageName = context.getPackageName();
644         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
645         checkFlags(flags, packageName);
646         try {
647             intent.prepareToLeaveProcess(context);
648             IIntentSender target =
649                 ActivityManager.getService().getIntentSenderWithFeature(
650                     INTENT_SENDER_BROADCAST, packageName,
651                     context.getAttributionTag(), null, null, requestCode, new Intent[] { intent },
652                     resolvedType != null ? new String[] { resolvedType } : null,
653                     flags, null, userHandle.getIdentifier());
654             return target != null ? new PendingIntent(target) : null;
655         } catch (RemoteException e) {
656             throw e.rethrowFromSystemServer();
657         }
658     }
659 
660     /**
661      * Retrieve a PendingIntent that will start a service, like calling
662      * {@link Context#startService Context.startService()}.  The start
663      * arguments given to the service will come from the extras of the Intent.
664      *
665      * <p class="note">For security reasons, the {@link android.content.Intent}
666      * you supply here should almost always be an <em>explicit intent</em>,
667      * that is specify an explicit component to be delivered to through
668      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
669      *
670      * @param context The Context in which this PendingIntent should start
671      * the service.
672      * @param requestCode Private request code for the sender
673      * @param intent An Intent describing the service to be started.
674      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
675      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
676      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
677      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
678      * of the intent that can be supplied when the actual send happens.
679      *
680      * @return Returns an existing or new PendingIntent matching the given
681      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
682      * supplied.
683      */
getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)684     public static PendingIntent getService(Context context, int requestCode,
685             @NonNull Intent intent, @Flags int flags) {
686         return buildServicePendingIntent(context, requestCode, intent, flags,
687                 INTENT_SENDER_SERVICE);
688     }
689 
690     /**
691      * Retrieve a PendingIntent that will start a foreground service, like calling
692      * {@link Context#startForegroundService Context.startForegroundService()}.  The start
693      * arguments given to the service will come from the extras of the Intent.
694      *
695      * <p class="note">For security reasons, the {@link android.content.Intent}
696      * you supply here should almost always be an <em>explicit intent</em>,
697      * that is specify an explicit component to be delivered to through
698      * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
699      *
700      * @param context The Context in which this PendingIntent should start
701      * the service.
702      * @param requestCode Private request code for the sender
703      * @param intent An Intent describing the service to be started.
704      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
705      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
706      * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
707      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
708      * of the intent that can be supplied when the actual send happens.
709      *
710      * @return Returns an existing or new PendingIntent matching the given
711      * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
712      * supplied.
713      */
getForegroundService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)714     public static PendingIntent getForegroundService(Context context, int requestCode,
715             @NonNull Intent intent, @Flags int flags) {
716         return buildServicePendingIntent(context, requestCode, intent, flags,
717                 INTENT_SENDER_FOREGROUND_SERVICE);
718     }
719 
buildServicePendingIntent(Context context, int requestCode, Intent intent, int flags, int serviceKind)720     private static PendingIntent buildServicePendingIntent(Context context, int requestCode,
721             Intent intent, int flags, int serviceKind) {
722         String packageName = context.getPackageName();
723         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
724         checkFlags(flags, packageName);
725         try {
726             intent.prepareToLeaveProcess(context);
727             IIntentSender target =
728                 ActivityManager.getService().getIntentSenderWithFeature(
729                     serviceKind, packageName, context.getAttributionTag(),
730                     null, null, requestCode, new Intent[] { intent },
731                     resolvedType != null ? new String[] { resolvedType } : null,
732                     flags, null, context.getUserId());
733             return target != null ? new PendingIntent(target) : null;
734         } catch (RemoteException e) {
735             throw e.rethrowFromSystemServer();
736         }
737     }
738 
739     /**
740      * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
741      *
742      * @return Returns a IntentSender object that wraps the sender of PendingIntent
743      *
744      */
745     @NonNull
getIntentSender()746     public IntentSender getIntentSender() {
747         return new IntentSender(mTarget, mWhitelistToken);
748     }
749 
750     /**
751      * Cancel a currently active PendingIntent.  Only the original application
752      * owning a PendingIntent can cancel it.
753      */
cancel()754     public void cancel() {
755         try {
756             ActivityManager.getService().cancelIntentSender(mTarget);
757         } catch (RemoteException e) {
758             throw e.rethrowFromSystemServer();
759         }
760     }
761 
762     /**
763      * Perform the operation associated with this PendingIntent.
764      *
765      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
766      *
767      * @throws CanceledException Throws CanceledException if the PendingIntent
768      * is no longer allowing more intents to be sent through it.
769      */
send()770     public void send() throws CanceledException {
771         send(null, 0, null, null, null, null, null);
772     }
773 
774     /**
775      * Perform the operation associated with this PendingIntent.
776      *
777      * @param code Result code to supply back to the PendingIntent's target.
778      *
779      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
780      *
781      * @throws CanceledException Throws CanceledException if the PendingIntent
782      * is no longer allowing more intents to be sent through it.
783      */
send(int code)784     public void send(int code) throws CanceledException {
785         send(null, code, null, null, null, null, null);
786     }
787 
788     /**
789      * Perform the operation associated with this PendingIntent, allowing the
790      * caller to specify information about the Intent to use.
791      *
792      * @param context The Context of the caller.
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. If flag {@link #FLAG_IMMUTABLE} was set when this
797      * pending intent was created, this argument will be ignored.
798      *
799      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
800      *
801      * @throws CanceledException Throws CanceledException if the PendingIntent
802      * is no longer allowing more intents to be sent through it.
803      */
send(Context context, int code, @Nullable Intent intent)804     public void send(Context context, int code, @Nullable Intent intent)
805             throws CanceledException {
806         send(context, code, intent, null, null, null, null);
807     }
808 
809     /**
810      * Perform the operation associated with this PendingIntent, allowing the
811      * caller to be notified when the send has completed.
812      *
813      * @param code Result code to supply back to the PendingIntent's target.
814      * @param onFinished The object to call back on when the send has
815      * completed, or null for no callback.
816      * @param handler Handler identifying the thread on which the callback
817      * should happen.  If null, the callback will happen from the thread
818      * pool of the process.
819      *
820      * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
821      *
822      * @throws CanceledException Throws CanceledException if the PendingIntent
823      * is no longer allowing more intents to be sent through it.
824      */
send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)825     public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)
826             throws CanceledException {
827         send(null, code, null, onFinished, handler, null, null);
828     }
829 
830     /**
831      * Perform the operation associated with this PendingIntent, allowing the
832      * caller to specify information about the Intent to use and be notified
833      * when the send has completed.
834      *
835      * <p>For the intent parameter, a PendingIntent
836      * often has restrictions on which fields can be supplied here, based on
837      * how the PendingIntent was retrieved in {@link #getActivity},
838      * {@link #getBroadcast}, or {@link #getService}.
839      *
840      * @param context The Context of the caller.  This may be null if
841      * <var>intent</var> is also null.
842      * @param code Result code to supply back to the PendingIntent's target.
843      * @param intent Additional Intent data.  See {@link Intent#fillIn
844      * Intent.fillIn()} for information on how this is applied to the
845      * original Intent.  Use null to not modify the original Intent.
846      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
847      * created, this argument will be ignored.
848      * @param onFinished The object to call back on when the send has
849      * completed, or null for no callback.
850      * @param handler Handler identifying the thread on which the callback
851      * should happen.  If null, the callback will happen from the thread
852      * pool of the process.
853      *
854      * @see #send()
855      * @see #send(int)
856      * @see #send(Context, int, Intent)
857      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
858      * @see #send(Context, int, Intent, OnFinished, Handler, String)
859      *
860      * @throws CanceledException Throws CanceledException if the PendingIntent
861      * is no longer allowing more intents to be sent through it.
862      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)863     public void send(Context context, int code, @Nullable Intent intent,
864             @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException {
865         send(context, code, intent, onFinished, handler, null, null);
866     }
867 
868     /**
869      * Perform the operation associated with this PendingIntent, allowing the
870      * caller to specify information about the Intent to use and be notified
871      * when the send has completed.
872      *
873      * <p>For the intent parameter, a PendingIntent
874      * often has restrictions on which fields can be supplied here, based on
875      * how the PendingIntent was retrieved in {@link #getActivity},
876      * {@link #getBroadcast}, or {@link #getService}.
877      *
878      * @param context The Context of the caller.  This may be null if
879      * <var>intent</var> is also null.
880      * @param code Result code to supply back to the PendingIntent's target.
881      * @param intent Additional Intent data.  See {@link Intent#fillIn
882      * Intent.fillIn()} for information on how this is applied to the
883      * original Intent.  Use null to not modify the original Intent.
884      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
885      * created, this argument will be ignored.
886      * @param onFinished The object to call back on when the send has
887      * completed, or null for no callback.
888      * @param handler Handler identifying the thread on which the callback
889      * should happen.  If null, the callback will happen from the thread
890      * pool of the process.
891      * @param requiredPermission Name of permission that a recipient of the PendingIntent
892      * is required to hold.  This is only valid for broadcast intents, and
893      * corresponds to the permission argument in
894      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
895      * If null, no permission is required.
896      *
897      * @see #send()
898      * @see #send(int)
899      * @see #send(Context, int, Intent)
900      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
901      * @see #send(Context, int, Intent, OnFinished, Handler)
902      *
903      * @throws CanceledException Throws CanceledException if the PendingIntent
904      * is no longer allowing more intents to be sent through it.
905      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)906     public void send(Context context, int code, @Nullable Intent intent,
907             @Nullable OnFinished onFinished, @Nullable Handler handler,
908             @Nullable String requiredPermission)
909             throws CanceledException {
910         send(context, code, intent, onFinished, handler, requiredPermission, null);
911     }
912 
913     /**
914      * Perform the operation associated with this PendingIntent, allowing the
915      * caller to specify information about the Intent to use and be notified
916      * when the send has completed.
917      *
918      * <p>For the intent parameter, a PendingIntent
919      * often has restrictions on which fields can be supplied here, based on
920      * how the PendingIntent was retrieved in {@link #getActivity},
921      * {@link #getBroadcast}, or {@link #getService}.
922      *
923      * @param context The Context of the caller.  This may be null if
924      * <var>intent</var> is also null.
925      * @param code Result code to supply back to the PendingIntent's target.
926      * @param intent Additional Intent data.  See {@link Intent#fillIn
927      * Intent.fillIn()} for information on how this is applied to the
928      * original Intent.  Use null to not modify the original Intent.
929      * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
930      * created, this argument will be ignored.
931      * @param onFinished The object to call back on when the send has
932      * completed, or null for no callback.
933      * @param handler Handler identifying the thread on which the callback
934      * should happen.  If null, the callback will happen from the thread
935      * pool of the process.
936      * @param requiredPermission Name of permission that a recipient of the PendingIntent
937      * is required to hold.  This is only valid for broadcast intents, and
938      * corresponds to the permission argument in
939      * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
940      * If null, no permission is required.
941      * @param options Additional options the caller would like to provide to modify the sending
942      * behavior.  May be built from an {@link ActivityOptions} to apply to an activity start.
943      *
944      * @see #send()
945      * @see #send(int)
946      * @see #send(Context, int, Intent)
947      * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
948      * @see #send(Context, int, Intent, OnFinished, Handler)
949      *
950      * @throws CanceledException Throws CanceledException if the PendingIntent
951      * is no longer allowing more intents to be sent through it.
952      */
send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)953     public void send(Context context, int code, @Nullable Intent intent,
954             @Nullable OnFinished onFinished, @Nullable Handler handler,
955             @Nullable String requiredPermission, @Nullable Bundle options)
956             throws CanceledException {
957         if (sendAndReturnResult(context, code, intent, onFinished, handler, requiredPermission,
958                 options) < 0) {
959             throw new CanceledException();
960         }
961     }
962 
963     /**
964      * Like {@link #send}, but returns the result
965      * @hide
966      */
sendAndReturnResult(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)967     public int sendAndReturnResult(Context context, int code, @Nullable Intent intent,
968             @Nullable OnFinished onFinished, @Nullable Handler handler,
969             @Nullable String requiredPermission, @Nullable Bundle options)
970             throws CanceledException {
971         try {
972             String resolvedType = intent != null ?
973                     intent.resolveTypeIfNeeded(context.getContentResolver())
974                     : null;
975 
976             if (context != null && isActivity()) {
977                 // Set the context display id as preferred for this activity launches, so that it
978                 // can land on caller's display. Or just brought the task to front at the display
979                 // where it was on since it has higher preference.
980                 ActivityOptions activityOptions = options != null ? new ActivityOptions(options)
981                         : ActivityOptions.makeBasic();
982                 activityOptions.setCallerDisplayId(context.getDisplayId());
983                 options = activityOptions.toBundle();
984             }
985 
986             return ActivityManager.getService().sendIntentSender(
987                     mTarget, mWhitelistToken, code, intent, resolvedType,
988                     onFinished != null
989                             ? new FinishedDispatcher(this, onFinished, handler)
990                             : null,
991                     requiredPermission, options);
992         } catch (RemoteException e) {
993             throw new CanceledException(e);
994         }
995     }
996 
997     /**
998      * @deprecated Renamed to {@link #getCreatorPackage()}.
999      */
1000     @Deprecated
1001     @Nullable
getTargetPackage()1002     public String getTargetPackage() {
1003         return getCreatorPackage();
1004     }
1005 
1006     /**
1007      * Return the package name of the application that created this
1008      * PendingIntent, that is the identity under which you will actually be
1009      * sending the Intent.  The returned string is supplied by the system, so
1010      * that an application can not spoof its package.
1011      *
1012      * <p class="note">Be careful about how you use this.  All this tells you is
1013      * who created the PendingIntent.  It does <strong>not</strong> tell you who
1014      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
1015      * passed between applications, so the PendingIntent you receive from an application
1016      * could actually be one it received from another application, meaning the result
1017      * you get here will identify the original application.  Because of this, you should
1018      * only use this information to identify who you expect to be interacting with
1019      * through a {@link #send} call, not who gave you the PendingIntent.</p>
1020      *
1021      * @return The package name of the PendingIntent.
1022      */
1023     @Nullable
getCreatorPackage()1024     public String getCreatorPackage() {
1025         return getCachedInfo().getCreatorPackage();
1026     }
1027 
1028     /**
1029      * Return the uid of the application that created this
1030      * PendingIntent, that is the identity under which you will actually be
1031      * sending the Intent.  The returned integer is supplied by the system, so
1032      * that an application can not spoof its uid.
1033      *
1034      * <p class="note">Be careful about how you use this.  All this tells you is
1035      * who created the PendingIntent.  It does <strong>not</strong> tell you who
1036      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
1037      * passed between applications, so the PendingIntent you receive from an application
1038      * could actually be one it received from another application, meaning the result
1039      * you get here will identify the original application.  Because of this, you should
1040      * only use this information to identify who you expect to be interacting with
1041      * through a {@link #send} call, not who gave you the PendingIntent.</p>
1042      *
1043      * @return The uid of the PendingIntent, or -1 if there is
1044      * none associated with it.
1045      */
getCreatorUid()1046     public int getCreatorUid() {
1047         return getCachedInfo().getCreatorUid();
1048     }
1049 
1050     /**
1051      * Register a listener to when this pendingIntent is cancelled. There are no guarantees on which
1052      * thread a listener will be called and it's up to the caller to synchronize. This may
1053      * trigger a synchronous binder call so should therefore usually be called on a background
1054      * thread.
1055      *
1056      * @hide
1057      */
registerCancelListener(CancelListener cancelListener)1058     public void registerCancelListener(CancelListener cancelListener) {
1059         synchronized (this) {
1060             if (mCancelReceiver == null) {
1061                 mCancelReceiver = new IResultReceiver.Stub() {
1062                     @Override
1063                     public void send(int resultCode, Bundle resultData) throws RemoteException {
1064                         notifyCancelListeners();
1065                     }
1066                 };
1067             }
1068             if (mCancelListeners == null) {
1069                 mCancelListeners = new ArraySet<>();
1070             }
1071             boolean wasEmpty = mCancelListeners.isEmpty();
1072             mCancelListeners.add(cancelListener);
1073             if (wasEmpty) {
1074                 try {
1075                     ActivityManager.getService().registerIntentSenderCancelListener(mTarget,
1076                             mCancelReceiver);
1077                 } catch (RemoteException e) {
1078                     throw e.rethrowFromSystemServer();
1079                 }
1080             }
1081         }
1082     }
1083 
notifyCancelListeners()1084     private void notifyCancelListeners() {
1085         ArraySet<CancelListener> cancelListeners;
1086         synchronized (this) {
1087             cancelListeners = new ArraySet<>(mCancelListeners);
1088         }
1089         int size = cancelListeners.size();
1090         for (int i = 0; i < size; i++) {
1091             cancelListeners.valueAt(i).onCancelled(this);
1092         }
1093     }
1094 
1095     /**
1096      * Un-register a listener to when this pendingIntent is cancelled.
1097      *
1098      * @hide
1099      */
unregisterCancelListener(CancelListener cancelListener)1100     public void unregisterCancelListener(CancelListener cancelListener) {
1101         synchronized (this) {
1102             if (mCancelListeners == null) {
1103                 return;
1104             }
1105             boolean wasEmpty = mCancelListeners.isEmpty();
1106             mCancelListeners.remove(cancelListener);
1107             if (mCancelListeners.isEmpty() && !wasEmpty) {
1108                 try {
1109                     ActivityManager.getService().unregisterIntentSenderCancelListener(mTarget,
1110                             mCancelReceiver);
1111                 } catch (RemoteException e) {
1112                     throw e.rethrowFromSystemServer();
1113                 }
1114             }
1115         }
1116     }
1117 
1118     /**
1119      * Return the user handle of the application that created this
1120      * PendingIntent, that is the user under which you will actually be
1121      * sending the Intent.  The returned UserHandle is supplied by the system, so
1122      * that an application can not spoof its user.  See
1123      * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
1124      * more explanation of user handles.
1125      *
1126      * <p class="note">Be careful about how you use this.  All this tells you is
1127      * who created the PendingIntent.  It does <strong>not</strong> tell you who
1128      * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
1129      * passed between applications, so the PendingIntent you receive from an application
1130      * could actually be one it received from another application, meaning the result
1131      * you get here will identify the original application.  Because of this, you should
1132      * only use this information to identify who you expect to be interacting with
1133      * through a {@link #send} call, not who gave you the PendingIntent.</p>
1134      *
1135      * @return The user handle of the PendingIntent
1136      */
1137     @NonNull
getCreatorUserHandle()1138     public UserHandle getCreatorUserHandle() {
1139         int uid = getCachedInfo().getCreatorUid();
1140         return UserHandle.getUserHandleForUid(uid);
1141     }
1142 
1143     /**
1144      * @hide
1145      * Check to verify that this PendingIntent targets a specific package.
1146      */
isTargetedToPackage()1147     public boolean isTargetedToPackage() {
1148         try {
1149             return ActivityManager.getService()
1150                 .isIntentSenderTargetedToPackage(mTarget);
1151         } catch (RemoteException e) {
1152             throw e.rethrowFromSystemServer();
1153         }
1154     }
1155 
1156     /**
1157      * Check if this PendingIntent is marked with {@link #FLAG_IMMUTABLE}.
1158      */
isImmutable()1159     public boolean isImmutable() {
1160         return getCachedInfo().isImmutable();
1161     }
1162 
1163     /**
1164      * @return TRUE if this {@link PendingIntent} was created with
1165      * {@link #getActivity} or {@link #getActivities}.
1166      */
isActivity()1167     public boolean isActivity() {
1168         return getCachedInfo().getIntentSenderType() == INTENT_SENDER_ACTIVITY;
1169     }
1170 
1171     /**
1172      * @return TRUE if this {@link PendingIntent} was created with {@link #getForegroundService}.
1173      */
isForegroundService()1174     public boolean isForegroundService() {
1175         return getCachedInfo().getIntentSenderType() == INTENT_SENDER_FOREGROUND_SERVICE;
1176     }
1177 
1178     /**
1179      * @return TRUE if this {@link PendingIntent} was created with {@link #getService}.
1180      */
isService()1181     public boolean isService() {
1182         return getCachedInfo().getIntentSenderType() == INTENT_SENDER_SERVICE;
1183     }
1184 
1185     /**
1186      * @return TRUE if this {@link PendingIntent} was created with {@link #getBroadcast}.
1187      */
isBroadcast()1188     public boolean isBroadcast() {
1189         return getCachedInfo().getIntentSenderType() == INTENT_SENDER_BROADCAST;
1190     }
1191 
1192     /**
1193      * @hide
1194      * Return the Intent of this PendingIntent.
1195      */
1196     @UnsupportedAppUsage
getIntent()1197     public Intent getIntent() {
1198         try {
1199             return ActivityManager.getService()
1200                 .getIntentForIntentSender(mTarget);
1201         } catch (RemoteException e) {
1202             throw e.rethrowFromSystemServer();
1203         }
1204     }
1205 
1206     /**
1207      * @hide
1208      * Return descriptive tag for this PendingIntent.
1209      */
1210     @UnsupportedAppUsage
getTag(String prefix)1211     public String getTag(String prefix) {
1212         try {
1213             return ActivityManager.getService()
1214                 .getTagForIntentSender(mTarget, prefix);
1215         } catch (RemoteException e) {
1216             throw e.rethrowFromSystemServer();
1217         }
1218     }
1219 
1220     /**
1221      * Resolve the intent set in this {@link PendingIntent}. Note if the pending intent is
1222      * generated for another user, the resulting component may not exist on the calling user.
1223      * Use {@link android.content.pm.ApplicationInfo#uid} of the resulting
1224      * {@link android.content.pm.ComponentInfo} with
1225      * {@link android.os.UserHandle#getUserHandleForUid(int)} to see which user will receive
1226      * the intent.
1227      *
1228      * @param flags MATCH_* flags from {@link android.content.pm.PackageManager}.
1229      * @hide
1230      */
1231     @RequiresPermission(permission.GET_INTENT_SENDER_INTENT)
1232     @SystemApi(client = Client.MODULE_LIBRARIES)
1233     @TestApi
queryIntentComponents(@esolveInfoFlags int flags)1234     public @NonNull List<ResolveInfo> queryIntentComponents(@ResolveInfoFlags int flags) {
1235         try {
1236             ParceledListSlice<ResolveInfo> parceledList = ActivityManager.getService()
1237                     .queryIntentComponentsForIntentSender(mTarget, flags);
1238             if (parceledList == null) {
1239                 return Collections.emptyList();
1240             }
1241             return parceledList.getList();
1242         } catch (RemoteException e) {
1243             throw e.rethrowFromSystemServer();
1244         }
1245     }
1246 
1247     /**
1248      * Comparison operator on two PendingIntent objects, such that true is returned when they
1249      * represent {@link Intent}s that are equal as per {@link Intent#filterEquals}.
1250      *
1251      * @param other The other PendingIntent to compare against.
1252      * @return True if action, data, type, class, and categories on two intents are the same.
1253      *
1254      * @hide
1255      */
1256     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1257     @TestApi
1258     @RequiresPermission(android.Manifest.permission.GET_INTENT_SENDER_INTENT)
intentFilterEquals(@ullable PendingIntent other)1259     public boolean intentFilterEquals(@Nullable PendingIntent other) {
1260         if (other == null) {
1261             return false;
1262         }
1263         try {
1264             return ActivityManager.getService().getIntentForIntentSender(other.mTarget)
1265                     .filterEquals(getIntent());
1266         } catch (RemoteException e) {
1267             throw e.rethrowFromSystemServer();
1268         }
1269     }
1270 
1271     /**
1272      * Comparison operator on two PendingIntent objects, such that true
1273      * is returned then they both represent the same operation from the
1274      * same package.  This allows you to use {@link #getActivity},
1275      * {@link #getBroadcast}, or {@link #getService} multiple times (even
1276      * across a process being killed), resulting in different PendingIntent
1277      * objects but whose equals() method identifies them as being the same
1278      * operation.
1279      */
1280     @Override
equals(@ullable Object otherObj)1281     public boolean equals(@Nullable Object otherObj) {
1282         if (otherObj instanceof PendingIntent) {
1283             return mTarget.asBinder().equals(((PendingIntent)otherObj)
1284                     .mTarget.asBinder());
1285         }
1286         return false;
1287     }
1288 
1289     @Override
hashCode()1290     public int hashCode() {
1291         return mTarget.asBinder().hashCode();
1292     }
1293 
1294     @Override
toString()1295     public String toString() {
1296         StringBuilder sb = new StringBuilder(128);
1297         sb.append("PendingIntent{");
1298         sb.append(Integer.toHexString(System.identityHashCode(this)));
1299         sb.append(": ");
1300         sb.append(mTarget.asBinder());
1301         sb.append('}');
1302         return sb.toString();
1303     }
1304 
1305     /** @hide */
dumpDebug(ProtoOutputStream proto, long fieldId)1306     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1307         final long token = proto.start(fieldId);
1308         proto.write(PendingIntentProto.TARGET, mTarget.asBinder().toString());
1309         proto.end(token);
1310     }
1311 
describeContents()1312     public int describeContents() {
1313         return 0;
1314     }
1315 
writeToParcel(Parcel out, int flags)1316     public void writeToParcel(Parcel out, int flags) {
1317         out.writeStrongBinder(mTarget.asBinder());
1318         OnMarshaledListener listener = sOnMarshaledListener.get();
1319         if (listener != null) {
1320             listener.onMarshaled(this, out, flags);
1321         }
1322 
1323     }
1324 
1325     public static final @NonNull Creator<PendingIntent> CREATOR = new Creator<PendingIntent>() {
1326         public PendingIntent createFromParcel(Parcel in) {
1327             IBinder target = in.readStrongBinder();
1328             return target != null
1329                     ? new PendingIntent(target, in.getClassCookie(PendingIntent.class))
1330                     : null;
1331         }
1332 
1333         public PendingIntent[] newArray(int size) {
1334             return new PendingIntent[size];
1335         }
1336     };
1337 
1338     /**
1339      * Convenience function for writing either a PendingIntent or null pointer to
1340      * a Parcel.  You must use this with {@link #readPendingIntentOrNullFromParcel}
1341      * for later reading it.
1342      *
1343      * @param sender The PendingIntent to write, or null.
1344      * @param out Where to write the PendingIntent.
1345      */
writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)1346     public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
1347             @NonNull Parcel out) {
1348         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() : null);
1349         if (sender != null) {
1350             OnMarshaledListener listener = sOnMarshaledListener.get();
1351             if (listener != null) {
1352                 listener.onMarshaled(sender, out, 0 /* flags */);
1353             }
1354         }
1355     }
1356 
1357     /**
1358      * Convenience function for reading either a PendingIntent or null pointer from
1359      * a Parcel.  You must have previously written the PendingIntent with
1360      * {@link #writePendingIntentOrNullToParcel}.
1361      *
1362      * @param in The Parcel containing the written PendingIntent.
1363      *
1364      * @return Returns the PendingIntent read from the Parcel, or null if null had
1365      * been written.
1366      */
1367     @Nullable
readPendingIntentOrNullFromParcel(@onNull Parcel in)1368     public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
1369         IBinder b = in.readStrongBinder();
1370         return b != null ? new PendingIntent(b, in.getClassCookie(PendingIntent.class)) : null;
1371     }
1372 
1373     /**
1374      * Creates a PendingIntent with the given target.
1375      * @param target the backing IIntentSender
1376      * @hide
1377      */
PendingIntent(IIntentSender target)1378     public PendingIntent(IIntentSender target) {
1379         mTarget = Objects.requireNonNull(target);
1380     }
1381 
PendingIntent(IBinder target, Object cookie)1382     /*package*/ PendingIntent(IBinder target, Object cookie) {
1383         mTarget = Objects.requireNonNull(IIntentSender.Stub.asInterface(target));
1384         if (cookie != null) {
1385             mWhitelistToken = (IBinder)cookie;
1386         }
1387     }
1388 
1389     /** @hide */
getTarget()1390     public IIntentSender getTarget() {
1391         return mTarget;
1392     }
1393 
1394     /** @hide */
getWhitelistToken()1395     public IBinder getWhitelistToken() {
1396         return mWhitelistToken;
1397     }
1398 
1399     /**
1400      * A listener to when a pending intent is cancelled
1401      *
1402      * @hide
1403      */
1404     public interface CancelListener {
1405         /**
1406          * Called when a Pending Intent is cancelled.
1407          *
1408          * @param intent The intent that was cancelled.
1409          */
onCancelled(PendingIntent intent)1410         void onCancelled(PendingIntent intent);
1411     }
1412 
getCachedInfo()1413     private PendingIntentInfo getCachedInfo() {
1414         if (mCachedInfo == null) {
1415             try {
1416                 mCachedInfo = ActivityManager.getService().getInfoForIntentSender(mTarget);
1417             } catch (RemoteException e) {
1418                 throw e.rethrowFromSystemServer();
1419             }
1420         }
1421 
1422         return mCachedInfo;
1423     }
1424 }
1425