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