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 static android.app.ActivityManager.INTENT_SENDER_ACTIVITY; 20 import static android.app.ActivityManager.INTENT_SENDER_BROADCAST; 21 import static android.app.ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE; 22 import static android.app.ActivityManager.INTENT_SENDER_SERVICE; 23 24 import android.Manifest.permission; 25 import android.annotation.IntDef; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.annotation.RequiresPermission; 29 import android.annotation.SystemApi; 30 import android.annotation.SystemApi.Client; 31 import android.annotation.TestApi; 32 import android.app.ActivityManager.PendingIntentInfo; 33 import android.compat.Compatibility; 34 import android.compat.annotation.ChangeId; 35 import android.compat.annotation.EnabledAfter; 36 import android.compat.annotation.EnabledSince; 37 import android.compat.annotation.Overridable; 38 import android.compat.annotation.UnsupportedAppUsage; 39 import android.content.Context; 40 import android.content.IIntentReceiver; 41 import android.content.IIntentSender; 42 import android.content.Intent; 43 import android.content.IntentSender; 44 import android.content.pm.PackageManager.ResolveInfoFlagsBits; 45 import android.content.pm.ParceledListSlice; 46 import android.content.pm.ResolveInfo; 47 import android.os.Build; 48 import android.os.Bundle; 49 import android.os.Handler; 50 import android.os.IBinder; 51 import android.os.Looper; 52 import android.os.Parcel; 53 import android.os.Parcelable; 54 import android.os.RemoteException; 55 import android.os.UserHandle; 56 import android.util.AndroidException; 57 import android.util.ArraySet; 58 import android.util.Log; 59 import android.util.Pair; 60 import android.util.proto.ProtoOutputStream; 61 62 import com.android.internal.annotations.GuardedBy; 63 import com.android.internal.os.IResultReceiver; 64 65 import java.lang.annotation.Retention; 66 import java.lang.annotation.RetentionPolicy; 67 import java.util.ArrayList; 68 import java.util.Collections; 69 import java.util.List; 70 import java.util.Objects; 71 import java.util.concurrent.Executor; 72 73 /** 74 * A description of an Intent and target action to perform with it. Instances 75 * of this class are created with {@link #getActivity}, {@link #getActivities}, 76 * {@link #getBroadcast}, and {@link #getService}; the returned object can be 77 * handed to other applications so that they can perform the action you 78 * described on your behalf at a later time. 79 * 80 * <p>By giving a PendingIntent to another application, 81 * you are granting it the right to perform the operation you have specified 82 * as if the other application was yourself (with the same permissions and 83 * identity). As such, you should be careful about how you build the PendingIntent: 84 * almost always, for example, the base Intent you supply should have the component 85 * name explicitly set to one of your own components, to ensure it is ultimately 86 * sent there and nowhere else. 87 * 88 * <p>A PendingIntent itself is simply a reference to a token maintained by 89 * the system describing the original data used to retrieve it. This means 90 * that, even if its owning application's process is killed, the 91 * PendingIntent itself will remain usable from other processes that 92 * have been given it. If the creating application later re-retrieves the 93 * same kind of PendingIntent (same operation, same Intent action, data, 94 * categories, and components, and same flags), it will receive a PendingIntent 95 * representing the same token if that is still valid, and can thus call 96 * {@link #cancel} to remove it. 97 * 98 * <p>Because of this behavior, it is important to know when two Intents 99 * are considered to be the same for purposes of retrieving a PendingIntent. 100 * A common mistake people make is to create multiple PendingIntent objects 101 * with Intents that only vary in their "extra" contents, expecting to get 102 * a different PendingIntent each time. This does <em>not</em> happen. The 103 * parts of the Intent that are used for matching are the same ones defined 104 * by {@link Intent#filterEquals(Intent) Intent.filterEquals}. If you use two 105 * Intent objects that are equivalent as per 106 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get 107 * the same PendingIntent for both of them. 108 * 109 * <p>There are two typical ways to deal with this. 110 * 111 * <p>If you truly need multiple distinct PendingIntent objects active at 112 * the same time (such as to use as two notifications that are both shown 113 * at the same time), then you will need to ensure there is something that 114 * is different about them to associate them with different PendingIntents. 115 * This may be any of the Intent attributes considered by 116 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different 117 * request code integers supplied to {@link #getActivity}, {@link #getActivities}, 118 * {@link #getBroadcast}, or {@link #getService}. 119 * 120 * <p>If you only need one PendingIntent active at a time for any of the 121 * Intents you will use, then you can alternatively use the flags 122 * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either 123 * cancel or modify whatever current PendingIntent is associated with the 124 * Intent you are supplying. 125 * 126 * <p>Also note that flags like {@link #FLAG_ONE_SHOT} or {@link #FLAG_IMMUTABLE} describe the 127 * PendingIntent instance and thus, are used to identify it. Any calls to retrieve or modify a 128 * PendingIntent created with these flags will also require these flags to be supplied in 129 * conjunction with others. E.g. To retrieve an existing PendingIntent created with 130 * FLAG_ONE_SHOT, <b>both</b> FLAG_ONE_SHOT and FLAG_NO_CREATE need to be supplied. 131 */ 132 public final class PendingIntent implements Parcelable { 133 private static final String TAG = "PendingIntent"; 134 @NonNull 135 private final IIntentSender mTarget; 136 private IBinder mWhitelistToken; 137 138 // cached pending intent information 139 private @Nullable PendingIntentInfo mCachedInfo; 140 141 /** 142 * Structure to store information related to {@link #addCancelListener}, which is rarely used, 143 * so we lazily allocate it to keep the PendingIntent class size small. 144 */ 145 private final class CancelListerInfo extends IResultReceiver.Stub { 146 private final ArraySet<Pair<Executor, CancelListener>> mCancelListeners = new ArraySet<>(); 147 148 /** 149 * Whether the PI is canceled or not. Note this is essentially a "cache" that's updated 150 * only when the client uses {@link #addCancelListener}. Even if this is false, that 151 * still doesn't know the PI is *not* canceled, but if it's true, this PI is definitely 152 * canceled. 153 */ 154 private boolean mCanceled; 155 156 @Override send(int resultCode, Bundle resultData)157 public void send(int resultCode, Bundle resultData) throws RemoteException { 158 notifyCancelListeners(); 159 } 160 } 161 162 @GuardedBy("mTarget") 163 private @Nullable CancelListerInfo mCancelListerInfo; 164 165 /** 166 * It is now required to specify either {@link #FLAG_IMMUTABLE} 167 * or {@link #FLAG_MUTABLE} when creating a PendingIntent. 168 */ 169 @ChangeId 170 @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.R) 171 static final long PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED = 160794467L; 172 173 /** @hide */ 174 @ChangeId 175 @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 176 @Overridable 177 public static final long BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT = 236704164L; 178 179 /** 180 * Validate options passed in as bundle. 181 * @hide 182 */ 183 @ChangeId 184 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 185 public static final long PENDING_INTENT_OPTIONS_CHECK = 320664730L; 186 187 /** @hide */ 188 @IntDef(flag = true, 189 value = { 190 FLAG_ONE_SHOT, 191 FLAG_NO_CREATE, 192 FLAG_CANCEL_CURRENT, 193 FLAG_UPDATE_CURRENT, 194 FLAG_IMMUTABLE, 195 FLAG_MUTABLE, 196 FLAG_MUTABLE_UNAUDITED, 197 FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT, 198 199 Intent.FILL_IN_ACTION, 200 Intent.FILL_IN_DATA, 201 Intent.FILL_IN_CATEGORIES, 202 Intent.FILL_IN_COMPONENT, 203 Intent.FILL_IN_PACKAGE, 204 Intent.FILL_IN_SOURCE_BOUNDS, 205 Intent.FILL_IN_SELECTOR, 206 Intent.FILL_IN_CLIP_DATA 207 }) 208 @Retention(RetentionPolicy.SOURCE) 209 public @interface Flags {} 210 211 /** 212 * Flag indicating that this PendingIntent can be used only once. 213 * For use with {@link #getActivity}, {@link #getBroadcast}, and 214 * {@link #getService}. <p>If set, after 215 * {@link #send()} is called on it, it will be automatically 216 * canceled for you and any future attempt to send through it will fail. 217 */ 218 public static final int FLAG_ONE_SHOT = 1<<30; 219 /** 220 * Flag indicating that if the described PendingIntent does not 221 * already exist, then simply return null instead of creating it. 222 * For use with {@link #getActivity}, {@link #getBroadcast}, and 223 * {@link #getService}. 224 */ 225 public static final int FLAG_NO_CREATE = 1<<29; 226 /** 227 * Flag indicating that if the described PendingIntent already exists, 228 * the current one should be canceled before generating a new one. 229 * For use with {@link #getActivity}, {@link #getBroadcast}, and 230 * {@link #getService}. <p>You can use 231 * this to retrieve a new PendingIntent when you are only changing the 232 * extra data in the Intent; by canceling the previous pending intent, 233 * this ensures that only entities given the new data will be able to 234 * launch it. If this assurance is not an issue, consider 235 * {@link #FLAG_UPDATE_CURRENT}. 236 */ 237 public static final int FLAG_CANCEL_CURRENT = 1<<28; 238 /** 239 * Flag indicating that if the described PendingIntent already exists, 240 * then keep it but replace its extra data with what is in this new 241 * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and 242 * {@link #getService}. <p>This can be used if you are creating intents where only the 243 * extras change, and don't care that any entities that received your 244 * previous PendingIntent will be able to launch it with your new 245 * extras even if they are not explicitly given to it. 246 * 247 * <p>{@link #FLAG_UPDATE_CURRENT} still works even if {@link 248 * #FLAG_IMMUTABLE} is set - the creator of the PendingIntent can always 249 * update the PendingIntent itself. The IMMUTABLE flag only limits the 250 * ability to alter the semantics of the intent that is sent by {@link 251 * #send} by the invoker of {@link #send}. 252 */ 253 public static final int FLAG_UPDATE_CURRENT = 1<<27; 254 255 /** 256 * Flag indicating that the created PendingIntent should be immutable. 257 * This means that the additional intent argument passed to the send 258 * methods to fill in unpopulated properties of this intent will be 259 * ignored. 260 * 261 * <p>{@link #FLAG_IMMUTABLE} only limits the ability to alter the 262 * semantics of the intent that is sent by {@link #send} by the invoker of 263 * {@link #send}. The creator of the PendingIntent can always update the 264 * PendingIntent itself via {@link #FLAG_UPDATE_CURRENT}. 265 */ 266 public static final int FLAG_IMMUTABLE = 1<<26; 267 268 /** 269 * Flag indicating that the created PendingIntent should be mutable. 270 * This flag cannot be combined with {@link #FLAG_IMMUTABLE}. <p>Up until 271 * {@link android.os.Build.VERSION_CODES#R}, PendingIntents are assumed to 272 * be mutable by default, unless {@link #FLAG_IMMUTABLE} is set. Starting 273 * with {@link android.os.Build.VERSION_CODES#S}, it will be required to 274 * explicitly specify the mutability of PendingIntents on creation with 275 * either {@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE}. It is strongly 276 * recommended to use {@link #FLAG_IMMUTABLE} when creating a 277 * PendingIntent. {@link #FLAG_MUTABLE} should only be used when some 278 * functionality relies on modifying the underlying intent, e.g. any 279 * PendingIntent that needs to be used with inline reply or bubbles. 280 */ 281 public static final int FLAG_MUTABLE = 1<<25; 282 283 /** 284 * @deprecated Use {@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE} instead. 285 * @hide 286 */ 287 @Deprecated 288 @TestApi 289 public static final int FLAG_MUTABLE_UNAUDITED = FLAG_MUTABLE; 290 291 /** 292 * Flag indicating that the created PendingIntent with {@link #FLAG_MUTABLE} 293 * is allowed to have an unsafe implicit Intent within. <p>Starting with 294 * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, for apps that 295 * target SDK {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or 296 * higher, creation of a PendingIntent with {@link #FLAG_MUTABLE} and an 297 * implicit Intent within will throw an {@link IllegalArgumentException} 298 * for security reasons. To bypass this check, use 299 * {@link #FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT} when creating a PendingIntent. 300 * However, it is strongly recommended to not to use this flag and make the 301 * Intent explicit or the PendingIntent immutable, thereby making the Intent 302 * safe. 303 */ 304 public static final int FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT = 1<<24; 305 306 /** 307 * Exception thrown when trying to send through a PendingIntent that 308 * has been canceled or is otherwise no longer able to execute the request. 309 */ 310 public static class CanceledException extends AndroidException { CanceledException()311 public CanceledException() { 312 } 313 CanceledException(String name)314 public CanceledException(String name) { 315 super(name); 316 } 317 CanceledException(Exception cause)318 public CanceledException(Exception cause) { 319 super(cause); 320 } 321 } 322 323 /** 324 * Callback interface for discovering when a send operation has 325 * completed. Primarily for use with a PendingIntent that is 326 * performing a broadcast, this provides the same information as 327 * calling {@link Context#sendOrderedBroadcast(Intent, String, 328 * android.content.BroadcastReceiver, Handler, int, String, Bundle) 329 * Context.sendBroadcast()} with a final BroadcastReceiver. 330 */ 331 public interface OnFinished { 332 /** 333 * Called when a send operation as completed. 334 * 335 * @param pendingIntent The PendingIntent this operation was sent through. 336 * @param intent The original Intent that was sent. 337 * @param resultCode The final result code determined by the send. 338 * @param resultData The final data collected by a broadcast. 339 * @param resultExtras The final extras collected by a broadcast. 340 */ onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)341 void onSendFinished(PendingIntent pendingIntent, Intent intent, 342 int resultCode, String resultData, Bundle resultExtras); 343 } 344 345 private static class FinishedDispatcher extends IIntentReceiver.Stub 346 implements Runnable { 347 private final PendingIntent mPendingIntent; 348 private final OnFinished mWho; 349 private final Handler mHandler; 350 private Intent mIntent; 351 private int mResultCode; 352 private String mResultData; 353 private Bundle mResultExtras; 354 private static Handler sDefaultSystemHandler; FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler)355 FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) { 356 mPendingIntent = pi; 357 mWho = who; 358 if (handler == null && ActivityThread.isSystem()) { 359 // We assign a default handler for the system process to avoid deadlocks when 360 // processing receivers in various components that hold global service locks. 361 if (sDefaultSystemHandler == null) { 362 sDefaultSystemHandler = new Handler(Looper.getMainLooper()); 363 } 364 mHandler = sDefaultSystemHandler; 365 } else { 366 mHandler = handler; 367 } 368 } performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean serialized, boolean sticky, int sendingUser)369 public void performReceive(Intent intent, int resultCode, String data, 370 Bundle extras, boolean serialized, boolean sticky, int sendingUser) { 371 mIntent = intent; 372 mResultCode = resultCode; 373 mResultData = data; 374 mResultExtras = extras; 375 if (mHandler == null) { 376 run(); 377 } else { 378 mHandler.post(this); 379 } 380 } run()381 public void run() { 382 mWho.onSendFinished(mPendingIntent, mIntent, mResultCode, 383 mResultData, mResultExtras); 384 } 385 } 386 387 /** 388 * Listener for observing when pending intents are written to a parcel. 389 * 390 * @hide 391 */ 392 public interface OnMarshaledListener { 393 /** 394 * Called when a pending intent is written to a parcel. 395 * 396 * @param intent The pending intent. 397 * @param parcel The parcel to which it was written. 398 * @param flags The parcel flags when it was written. 399 */ onMarshaled(PendingIntent intent, Parcel parcel, int flags)400 void onMarshaled(PendingIntent intent, Parcel parcel, int flags); 401 } 402 403 private static final ThreadLocal<List<OnMarshaledListener>> sOnMarshaledListener = 404 ThreadLocal.withInitial(ArrayList::new); 405 406 /** 407 * Registers an listener for pending intents being written to a parcel. This replaces any 408 * listeners previously added. 409 * 410 * @param listener The listener, null to clear. 411 * 412 * @hide 413 */ 414 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setOnMarshaledListener(OnMarshaledListener listener)415 public static void setOnMarshaledListener(OnMarshaledListener listener) { 416 final List<OnMarshaledListener> listeners = sOnMarshaledListener.get(); 417 listeners.clear(); 418 if (listener != null) { 419 listeners.add(listener); 420 } 421 } 422 423 /** 424 * Adds a listener for pending intents being written to a parcel. 425 * @hide 426 */ addOnMarshaledListener(OnMarshaledListener listener)427 static void addOnMarshaledListener(OnMarshaledListener listener) { 428 sOnMarshaledListener.get().add(listener); 429 } 430 431 /** 432 * Removes a listener for pending intents being written to a parcel. 433 * @hide 434 */ removeOnMarshaledListener(OnMarshaledListener listener)435 static void removeOnMarshaledListener(OnMarshaledListener listener) { 436 sOnMarshaledListener.get().remove(listener); 437 } 438 checkPendingIntent(int flags, @NonNull Intent intent, @NonNull Context context, boolean isActivityResultType)439 private static void checkPendingIntent(int flags, @NonNull Intent intent, 440 @NonNull Context context, boolean isActivityResultType) { 441 final boolean isFlagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0; 442 final boolean isFlagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0; 443 final String packageName = context.getPackageName(); 444 445 if (isFlagImmutableSet && isFlagMutableSet) { 446 throw new IllegalArgumentException( 447 "Cannot set both FLAG_IMMUTABLE and FLAG_MUTABLE for PendingIntent"); 448 } 449 450 if (Compatibility.isChangeEnabled(PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED) 451 && !isFlagImmutableSet && !isFlagMutableSet) { 452 String msg = packageName + ": Targeting S+ (version " + Build.VERSION_CODES.S 453 + " and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE" 454 + " be specified when creating a PendingIntent.\nStrongly consider" 455 + " using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality" 456 + " depends on the PendingIntent being mutable, e.g. if it needs to" 457 + " be used with inline replies or bubbles."; 458 throw new IllegalArgumentException(msg); 459 } 460 461 // For apps with target SDK < U, warn that creation or retrieval of a mutable implicit 462 // PendingIntent that is not of type {@link ActivityManager#INTENT_SENDER_ACTIVITY_RESULT} 463 // will be blocked from target SDK U onwards for security reasons. The block itself 464 // happens on the server side, but this warning has to stay here to preserve the client 465 // side stack trace for app developers. 466 if (isNewMutableDisallowedImplicitPendingIntent(flags, intent, isActivityResultType) 467 && !Compatibility.isChangeEnabled(BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT)) { 468 String msg = "New mutable implicit PendingIntent: pkg=" + packageName 469 + ", action=" + intent.getAction() 470 + ", featureId=" + context.getAttributionTag() 471 + ". This will be blocked once the app targets U+" 472 + " for security reasons."; 473 Log.w(TAG, new StackTrace(msg)); 474 } 475 } 476 477 /** @hide */ isNewMutableDisallowedImplicitPendingIntent(int flags, @NonNull Intent intent, boolean isActivityResultType)478 public static boolean isNewMutableDisallowedImplicitPendingIntent(int flags, 479 @NonNull Intent intent, boolean isActivityResultType) { 480 if (isActivityResultType) { 481 // Pending intents of type {@link ActivityManager#INTENT_SENDER_ACTIVITY_RESULT} 482 // should be ignored as they are intrinsically tied to a target which means they 483 // are already explicit. 484 return false; 485 } 486 boolean isFlagNoCreateSet = (flags & PendingIntent.FLAG_NO_CREATE) != 0; 487 boolean isFlagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0; 488 boolean isImplicit = (intent.getComponent() == null) && (intent.getPackage() == null); 489 boolean isFlagAllowUnsafeImplicitIntentSet = 490 (flags & PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT) != 0; 491 return !isFlagNoCreateSet && isFlagMutableSet && isImplicit 492 && !isFlagAllowUnsafeImplicitIntentSet; 493 } 494 495 /** 496 * Retrieve a PendingIntent that will start a new activity, like calling 497 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 498 * Note that the activity will be started outside of the context of an 499 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 500 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 501 * 502 * <p class="note">For security reasons, the {@link android.content.Intent} 503 * you supply here should almost always be an <em>explicit intent</em>, 504 * that is specify an explicit component to be delivered to through 505 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 506 * 507 * @param context The Context in which this PendingIntent should start 508 * the activity. 509 * @param requestCode Private request code for the sender 510 * @param intent Intent of the activity to be launched. 511 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 512 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 513 * or any of the flags as supported by 514 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 515 * of the intent that can be supplied when the actual send happens. 516 * 517 * @return Returns an existing or new PendingIntent matching the given 518 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 519 * supplied. 520 */ 521 @SuppressWarnings("AndroidFrameworkPendingIntentMutability") getActivity(Context context, int requestCode, Intent intent, @Flags int flags)522 public static PendingIntent getActivity(Context context, int requestCode, 523 Intent intent, @Flags int flags) { 524 return getActivity(context, requestCode, intent, flags, null); 525 } 526 527 /** 528 * Retrieve a PendingIntent that will start a new activity, like calling 529 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 530 * Note that the activity will be started outside of the context of an 531 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 532 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 533 * 534 * <p class="note">For security reasons, the {@link android.content.Intent} 535 * you supply here should almost always be an <em>explicit intent</em>, 536 * that is specify an explicit component to be delivered to through 537 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 538 * 539 * @param context The Context in which this PendingIntent should start 540 * the activity. 541 * @param requestCode Private request code for the sender 542 * @param intent Intent of the activity to be launched. 543 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 544 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 545 * or any of the flags as supported by 546 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 547 * of the intent that can be supplied when the actual send happens. 548 * @param options Additional options for how the Activity should be started. 549 * May be null if there are no options. 550 * 551 * @return Returns an existing or new PendingIntent matching the given 552 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 553 * supplied. 554 */ 555 @SuppressWarnings("AndroidFrameworkPendingIntentMutability") getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)556 public static PendingIntent getActivity(Context context, int requestCode, 557 @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) { 558 // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null 559 final UserHandle user = context.getUser(); 560 return getActivityAsUser(context, requestCode, intent, flags, options, 561 user != null ? user : UserHandle.of(context.getUserId())); 562 } 563 564 /** 565 * @hide 566 * Note that UserHandle.CURRENT will be interpreted at the time the 567 * activity is started, not when the pending intent is created. 568 */ 569 @UnsupportedAppUsage getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)570 public static PendingIntent getActivityAsUser(Context context, int requestCode, 571 @NonNull Intent intent, int flags, Bundle options, UserHandle user) { 572 String packageName = context.getPackageName(); 573 String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver()); 574 checkPendingIntent(flags, intent, context, /* isActivityResultType */ false); 575 try { 576 intent.migrateExtraStreamToClipData(context); 577 intent.prepareToLeaveProcess(context); 578 IIntentSender target = 579 ActivityManager.getService().getIntentSenderWithFeature( 580 INTENT_SENDER_ACTIVITY, packageName, 581 context.getAttributionTag(), null, null, requestCode, new Intent[] { intent }, 582 resolvedType != null ? new String[] { resolvedType } : null, 583 flags, options, user.getIdentifier()); 584 return target != null ? new PendingIntent(target) : null; 585 } catch (RemoteException e) { 586 throw e.rethrowFromSystemServer(); 587 } 588 } 589 590 /** 591 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 592 * array of Intents to be supplied. The last Intent in the array is 593 * taken as the primary key for the PendingIntent, like the single Intent 594 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 595 * the resulting PendingIntent, all of the Intents are started in the same 596 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 597 * 598 * <p class="note"> 599 * The <em>first</em> intent in the array will be started outside of the context of an 600 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 601 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 602 * the first in the array are started in the context of the previous activity 603 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 604 * </p> 605 * 606 * <p class="note"> 607 * The <em>last</em> intent in the array represents the key for the 608 * PendingIntent. In other words, it is the significant element for matching 609 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 610 * its content will be the subject of replacement by 611 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 612 * This is because it is the most specific of the supplied intents, and the 613 * UI the user actually sees when the intents are started. 614 * </p> 615 * 616 * <p class="note">For security reasons, the {@link android.content.Intent} objects 617 * you supply here should almost always be <em>explicit intents</em>, 618 * that is specify an explicit component to be delivered to through 619 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 620 * 621 * @param context The Context in which this PendingIntent should start 622 * the activity. 623 * @param requestCode Private request code for the sender 624 * @param intents Array of Intents of the activities to be launched. 625 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 626 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 627 * or any of the flags as supported by 628 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 629 * of the intent that can be supplied when the actual send happens. 630 * 631 * @return Returns an existing or new PendingIntent matching the given 632 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 633 * supplied. 634 */ 635 @SuppressWarnings("AndroidFrameworkPendingIntentMutability") getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)636 public static PendingIntent getActivities(Context context, int requestCode, 637 @NonNull Intent[] intents, @Flags int flags) { 638 return getActivities(context, requestCode, intents, flags, null); 639 } 640 641 /** 642 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 643 * array of Intents to be supplied. The last Intent in the array is 644 * taken as the primary key for the PendingIntent, like the single Intent 645 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 646 * the resulting PendingIntent, all of the Intents are started in the same 647 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 648 * 649 * <p class="note"> 650 * The <em>first</em> intent in the array will be started outside of the context of an 651 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 652 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 653 * the first in the array are started in the context of the previous activity 654 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 655 * </p> 656 * 657 * <p class="note"> 658 * The <em>last</em> intent in the array represents the key for the 659 * PendingIntent. In other words, it is the significant element for matching 660 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 661 * its content will be the subject of replacement by 662 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 663 * This is because it is the most specific of the supplied intents, and the 664 * UI the user actually sees when the intents are started. 665 * </p> 666 * 667 * <p class="note">For security reasons, the {@link android.content.Intent} objects 668 * you supply here should almost always be <em>explicit intents</em>, 669 * that is specify an explicit component to be delivered to through 670 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 671 * 672 * @param context The Context in which this PendingIntent should start 673 * the activity. 674 * @param requestCode Private request code for the sender 675 * @param intents Array of Intents of the activities to be launched. 676 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 677 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 678 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 679 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 680 * of the intent that can be supplied when the actual send happens. 681 * 682 * @return Returns an existing or new PendingIntent matching the given 683 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 684 * supplied. 685 */ 686 @SuppressWarnings("AndroidFrameworkPendingIntentMutability") getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)687 public static PendingIntent getActivities(Context context, int requestCode, 688 @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) { 689 // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null 690 final UserHandle user = context.getUser(); 691 return getActivitiesAsUser(context, requestCode, intents, flags, options, 692 user != null ? user : UserHandle.of(context.getUserId())); 693 } 694 695 /** 696 * @hide 697 * Note that UserHandle.CURRENT will be interpreted at the time the 698 * activity is started, not when the pending intent is created. 699 */ getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)700 public static PendingIntent getActivitiesAsUser(Context context, int requestCode, 701 @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { 702 String packageName = context.getPackageName(); 703 String[] resolvedTypes = new String[intents.length]; 704 for (int i=0; i<intents.length; i++) { 705 intents[i].migrateExtraStreamToClipData(context); 706 intents[i].prepareToLeaveProcess(context); 707 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver()); 708 checkPendingIntent(flags, intents[i], context, /* isActivityResultType */ false); 709 } 710 try { 711 IIntentSender target = 712 ActivityManager.getService().getIntentSenderWithFeature( 713 INTENT_SENDER_ACTIVITY, packageName, 714 context.getAttributionTag(), null, null, requestCode, intents, resolvedTypes, 715 flags, options, user.getIdentifier()); 716 return target != null ? new PendingIntent(target) : null; 717 } catch (RemoteException e) { 718 throw e.rethrowFromSystemServer(); 719 } 720 } 721 722 /** 723 * Retrieve a PendingIntent that will perform a broadcast, like calling 724 * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}. 725 * 726 * <p class="note">For security reasons, the {@link android.content.Intent} 727 * you supply here should almost always be an <em>explicit intent</em>, 728 * that is specify an explicit component to be delivered to through 729 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 730 * 731 * @param context The Context in which this PendingIntent should perform 732 * the broadcast. 733 * @param requestCode Private request code for the sender 734 * @param intent The Intent to be broadcast. 735 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 736 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 737 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 738 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 739 * of the intent that can be supplied when the actual send happens. 740 * 741 * @return Returns an existing or new PendingIntent matching the given 742 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 743 * supplied. 744 */ 745 @SuppressWarnings("AndroidFrameworkPendingIntentMutability") getBroadcast(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)746 public static PendingIntent getBroadcast(Context context, int requestCode, 747 @NonNull Intent intent, @Flags int flags) { 748 return getBroadcastAsUser(context, requestCode, intent, flags, context.getUser()); 749 } 750 751 /** 752 * @hide 753 * Note that UserHandle.CURRENT will be interpreted at the time the 754 * broadcast is sent, not when the pending intent is created. 755 */ 756 @UnsupportedAppUsage getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)757 public static PendingIntent getBroadcastAsUser(Context context, int requestCode, 758 Intent intent, int flags, UserHandle userHandle) { 759 String packageName = context.getPackageName(); 760 String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver()); 761 checkPendingIntent(flags, intent, context, /* isActivityResultType */ false); 762 try { 763 intent.prepareToLeaveProcess(context); 764 IIntentSender target = 765 ActivityManager.getService().getIntentSenderWithFeature( 766 INTENT_SENDER_BROADCAST, packageName, 767 context.getAttributionTag(), null, null, requestCode, new Intent[] { intent }, 768 resolvedType != null ? new String[] { resolvedType } : null, 769 flags, null, userHandle.getIdentifier()); 770 return target != null ? new PendingIntent(target) : null; 771 } catch (RemoteException e) { 772 throw e.rethrowFromSystemServer(); 773 } 774 } 775 776 /** 777 * Retrieve a PendingIntent that will start a service, like calling 778 * {@link Context#startService Context.startService()}. The start 779 * arguments given to the service will come from the extras of the Intent. 780 * 781 * <p class="note">For security reasons, the {@link android.content.Intent} 782 * you supply here should almost always be an <em>explicit intent</em>, 783 * that is specify an explicit component to be delivered to through 784 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 785 * 786 * @param context The Context in which this PendingIntent should start 787 * the service. 788 * @param requestCode Private request code for the sender 789 * @param intent An Intent describing the service to be started. 790 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 791 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 792 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 793 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 794 * of the intent that can be supplied when the actual send happens. 795 * 796 * @return Returns an existing or new PendingIntent matching the given 797 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 798 * supplied. 799 */ getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)800 public static PendingIntent getService(Context context, int requestCode, 801 @NonNull Intent intent, @Flags int flags) { 802 return buildServicePendingIntent(context, requestCode, intent, flags, 803 INTENT_SENDER_SERVICE); 804 } 805 806 /** 807 * Retrieve a PendingIntent that will start a foreground service, like calling 808 * {@link Context#startForegroundService Context.startForegroundService()}. The start 809 * arguments given to the service will come from the extras of the Intent. 810 * 811 * <p class="note">For security reasons, the {@link android.content.Intent} 812 * you supply here should almost always be an <em>explicit intent</em>, 813 * that is specify an explicit component to be delivered to through 814 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 815 * 816 * @param context The Context in which this PendingIntent should start 817 * the service. 818 * @param requestCode Private request code for the sender 819 * @param intent An Intent describing the service to be started. 820 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 821 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 822 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 823 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 824 * of the intent that can be supplied when the actual send happens. 825 * 826 * @return Returns an existing or new PendingIntent matching the given 827 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 828 * supplied. 829 */ getForegroundService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)830 public static PendingIntent getForegroundService(Context context, int requestCode, 831 @NonNull Intent intent, @Flags int flags) { 832 return buildServicePendingIntent(context, requestCode, intent, flags, 833 INTENT_SENDER_FOREGROUND_SERVICE); 834 } 835 buildServicePendingIntent(Context context, int requestCode, Intent intent, int flags, int serviceKind)836 private static PendingIntent buildServicePendingIntent(Context context, int requestCode, 837 Intent intent, int flags, int serviceKind) { 838 String packageName = context.getPackageName(); 839 String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver()); 840 checkPendingIntent(flags, intent, context, /* isActivityResultType */ false); 841 try { 842 intent.prepareToLeaveProcess(context); 843 IIntentSender target = 844 ActivityManager.getService().getIntentSenderWithFeature( 845 serviceKind, packageName, context.getAttributionTag(), 846 null, null, requestCode, new Intent[] { intent }, 847 resolvedType != null ? new String[] { resolvedType } : null, 848 flags, null, context.getUserId()); 849 return target != null ? new PendingIntent(target) : null; 850 } catch (RemoteException e) { 851 throw e.rethrowFromSystemServer(); 852 } 853 } 854 855 /** 856 * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent 857 * 858 * @return Returns a IntentSender object that wraps the sender of PendingIntent 859 * 860 */ 861 @NonNull getIntentSender()862 public IntentSender getIntentSender() { 863 return new IntentSender(mTarget, mWhitelistToken); 864 } 865 866 /** 867 * Cancel a currently active PendingIntent. Only the original application 868 * owning a PendingIntent can cancel it. 869 */ cancel()870 public void cancel() { 871 try { 872 ActivityManager.getService().cancelIntentSender(mTarget); 873 } catch (RemoteException e) { 874 throw e.rethrowFromSystemServer(); 875 } 876 } 877 878 /** 879 * Perform the operation associated with this PendingIntent. 880 * 881 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 882 * Bundle) 883 * 884 * @throws CanceledException Throws CanceledException if the PendingIntent 885 * is no longer allowing more intents to be sent through it. 886 */ send()887 public void send() throws CanceledException { 888 send(null, 0, null, null, null, null, null); 889 } 890 891 /** 892 * Perform the operation associated with this PendingIntent. 893 * 894 * @param code Result code to supply back to the PendingIntent's target. 895 * 896 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 897 * Bundle) 898 * 899 * @throws CanceledException Throws CanceledException if the PendingIntent 900 * is no longer allowing more intents to be sent through it. 901 */ send(int code)902 public void send(int code) throws CanceledException { 903 send(null, code, null, null, null, null, null); 904 } 905 906 /** 907 * Perform the operation associated with this PendingIntent, allowing the 908 * caller to specify information about the Intent to use. 909 * 910 * @param context The Context of the caller. 911 * @param code Result code to supply back to the PendingIntent's target. 912 * @param intent Additional Intent data. See {@link Intent#fillIn 913 * Intent.fillIn()} for information on how this is applied to the 914 * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this 915 * pending intent was created, this argument will be ignored. 916 * 917 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 918 * Bundle) 919 * 920 * @throws CanceledException Throws CanceledException if the PendingIntent 921 * is no longer allowing more intents to be sent through it. 922 */ send(Context context, int code, @Nullable Intent intent)923 public void send(Context context, int code, @Nullable Intent intent) 924 throws CanceledException { 925 send(context, code, intent, null, null, null, null); 926 } 927 928 /** 929 * Perform the operation associated with this PendingIntent, supplying additional 930 * options for the operation. 931 * 932 * @param options Additional options the caller would like to provide to modify the 933 * sending behavior. May be built from an {@link ActivityOptions} to apply to an 934 * activity start. 935 * 936 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String) 937 * 938 * @throws CanceledException Throws CanceledException if the PendingIntent 939 * is no longer allowing more intents to be sent through it. 940 */ send(@ullable Bundle options)941 public void send(@Nullable Bundle options) throws CanceledException { 942 send(null, 0, null, null, null, null, options); 943 } 944 945 /** 946 * Perform the operation associated with this PendingIntent, allowing the 947 * caller to be notified when the send has completed. 948 * 949 * @param code Result code to supply back to the PendingIntent's target. 950 * @param onFinished The object to call back on when the send has 951 * completed, or null for no callback. 952 * @param handler Handler identifying the thread on which the callback 953 * should happen. If null, the callback will happen from the thread 954 * pool of the process. 955 * 956 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 957 * Bundle) 958 * 959 * @throws CanceledException Throws CanceledException if the PendingIntent 960 * is no longer allowing more intents to be sent through it. 961 */ send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)962 public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler) 963 throws CanceledException { 964 send(null, code, null, onFinished, handler, null, null); 965 } 966 967 /** 968 * Perform the operation associated with this PendingIntent, allowing the 969 * caller to specify information about the Intent to use and be notified 970 * when the send has completed. 971 * 972 * <p>For the intent parameter, a PendingIntent 973 * often has restrictions on which fields can be supplied here, based on 974 * how the PendingIntent was retrieved in {@link #getActivity}, 975 * {@link #getBroadcast}, or {@link #getService}. 976 * 977 * @param context The Context of the caller. This may be null if 978 * <var>intent</var> is also null. 979 * @param code Result code to supply back to the PendingIntent's target. 980 * @param intent Additional Intent data. See {@link Intent#fillIn 981 * Intent.fillIn()} for information on how this is applied to the 982 * original Intent. Use null to not modify the original Intent. 983 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 984 * created, this argument will be ignored. 985 * @param onFinished The object to call back on when the send has 986 * completed, or null for no callback. 987 * @param handler Handler identifying the thread on which the callback 988 * should happen. If null, the callback will happen from the thread 989 * pool of the process. 990 * 991 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 992 * Bundle) 993 * 994 * @throws CanceledException Throws CanceledException if the PendingIntent 995 * is no longer allowing more intents to be sent through it. 996 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)997 public void send(Context context, int code, @Nullable Intent intent, 998 @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException { 999 send(context, code, intent, onFinished, handler, null, null); 1000 } 1001 1002 /** 1003 * Perform the operation associated with this PendingIntent, allowing the 1004 * caller to specify information about the Intent to use and be notified 1005 * when the send has completed. 1006 * 1007 * <p>For the intent parameter, a PendingIntent 1008 * often has restrictions on which fields can be supplied here, based on 1009 * how the PendingIntent was retrieved in {@link #getActivity}, 1010 * {@link #getBroadcast}, or {@link #getService}. 1011 * 1012 * @param context The Context of the caller. This may be null if 1013 * <var>intent</var> is also null. 1014 * @param code Result code to supply back to the PendingIntent's target. 1015 * @param intent Additional Intent data. See {@link Intent#fillIn 1016 * Intent.fillIn()} for information on how this is applied to the 1017 * original Intent. Use null to not modify the original Intent. 1018 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 1019 * created, this argument will be ignored. 1020 * @param onFinished The object to call back on when the send has 1021 * completed, or null for no callback. 1022 * @param handler Handler identifying the thread on which the callback 1023 * should happen. If null, the callback will happen from the thread 1024 * pool of the process. 1025 * @param requiredPermission Name of permission that a recipient of the PendingIntent 1026 * is required to hold. This is only valid for broadcast intents, and 1027 * corresponds to the permission argument in 1028 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 1029 * If null, no permission is required. 1030 * 1031 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, 1032 * Bundle) 1033 * 1034 * @throws CanceledException Throws CanceledException if the PendingIntent 1035 * is no longer allowing more intents to be sent through it. 1036 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)1037 public void send(Context context, int code, @Nullable Intent intent, 1038 @Nullable OnFinished onFinished, @Nullable Handler handler, 1039 @Nullable String requiredPermission) 1040 throws CanceledException { 1041 send(context, code, intent, onFinished, handler, requiredPermission, null); 1042 } 1043 1044 /** 1045 * Perform the operation associated with this PendingIntent, allowing the 1046 * caller to specify information about the Intent to use and be notified 1047 * when the send has completed. 1048 * 1049 * <p>For the intent parameter, a PendingIntent 1050 * often has restrictions on which fields can be supplied here, based on 1051 * how the PendingIntent was retrieved in {@link #getActivity}, 1052 * {@link #getBroadcast}, or {@link #getService}. 1053 * 1054 * @param context The Context of the caller. This may be null if 1055 * <var>intent</var> is also null. 1056 * @param code Result code to supply back to the PendingIntent's target. 1057 * @param intent Additional Intent data. See {@link Intent#fillIn 1058 * Intent.fillIn()} for information on how this is applied to the 1059 * original Intent. Use null to not modify the original Intent. 1060 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 1061 * created, this argument will be ignored. 1062 * @param onFinished The object to call back on when the send has 1063 * completed, or null for no callback. 1064 * @param handler Handler identifying the thread on which the callback 1065 * should happen. If null, the callback will happen from the thread 1066 * pool of the process. 1067 * @param requiredPermission Name of permission that a recipient of the PendingIntent 1068 * is required to hold. This is only valid for broadcast intents, and 1069 * corresponds to the permission argument in 1070 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 1071 * If null, no permission is required. 1072 * @param options Additional options the caller would like to provide to modify the sending 1073 * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. 1074 * 1075 * @throws CanceledException Throws CanceledException if the PendingIntent 1076 * is no longer allowing more intents to be sent through it. 1077 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)1078 public void send(Context context, int code, @Nullable Intent intent, 1079 @Nullable OnFinished onFinished, @Nullable Handler handler, 1080 @Nullable String requiredPermission, @Nullable Bundle options) 1081 throws CanceledException { 1082 if (sendAndReturnResult(context, code, intent, onFinished, handler, requiredPermission, 1083 options) < 0) { 1084 throw new CanceledException(); 1085 } 1086 } 1087 1088 /** 1089 * Like {@link #send}, but returns the result 1090 * @hide 1091 */ sendAndReturnResult(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)1092 public int sendAndReturnResult(Context context, int code, @Nullable Intent intent, 1093 @Nullable OnFinished onFinished, @Nullable Handler handler, 1094 @Nullable String requiredPermission, @Nullable Bundle options) 1095 throws CanceledException { 1096 try { 1097 String resolvedType = intent != null ? 1098 intent.resolveTypeIfNeeded(context.getContentResolver()) 1099 : null; 1100 1101 if (context != null && isActivity()) { 1102 // Set the context display id as preferred for this activity launches, so that it 1103 // can land on caller's display. Or just brought the task to front at the display 1104 // where it was on since it has higher preference. 1105 ActivityOptions activityOptions = options != null ? new ActivityOptions(options) 1106 : ActivityOptions.makeBasic(); 1107 activityOptions.setCallerDisplayId(context.getDisplayId()); 1108 options = activityOptions.toBundle(); 1109 } 1110 1111 final IApplicationThread app = ActivityThread.currentActivityThread() 1112 .getApplicationThread(); 1113 return ActivityManager.getService().sendIntentSender(app, 1114 mTarget, mWhitelistToken, code, intent, resolvedType, 1115 onFinished != null 1116 ? new FinishedDispatcher(this, onFinished, handler) 1117 : null, 1118 requiredPermission, options); 1119 } catch (RemoteException e) { 1120 throw new CanceledException(e); 1121 } 1122 } 1123 1124 /** 1125 * @deprecated Renamed to {@link #getCreatorPackage()}. 1126 */ 1127 @Deprecated 1128 @Nullable getTargetPackage()1129 public String getTargetPackage() { 1130 return getCreatorPackage(); 1131 } 1132 1133 /** 1134 * Return the package name of the application that created this 1135 * PendingIntent, that is the identity under which you will actually be 1136 * sending the Intent. The returned string is supplied by the system, so 1137 * that an application can not spoof its package. 1138 * 1139 * <p class="note">Be careful about how you use this. All this tells you is 1140 * who created the PendingIntent. It does <strong>not</strong> tell you who 1141 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 1142 * passed between applications, so the PendingIntent you receive from an application 1143 * could actually be one it received from another application, meaning the result 1144 * you get here will identify the original application. Because of this, you should 1145 * only use this information to identify who you expect to be interacting with 1146 * through a {@link #send} call, not who gave you the PendingIntent.</p> 1147 * 1148 * @return The package name of the PendingIntent. 1149 */ 1150 @Nullable getCreatorPackage()1151 public String getCreatorPackage() { 1152 return getCachedInfo().getCreatorPackage(); 1153 } 1154 1155 /** 1156 * Return the uid of the application that created this 1157 * PendingIntent, that is the identity under which you will actually be 1158 * sending the Intent. The returned integer is supplied by the system, so 1159 * that an application can not spoof its uid. 1160 * 1161 * <p class="note">Be careful about how you use this. All this tells you is 1162 * who created the PendingIntent. It does <strong>not</strong> tell you who 1163 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 1164 * passed between applications, so the PendingIntent you receive from an application 1165 * could actually be one it received from another application, meaning the result 1166 * you get here will identify the original application. Because of this, you should 1167 * only use this information to identify who you expect to be interacting with 1168 * through a {@link #send} call, not who gave you the PendingIntent.</p> 1169 * 1170 * @return The uid of the PendingIntent, or -1 if there is 1171 * none associated with it. 1172 */ getCreatorUid()1173 public int getCreatorUid() { 1174 return getCachedInfo().getCreatorUid(); 1175 } 1176 1177 /** 1178 * @hide 1179 * @deprecated use {@link #addCancelListener(Executor, CancelListener)} instead. 1180 */ 1181 @Deprecated registerCancelListener(@onNull CancelListener cancelListener)1182 public void registerCancelListener(@NonNull CancelListener cancelListener) { 1183 if (!addCancelListener(Runnable::run, cancelListener)) { 1184 // Call the callback right away synchronously, if the PI has been canceled already. 1185 cancelListener.onCanceled(this); 1186 } 1187 } 1188 1189 /** 1190 * Register a listener to when this pendingIntent is canceled. 1191 * 1192 * @return true if the listener has been set successfully. false if the {@link PendingIntent} 1193 * has already been canceled. 1194 * 1195 * @hide 1196 */ 1197 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1198 @TestApi addCancelListener(@onNull Executor executor, @NonNull CancelListener cancelListener)1199 public boolean addCancelListener(@NonNull Executor executor, 1200 @NonNull CancelListener cancelListener) { 1201 synchronized (mTarget) { 1202 if (mCancelListerInfo != null && mCancelListerInfo.mCanceled) { 1203 return false; 1204 } 1205 if (mCancelListerInfo == null) { 1206 mCancelListerInfo = new CancelListerInfo(); 1207 } 1208 final CancelListerInfo cli = mCancelListerInfo; 1209 1210 boolean wasEmpty = cli.mCancelListeners.isEmpty(); 1211 cli.mCancelListeners.add(Pair.create(executor, cancelListener)); 1212 if (wasEmpty) { 1213 boolean success; 1214 try { 1215 success = ActivityManager.getService().registerIntentSenderCancelListenerEx( 1216 mTarget, cli); 1217 } catch (RemoteException e) { 1218 throw e.rethrowFromSystemServer(); 1219 } 1220 if (!success) { 1221 cli.mCanceled = true; 1222 } 1223 return success; 1224 } else { 1225 return !cli.mCanceled; 1226 } 1227 } 1228 } 1229 notifyCancelListeners()1230 private void notifyCancelListeners() { 1231 ArraySet<Pair<Executor, CancelListener>> cancelListeners; 1232 synchronized (mTarget) { 1233 // When notifyCancelListeners() is called, mCancelListerInfo must always be non-null. 1234 final CancelListerInfo cli = mCancelListerInfo; 1235 cli.mCanceled = true; 1236 cancelListeners = new ArraySet<>(cli.mCancelListeners); 1237 cli.mCancelListeners.clear(); 1238 } 1239 int size = cancelListeners.size(); 1240 for (int i = 0; i < size; i++) { 1241 final Pair<Executor, CancelListener> pair = cancelListeners.valueAt(i); 1242 pair.first.execute(() -> pair.second.onCanceled(this)); 1243 } 1244 } 1245 1246 /** 1247 * @hide 1248 * @deprecated use {@link #removeCancelListener(CancelListener)} instead. 1249 */ 1250 @Deprecated unregisterCancelListener(CancelListener cancelListener)1251 public void unregisterCancelListener(CancelListener cancelListener) { 1252 removeCancelListener(cancelListener); 1253 } 1254 1255 /** 1256 * Un-register a listener to when this pendingIntent is canceled. 1257 * 1258 * @hide 1259 */ 1260 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1261 @TestApi removeCancelListener(@onNull CancelListener cancelListener)1262 public void removeCancelListener(@NonNull CancelListener cancelListener) { 1263 synchronized (mTarget) { 1264 final CancelListerInfo cli = mCancelListerInfo; 1265 if (cli == null || cli.mCancelListeners.size() == 0) { 1266 return; 1267 } 1268 for (int i = cli.mCancelListeners.size() - 1; i >= 0; i--) { 1269 if (cli.mCancelListeners.valueAt(i).second == cancelListener) { 1270 cli.mCancelListeners.removeAt(i); 1271 } 1272 } 1273 if (cli.mCancelListeners.isEmpty()) { 1274 try { 1275 ActivityManager.getService().unregisterIntentSenderCancelListener(mTarget, 1276 cli); 1277 } catch (RemoteException e) { 1278 throw e.rethrowFromSystemServer(); 1279 } 1280 } 1281 } 1282 } 1283 1284 /** 1285 * Return the user handle of the application that created this 1286 * PendingIntent, that is the user under which you will actually be 1287 * sending the Intent. The returned UserHandle is supplied by the system, so 1288 * that an application can not spoof its user. See 1289 * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for 1290 * more explanation of user handles. 1291 * 1292 * <p class="note">Be careful about how you use this. All this tells you is 1293 * who created the PendingIntent. It does <strong>not</strong> tell you who 1294 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 1295 * passed between applications, so the PendingIntent you receive from an application 1296 * could actually be one it received from another application, meaning the result 1297 * you get here will identify the original application. Because of this, you should 1298 * only use this information to identify who you expect to be interacting with 1299 * through a {@link #send} call, not who gave you the PendingIntent.</p> 1300 * 1301 * @return The user handle of the PendingIntent 1302 */ 1303 @NonNull getCreatorUserHandle()1304 public UserHandle getCreatorUserHandle() { 1305 int uid = getCachedInfo().getCreatorUid(); 1306 return UserHandle.getUserHandleForUid(uid); 1307 } 1308 1309 /** 1310 * @hide 1311 * Check to verify that this PendingIntent targets a specific package. 1312 */ isTargetedToPackage()1313 public boolean isTargetedToPackage() { 1314 try { 1315 return ActivityManager.getService() 1316 .isIntentSenderTargetedToPackage(mTarget); 1317 } catch (RemoteException e) { 1318 throw e.rethrowFromSystemServer(); 1319 } 1320 } 1321 1322 /** 1323 * Check if this PendingIntent is marked with {@link #FLAG_IMMUTABLE}. 1324 */ isImmutable()1325 public boolean isImmutable() { 1326 return getCachedInfo().isImmutable(); 1327 } 1328 1329 /** 1330 * @return TRUE if this {@link PendingIntent} was created with 1331 * {@link #getActivity} or {@link #getActivities}. 1332 */ isActivity()1333 public boolean isActivity() { 1334 return getCachedInfo().getIntentSenderType() == INTENT_SENDER_ACTIVITY; 1335 } 1336 1337 /** 1338 * @return TRUE if this {@link PendingIntent} was created with {@link #getForegroundService}. 1339 */ isForegroundService()1340 public boolean isForegroundService() { 1341 return getCachedInfo().getIntentSenderType() == INTENT_SENDER_FOREGROUND_SERVICE; 1342 } 1343 1344 /** 1345 * @return TRUE if this {@link PendingIntent} was created with {@link #getService}. 1346 */ isService()1347 public boolean isService() { 1348 return getCachedInfo().getIntentSenderType() == INTENT_SENDER_SERVICE; 1349 } 1350 1351 /** 1352 * @return TRUE if this {@link PendingIntent} was created with {@link #getBroadcast}. 1353 */ isBroadcast()1354 public boolean isBroadcast() { 1355 return getCachedInfo().getIntentSenderType() == INTENT_SENDER_BROADCAST; 1356 } 1357 1358 /** 1359 * @hide 1360 * Return the Intent of this PendingIntent. 1361 */ 1362 @UnsupportedAppUsage getIntent()1363 public Intent getIntent() { 1364 try { 1365 return ActivityManager.getService() 1366 .getIntentForIntentSender(mTarget); 1367 } catch (RemoteException e) { 1368 throw e.rethrowFromSystemServer(); 1369 } 1370 } 1371 1372 /** 1373 * @hide 1374 * Return descriptive tag for this PendingIntent. 1375 */ 1376 @UnsupportedAppUsage getTag(String prefix)1377 public String getTag(String prefix) { 1378 try { 1379 return ActivityManager.getService() 1380 .getTagForIntentSender(mTarget, prefix); 1381 } catch (RemoteException e) { 1382 throw e.rethrowFromSystemServer(); 1383 } 1384 } 1385 1386 /** 1387 * Resolve the intent set in this {@link PendingIntent}. Note if the pending intent is 1388 * generated for another user, the resulting component may not exist on the calling user. 1389 * Use {@link android.content.pm.ApplicationInfo#uid} of the resulting 1390 * {@link android.content.pm.ComponentInfo} with 1391 * {@link android.os.UserHandle#getUserHandleForUid(int)} to see which user will receive 1392 * the intent. 1393 * 1394 * @param flags MATCH_* flags from {@link android.content.pm.PackageManager}. 1395 * @hide 1396 */ 1397 @RequiresPermission(permission.GET_INTENT_SENDER_INTENT) 1398 @SystemApi(client = Client.MODULE_LIBRARIES) 1399 @TestApi queryIntentComponents(@esolveInfoFlagsBits int flags)1400 public @NonNull List<ResolveInfo> queryIntentComponents(@ResolveInfoFlagsBits int flags) { 1401 try { 1402 ParceledListSlice<ResolveInfo> parceledList = ActivityManager.getService() 1403 .queryIntentComponentsForIntentSender(mTarget, flags); 1404 if (parceledList == null) { 1405 return Collections.emptyList(); 1406 } 1407 return parceledList.getList(); 1408 } catch (RemoteException e) { 1409 throw e.rethrowFromSystemServer(); 1410 } 1411 } 1412 1413 /** 1414 * Comparison operator on two PendingIntent objects, such that true is returned when they 1415 * represent {@link Intent}s that are equal as per {@link Intent#filterEquals}. 1416 * 1417 * @param other The other PendingIntent to compare against. 1418 * @return True if action, data, type, class, and categories on two intents are the same. 1419 * 1420 * @hide 1421 */ 1422 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1423 @TestApi 1424 @RequiresPermission(android.Manifest.permission.GET_INTENT_SENDER_INTENT) intentFilterEquals(@ullable PendingIntent other)1425 public boolean intentFilterEquals(@Nullable PendingIntent other) { 1426 if (other == null) { 1427 return false; 1428 } 1429 try { 1430 return ActivityManager.getService().getIntentForIntentSender(other.mTarget) 1431 .filterEquals(getIntent()); 1432 } catch (RemoteException e) { 1433 throw e.rethrowFromSystemServer(); 1434 } 1435 } 1436 1437 /** 1438 * Comparison operator on two PendingIntent objects, such that true 1439 * is returned then they both represent the same operation from the 1440 * same package. This allows you to use {@link #getActivity}, 1441 * {@link #getBroadcast}, or {@link #getService} multiple times (even 1442 * across a process being killed), resulting in different PendingIntent 1443 * objects but whose equals() method identifies them as being the same 1444 * operation. 1445 */ 1446 @Override equals(@ullable Object otherObj)1447 public boolean equals(@Nullable Object otherObj) { 1448 if (otherObj instanceof PendingIntent) { 1449 return mTarget.asBinder().equals(((PendingIntent)otherObj) 1450 .mTarget.asBinder()); 1451 } 1452 return false; 1453 } 1454 1455 @Override hashCode()1456 public int hashCode() { 1457 return mTarget.asBinder().hashCode(); 1458 } 1459 1460 @Override toString()1461 public String toString() { 1462 StringBuilder sb = new StringBuilder(128); 1463 sb.append("PendingIntent{"); 1464 sb.append(Integer.toHexString(System.identityHashCode(this))); 1465 sb.append(": "); 1466 sb.append(mTarget.asBinder()); 1467 sb.append('}'); 1468 return sb.toString(); 1469 } 1470 1471 /** @hide */ dumpDebug(ProtoOutputStream proto, long fieldId)1472 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1473 final long token = proto.start(fieldId); 1474 proto.write(PendingIntentProto.TARGET, mTarget.asBinder().toString()); 1475 proto.end(token); 1476 } 1477 describeContents()1478 public int describeContents() { 1479 return 0; 1480 } 1481 writeToParcel(Parcel out, int flags)1482 public void writeToParcel(Parcel out, int flags) { 1483 out.writeStrongBinder(mTarget.asBinder()); 1484 final List<OnMarshaledListener> listeners = sOnMarshaledListener.get(); 1485 final int numListeners = listeners.size(); 1486 for (int i = 0; i < numListeners; i++) { 1487 listeners.get(i).onMarshaled(this, out, flags); 1488 } 1489 } 1490 1491 public static final @NonNull Creator<PendingIntent> CREATOR = new Creator<PendingIntent>() { 1492 public PendingIntent createFromParcel(Parcel in) { 1493 IBinder target = in.readStrongBinder(); 1494 return target != null 1495 ? new PendingIntent(target, in.getClassCookie(PendingIntent.class)) 1496 : null; 1497 } 1498 1499 public PendingIntent[] newArray(int size) { 1500 return new PendingIntent[size]; 1501 } 1502 }; 1503 1504 /** 1505 * Convenience function for writing either a PendingIntent or null pointer to 1506 * a Parcel. You must use this with {@link #readPendingIntentOrNullFromParcel} 1507 * for later reading it. 1508 * 1509 * @param sender The PendingIntent to write, or null. 1510 * @param out Where to write the PendingIntent. 1511 */ writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)1512 public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender, 1513 @NonNull Parcel out) { 1514 out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() : null); 1515 if (sender != null) { 1516 final List<OnMarshaledListener> listeners = sOnMarshaledListener.get(); 1517 final int numListeners = listeners.size(); 1518 for (int i = 0; i < numListeners; i++) { 1519 listeners.get(i).onMarshaled(sender, out, 0 /* flags */); 1520 } 1521 } 1522 } 1523 1524 /** 1525 * Convenience function for reading either a PendingIntent or null pointer from 1526 * a Parcel. You must have previously written the PendingIntent with 1527 * {@link #writePendingIntentOrNullToParcel}. 1528 * 1529 * @param in The Parcel containing the written PendingIntent. 1530 * 1531 * @return Returns the PendingIntent read from the Parcel, or null if null had 1532 * been written. 1533 */ 1534 @Nullable readPendingIntentOrNullFromParcel(@onNull Parcel in)1535 public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) { 1536 IBinder b = in.readStrongBinder(); 1537 return b != null ? new PendingIntent(b, in.getClassCookie(PendingIntent.class)) : null; 1538 } 1539 1540 /** 1541 * Creates a PendingIntent with the given target. 1542 * @param target the backing IIntentSender 1543 * @hide 1544 */ PendingIntent(IIntentSender target)1545 public PendingIntent(IIntentSender target) { 1546 mTarget = Objects.requireNonNull(target); 1547 } 1548 PendingIntent(IBinder target, Object cookie)1549 /*package*/ PendingIntent(IBinder target, Object cookie) { 1550 mTarget = Objects.requireNonNull(IIntentSender.Stub.asInterface(target)); 1551 if (cookie != null) { 1552 mWhitelistToken = (IBinder)cookie; 1553 } 1554 } 1555 1556 /** @hide */ getTarget()1557 public IIntentSender getTarget() { 1558 return mTarget; 1559 } 1560 1561 /** @hide */ getWhitelistToken()1562 public IBinder getWhitelistToken() { 1563 return mWhitelistToken; 1564 } 1565 1566 /** 1567 * A listener to when a pending intent is canceled 1568 * 1569 * @hide 1570 */ 1571 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1572 @TestApi 1573 public interface CancelListener { 1574 /** 1575 * Called when a Pending Intent is canceled. 1576 * 1577 * @param intent The intent that was canceled. 1578 */ onCanceled(@onNull PendingIntent intent)1579 void onCanceled(@NonNull PendingIntent intent); 1580 } 1581 getCachedInfo()1582 private PendingIntentInfo getCachedInfo() { 1583 if (mCachedInfo == null) { 1584 try { 1585 mCachedInfo = ActivityManager.getService().getInfoForIntentSender(mTarget); 1586 } catch (RemoteException e) { 1587 throw e.rethrowFromSystemServer(); 1588 } 1589 } 1590 1591 return mCachedInfo; 1592 } 1593 } 1594