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