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.START_SUCCESS; 20 21 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 22 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 23 24 import android.annotation.Nullable; 25 import android.app.ActivityManager; 26 import android.app.ActivityOptions; 27 import android.app.PendingIntent; 28 import android.content.IIntentReceiver; 29 import android.content.IIntentSender; 30 import android.content.Intent; 31 import android.os.Binder; 32 import android.os.Bundle; 33 import android.os.IBinder; 34 import android.os.RemoteCallbackList; 35 import android.os.RemoteException; 36 import android.os.TransactionTooLargeException; 37 import android.os.UserHandle; 38 import android.util.ArrayMap; 39 import android.util.ArraySet; 40 import android.util.Slog; 41 import android.util.TimeUtils; 42 43 import com.android.internal.os.IResultReceiver; 44 import com.android.internal.util.function.pooled.PooledLambda; 45 import com.android.server.wm.SafeActivityOptions; 46 47 import java.io.PrintWriter; 48 import java.lang.ref.WeakReference; 49 import java.util.Objects; 50 51 public final class PendingIntentRecord extends IIntentSender.Stub { 52 private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM; 53 54 public static final int FLAG_ACTIVITY_SENDER = 1 << 0; 55 public static final int FLAG_BROADCAST_SENDER = 1 << 1; 56 public static final int FLAG_SERVICE_SENDER = 1 << 2; 57 58 final PendingIntentController controller; 59 final Key key; 60 final int uid; 61 public final WeakReference<PendingIntentRecord> ref; 62 boolean sent = false; 63 boolean canceled = false; 64 private ArrayMap<IBinder, Long> whitelistDuration; 65 private RemoteCallbackList<IResultReceiver> mCancelCallbacks; 66 private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>(); 67 private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>(); 68 private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>(); 69 70 String stringName; 71 String lastTagPrefix; 72 String lastTag; 73 74 final static class Key { 75 final int type; 76 final String packageName; 77 final String featureId; 78 final IBinder activity; 79 final String who; 80 final int requestCode; 81 final Intent requestIntent; 82 final String requestResolvedType; 83 final SafeActivityOptions options; 84 Intent[] allIntents; 85 String[] allResolvedTypes; 86 final int flags; 87 final int hashCode; 88 final int userId; 89 90 private static final int ODD_PRIME_NUMBER = 37; 91 Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w, int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId)92 Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w, 93 int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId) { 94 type = _t; 95 packageName = _p; 96 featureId = _featureId; 97 activity = _a; 98 who = _w; 99 requestCode = _r; 100 requestIntent = _i != null ? _i[_i.length-1] : null; 101 requestResolvedType = _it != null ? _it[_it.length-1] : null; 102 allIntents = _i; 103 allResolvedTypes = _it; 104 flags = _f; 105 options = _o; 106 userId = _userId; 107 108 int hash = 23; 109 hash = (ODD_PRIME_NUMBER*hash) + _f; 110 hash = (ODD_PRIME_NUMBER*hash) + _r; 111 hash = (ODD_PRIME_NUMBER*hash) + _userId; 112 if (_w != null) { 113 hash = (ODD_PRIME_NUMBER*hash) + _w.hashCode(); 114 } 115 if (_a != null) { 116 hash = (ODD_PRIME_NUMBER*hash) + _a.hashCode(); 117 } 118 if (requestIntent != null) { 119 hash = (ODD_PRIME_NUMBER*hash) + requestIntent.filterHashCode(); 120 } 121 if (requestResolvedType != null) { 122 hash = (ODD_PRIME_NUMBER*hash) + requestResolvedType.hashCode(); 123 } 124 hash = (ODD_PRIME_NUMBER*hash) + (_p != null ? _p.hashCode() : 0); 125 hash = (ODD_PRIME_NUMBER*hash) + _t; 126 hashCode = hash; 127 //Slog.i(ActivityManagerService.TAG, this + " hashCode=0x" 128 // + Integer.toHexString(hashCode)); 129 } 130 131 @Override equals(Object otherObj)132 public boolean equals(Object otherObj) { 133 if (otherObj == null) { 134 return false; 135 } 136 try { 137 Key other = (Key)otherObj; 138 if (type != other.type) { 139 return false; 140 } 141 if (userId != other.userId){ 142 return false; 143 } 144 if (!Objects.equals(packageName, other.packageName)) { 145 return false; 146 } 147 if (!Objects.equals(featureId, other.featureId)) { 148 return false; 149 } 150 if (activity != other.activity) { 151 return false; 152 } 153 if (!Objects.equals(who, other.who)) { 154 return false; 155 } 156 if (requestCode != other.requestCode) { 157 return false; 158 } 159 if (requestIntent != other.requestIntent) { 160 if (requestIntent != null) { 161 if (!requestIntent.filterEquals(other.requestIntent)) { 162 return false; 163 } 164 } else if (other.requestIntent != null) { 165 return false; 166 } 167 } 168 if (!Objects.equals(requestResolvedType, other.requestResolvedType)) { 169 return false; 170 } 171 if (flags != other.flags) { 172 return false; 173 } 174 return true; 175 } catch (ClassCastException e) { 176 } 177 return false; 178 } 179 hashCode()180 public int hashCode() { 181 return hashCode; 182 } 183 toString()184 public String toString() { 185 return "Key{" + typeName() 186 + " pkg=" + packageName + (featureId != null ? "/" + featureId : "") 187 + " intent=" 188 + (requestIntent != null 189 ? requestIntent.toShortString(false, true, false, false) : "<null>") 190 + " flags=0x" + Integer.toHexString(flags) + " u=" + userId + "}" 191 + " requestCode=" + requestCode; 192 } 193 typeName()194 String typeName() { 195 switch (type) { 196 case ActivityManager.INTENT_SENDER_ACTIVITY: 197 return "startActivity"; 198 case ActivityManager.INTENT_SENDER_BROADCAST: 199 return "broadcastIntent"; 200 case ActivityManager.INTENT_SENDER_SERVICE: 201 return "startService"; 202 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: 203 return "startForegroundService"; 204 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT: 205 return "activityResult"; 206 } 207 return Integer.toString(type); 208 } 209 } 210 PendingIntentRecord(PendingIntentController _controller, Key _k, int _u)211 PendingIntentRecord(PendingIntentController _controller, Key _k, int _u) { 212 controller = _controller; 213 key = _k; 214 uid = _u; 215 ref = new WeakReference<>(this); 216 } 217 setWhitelistDurationLocked(IBinder whitelistToken, long duration)218 void setWhitelistDurationLocked(IBinder whitelistToken, long duration) { 219 if (duration > 0) { 220 if (whitelistDuration == null) { 221 whitelistDuration = new ArrayMap<>(); 222 } 223 whitelistDuration.put(whitelistToken, duration); 224 } else if (whitelistDuration != null) { 225 whitelistDuration.remove(whitelistToken); 226 if (whitelistDuration.size() <= 0) { 227 whitelistDuration = null; 228 } 229 230 } 231 this.stringName = null; 232 } 233 setAllowBgActivityStarts(IBinder token, int flags)234 void setAllowBgActivityStarts(IBinder token, int flags) { 235 if (token == null) return; 236 if ((flags & FLAG_ACTIVITY_SENDER) != 0) { 237 mAllowBgActivityStartsForActivitySender.add(token); 238 } 239 if ((flags & FLAG_BROADCAST_SENDER) != 0) { 240 mAllowBgActivityStartsForBroadcastSender.add(token); 241 } 242 if ((flags & FLAG_SERVICE_SENDER) != 0) { 243 mAllowBgActivityStartsForServiceSender.add(token); 244 } 245 } 246 clearAllowBgActivityStarts(IBinder token)247 void clearAllowBgActivityStarts(IBinder token) { 248 if (token == null) return; 249 mAllowBgActivityStartsForActivitySender.remove(token); 250 mAllowBgActivityStartsForBroadcastSender.remove(token); 251 mAllowBgActivityStartsForServiceSender.remove(token); 252 } 253 registerCancelListenerLocked(IResultReceiver receiver)254 public void registerCancelListenerLocked(IResultReceiver receiver) { 255 if (mCancelCallbacks == null) { 256 mCancelCallbacks = new RemoteCallbackList<>(); 257 } 258 mCancelCallbacks.register(receiver); 259 } 260 unregisterCancelListenerLocked(IResultReceiver receiver)261 public void unregisterCancelListenerLocked(IResultReceiver receiver) { 262 if (mCancelCallbacks == null) { 263 return; // Already unregistered or detached. 264 } 265 mCancelCallbacks.unregister(receiver); 266 if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) { 267 mCancelCallbacks = null; 268 } 269 } 270 detachCancelListenersLocked()271 public RemoteCallbackList<IResultReceiver> detachCancelListenersLocked() { 272 RemoteCallbackList<IResultReceiver> listeners = mCancelCallbacks; 273 mCancelCallbacks = null; 274 return listeners; 275 } 276 send(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)277 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 278 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 279 sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, 280 requiredPermission, null, null, 0, 0, 0, options); 281 } 282 sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)283 public int sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken, 284 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 285 return sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, 286 requiredPermission, null, null, 0, 0, 0, options); 287 } 288 sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)289 public int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken, 290 IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, 291 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) { 292 if (intent != null) intent.setDefusable(true); 293 if (options != null) options.setDefusable(true); 294 295 Long duration = null; 296 Intent finalIntent = null; 297 Intent[] allIntents = null; 298 String[] allResolvedTypes = null; 299 SafeActivityOptions mergedOptions = null; 300 synchronized (controller.mLock) { 301 if (canceled) { 302 return ActivityManager.START_CANCELED; 303 } 304 305 sent = true; 306 if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) { 307 controller.cancelIntentSender(this, true); 308 } 309 310 finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent(); 311 312 final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0; 313 if (!immutable) { 314 if (intent != null) { 315 int changes = finalIntent.fillIn(intent, key.flags); 316 if ((changes & Intent.FILL_IN_DATA) == 0) { 317 resolvedType = key.requestResolvedType; 318 } 319 } else { 320 resolvedType = key.requestResolvedType; 321 } 322 flagsMask &= ~Intent.IMMUTABLE_FLAGS; 323 flagsValues &= flagsMask; 324 finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues); 325 } else { 326 resolvedType = key.requestResolvedType; 327 } 328 329 // Apply any launch flags from the ActivityOptions. This is to ensure that the caller 330 // can specify a consistent launch mode even if the PendingIntent is immutable 331 final ActivityOptions opts = ActivityOptions.fromBundle(options); 332 if (opts != null) { 333 finalIntent.addFlags(opts.getPendingIntentLaunchFlags()); 334 } 335 336 // Extract options before clearing calling identity 337 mergedOptions = key.options; 338 if (mergedOptions == null) { 339 mergedOptions = new SafeActivityOptions(opts); 340 } else { 341 mergedOptions.setCallerOptions(opts); 342 } 343 344 if (whitelistDuration != null) { 345 duration = whitelistDuration.get(whitelistToken); 346 } 347 348 if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY 349 && key.allIntents != null && key.allIntents.length > 1) { 350 // Copy all intents and resolved types while we have the controller lock so we can 351 // use it later when the lock isn't held. 352 allIntents = new Intent[key.allIntents.length]; 353 allResolvedTypes = new String[key.allIntents.length]; 354 System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length); 355 if (key.allResolvedTypes != null) { 356 System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0, 357 key.allResolvedTypes.length); 358 } 359 allIntents[allIntents.length - 1] = finalIntent; 360 allResolvedTypes[allResolvedTypes.length - 1] = resolvedType; 361 } 362 363 } 364 // We don't hold the controller lock beyond this point as we will be calling into AM and WM. 365 366 final int callingUid = Binder.getCallingUid(); 367 final int callingPid = Binder.getCallingPid(); 368 final long origId = Binder.clearCallingIdentity(); 369 370 int res = START_SUCCESS; 371 try { 372 if (duration != null) { 373 int procState = controller.mAmInternal.getUidProcessState(callingUid); 374 if (!ActivityManager.isProcStateBackground(procState)) { 375 StringBuilder tag = new StringBuilder(64); 376 tag.append("pendingintent:"); 377 UserHandle.formatUid(tag, callingUid); 378 tag.append(":"); 379 if (finalIntent.getAction() != null) { 380 tag.append(finalIntent.getAction()); 381 } else if (finalIntent.getComponent() != null) { 382 finalIntent.getComponent().appendShortString(tag); 383 } else if (finalIntent.getData() != null) { 384 tag.append(finalIntent.getData().toSafeString()); 385 } 386 controller.mAmInternal.tempWhitelistForPendingIntent(callingPid, callingUid, 387 uid, duration, tag.toString()); 388 } else { 389 Slog.w(TAG, "Not doing whitelist " + this + ": caller state=" + procState); 390 } 391 } 392 393 boolean sendFinish = finishedReceiver != null; 394 int userId = key.userId; 395 if (userId == UserHandle.USER_CURRENT) { 396 userId = controller.mUserController.getCurrentOrTargetUserId(); 397 } 398 // temporarily allow receivers and services to open activities from background if the 399 // PendingIntent.send() caller was foreground at the time of sendInner() call 400 final boolean allowTrampoline = uid != callingUid 401 && controller.mAtmInternal.isUidForeground(callingUid); 402 403 // note: we on purpose don't pass in the information about the PendingIntent's creator, 404 // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because 405 // it's not unusual for the creator's process to not be alive at this time 406 switch (key.type) { 407 case ActivityManager.INTENT_SENDER_ACTIVITY: 408 try { 409 // Note when someone has a pending intent, even from different 410 // users, then there's no need to ensure the calling user matches 411 // the target user, so validateIncomingUser is always false below. 412 413 if (key.allIntents != null && key.allIntents.length > 1) { 414 res = controller.mAtmInternal.startActivitiesInPackage( 415 uid, callingPid, callingUid, key.packageName, key.featureId, 416 allIntents, allResolvedTypes, resultTo, mergedOptions, userId, 417 false /* validateIncomingUser */, 418 this /* originatingPendingIntent */, 419 mAllowBgActivityStartsForActivitySender.contains(whitelistToken)); 420 } else { 421 res = controller.mAtmInternal.startActivityInPackage(uid, callingPid, 422 callingUid, key.packageName, key.featureId, finalIntent, 423 resolvedType, resultTo, resultWho, requestCode, 0, 424 mergedOptions, userId, null, "PendingIntentRecord", 425 false /* validateIncomingUser */, 426 this /* originatingPendingIntent */, 427 mAllowBgActivityStartsForActivitySender.contains( 428 whitelistToken)); 429 } 430 } catch (RuntimeException e) { 431 Slog.w(TAG, "Unable to send startActivity intent", e); 432 } 433 break; 434 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT: 435 controller.mAtmInternal.sendActivityResult(-1, key.activity, key.who, 436 key.requestCode, code, finalIntent); 437 break; 438 case ActivityManager.INTENT_SENDER_BROADCAST: 439 try { 440 // If a completion callback has been requested, require 441 // that the broadcast be delivered synchronously 442 int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName, 443 key.featureId, uid, callingUid, callingPid, finalIntent, 444 resolvedType, finishedReceiver, code, null, null, 445 requiredPermission, options, (finishedReceiver != null), false, 446 userId, 447 mAllowBgActivityStartsForBroadcastSender.contains(whitelistToken) 448 || allowTrampoline); 449 if (sent == ActivityManager.BROADCAST_SUCCESS) { 450 sendFinish = false; 451 } 452 } catch (RuntimeException e) { 453 Slog.w(TAG, "Unable to send startActivity intent", e); 454 } 455 break; 456 case ActivityManager.INTENT_SENDER_SERVICE: 457 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: 458 try { 459 controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType, 460 key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, 461 key.packageName, key.featureId, userId, 462 mAllowBgActivityStartsForServiceSender.contains(whitelistToken) 463 || allowTrampoline); 464 } catch (RuntimeException e) { 465 Slog.w(TAG, "Unable to send startService intent", e); 466 } catch (TransactionTooLargeException e) { 467 res = ActivityManager.START_CANCELED; 468 } 469 break; 470 } 471 472 if (sendFinish && res != ActivityManager.START_CANCELED) { 473 try { 474 finishedReceiver.performReceive(new Intent(finalIntent), 0, 475 null, null, false, false, key.userId); 476 } catch (RemoteException e) { 477 } 478 } 479 } finally { 480 Binder.restoreCallingIdentity(origId); 481 } 482 483 return res; 484 } 485 486 @Override finalize()487 protected void finalize() throws Throwable { 488 try { 489 if (!canceled) { 490 controller.mH.sendMessage(PooledLambda.obtainMessage( 491 PendingIntentRecord::completeFinalize, this)); 492 } 493 } finally { 494 super.finalize(); 495 } 496 } 497 completeFinalize()498 private void completeFinalize() { 499 synchronized(controller.mLock) { 500 WeakReference<PendingIntentRecord> current = controller.mIntentSenderRecords.get(key); 501 if (current == ref) { 502 controller.mIntentSenderRecords.remove(key); 503 controller.decrementUidStatLocked(this); 504 } 505 } 506 } 507 dump(PrintWriter pw, String prefix)508 public void dump(PrintWriter pw, String prefix) { 509 pw.print(prefix); pw.print("uid="); pw.print(uid); 510 pw.print(" packageName="); pw.print(key.packageName); 511 pw.print(" featureId="); pw.print(key.featureId); 512 pw.print(" type="); pw.print(key.typeName()); 513 pw.print(" flags=0x"); pw.println(Integer.toHexString(key.flags)); 514 if (key.activity != null || key.who != null) { 515 pw.print(prefix); pw.print("activity="); pw.print(key.activity); 516 pw.print(" who="); pw.println(key.who); 517 } 518 if (key.requestCode != 0 || key.requestResolvedType != null) { 519 pw.print(prefix); pw.print("requestCode="); pw.print(key.requestCode); 520 pw.print(" requestResolvedType="); pw.println(key.requestResolvedType); 521 } 522 if (key.requestIntent != null) { 523 pw.print(prefix); pw.print("requestIntent="); 524 pw.println(key.requestIntent.toShortString(false, true, true, false)); 525 } 526 if (sent || canceled) { 527 pw.print(prefix); pw.print("sent="); pw.print(sent); 528 pw.print(" canceled="); pw.println(canceled); 529 } 530 if (whitelistDuration != null) { 531 pw.print(prefix); 532 pw.print("whitelistDuration="); 533 for (int i = 0; i < whitelistDuration.size(); i++) { 534 if (i != 0) { 535 pw.print(", "); 536 } 537 pw.print(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i)))); 538 pw.print(":"); 539 TimeUtils.formatDuration(whitelistDuration.valueAt(i), pw); 540 } 541 pw.println(); 542 } 543 if (mCancelCallbacks != null) { 544 pw.print(prefix); pw.println("mCancelCallbacks:"); 545 for (int i = 0; i < mCancelCallbacks.getRegisteredCallbackCount(); i++) { 546 pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": "); 547 pw.println(mCancelCallbacks.getRegisteredCallbackItem(i)); 548 } 549 } 550 } 551 toString()552 public String toString() { 553 if (stringName != null) { 554 return stringName; 555 } 556 StringBuilder sb = new StringBuilder(128); 557 sb.append("PendingIntentRecord{"); 558 sb.append(Integer.toHexString(System.identityHashCode(this))); 559 sb.append(' '); 560 sb.append(key.packageName); 561 if (key.featureId != null) { 562 sb.append('/'); 563 sb.append(key.featureId); 564 } 565 sb.append(' '); 566 sb.append(key.typeName()); 567 if (whitelistDuration != null) { 568 sb.append( " (whitelist: "); 569 for (int i = 0; i < whitelistDuration.size(); i++) { 570 if (i != 0) { 571 sb.append(","); 572 } 573 sb.append(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i)))); 574 sb.append(":"); 575 TimeUtils.formatDuration(whitelistDuration.valueAt(i), sb); 576 } 577 sb.append(")"); 578 } 579 sb.append('}'); 580 return stringName = sb.toString(); 581 } 582 } 583