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 (currently
211     * not used).
212     * @param intent Intent of the activity to be launched.
213     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
214     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
215     * or any of the flags as supported by
216     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
217     * of the intent that can be supplied when the actual send happens.
218     *
219     * @return Returns an existing or new PendingIntent matching the given
220     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
221     * supplied.
222     */
223    public static PendingIntent getActivity(Context context, int requestCode,
224            Intent intent, int flags) {
225        return getActivity(context, requestCode, intent, flags, null);
226    }
227
228    /**
229     * Retrieve a PendingIntent that will start a new activity, like calling
230     * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
231     * Note that the activity will be started outside of the context of an
232     * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
233     * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
234     *
235     * <p class="note">For security reasons, the {@link android.content.Intent}
236     * you supply here should almost always be an <em>explicit intent</em>,
237     * that is specify an explicit component to be delivered to through
238     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
239     *
240     * @param context The Context in which this PendingIntent should start
241     * the activity.
242     * @param requestCode Private request code for the sender (currently
243     * not used).
244     * @param intent Intent of the activity to be launched.
245     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
246     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
247     * or any of the flags as supported by
248     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
249     * of the intent that can be supplied when the actual send happens.
250     * @param options Additional options for how the Activity should be started.
251     * May be null if there are no options.
252     *
253     * @return Returns an existing or new PendingIntent matching the given
254     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
255     * supplied.
256     */
257    public static PendingIntent getActivity(Context context, int requestCode,
258            Intent intent, int flags, Bundle options) {
259        String packageName = context.getPackageName();
260        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
261                context.getContentResolver()) : null;
262        try {
263            intent.migrateExtraStreamToClipData();
264            intent.prepareToLeaveProcess();
265            IIntentSender target =
266                ActivityManagerNative.getDefault().getIntentSender(
267                    ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
268                    null, null, requestCode, new Intent[] { intent },
269                    resolvedType != null ? new String[] { resolvedType } : null,
270                    flags, options, UserHandle.myUserId());
271            return target != null ? new PendingIntent(target) : null;
272        } catch (RemoteException e) {
273        }
274        return null;
275    }
276
277    /**
278     * @hide
279     * Note that UserHandle.CURRENT will be interpreted at the time the
280     * activity is started, not when the pending intent is created.
281     */
282    public static PendingIntent getActivityAsUser(Context context, int requestCode,
283            Intent intent, int flags, Bundle options, UserHandle user) {
284        String packageName = context.getPackageName();
285        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
286                context.getContentResolver()) : null;
287        try {
288            intent.migrateExtraStreamToClipData();
289            intent.prepareToLeaveProcess();
290            IIntentSender target =
291                ActivityManagerNative.getDefault().getIntentSender(
292                    ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
293                    null, null, requestCode, new Intent[] { intent },
294                    resolvedType != null ? new String[] { resolvedType } : null,
295                    flags, options, user.getIdentifier());
296            return target != null ? new PendingIntent(target) : null;
297        } catch (RemoteException e) {
298        }
299        return null;
300    }
301
302    /**
303     * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
304     * array of Intents to be supplied.  The last Intent in the array is
305     * taken as the primary key for the PendingIntent, like the single Intent
306     * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
307     * the resulting PendingIntent, all of the Intents are started in the same
308     * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
309     *
310     * <p class="note">
311     * The <em>first</em> intent in the array will be started outside of the context of an
312     * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
313     * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
314     * the first in the array are started in the context of the previous activity
315     * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
316     * </p>
317     *
318     * <p class="note">
319     * The <em>last</em> intent in the array represents the key for the
320     * PendingIntent.  In other words, it is the significant element for matching
321     * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
322     * its content will be the subject of replacement by
323     * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
324     * This is because it is the most specific of the supplied intents, and the
325     * UI the user actually sees when the intents are started.
326     * </p>
327     *
328     * <p class="note">For security reasons, the {@link android.content.Intent} objects
329     * you supply here should almost always be <em>explicit intents</em>,
330     * that is specify an explicit component to be delivered to through
331     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
332     *
333     * @param context The Context in which this PendingIntent should start
334     * the activity.
335     * @param requestCode Private request code for the sender (currently
336     * not used).
337     * @param intents Array of Intents of the activities to be launched.
338     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
339     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
340     * or any of the flags as supported by
341     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
342     * of the intent that can be supplied when the actual send happens.
343     *
344     * @return Returns an existing or new PendingIntent matching the given
345     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
346     * supplied.
347     */
348    public static PendingIntent getActivities(Context context, int requestCode,
349            Intent[] intents, int flags) {
350        return getActivities(context, requestCode, intents, flags, null);
351    }
352
353    /**
354     * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
355     * array of Intents to be supplied.  The last Intent in the array is
356     * taken as the primary key for the PendingIntent, like the single Intent
357     * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
358     * the resulting PendingIntent, all of the Intents are started in the same
359     * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
360     *
361     * <p class="note">
362     * The <em>first</em> intent in the array will be started outside of the context of an
363     * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
364     * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.  (Activities after
365     * the first in the array are started in the context of the previous activity
366     * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
367     * </p>
368     *
369     * <p class="note">
370     * The <em>last</em> intent in the array represents the key for the
371     * PendingIntent.  In other words, it is the significant element for matching
372     * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
373     * its content will be the subject of replacement by
374     * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
375     * This is because it is the most specific of the supplied intents, and the
376     * UI the user actually sees when the intents are started.
377     * </p>
378     *
379     * <p class="note">For security reasons, the {@link android.content.Intent} objects
380     * you supply here should almost always be <em>explicit intents</em>,
381     * that is specify an explicit component to be delivered to through
382     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
383     *
384     * @param context The Context in which this PendingIntent should start
385     * the activity.
386     * @param requestCode Private request code for the sender (currently
387     * not used).
388     * @param intents Array of Intents of the activities to be launched.
389     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
390     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
391     * or any of the flags as supported by
392     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
393     * of the intent that can be supplied when the actual send happens.
394     *
395     * @return Returns an existing or new PendingIntent matching the given
396     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
397     * supplied.
398     */
399    public static PendingIntent getActivities(Context context, int requestCode,
400            Intent[] intents, int flags, Bundle options) {
401        String packageName = context.getPackageName();
402        String[] resolvedTypes = new String[intents.length];
403        for (int i=0; i<intents.length; i++) {
404            intents[i].migrateExtraStreamToClipData();
405            intents[i].prepareToLeaveProcess();
406            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
407        }
408        try {
409            IIntentSender target =
410                ActivityManagerNative.getDefault().getIntentSender(
411                    ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
412                    null, null, requestCode, intents, resolvedTypes, flags, options,
413                    UserHandle.myUserId());
414            return target != null ? new PendingIntent(target) : null;
415        } catch (RemoteException e) {
416        }
417        return null;
418    }
419
420    /**
421     * @hide
422     * Note that UserHandle.CURRENT will be interpreted at the time the
423     * activity is started, not when the pending intent is created.
424     */
425    public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
426            Intent[] intents, int flags, Bundle options, UserHandle user) {
427        String packageName = context.getPackageName();
428        String[] resolvedTypes = new String[intents.length];
429        for (int i=0; i<intents.length; i++) {
430            intents[i].migrateExtraStreamToClipData();
431            intents[i].prepareToLeaveProcess();
432            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
433        }
434        try {
435            IIntentSender target =
436                ActivityManagerNative.getDefault().getIntentSender(
437                    ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
438                    null, null, requestCode, intents, resolvedTypes,
439                    flags, options, user.getIdentifier());
440            return target != null ? new PendingIntent(target) : null;
441        } catch (RemoteException e) {
442        }
443        return null;
444    }
445
446    /**
447     * Retrieve a PendingIntent that will perform a broadcast, like calling
448     * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
449     *
450     * <p class="note">For security reasons, the {@link android.content.Intent}
451     * you supply here should almost always be an <em>explicit intent</em>,
452     * that is specify an explicit component to be delivered to through
453     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
454     *
455     * @param context The Context in which this PendingIntent should perform
456     * the broadcast.
457     * @param requestCode Private request code for the sender (currently
458     * not used).
459     * @param intent The Intent to be broadcast.
460     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
461     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
462     * or any of the flags as supported by
463     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
464     * of the intent that can be supplied when the actual send happens.
465     *
466     * @return Returns an existing or new PendingIntent matching the given
467     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
468     * supplied.
469     */
470    public static PendingIntent getBroadcast(Context context, int requestCode,
471            Intent intent, int flags) {
472        return getBroadcastAsUser(context, requestCode, intent, flags,
473                new UserHandle(UserHandle.myUserId()));
474    }
475
476    /**
477     * @hide
478     * Note that UserHandle.CURRENT will be interpreted at the time the
479     * broadcast is sent, not when the pending intent is created.
480     */
481    public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
482            Intent intent, int flags, UserHandle userHandle) {
483        String packageName = context.getPackageName();
484        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
485                context.getContentResolver()) : null;
486        try {
487            intent.prepareToLeaveProcess();
488            IIntentSender target =
489                ActivityManagerNative.getDefault().getIntentSender(
490                    ActivityManager.INTENT_SENDER_BROADCAST, packageName,
491                    null, null, requestCode, new Intent[] { intent },
492                    resolvedType != null ? new String[] { resolvedType } : null,
493                    flags, null, userHandle.getIdentifier());
494            return target != null ? new PendingIntent(target) : null;
495        } catch (RemoteException e) {
496        }
497        return null;
498    }
499
500    /**
501     * Retrieve a PendingIntent that will start a service, like calling
502     * {@link Context#startService Context.startService()}.  The start
503     * arguments given to the service will come from the extras of the Intent.
504     *
505     * <p class="note">For security reasons, the {@link android.content.Intent}
506     * you supply here should almost always be an <em>explicit intent</em>,
507     * that is specify an explicit component to be delivered to through
508     * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
509     *
510     * @param context The Context in which this PendingIntent should start
511     * the service.
512     * @param requestCode Private request code for the sender (currently
513     * not used).
514     * @param intent An Intent describing the service to be started.
515     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
516     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
517     * or any of the flags as supported by
518     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
519     * of the intent that can be supplied when the actual send happens.
520     *
521     * @return Returns an existing or new PendingIntent matching the given
522     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
523     * supplied.
524     */
525    public static PendingIntent getService(Context context, int requestCode,
526            Intent intent, int flags) {
527        String packageName = context.getPackageName();
528        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
529                context.getContentResolver()) : null;
530        try {
531            intent.prepareToLeaveProcess();
532            IIntentSender target =
533                ActivityManagerNative.getDefault().getIntentSender(
534                    ActivityManager.INTENT_SENDER_SERVICE, packageName,
535                    null, null, requestCode, new Intent[] { intent },
536                    resolvedType != null ? new String[] { resolvedType } : null,
537                    flags, null, UserHandle.myUserId());
538            return target != null ? new PendingIntent(target) : null;
539        } catch (RemoteException e) {
540        }
541        return null;
542    }
543
544    /**
545     * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
546     *
547     * @return Returns a IntentSender object that wraps the sender of PendingIntent
548     *
549     */
550    public IntentSender getIntentSender() {
551        return new IntentSender(mTarget);
552    }
553
554    /**
555     * Cancel a currently active PendingIntent.  Only the original application
556     * owning a PendingIntent can cancel it.
557     */
558    public void cancel() {
559        try {
560            ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
561        } catch (RemoteException e) {
562        }
563    }
564
565    /**
566     * Perform the operation associated with this PendingIntent.
567     *
568     * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
569     *
570     * @throws CanceledException Throws CanceledException if the PendingIntent
571     * is no longer allowing more intents to be sent through it.
572     */
573    public void send() throws CanceledException {
574        send(null, 0, null, null, null, null);
575    }
576
577    /**
578     * Perform the operation associated with this PendingIntent.
579     *
580     * @param code Result code to supply back to the PendingIntent's target.
581     *
582     * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
583     *
584     * @throws CanceledException Throws CanceledException if the PendingIntent
585     * is no longer allowing more intents to be sent through it.
586     */
587    public void send(int code) throws CanceledException {
588        send(null, code, null, null, null, null);
589    }
590
591    /**
592     * Perform the operation associated with this PendingIntent, allowing the
593     * caller to specify information about the Intent to use.
594     *
595     * @param context The Context of the caller.
596     * @param code Result code to supply back to the PendingIntent's target.
597     * @param intent Additional Intent data.  See {@link Intent#fillIn
598     * Intent.fillIn()} for information on how this is applied to the
599     * original Intent.
600     *
601     * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
602     *
603     * @throws CanceledException Throws CanceledException if the PendingIntent
604     * is no longer allowing more intents to be sent through it.
605     */
606    public void send(Context context, int code, Intent intent)
607            throws CanceledException {
608        send(context, code, intent, null, null, null);
609    }
610
611    /**
612     * Perform the operation associated with this PendingIntent, allowing the
613     * caller to be notified when the send has completed.
614     *
615     * @param code Result code to supply back to the PendingIntent's target.
616     * @param onFinished The object to call back on when the send has
617     * completed, or null for no callback.
618     * @param handler Handler identifying the thread on which the callback
619     * should happen.  If null, the callback will happen from the thread
620     * pool of the process.
621     *
622     * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
623     *
624     * @throws CanceledException Throws CanceledException if the PendingIntent
625     * is no longer allowing more intents to be sent through it.
626     */
627    public void send(int code, OnFinished onFinished, Handler handler)
628            throws CanceledException {
629        send(null, code, null, onFinished, handler, null);
630    }
631
632    /**
633     * Perform the operation associated with this PendingIntent, allowing the
634     * caller to specify information about the Intent to use and be notified
635     * when the send has completed.
636     *
637     * <p>For the intent parameter, a PendingIntent
638     * often has restrictions on which fields can be supplied here, based on
639     * how the PendingIntent was retrieved in {@link #getActivity},
640     * {@link #getBroadcast}, or {@link #getService}.
641     *
642     * @param context The Context of the caller.  This may be null if
643     * <var>intent</var> is also null.
644     * @param code Result code to supply back to the PendingIntent's target.
645     * @param intent Additional Intent data.  See {@link Intent#fillIn
646     * Intent.fillIn()} for information on how this is applied to the
647     * original Intent.  Use null to not modify the original Intent.
648     * @param onFinished The object to call back on when the send has
649     * completed, or null for no callback.
650     * @param handler Handler identifying the thread on which the callback
651     * should happen.  If null, the callback will happen from the thread
652     * pool of the process.
653     *
654     * @see #send()
655     * @see #send(int)
656     * @see #send(Context, int, Intent)
657     * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
658     * @see #send(Context, int, Intent, OnFinished, Handler, String)
659     *
660     * @throws CanceledException Throws CanceledException if the PendingIntent
661     * is no longer allowing more intents to be sent through it.
662     */
663    public void send(Context context, int code, Intent intent,
664            OnFinished onFinished, Handler handler) throws CanceledException {
665        send(context, code, intent, onFinished, handler, null);
666    }
667
668    /**
669     * Perform the operation associated with this PendingIntent, allowing the
670     * caller to specify information about the Intent to use and be notified
671     * when the send has completed.
672     *
673     * <p>For the intent parameter, a PendingIntent
674     * often has restrictions on which fields can be supplied here, based on
675     * how the PendingIntent was retrieved in {@link #getActivity},
676     * {@link #getBroadcast}, or {@link #getService}.
677     *
678     * @param context The Context of the caller.  This may be null if
679     * <var>intent</var> is also null.
680     * @param code Result code to supply back to the PendingIntent's target.
681     * @param intent Additional Intent data.  See {@link Intent#fillIn
682     * Intent.fillIn()} for information on how this is applied to the
683     * original Intent.  Use null to not modify the original Intent.
684     * @param onFinished The object to call back on when the send has
685     * completed, or null for no callback.
686     * @param handler Handler identifying the thread on which the callback
687     * should happen.  If null, the callback will happen from the thread
688     * pool of the process.
689     * @param requiredPermission Name of permission that a recipient of the PendingIntent
690     * is required to hold.  This is only valid for broadcast intents, and
691     * corresponds to the permission argument in
692     * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
693     * If null, no permission is required.
694     *
695     * @see #send()
696     * @see #send(int)
697     * @see #send(Context, int, Intent)
698     * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
699     * @see #send(Context, int, Intent, OnFinished, Handler)
700     *
701     * @throws CanceledException Throws CanceledException if the PendingIntent
702     * is no longer allowing more intents to be sent through it.
703     */
704    public void send(Context context, int code, Intent intent,
705            OnFinished onFinished, Handler handler, String requiredPermission)
706            throws CanceledException {
707        try {
708            String resolvedType = intent != null ?
709                    intent.resolveTypeIfNeeded(context.getContentResolver())
710                    : null;
711            int res = mTarget.send(code, intent, resolvedType,
712                    onFinished != null
713                            ? new FinishedDispatcher(this, onFinished, handler)
714                            : null,
715                    requiredPermission);
716            if (res < 0) {
717                throw new CanceledException();
718            }
719        } catch (RemoteException e) {
720            throw new CanceledException(e);
721        }
722    }
723
724    /**
725     * @deprecated Renamed to {@link #getCreatorPackage()}.
726     */
727    @Deprecated
728    public String getTargetPackage() {
729        try {
730            return ActivityManagerNative.getDefault()
731                .getPackageForIntentSender(mTarget);
732        } catch (RemoteException e) {
733            // Should never happen.
734            return null;
735        }
736    }
737
738    /**
739     * Return the package name of the application that created this
740     * PendingIntent, that is the identity under which you will actually be
741     * sending the Intent.  The returned string is supplied by the system, so
742     * that an application can not spoof its package.
743     *
744     * <p class="note">Be careful about how you use this.  All this tells you is
745     * who created the PendingIntent.  It does <strong>not</strong> tell you who
746     * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
747     * passed between applications, so the PendingIntent you receive from an application
748     * could actually be one it received from another application, meaning the result
749     * you get here will identify the original application.  Because of this, you should
750     * only use this information to identify who you expect to be interacting with
751     * through a {@link #send} call, not who gave you the PendingIntent.</p>
752     *
753     * @return The package name of the PendingIntent, or null if there is
754     * none associated with it.
755     */
756    public String getCreatorPackage() {
757        try {
758            return ActivityManagerNative.getDefault()
759                .getPackageForIntentSender(mTarget);
760        } catch (RemoteException e) {
761            // Should never happen.
762            return null;
763        }
764    }
765
766    /**
767     * Return the uid of the application that created this
768     * PendingIntent, that is the identity under which you will actually be
769     * sending the Intent.  The returned integer is supplied by the system, so
770     * that an application can not spoof its uid.
771     *
772     * <p class="note">Be careful about how you use this.  All this tells you is
773     * who created the PendingIntent.  It does <strong>not</strong> tell you who
774     * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
775     * passed between applications, so the PendingIntent you receive from an application
776     * could actually be one it received from another application, meaning the result
777     * you get here will identify the original application.  Because of this, you should
778     * only use this information to identify who you expect to be interacting with
779     * through a {@link #send} call, not who gave you the PendingIntent.</p>
780     *
781     * @return The uid of the PendingIntent, or -1 if there is
782     * none associated with it.
783     */
784    public int getCreatorUid() {
785        try {
786            return ActivityManagerNative.getDefault()
787                .getUidForIntentSender(mTarget);
788        } catch (RemoteException e) {
789            // Should never happen.
790            return -1;
791        }
792    }
793
794    /**
795     * Return the user handle of the application that created this
796     * PendingIntent, that is the user under which you will actually be
797     * sending the Intent.  The returned UserHandle is supplied by the system, so
798     * that an application can not spoof its user.  See
799     * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
800     * more explanation of user handles.
801     *
802     * <p class="note">Be careful about how you use this.  All this tells you is
803     * who created the PendingIntent.  It does <strong>not</strong> tell you who
804     * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
805     * passed between applications, so the PendingIntent you receive from an application
806     * could actually be one it received from another application, meaning the result
807     * you get here will identify the original application.  Because of this, you should
808     * only use this information to identify who you expect to be interacting with
809     * through a {@link #send} call, not who gave you the PendingIntent.</p>
810     *
811     * @return The user handle of the PendingIntent, or null if there is
812     * none associated with it.
813     */
814    public UserHandle getCreatorUserHandle() {
815        try {
816            int uid = ActivityManagerNative.getDefault()
817                .getUidForIntentSender(mTarget);
818            return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
819        } catch (RemoteException e) {
820            // Should never happen.
821            return null;
822        }
823    }
824
825    /**
826     * @hide
827     * Check to verify that this PendingIntent targets a specific package.
828     */
829    public boolean isTargetedToPackage() {
830        try {
831            return ActivityManagerNative.getDefault()
832                .isIntentSenderTargetedToPackage(mTarget);
833        } catch (RemoteException e) {
834            // Should never happen.
835            return false;
836        }
837    }
838
839    /**
840     * @hide
841     * Check whether this PendingIntent will launch an Activity.
842     */
843    public boolean isActivity() {
844        try {
845            return ActivityManagerNative.getDefault()
846                .isIntentSenderAnActivity(mTarget);
847        } catch (RemoteException e) {
848            // Should never happen.
849            return false;
850        }
851    }
852
853    /**
854     * @hide
855     * Return the Intent of this PendingIntent.
856     */
857    public Intent getIntent() {
858        try {
859            return ActivityManagerNative.getDefault()
860                .getIntentForIntentSender(mTarget);
861        } catch (RemoteException e) {
862            // Should never happen.
863            return null;
864        }
865    }
866
867    /**
868     * Comparison operator on two PendingIntent objects, such that true
869     * is returned then they both represent the same operation from the
870     * same package.  This allows you to use {@link #getActivity},
871     * {@link #getBroadcast}, or {@link #getService} multiple times (even
872     * across a process being killed), resulting in different PendingIntent
873     * objects but whose equals() method identifies them as being the same
874     * operation.
875     */
876    @Override
877    public boolean equals(Object otherObj) {
878        if (otherObj instanceof PendingIntent) {
879            return mTarget.asBinder().equals(((PendingIntent)otherObj)
880                    .mTarget.asBinder());
881        }
882        return false;
883    }
884
885    @Override
886    public int hashCode() {
887        return mTarget.asBinder().hashCode();
888    }
889
890    @Override
891    public String toString() {
892        StringBuilder sb = new StringBuilder(128);
893        sb.append("PendingIntent{");
894        sb.append(Integer.toHexString(System.identityHashCode(this)));
895        sb.append(": ");
896        sb.append(mTarget != null ? mTarget.asBinder() : null);
897        sb.append('}');
898        return sb.toString();
899    }
900
901    public int describeContents() {
902        return 0;
903    }
904
905    public void writeToParcel(Parcel out, int flags) {
906        out.writeStrongBinder(mTarget.asBinder());
907    }
908
909    public static final Parcelable.Creator<PendingIntent> CREATOR
910            = new Parcelable.Creator<PendingIntent>() {
911        public PendingIntent createFromParcel(Parcel in) {
912            IBinder target = in.readStrongBinder();
913            return target != null ? new PendingIntent(target) : null;
914        }
915
916        public PendingIntent[] newArray(int size) {
917            return new PendingIntent[size];
918        }
919    };
920
921    /**
922     * Convenience function for writing either a PendingIntent or null pointer to
923     * a Parcel.  You must use this with {@link #readPendingIntentOrNullFromParcel}
924     * for later reading it.
925     *
926     * @param sender The PendingIntent to write, or null.
927     * @param out Where to write the PendingIntent.
928     */
929    public static void writePendingIntentOrNullToParcel(PendingIntent sender,
930            Parcel out) {
931        out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
932                : null);
933    }
934
935    /**
936     * Convenience function for reading either a Messenger or null pointer from
937     * a Parcel.  You must have previously written the Messenger with
938     * {@link #writePendingIntentOrNullToParcel}.
939     *
940     * @param in The Parcel containing the written Messenger.
941     *
942     * @return Returns the Messenger read from the Parcel, or null if null had
943     * been written.
944     */
945    public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
946        IBinder b = in.readStrongBinder();
947        return b != null ? new PendingIntent(b) : null;
948    }
949
950    /*package*/ PendingIntent(IIntentSender target) {
951        mTarget = target;
952    }
953
954    /*package*/ PendingIntent(IBinder target) {
955        mTarget = IIntentSender.Stub.asInterface(target);
956    }
957
958    /** @hide */
959    public IIntentSender getTarget() {
960        return mTarget;
961    }
962}
963