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