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