1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import android.annotation.IntDef; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.content.Context; 23import android.content.Intent; 24import android.content.IIntentReceiver; 25import android.content.IIntentSender; 26import android.content.IntentSender; 27import android.os.Bundle; 28import android.os.Looper; 29import android.os.RemoteException; 30import android.os.Handler; 31import android.os.IBinder; 32import android.os.Parcel; 33import android.os.Parcelable; 34import android.os.Process; 35import android.os.UserHandle; 36import android.util.AndroidException; 37 38import java.lang.annotation.Retention; 39import 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 */ 94public 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 { 169 public CanceledException() { 170 } 171 172 public CanceledException(String name) { 173 super(name); 174 } 175 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 */ 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; 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 } 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 } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 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 1057 public int hashCode() { 1058 return mTarget.asBinder().hashCode(); 1059 } 1060 1061 @Override 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 1072 public int describeContents() { 1073 return 0; 1074 } 1075 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 */ 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 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 1129 /*package*/ PendingIntent(IIntentSender target) { 1130 mTarget = target; 1131 } 1132 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 */ 1141 public IIntentSender getTarget() { 1142 return mTarget; 1143 } 1144 1145 /** @hide */ 1146 public IBinder getWhitelistToken() { 1147 return mWhitelistToken; 1148 } 1149} 1150