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