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 com.android.server.am; 18 19 import static android.app.ActivityManager.PROCESS_STATE_TOP; 20 import static android.app.ActivityManager.START_SUCCESS; 21 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 22 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_COMPAT; 23 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED; 24 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 25 import static android.os.Process.ROOT_UID; 26 import static android.os.Process.SYSTEM_UID; 27 28 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 29 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 30 31 import android.annotation.IntDef; 32 import android.annotation.Nullable; 33 import android.annotation.RequiresPermission; 34 import android.app.ActivityManager; 35 import android.app.ActivityOptions; 36 import android.app.BackgroundStartPrivileges; 37 import android.app.BroadcastOptions; 38 import android.app.IApplicationThread; 39 import android.app.PendingIntent; 40 import android.app.compat.CompatChanges; 41 import android.compat.annotation.ChangeId; 42 import android.compat.annotation.EnabledAfter; 43 import android.compat.annotation.Overridable; 44 import android.content.IIntentReceiver; 45 import android.content.IIntentSender; 46 import android.content.Intent; 47 import android.os.Binder; 48 import android.os.Build; 49 import android.os.Bundle; 50 import android.os.IBinder; 51 import android.os.PowerWhitelistManager; 52 import android.os.PowerWhitelistManager.ReasonCode; 53 import android.os.RemoteCallbackList; 54 import android.os.RemoteException; 55 import android.os.TransactionTooLargeException; 56 import android.os.UserHandle; 57 import android.util.ArrayMap; 58 import android.util.ArraySet; 59 import android.util.Slog; 60 import android.util.TimeUtils; 61 62 import com.android.internal.annotations.VisibleForTesting; 63 import com.android.internal.os.IResultReceiver; 64 import com.android.internal.util.function.pooled.PooledLambda; 65 import com.android.modules.expresslog.Counter; 66 import com.android.server.wm.SafeActivityOptions; 67 68 import java.io.PrintWriter; 69 import java.lang.annotation.Retention; 70 import java.lang.annotation.RetentionPolicy; 71 import java.lang.ref.WeakReference; 72 import java.util.Objects; 73 74 public final class PendingIntentRecord extends IIntentSender.Stub { 75 private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM; 76 77 /** If enabled BAL are prevented by default in applications targeting U and later. */ 78 @ChangeId 79 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) 80 @Overridable 81 private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = 244637991; 82 public static final int FLAG_ACTIVITY_SENDER = 1 << 0; 83 public static final int FLAG_BROADCAST_SENDER = 1 << 1; 84 public static final int FLAG_SERVICE_SENDER = 1 << 2; 85 86 public static final int CANCEL_REASON_NULL = 0; 87 public static final int CANCEL_REASON_USER_STOPPED = 1 << 0; 88 public static final int CANCEL_REASON_OWNER_UNINSTALLED = 1 << 1; 89 public static final int CANCEL_REASON_OWNER_FORCE_STOPPED = 1 << 2; 90 public static final int CANCEL_REASON_OWNER_CANCELED = 1 << 3; 91 public static final int CANCEL_REASON_HOSTING_ACTIVITY_DESTROYED = 1 << 4; 92 public static final int CANCEL_REASON_SUPERSEDED = 1 << 5; 93 public static final int CANCEL_REASON_ONE_SHOT_SENT = 1 << 6; 94 95 @IntDef({ 96 CANCEL_REASON_NULL, 97 CANCEL_REASON_USER_STOPPED, 98 CANCEL_REASON_OWNER_UNINSTALLED, 99 CANCEL_REASON_OWNER_FORCE_STOPPED, 100 CANCEL_REASON_OWNER_CANCELED, 101 CANCEL_REASON_HOSTING_ACTIVITY_DESTROYED, 102 CANCEL_REASON_SUPERSEDED, 103 CANCEL_REASON_ONE_SHOT_SENT 104 }) 105 @Retention(RetentionPolicy.SOURCE) 106 public @interface CancellationReason {} 107 108 final PendingIntentController controller; 109 final Key key; 110 final int uid; 111 public final WeakReference<PendingIntentRecord> ref; 112 boolean sent = false; 113 boolean canceled = false; 114 @CancellationReason int cancelReason = CANCEL_REASON_NULL; 115 /** 116 * Map IBinder to duration specified as Pair<Long, Integer>, Long is allowlist duration in 117 * milliseconds, Integer is allowlist type defined at 118 * {@link android.os.PowerExemptionManager.TempAllowListType} 119 */ 120 private ArrayMap<IBinder, TempAllowListDuration> mAllowlistDuration; 121 private RemoteCallbackList<IResultReceiver> mCancelCallbacks; 122 private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>(); 123 private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>(); 124 private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>(); 125 126 String stringName; 127 String lastTagPrefix; 128 String lastTag; 129 130 final static class Key { 131 final int type; 132 final String packageName; 133 final String featureId; 134 final IBinder activity; 135 final String who; 136 final int requestCode; 137 final Intent requestIntent; 138 final String requestResolvedType; 139 final SafeActivityOptions options; 140 Intent[] allIntents; 141 String[] allResolvedTypes; 142 final int flags; 143 final int hashCode; 144 final int userId; 145 146 private static final int ODD_PRIME_NUMBER = 37; 147 Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w, int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId)148 Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w, 149 int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId) { 150 type = _t; 151 packageName = _p; 152 featureId = _featureId; 153 activity = _a; 154 who = _w; 155 requestCode = _r; 156 requestIntent = _i != null ? _i[_i.length-1] : null; 157 requestResolvedType = _it != null ? _it[_it.length-1] : null; 158 allIntents = _i; 159 allResolvedTypes = _it; 160 flags = _f; 161 options = _o; 162 userId = _userId; 163 164 int hash = 23; 165 hash = (ODD_PRIME_NUMBER*hash) + _f; 166 hash = (ODD_PRIME_NUMBER*hash) + _r; 167 hash = (ODD_PRIME_NUMBER*hash) + _userId; 168 if (_w != null) { 169 hash = (ODD_PRIME_NUMBER*hash) + _w.hashCode(); 170 } 171 if (_a != null) { 172 hash = (ODD_PRIME_NUMBER*hash) + _a.hashCode(); 173 } 174 if (requestIntent != null) { 175 hash = (ODD_PRIME_NUMBER*hash) + requestIntent.filterHashCode(); 176 } 177 if (requestResolvedType != null) { 178 hash = (ODD_PRIME_NUMBER*hash) + requestResolvedType.hashCode(); 179 } 180 hash = (ODD_PRIME_NUMBER*hash) + (_p != null ? _p.hashCode() : 0); 181 hash = (ODD_PRIME_NUMBER*hash) + _t; 182 hashCode = hash; 183 //Slog.i(ActivityManagerService.TAG, this + " hashCode=0x" 184 // + Integer.toHexString(hashCode)); 185 } 186 187 @Override equals(Object otherObj)188 public boolean equals(Object otherObj) { 189 if (otherObj == null) { 190 return false; 191 } 192 try { 193 Key other = (Key)otherObj; 194 if (type != other.type) { 195 return false; 196 } 197 if (userId != other.userId){ 198 return false; 199 } 200 if (!Objects.equals(packageName, other.packageName)) { 201 return false; 202 } 203 if (!Objects.equals(featureId, other.featureId)) { 204 return false; 205 } 206 if (activity != other.activity) { 207 return false; 208 } 209 if (!Objects.equals(who, other.who)) { 210 return false; 211 } 212 if (requestCode != other.requestCode) { 213 return false; 214 } 215 if (requestIntent != other.requestIntent) { 216 if (requestIntent != null) { 217 if (!requestIntent.filterEquals(other.requestIntent)) { 218 return false; 219 } 220 } else if (other.requestIntent != null) { 221 return false; 222 } 223 } 224 if (!Objects.equals(requestResolvedType, other.requestResolvedType)) { 225 return false; 226 } 227 if (flags != other.flags) { 228 return false; 229 } 230 return true; 231 } catch (ClassCastException e) { 232 } 233 return false; 234 } 235 hashCode()236 public int hashCode() { 237 return hashCode; 238 } 239 toString()240 public String toString() { 241 return "Key{" + typeName() 242 + " pkg=" + packageName + (featureId != null ? "/" + featureId : "") 243 + " intent=" 244 + (requestIntent != null 245 ? requestIntent.toShortString(false, true, false, false) : "<null>") 246 + " flags=0x" + Integer.toHexString(flags) + " u=" + userId + "}" 247 + " requestCode=" + requestCode; 248 } 249 typeName()250 String typeName() { 251 switch (type) { 252 case ActivityManager.INTENT_SENDER_ACTIVITY: 253 return "startActivity"; 254 case ActivityManager.INTENT_SENDER_BROADCAST: 255 return "broadcastIntent"; 256 case ActivityManager.INTENT_SENDER_SERVICE: 257 return "startService"; 258 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: 259 return "startForegroundService"; 260 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT: 261 return "activityResult"; 262 } 263 return Integer.toString(type); 264 } 265 } 266 267 static final class TempAllowListDuration { 268 long duration; 269 int type; 270 @ReasonCode int reasonCode; 271 @Nullable String reason; 272 TempAllowListDuration(long _duration, int _type, @ReasonCode int _reasonCode, String _reason)273 TempAllowListDuration(long _duration, int _type, @ReasonCode int _reasonCode, 274 String _reason) { 275 duration = _duration; 276 type = _type; 277 reasonCode = _reasonCode; 278 reason = _reason; 279 } 280 } 281 PendingIntentRecord(PendingIntentController _controller, Key _k, int _u)282 PendingIntentRecord(PendingIntentController _controller, Key _k, int _u) { 283 controller = _controller; 284 key = _k; 285 uid = _u; 286 ref = new WeakReference<>(this); 287 } 288 setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type, @ReasonCode int reasonCode, @Nullable String reason)289 void setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type, 290 @ReasonCode int reasonCode, @Nullable String reason) { 291 if (duration > 0) { 292 if (mAllowlistDuration == null) { 293 mAllowlistDuration = new ArrayMap<>(); 294 } 295 mAllowlistDuration.put(allowlistToken, 296 new TempAllowListDuration(duration, type, reasonCode, reason)); 297 } else if (mAllowlistDuration != null) { 298 mAllowlistDuration.remove(allowlistToken); 299 if (mAllowlistDuration.size() <= 0) { 300 mAllowlistDuration = null; 301 } 302 } 303 this.stringName = null; 304 } 305 setAllowBgActivityStarts(IBinder token, int flags)306 void setAllowBgActivityStarts(IBinder token, int flags) { 307 if (token == null) return; 308 if ((flags & FLAG_ACTIVITY_SENDER) != 0) { 309 mAllowBgActivityStartsForActivitySender.add(token); 310 } 311 if ((flags & FLAG_BROADCAST_SENDER) != 0) { 312 mAllowBgActivityStartsForBroadcastSender.add(token); 313 } 314 if ((flags & FLAG_SERVICE_SENDER) != 0) { 315 mAllowBgActivityStartsForServiceSender.add(token); 316 } 317 } 318 clearAllowBgActivityStarts(IBinder token)319 void clearAllowBgActivityStarts(IBinder token) { 320 if (token == null) return; 321 mAllowBgActivityStartsForActivitySender.remove(token); 322 mAllowBgActivityStartsForBroadcastSender.remove(token); 323 mAllowBgActivityStartsForServiceSender.remove(token); 324 } 325 registerCancelListenerLocked(IResultReceiver receiver)326 public void registerCancelListenerLocked(IResultReceiver receiver) { 327 if (mCancelCallbacks == null) { 328 mCancelCallbacks = new RemoteCallbackList<>(); 329 } 330 mCancelCallbacks.register(receiver); 331 } 332 unregisterCancelListenerLocked(IResultReceiver receiver)333 public void unregisterCancelListenerLocked(IResultReceiver receiver) { 334 if (mCancelCallbacks == null) { 335 return; // Already unregistered or detached. 336 } 337 mCancelCallbacks.unregister(receiver); 338 if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) { 339 mCancelCallbacks = null; 340 } 341 } 342 detachCancelListenersLocked()343 public RemoteCallbackList<IResultReceiver> detachCancelListenersLocked() { 344 RemoteCallbackList<IResultReceiver> listeners = mCancelCallbacks; 345 mCancelCallbacks = null; 346 return listeners; 347 } 348 send(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)349 public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken, 350 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 351 sendInner(null, code, intent, resolvedType, allowlistToken, finishedReceiver, 352 requiredPermission, null, null, 0, 0, 0, options); 353 } 354 send(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)355 public void send(IApplicationThread caller, int code, Intent intent, String resolvedType, 356 IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, 357 Bundle options) { 358 sendInner(caller, code, intent, resolvedType, allowlistToken, finishedReceiver, 359 requiredPermission, null, null, 0, 0, 0, options); 360 } 361 sendWithResult(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)362 public int sendWithResult(IApplicationThread caller, int code, Intent intent, 363 String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, 364 String requiredPermission, Bundle options) { 365 return sendInner(caller, code, intent, resolvedType, allowlistToken, finishedReceiver, 366 requiredPermission, null, null, 0, 0, 0, options); 367 } 368 369 /** 370 * Return true if the activity options allows PendingIntent to use caller's BAL permission. 371 */ isPendingIntentBalAllowedByPermission( @ullable ActivityOptions activityOptions)372 public static boolean isPendingIntentBalAllowedByPermission( 373 @Nullable ActivityOptions activityOptions) { 374 if (activityOptions == null) { 375 return false; 376 } 377 return activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission(); 378 } 379 380 /** 381 * Return the {@link BackgroundStartPrivileges} the activity options grant the PendingIntent to 382 * use caller's BAL permission. 383 */ getBackgroundStartPrivilegesAllowedByCaller( @ullable ActivityOptions activityOptions, int callingUid, @Nullable String callingPackage)384 public static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller( 385 @Nullable ActivityOptions activityOptions, int callingUid, 386 @Nullable String callingPackage) { 387 if (activityOptions == null) { 388 // since the ActivityOptions were not created by the app itself, determine the default 389 // for the app 390 return getDefaultBackgroundStartPrivileges(callingUid, callingPackage); 391 } 392 return getBackgroundStartPrivilegesAllowedByCaller(activityOptions.toBundle(), 393 callingUid, callingPackage); 394 } 395 getBackgroundStartPrivilegesAllowedByCaller( @ullable Bundle options, int callingUid, @Nullable String callingPackage)396 private static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller( 397 @Nullable Bundle options, int callingUid, @Nullable String callingPackage) { 398 if (options == null) { 399 return getDefaultBackgroundStartPrivileges(callingUid, callingPackage); 400 } 401 switch (options.getInt(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, 402 MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED)) { 403 case MODE_BACKGROUND_ACTIVITY_START_DENIED: 404 return BackgroundStartPrivileges.NONE; 405 case MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED: 406 return getDefaultBackgroundStartPrivileges(callingUid, callingPackage); 407 case MODE_BACKGROUND_ACTIVITY_START_ALLOWED: 408 case MODE_BACKGROUND_ACTIVITY_START_COMPAT: 409 default: 410 return BackgroundStartPrivileges.ALLOW_BAL; 411 } 412 } 413 414 /** 415 * Default {@link BackgroundStartPrivileges} to be used if the intent sender has not made an 416 * explicit choice. 417 * 418 * @hide 419 */ 420 @RequiresPermission( 421 allOf = { 422 android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, 423 android.Manifest.permission.LOG_COMPAT_CHANGE 424 }) getDefaultBackgroundStartPrivileges( int callingUid, @Nullable String callingPackage)425 public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges( 426 int callingUid, @Nullable String callingPackage) { 427 if (callingUid == ROOT_UID || callingUid == SYSTEM_UID) { 428 // root and system must always opt in explicitly 429 return BackgroundStartPrivileges.ALLOW_FGS; 430 } 431 boolean isChangeEnabledForApp = callingPackage != null ? CompatChanges.isChangeEnabled( 432 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingPackage, 433 UserHandle.getUserHandleForUid(callingUid)) : CompatChanges.isChangeEnabled( 434 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingUid); 435 if (isChangeEnabledForApp) { 436 return BackgroundStartPrivileges.ALLOW_FGS; 437 } else { 438 return BackgroundStartPrivileges.ALLOW_BAL; 439 } 440 } 441 442 @Deprecated sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)443 public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, 444 IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, 445 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) { 446 return sendInner(null, code, intent, resolvedType, allowlistToken, finishedReceiver, 447 requiredPermission, resultTo, resultWho, requestCode, flagsMask, flagsValues, 448 options); 449 } 450 sendInner(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)451 public int sendInner(IApplicationThread caller, int code, Intent intent, 452 String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, 453 String requiredPermission, IBinder resultTo, String resultWho, int requestCode, 454 int flagsMask, int flagsValues, Bundle options) { 455 final int callingUid = Binder.getCallingUid(); 456 final int callingPid = Binder.getCallingPid(); 457 458 if (intent != null) intent.setDefusable(true); 459 if (options != null) options.setDefusable(true); 460 461 TempAllowListDuration duration = null; 462 Intent finalIntent = null; 463 Intent[] allIntents = null; 464 String[] allResolvedTypes = null; 465 SafeActivityOptions mergedOptions = null; 466 synchronized (controller.mLock) { 467 if (canceled) { 468 if (cancelReason == CANCEL_REASON_OWNER_FORCE_STOPPED 469 && controller.mAmInternal.getUidProcessState(callingUid) 470 == PROCESS_STATE_TOP) { 471 Counter.logIncrementWithUid( 472 "app.value_force_stop_cancelled_pi_sent_from_top_per_caller", 473 callingUid); 474 Counter.logIncrementWithUid( 475 "app.value_force_stop_cancelled_pi_sent_from_top_per_owner", 476 uid); 477 } 478 return ActivityManager.START_CANCELED; 479 } 480 481 sent = true; 482 if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) { 483 controller.cancelIntentSender(this, true, CANCEL_REASON_ONE_SHOT_SENT); 484 } 485 486 finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent(); 487 488 final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0; 489 if (!immutable) { 490 if (intent != null) { 491 int changes = finalIntent.fillIn(intent, key.flags); 492 if ((changes & Intent.FILL_IN_DATA) == 0) { 493 resolvedType = key.requestResolvedType; 494 } 495 } else { 496 resolvedType = key.requestResolvedType; 497 } 498 flagsMask &= ~Intent.IMMUTABLE_FLAGS; 499 flagsValues &= flagsMask; 500 finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues); 501 } else { 502 resolvedType = key.requestResolvedType; 503 } 504 505 // Apply any launch flags from the ActivityOptions. This is to ensure that the caller 506 // can specify a consistent launch mode even if the PendingIntent is immutable 507 final ActivityOptions opts = ActivityOptions.fromBundle(options); 508 if (opts != null) { 509 if (opts.getPendingIntentCreatorBackgroundActivityStartMode() 510 != ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) { 511 Slog.wtf(TAG, 512 "Resetting option " 513 + "setPendingIntentCreatorBackgroundActivityStartMode(" 514 + opts.getPendingIntentCreatorBackgroundActivityStartMode() 515 + ") to SYSTEM_DEFINED from the options provided by the " 516 + "pending intent sender (" 517 + key.packageName 518 + ") because this option is meant for the pending intent " 519 + "creator"); 520 if (CompatChanges.isChangeEnabled(PendingIntent.PENDING_INTENT_OPTIONS_CHECK, 521 callingUid)) { 522 throw new IllegalArgumentException( 523 "pendingIntentCreatorBackgroundActivityStartMode " 524 + "must not be set when sending a PendingIntent"); 525 } 526 opts.setPendingIntentCreatorBackgroundActivityStartMode( 527 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); 528 } 529 finalIntent.addFlags(opts.getPendingIntentLaunchFlags()); 530 } 531 532 // Extract options before clearing calling identity 533 mergedOptions = key.options; 534 if (mergedOptions == null) { 535 mergedOptions = new SafeActivityOptions(opts); 536 } else { 537 mergedOptions.setCallerOptions(opts); 538 } 539 540 if (mAllowlistDuration != null) { 541 duration = mAllowlistDuration.get(allowlistToken); 542 } 543 544 if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY 545 && key.allIntents != null && key.allIntents.length > 1) { 546 // Copy all intents and resolved types while we have the controller lock so we can 547 // use it later when the lock isn't held. 548 allIntents = new Intent[key.allIntents.length]; 549 allResolvedTypes = new String[key.allIntents.length]; 550 System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length); 551 if (key.allResolvedTypes != null) { 552 System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0, 553 key.allResolvedTypes.length); 554 } 555 allIntents[allIntents.length - 1] = finalIntent; 556 allResolvedTypes[allResolvedTypes.length - 1] = resolvedType; 557 } 558 559 } 560 // We don't hold the controller lock beyond this point as we will be calling into AM and WM. 561 562 // Only system senders can declare a broadcast to be alarm-originated. We check 563 // this here rather than in the general case handling below to fail before the other 564 // invocation side effects such as allowlisting. 565 if (key.type == ActivityManager.INTENT_SENDER_BROADCAST) { 566 controller.mAmInternal.enforceBroadcastOptionsPermissions(options, callingUid); 567 } 568 569 final long origId = Binder.clearCallingIdentity(); 570 571 int res = START_SUCCESS; 572 try { 573 if (duration != null) { 574 StringBuilder tag = new StringBuilder(64); 575 tag.append("setPendingIntentAllowlistDuration,reason:"); 576 tag.append(duration.reason == null ? "" : duration.reason); 577 tag.append(",pendingintent:"); 578 UserHandle.formatUid(tag, callingUid); 579 tag.append(":"); 580 if (finalIntent.getAction() != null) { 581 tag.append(finalIntent.getAction()); 582 } else if (finalIntent.getComponent() != null) { 583 finalIntent.getComponent().appendShortString(tag); 584 } else if (finalIntent.getData() != null) { 585 tag.append(finalIntent.getData().toSafeString()); 586 } 587 controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid, 588 uid, duration.duration, duration.type, duration.reasonCode, tag.toString()); 589 } else if (key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE 590 && options != null) { 591 // If this is a getForegroundService() type pending intent, use its BroadcastOptions 592 // temp allowlist duration as its pending intent temp allowlist duration. 593 BroadcastOptions brOptions = new BroadcastOptions(options); 594 if (brOptions.getTemporaryAppAllowlistDuration() > 0) { 595 controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid, 596 uid, brOptions.getTemporaryAppAllowlistDuration(), 597 brOptions.getTemporaryAppAllowlistType(), 598 brOptions.getTemporaryAppAllowlistReasonCode(), 599 brOptions.getTemporaryAppAllowlistReason()); 600 } 601 } 602 603 final IApplicationThread finishedReceiverThread = caller; 604 boolean sendFinish = finishedReceiver != null; 605 if ((finishedReceiver != null) && (finishedReceiverThread == null)) { 606 Slog.w(TAG, "Sending of " + intent + " from " + Binder.getCallingUid() 607 + " requested resultTo without an IApplicationThread!", new Throwable()); 608 } 609 610 int userId = key.userId; 611 if (userId == UserHandle.USER_CURRENT) { 612 userId = controller.mUserController.getCurrentOrTargetUserId(); 613 } 614 615 // note: we on purpose don't pass in the information about the PendingIntent's creator, 616 // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because 617 // it's not unusual for the creator's process to not be alive at this time 618 switch (key.type) { 619 case ActivityManager.INTENT_SENDER_ACTIVITY: 620 try { 621 // Note when someone has a pending intent, even from different 622 // users, then there's no need to ensure the calling user matches 623 // the target user, so validateIncomingUser is always false below. 624 625 if (key.allIntents != null && key.allIntents.length > 1) { 626 res = controller.mAtmInternal.startActivitiesInPackage( 627 uid, callingPid, callingUid, key.packageName, key.featureId, 628 allIntents, allResolvedTypes, resultTo, mergedOptions, userId, 629 false /* validateIncomingUser */, 630 this /* originatingPendingIntent */, 631 getBackgroundStartPrivilegesForActivitySender(allowlistToken)); 632 } else { 633 res = controller.mAtmInternal.startActivityInPackage(uid, callingPid, 634 callingUid, key.packageName, key.featureId, finalIntent, 635 resolvedType, resultTo, resultWho, requestCode, 0, 636 mergedOptions, userId, null, "PendingIntentRecord", 637 false /* validateIncomingUser */, 638 this /* originatingPendingIntent */, 639 getBackgroundStartPrivilegesForActivitySender(allowlistToken)); 640 } 641 } catch (RuntimeException e) { 642 Slog.w(TAG, "Unable to send startActivity intent", e); 643 } 644 break; 645 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT: 646 controller.mAtmInternal.sendActivityResult(-1, key.activity, key.who, 647 key.requestCode, code, finalIntent); 648 break; 649 case ActivityManager.INTENT_SENDER_BROADCAST: 650 try { 651 final BackgroundStartPrivileges backgroundStartPrivileges = 652 getBackgroundStartPrivilegesForActivitySender( 653 mAllowBgActivityStartsForBroadcastSender, allowlistToken, 654 options, callingUid); 655 // If a completion callback has been requested, require 656 // that the broadcast be delivered synchronously 657 int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName, 658 key.featureId, uid, callingUid, callingPid, finalIntent, 659 resolvedType, finishedReceiverThread, finishedReceiver, code, null, 660 null, requiredPermission, options, (finishedReceiver != null), 661 false, userId, backgroundStartPrivileges, 662 null /* broadcastAllowList */); 663 if (sent == ActivityManager.BROADCAST_SUCCESS) { 664 sendFinish = false; 665 } 666 } catch (RuntimeException e) { 667 Slog.w(TAG, "Unable to send startActivity intent", e); 668 } 669 break; 670 case ActivityManager.INTENT_SENDER_SERVICE: 671 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: 672 try { 673 final BackgroundStartPrivileges backgroundStartPrivileges = 674 getBackgroundStartPrivilegesForActivitySender( 675 mAllowBgActivityStartsForServiceSender, allowlistToken, 676 options, callingUid); 677 controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType, 678 key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, 679 key.packageName, key.featureId, userId, 680 backgroundStartPrivileges); 681 } catch (RuntimeException e) { 682 Slog.w(TAG, "Unable to send startService intent", e); 683 } catch (TransactionTooLargeException e) { 684 res = ActivityManager.START_CANCELED; 685 } 686 break; 687 } 688 689 if (sendFinish && res != ActivityManager.START_CANCELED) { 690 try { 691 finishedReceiver.performReceive(new Intent(finalIntent), 0, 692 null, null, false, false, key.userId); 693 } catch (RemoteException e) { 694 } 695 } 696 } finally { 697 Binder.restoreCallingIdentity(origId); 698 } 699 700 return res; 701 } 702 getBackgroundStartPrivilegesForActivitySender( IBinder allowlistToken)703 private BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender( 704 IBinder allowlistToken) { 705 return mAllowBgActivityStartsForActivitySender.contains(allowlistToken) 706 ? BackgroundStartPrivileges.allowBackgroundActivityStarts(allowlistToken) 707 : BackgroundStartPrivileges.NONE; 708 } 709 getBackgroundStartPrivilegesForActivitySender( ArraySet<IBinder> allowedTokenSet, IBinder allowlistToken, Bundle options, int callingUid)710 private BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender( 711 ArraySet<IBinder> allowedTokenSet, IBinder allowlistToken, 712 Bundle options, int callingUid) { 713 if (allowedTokenSet.contains(allowlistToken)) { 714 return BackgroundStartPrivileges.allowBackgroundActivityStarts(allowlistToken); 715 } 716 // temporarily allow receivers and services to open activities from background if the 717 // PendingIntent.send() caller was foreground at the time of sendInner() call 718 if (uid != callingUid && controller.mAtmInternal.isUidForeground(callingUid)) { 719 return getBackgroundStartPrivilegesAllowedByCaller(options, callingUid, null); 720 } 721 return BackgroundStartPrivileges.NONE; 722 } 723 724 @Override finalize()725 protected void finalize() throws Throwable { 726 try { 727 if (!canceled) { 728 controller.mH.sendMessage(PooledLambda.obtainMessage( 729 PendingIntentRecord::completeFinalize, this)); 730 } 731 } finally { 732 super.finalize(); 733 } 734 } 735 completeFinalize()736 private void completeFinalize() { 737 synchronized(controller.mLock) { 738 WeakReference<PendingIntentRecord> current = controller.mIntentSenderRecords.get(key); 739 if (current == ref) { 740 controller.mIntentSenderRecords.remove(key); 741 controller.decrementUidStatLocked(this); 742 } 743 } 744 } 745 746 @VisibleForTesting cancelReasonToString(@ancellationReason int cancelReason)747 static String cancelReasonToString(@CancellationReason int cancelReason) { 748 return switch (cancelReason) { 749 case CANCEL_REASON_NULL -> "NULL"; 750 case CANCEL_REASON_USER_STOPPED -> "USER_STOPPED"; 751 case CANCEL_REASON_OWNER_UNINSTALLED -> "OWNER_UNINSTALLED"; 752 case CANCEL_REASON_OWNER_FORCE_STOPPED -> "OWNER_FORCE_STOPPED"; 753 case CANCEL_REASON_OWNER_CANCELED -> "OWNER_CANCELED"; 754 case CANCEL_REASON_HOSTING_ACTIVITY_DESTROYED -> "HOSTING_ACTIVITY_DESTROYED"; 755 case CANCEL_REASON_SUPERSEDED -> "SUPERSEDED"; 756 case CANCEL_REASON_ONE_SHOT_SENT -> "ONE_SHOT_SENT"; 757 default -> "UNKNOWN"; 758 }; 759 } 760 dump(PrintWriter pw, String prefix)761 public void dump(PrintWriter pw, String prefix) { 762 pw.print(prefix); pw.print("uid="); pw.print(uid); 763 pw.print(" packageName="); pw.print(key.packageName); 764 pw.print(" featureId="); pw.print(key.featureId); 765 pw.print(" type="); pw.print(key.typeName()); 766 pw.print(" flags=0x"); pw.println(Integer.toHexString(key.flags)); 767 if (key.activity != null || key.who != null) { 768 pw.print(prefix); pw.print("activity="); pw.print(key.activity); 769 pw.print(" who="); pw.println(key.who); 770 } 771 if (key.requestCode != 0 || key.requestResolvedType != null) { 772 pw.print(prefix); pw.print("requestCode="); pw.print(key.requestCode); 773 pw.print(" requestResolvedType="); pw.println(key.requestResolvedType); 774 } 775 if (key.requestIntent != null) { 776 pw.print(prefix); pw.print("requestIntent="); 777 pw.println(key.requestIntent.toShortString(false, true, true, false)); 778 } 779 if (sent || canceled) { 780 pw.print(prefix); pw.print("sent="); pw.print(sent); 781 pw.print(" canceled="); pw.print(canceled); 782 pw.print(" cancelReason="); pw.println(cancelReasonToString(cancelReason)); 783 } 784 if (mAllowlistDuration != null) { 785 pw.print(prefix); 786 pw.print("allowlistDuration="); 787 for (int i = 0; i < mAllowlistDuration.size(); i++) { 788 if (i != 0) { 789 pw.print(", "); 790 } 791 TempAllowListDuration entry = mAllowlistDuration.valueAt(i); 792 pw.print(Integer.toHexString(System.identityHashCode(mAllowlistDuration.keyAt(i)))); 793 pw.print(":"); 794 TimeUtils.formatDuration(entry.duration, pw); 795 pw.print("/"); 796 pw.print(entry.type); 797 pw.print("/"); 798 pw.print(PowerWhitelistManager.reasonCodeToString(entry.reasonCode)); 799 pw.print("/"); 800 pw.print(entry.reason); 801 } 802 pw.println(); 803 } 804 if (mCancelCallbacks != null) { 805 pw.print(prefix); pw.println("mCancelCallbacks:"); 806 for (int i = 0; i < mCancelCallbacks.getRegisteredCallbackCount(); i++) { 807 pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": "); 808 pw.println(mCancelCallbacks.getRegisteredCallbackItem(i)); 809 } 810 } 811 } 812 toString()813 public String toString() { 814 if (stringName != null) { 815 return stringName; 816 } 817 StringBuilder sb = new StringBuilder(128); 818 sb.append("PendingIntentRecord{"); 819 sb.append(Integer.toHexString(System.identityHashCode(this))); 820 sb.append(' '); 821 sb.append(key.packageName); 822 if (key.featureId != null) { 823 sb.append('/'); 824 sb.append(key.featureId); 825 } 826 sb.append(' '); 827 sb.append(key.typeName()); 828 if (mAllowlistDuration != null) { 829 sb.append(" (allowlist: "); 830 for (int i = 0; i < mAllowlistDuration.size(); i++) { 831 if (i != 0) { 832 sb.append(","); 833 } 834 TempAllowListDuration entry = mAllowlistDuration.valueAt(i); 835 sb.append(Integer.toHexString(System.identityHashCode( 836 mAllowlistDuration.keyAt(i)))); 837 sb.append(":"); 838 TimeUtils.formatDuration(entry.duration, sb); 839 sb.append("/"); 840 sb.append(entry.type); 841 sb.append("/"); 842 sb.append(PowerWhitelistManager.reasonCodeToString(entry.reasonCode)); 843 sb.append("/"); 844 sb.append(entry.reason); 845 } 846 sb.append(")"); 847 } 848 sb.append('}'); 849 return stringName = sb.toString(); 850 } 851 } 852