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