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