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