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