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.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED; 20 21 import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_ALL; 22 import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY; 23 import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_CHANGE_ID; 24 import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_NONE; 25 import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY; 26 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.app.ActivityManagerInternal; 30 import android.app.AppOpsManager; 31 import android.app.BroadcastOptions; 32 import android.app.compat.CompatChanges; 33 import android.content.ComponentName; 34 import android.content.IIntentReceiver; 35 import android.content.Intent; 36 import android.content.pm.ActivityInfo; 37 import android.content.pm.ResolveInfo; 38 import android.os.Binder; 39 import android.os.Bundle; 40 import android.os.IBinder; 41 import android.os.SystemClock; 42 import android.os.UserHandle; 43 import android.util.PrintWriterPrinter; 44 import android.util.SparseArray; 45 import android.util.TimeUtils; 46 import android.util.proto.ProtoOutputStream; 47 48 import com.android.internal.annotations.VisibleForTesting; 49 50 import java.io.PrintWriter; 51 import java.text.SimpleDateFormat; 52 import java.util.ArrayList; 53 import java.util.Arrays; 54 import java.util.Date; 55 import java.util.List; 56 import java.util.Set; 57 import java.util.concurrent.atomic.AtomicInteger; 58 59 /** 60 * An active intent broadcast. 61 */ 62 final class BroadcastRecord extends Binder { 63 final Intent intent; // the original intent that generated us 64 final ComponentName targetComp; // original component name set on the intent 65 final ProcessRecord callerApp; // process that sent this 66 final String callerPackage; // who sent this 67 final @Nullable String callerFeatureId; // which feature in the package sent this 68 final int callingPid; // the pid of who sent this 69 final int callingUid; // the uid of who sent this 70 final boolean callerInstantApp; // caller is an Instant App? 71 final boolean ordered; // serialize the send to receivers? 72 final boolean sticky; // originated from existing sticky data? 73 final boolean alarm; // originated from an alarm triggering? 74 final boolean pushMessage; // originated from a push message? 75 final boolean pushMessageOverQuota; // originated from a push message which was over quota? 76 final boolean initialSticky; // initial broadcast from register to sticky? 77 final int userId; // user id this broadcast was for 78 final String resolvedType; // the resolved data type 79 final String[] requiredPermissions; // permissions the caller has required 80 final String[] excludedPermissions; // permissions to exclude 81 final String[] excludedPackages; // packages to exclude 82 final int appOp; // an app op that is associated with this broadcast 83 final BroadcastOptions options; // BroadcastOptions supplied by caller 84 final List receivers; // contains BroadcastFilter and ResolveInfo 85 final int[] delivery; // delivery state of each receiver 86 final long[] duration; // duration a receiver took to process broadcast 87 IIntentReceiver resultTo; // who receives final result if non-null 88 boolean deferred; 89 int splitCount; // refcount for result callback, when split 90 int splitToken; // identifier for cross-BroadcastRecord refcount 91 long enqueueTime; // uptimeMillis when the broadcast was enqueued 92 long enqueueRealTime; // elapsedRealtime when the broadcast was enqueued 93 long enqueueClockTime; // the clock time the broadcast was enqueued 94 long dispatchTime; // when dispatch started on this set of receivers 95 long dispatchRealTime; // elapsedRealtime when the broadcast was dispatched 96 long dispatchClockTime; // the clock time the dispatch started 97 long receiverTime; // when current receiver started for timeouts. 98 long finishTime; // when we finished the current receiver. 99 boolean timeoutExempt; // true if this broadcast is not subject to receiver timeouts 100 int resultCode; // current result code value. 101 String resultData; // current result data value. 102 Bundle resultExtras; // current result extra data values. 103 boolean resultAbort; // current result abortBroadcast value. 104 int nextReceiver; // next receiver to be executed. 105 IBinder receiver; // who is currently running, null if none. 106 int state; 107 int anrCount; // has this broadcast record hit any ANRs? 108 int manifestCount; // number of manifest receivers dispatched. 109 int manifestSkipCount; // number of manifest receivers skipped. 110 BroadcastQueue queue; // the outbound queue handling this broadcast 111 112 // if set to true, app's process will be temporarily allowed to start activities from background 113 // for the duration of the broadcast dispatch 114 final boolean allowBackgroundActivityStarts; 115 // token used to trace back the grant for activity starts, optional 116 @Nullable 117 final IBinder mBackgroundActivityStartsToken; 118 119 static final int IDLE = 0; 120 static final int APP_RECEIVE = 1; 121 static final int CALL_IN_RECEIVE = 2; 122 static final int CALL_DONE_RECEIVE = 3; 123 static final int WAITING_SERVICES = 4; 124 125 static final int DELIVERY_PENDING = 0; 126 static final int DELIVERY_DELIVERED = 1; 127 static final int DELIVERY_SKIPPED = 2; 128 static final int DELIVERY_TIMEOUT = 3; 129 130 // The following are set when we are calling a receiver (one that 131 // was found in our list of registered receivers). 132 BroadcastFilter curFilter; 133 134 // The following are set only when we are launching a receiver (one 135 // that was found by querying the package manager). 136 ProcessRecord curApp; // hosting application of current receiver. 137 ComponentName curComponent; // the receiver class that is currently running. 138 ActivityInfo curReceiver; // info about the receiver that is currently running. 139 140 boolean mIsReceiverAppRunning; // Was the receiver's app already running. 141 142 // Private refcount-management bookkeeping; start > 0 143 static AtomicInteger sNextToken = new AtomicInteger(1); 144 dump(PrintWriter pw, String prefix, SimpleDateFormat sdf)145 void dump(PrintWriter pw, String prefix, SimpleDateFormat sdf) { 146 final long now = SystemClock.uptimeMillis(); 147 148 pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId); 149 pw.print(prefix); pw.println(intent.toInsecureString()); 150 if (targetComp != null && targetComp != intent.getComponent()) { 151 pw.print(prefix); pw.print(" targetComp: "); pw.println(targetComp.toShortString()); 152 } 153 Bundle bundle = intent.getExtras(); 154 if (bundle != null) { 155 pw.print(prefix); pw.print(" extras: "); pw.println(bundle.toString()); 156 } 157 pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" "); 158 pw.print(callerApp != null ? callerApp.toShortString() : "null"); 159 pw.print(" pid="); pw.print(callingPid); 160 pw.print(" uid="); pw.println(callingUid); 161 if ((requiredPermissions != null && requiredPermissions.length > 0) 162 || appOp != AppOpsManager.OP_NONE) { 163 pw.print(prefix); pw.print("requiredPermissions="); 164 pw.print(Arrays.toString(requiredPermissions)); 165 pw.print(" appOp="); pw.println(appOp); 166 } 167 if (excludedPermissions != null && excludedPermissions.length > 0) { 168 pw.print(prefix); pw.print("excludedPermissions="); 169 pw.print(Arrays.toString(excludedPermissions)); 170 } 171 if (excludedPackages != null && excludedPackages.length > 0) { 172 pw.print(prefix); pw.print("excludedPackages="); 173 pw.print(Arrays.toString(excludedPackages)); 174 } 175 if (options != null) { 176 pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); 177 } 178 pw.print(prefix); pw.print("enqueueClockTime="); 179 pw.print(sdf.format(new Date(enqueueClockTime))); 180 pw.print(" dispatchClockTime="); 181 pw.println(sdf.format(new Date(dispatchClockTime))); 182 pw.print(prefix); pw.print("dispatchTime="); 183 TimeUtils.formatDuration(dispatchTime, now, pw); 184 pw.print(" ("); 185 TimeUtils.formatDuration(dispatchTime - enqueueTime, pw); 186 pw.print(" since enq)"); 187 if (finishTime != 0) { 188 pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw); 189 pw.print(" ("); 190 TimeUtils.formatDuration(finishTime-dispatchTime, pw); 191 pw.print(" since disp)"); 192 } else { 193 pw.print(" receiverTime="); TimeUtils.formatDuration(receiverTime, now, pw); 194 } 195 pw.println(""); 196 if (anrCount != 0) { 197 pw.print(prefix); pw.print("anrCount="); pw.println(anrCount); 198 } 199 if (resultTo != null || resultCode != -1 || resultData != null) { 200 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo); 201 pw.print(" resultCode="); pw.print(resultCode); 202 pw.print(" resultData="); pw.println(resultData); 203 } 204 if (resultExtras != null) { 205 pw.print(prefix); pw.print("resultExtras="); pw.println(resultExtras); 206 } 207 if (resultAbort || ordered || sticky || initialSticky) { 208 pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort); 209 pw.print(" ordered="); pw.print(ordered); 210 pw.print(" sticky="); pw.print(sticky); 211 pw.print(" initialSticky="); pw.println(initialSticky); 212 } 213 if (nextReceiver != 0 || receiver != null) { 214 pw.print(prefix); pw.print("nextReceiver="); pw.print(nextReceiver); 215 pw.print(" receiver="); pw.println(receiver); 216 } 217 if (curFilter != null) { 218 pw.print(prefix); pw.print("curFilter="); pw.println(curFilter); 219 } 220 if (curReceiver != null) { 221 pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver); 222 } 223 if (curApp != null) { 224 pw.print(prefix); pw.print("curApp="); pw.println(curApp); 225 pw.print(prefix); pw.print("curComponent="); 226 pw.println((curComponent != null ? curComponent.toShortString() : "--")); 227 if (curReceiver != null && curReceiver.applicationInfo != null) { 228 pw.print(prefix); pw.print("curSourceDir="); 229 pw.println(curReceiver.applicationInfo.sourceDir); 230 } 231 } 232 if (state != IDLE) { 233 String stateStr = " (?)"; 234 switch (state) { 235 case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break; 236 case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break; 237 case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break; 238 case WAITING_SERVICES: stateStr=" (WAITING_SERVICES)"; break; 239 } 240 pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr); 241 } 242 final int N = receivers != null ? receivers.size() : 0; 243 String p2 = prefix + " "; 244 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 245 for (int i = 0; i < N; i++) { 246 Object o = receivers.get(i); 247 pw.print(prefix); 248 switch (delivery[i]) { 249 case DELIVERY_PENDING: pw.print("Pending"); break; 250 case DELIVERY_DELIVERED: pw.print("Deliver"); break; 251 case DELIVERY_SKIPPED: pw.print("Skipped"); break; 252 case DELIVERY_TIMEOUT: pw.print("Timeout"); break; 253 default: pw.print("???????"); break; 254 } 255 pw.print(" "); TimeUtils.formatDuration(duration[i], pw); 256 pw.print(" #"); pw.print(i); pw.print(": "); 257 if (o instanceof BroadcastFilter) { 258 pw.println(o); 259 ((BroadcastFilter) o).dumpBrief(pw, p2); 260 } else if (o instanceof ResolveInfo) { 261 pw.println("(manifest)"); 262 ((ResolveInfo) o).dump(printer, p2, 0); 263 } else { 264 pw.println(o); 265 } 266 } 267 } 268 BroadcastRecord(BroadcastQueue _queue, Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType, String[] _requiredPermissions, String[] _excludedPermissions, String[] _excludedPackages, int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId, boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken, boolean timeoutExempt)269 BroadcastRecord(BroadcastQueue _queue, 270 Intent _intent, ProcessRecord _callerApp, String _callerPackage, 271 @Nullable String _callerFeatureId, int _callingPid, int _callingUid, 272 boolean _callerInstantApp, String _resolvedType, 273 String[] _requiredPermissions, String[] _excludedPermissions, 274 String[] _excludedPackages, int _appOp, 275 BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode, 276 String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, 277 boolean _initialSticky, int _userId, boolean allowBackgroundActivityStarts, 278 @Nullable IBinder backgroundActivityStartsToken, boolean timeoutExempt) { 279 if (_intent == null) { 280 throw new NullPointerException("Can't construct with a null intent"); 281 } 282 queue = _queue; 283 intent = _intent; 284 targetComp = _intent.getComponent(); 285 callerApp = _callerApp; 286 callerPackage = _callerPackage; 287 callerFeatureId = _callerFeatureId; 288 callingPid = _callingPid; 289 callingUid = _callingUid; 290 callerInstantApp = _callerInstantApp; 291 resolvedType = _resolvedType; 292 requiredPermissions = _requiredPermissions; 293 excludedPermissions = _excludedPermissions; 294 excludedPackages = _excludedPackages; 295 appOp = _appOp; 296 options = _options; 297 receivers = _receivers; 298 delivery = new int[_receivers != null ? _receivers.size() : 0]; 299 duration = new long[delivery.length]; 300 resultTo = _resultTo; 301 resultCode = _resultCode; 302 resultData = _resultData; 303 resultExtras = _resultExtras; 304 ordered = _serialized; 305 sticky = _sticky; 306 initialSticky = _initialSticky; 307 userId = _userId; 308 nextReceiver = 0; 309 state = IDLE; 310 this.allowBackgroundActivityStarts = allowBackgroundActivityStarts; 311 mBackgroundActivityStartsToken = backgroundActivityStartsToken; 312 this.timeoutExempt = timeoutExempt; 313 alarm = options != null && options.isAlarmBroadcast(); 314 pushMessage = options != null && options.isPushMessagingBroadcast(); 315 pushMessageOverQuota = options != null && options.isPushMessagingOverQuotaBroadcast(); 316 } 317 318 /** 319 * Copy constructor which takes a different intent. 320 * Only used by {@link #maybeStripForHistory}. 321 */ BroadcastRecord(BroadcastRecord from, Intent newIntent)322 private BroadcastRecord(BroadcastRecord from, Intent newIntent) { 323 intent = newIntent; 324 targetComp = newIntent.getComponent(); 325 326 callerApp = from.callerApp; 327 callerPackage = from.callerPackage; 328 callerFeatureId = from.callerFeatureId; 329 callingPid = from.callingPid; 330 callingUid = from.callingUid; 331 callerInstantApp = from.callerInstantApp; 332 ordered = from.ordered; 333 sticky = from.sticky; 334 initialSticky = from.initialSticky; 335 userId = from.userId; 336 resolvedType = from.resolvedType; 337 requiredPermissions = from.requiredPermissions; 338 excludedPermissions = from.excludedPermissions; 339 excludedPackages = from.excludedPackages; 340 appOp = from.appOp; 341 options = from.options; 342 receivers = from.receivers; 343 delivery = from.delivery; 344 duration = from.duration; 345 resultTo = from.resultTo; 346 enqueueTime = from.enqueueTime; 347 enqueueRealTime = from.enqueueRealTime; 348 enqueueClockTime = from.enqueueClockTime; 349 dispatchTime = from.dispatchTime; 350 dispatchRealTime = from.dispatchRealTime; 351 dispatchClockTime = from.dispatchClockTime; 352 receiverTime = from.receiverTime; 353 finishTime = from.finishTime; 354 resultCode = from.resultCode; 355 resultData = from.resultData; 356 resultExtras = from.resultExtras; 357 resultAbort = from.resultAbort; 358 nextReceiver = from.nextReceiver; 359 receiver = from.receiver; 360 state = from.state; 361 anrCount = from.anrCount; 362 manifestCount = from.manifestCount; 363 manifestSkipCount = from.manifestSkipCount; 364 queue = from.queue; 365 allowBackgroundActivityStarts = from.allowBackgroundActivityStarts; 366 mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken; 367 timeoutExempt = from.timeoutExempt; 368 alarm = from.alarm; 369 pushMessage = from.pushMessage; 370 pushMessageOverQuota = from.pushMessageOverQuota; 371 } 372 373 /** 374 * Split off a new BroadcastRecord that clones this one, but contains only the 375 * recipient records for the current (just-finished) receiver's app, starting 376 * after the just-finished receiver [i.e. at r.nextReceiver]. Returns null 377 * if there are no matching subsequent receivers in this BroadcastRecord. 378 */ splitRecipientsLocked(int slowAppUid, int startingAt)379 BroadcastRecord splitRecipientsLocked(int slowAppUid, int startingAt) { 380 // Do we actually have any matching receivers down the line...? 381 ArrayList splitReceivers = null; 382 for (int i = startingAt; i < receivers.size(); ) { 383 Object o = receivers.get(i); 384 if (getReceiverUid(o) == slowAppUid) { 385 if (splitReceivers == null) { 386 splitReceivers = new ArrayList<>(); 387 } 388 splitReceivers.add(o); 389 receivers.remove(i); 390 } else { 391 i++; 392 } 393 } 394 395 // No later receivers in the same app, so we have no more to do 396 if (splitReceivers == null) { 397 return null; 398 } 399 400 // build a new BroadcastRecord around that single-target list 401 BroadcastRecord split = new BroadcastRecord(queue, intent, callerApp, callerPackage, 402 callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, 403 requiredPermissions, excludedPermissions, excludedPackages, appOp, options, 404 splitReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, 405 initialSticky, userId, allowBackgroundActivityStarts, 406 mBackgroundActivityStartsToken, timeoutExempt); 407 split.enqueueTime = this.enqueueTime; 408 split.enqueueRealTime = this.enqueueRealTime; 409 split.enqueueClockTime = this.enqueueClockTime; 410 split.splitToken = this.splitToken; 411 return split; 412 } 413 414 /** 415 * Split a BroadcastRecord to a map of deferred receiver UID to deferred BroadcastRecord. 416 * 417 * The receivers that are deferred are removed from original BroadcastRecord's receivers list. 418 * The receivers that are not deferred are kept in original BroadcastRecord's receivers list. 419 * 420 * Only used to split LOCKED_BOOT_COMPLETED or BOOT_COMPLETED BroadcastRecord. 421 * LOCKED_BOOT_COMPLETED or BOOT_COMPLETED broadcast can be deferred until the first time 422 * the receiver's UID has a process started. 423 * 424 * @param ams The ActivityManagerService object. 425 * @param deferType Defer what UID? 426 * @return the deferred UID to BroadcastRecord map, the BroadcastRecord has the list of 427 * receivers in that UID. 428 */ splitDeferredBootCompletedBroadcastLocked( ActivityManagerInternal activityManagerInternal, @BroadcastConstants.DeferBootCompletedBroadcastType int deferType)429 @NonNull SparseArray<BroadcastRecord> splitDeferredBootCompletedBroadcastLocked( 430 ActivityManagerInternal activityManagerInternal, 431 @BroadcastConstants.DeferBootCompletedBroadcastType int deferType) { 432 final SparseArray<BroadcastRecord> ret = new SparseArray<>(); 433 if (deferType == DEFER_BOOT_COMPLETED_BROADCAST_NONE) { 434 return ret; 435 } 436 437 if (receivers == null) { 438 return ret; 439 } 440 441 final String action = intent.getAction(); 442 if (!Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action) 443 && !Intent.ACTION_BOOT_COMPLETED.equals(action)) { 444 return ret; 445 } 446 447 final SparseArray<List<Object>> uid2receiverList = new SparseArray<>(); 448 for (int i = receivers.size() - 1; i >= 0; i--) { 449 final Object receiver = receivers.get(i); 450 final int uid = getReceiverUid(receiver); 451 if (deferType != DEFER_BOOT_COMPLETED_BROADCAST_ALL) { 452 if ((deferType & DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY) != 0) { 453 if (activityManagerInternal.getRestrictionLevel(uid) 454 < RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) { 455 // skip if the UID is not background restricted. 456 continue; 457 } 458 } 459 if ((deferType & DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY) != 0) { 460 if (!CompatChanges.isChangeEnabled(DEFER_BOOT_COMPLETED_BROADCAST_CHANGE_ID, 461 uid)) { 462 // skip if the UID is not targetSdkVersion T+. 463 continue; 464 } 465 } 466 } 467 // Remove receiver from original BroadcastRecord's receivers list. 468 receivers.remove(i); 469 final List<Object> receiverList = uid2receiverList.get(uid); 470 if (receiverList != null) { 471 receiverList.add(0, receiver); 472 } else { 473 ArrayList<Object> splitReceivers = new ArrayList<>(); 474 splitReceivers.add(0, receiver); 475 uid2receiverList.put(uid, splitReceivers); 476 } 477 } 478 final int uidSize = uid2receiverList.size(); 479 for (int i = 0; i < uidSize; i++) { 480 final BroadcastRecord br = new BroadcastRecord(queue, intent, callerApp, callerPackage, 481 callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, 482 requiredPermissions, excludedPermissions, excludedPackages, appOp, options, 483 uid2receiverList.valueAt(i), null /* _resultTo */, 484 resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, 485 allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt); 486 br.enqueueTime = this.enqueueTime; 487 br.enqueueRealTime = this.enqueueRealTime; 488 br.enqueueClockTime = this.enqueueClockTime; 489 ret.put(uid2receiverList.keyAt(i), br); 490 } 491 return ret; 492 } 493 getReceiverUid(Object receiver)494 int getReceiverUid(Object receiver) { 495 if (receiver instanceof BroadcastFilter) { 496 return ((BroadcastFilter) receiver).owningUid; 497 } else /* if (receiver instanceof ResolveInfo) */ { 498 return ((ResolveInfo) receiver).activityInfo.applicationInfo.uid; 499 } 500 } 501 maybeStripForHistory()502 public BroadcastRecord maybeStripForHistory() { 503 if (!intent.canStripForHistory()) { 504 return this; 505 } 506 return new BroadcastRecord(this, intent.maybeStripForHistory()); 507 } 508 509 @VisibleForTesting cleanupDisabledPackageReceiversLocked( String packageName, Set<String> filterByClasses, int userId, boolean doit)510 boolean cleanupDisabledPackageReceiversLocked( 511 String packageName, Set<String> filterByClasses, int userId, boolean doit) { 512 if (receivers == null) { 513 return false; 514 } 515 516 final boolean cleanupAllUsers = userId == UserHandle.USER_ALL; 517 final boolean sendToAllUsers = this.userId == UserHandle.USER_ALL; 518 if (this.userId != userId && !cleanupAllUsers && !sendToAllUsers) { 519 return false; 520 } 521 522 boolean didSomething = false; 523 Object o; 524 for (int i = receivers.size() - 1; i >= 0; i--) { 525 o = receivers.get(i); 526 if (!(o instanceof ResolveInfo)) { 527 continue; 528 } 529 ActivityInfo info = ((ResolveInfo)o).activityInfo; 530 531 final boolean sameComponent = packageName == null 532 || (info.applicationInfo.packageName.equals(packageName) 533 && (filterByClasses == null || filterByClasses.contains(info.name))); 534 if (sameComponent && (cleanupAllUsers 535 || UserHandle.getUserId(info.applicationInfo.uid) == userId)) { 536 if (!doit) { 537 return true; 538 } 539 didSomething = true; 540 receivers.remove(i); 541 if (i < nextReceiver) { 542 nextReceiver--; 543 } 544 } 545 } 546 nextReceiver = Math.min(nextReceiver, receivers.size()); 547 548 return didSomething; 549 } 550 551 @Override toString()552 public String toString() { 553 return "BroadcastRecord{" 554 + Integer.toHexString(System.identityHashCode(this)) 555 + " u" + userId + " " + intent.getAction() + "}"; 556 } 557 dumpDebug(ProtoOutputStream proto, long fieldId)558 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 559 long token = proto.start(fieldId); 560 proto.write(BroadcastRecordProto.USER_ID, userId); 561 proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction()); 562 proto.end(token); 563 } 564 } 565