Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.content.IIntentReceiver;
     22 import android.content.IIntentSender;
     23 import android.content.IntentSender;
     24 import android.os.Bundle;
     25 import android.os.RemoteException;
     26 import android.os.Handler;
     27 import android.os.IBinder;
     28 import android.os.Parcel;
     29 import android.os.Parcelable;
     30 import android.os.UserHandle;
     31 import 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  */
     86 public 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