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.AppProtoEnums.BROADCAST_TYPE_ALARM; 20 import static android.app.AppProtoEnums.BROADCAST_TYPE_BACKGROUND; 21 import static android.app.AppProtoEnums.BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE; 22 import static android.app.AppProtoEnums.BROADCAST_TYPE_FOREGROUND; 23 import static android.app.AppProtoEnums.BROADCAST_TYPE_INITIAL_STICKY; 24 import static android.app.AppProtoEnums.BROADCAST_TYPE_INTERACTIVE; 25 import static android.app.AppProtoEnums.BROADCAST_TYPE_NONE; 26 import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED; 27 import static android.app.AppProtoEnums.BROADCAST_TYPE_PRIORITIZED; 28 import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE; 29 import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA; 30 import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO; 31 import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY; 32 33 import android.annotation.CheckResult; 34 import android.annotation.CurrentTimeMillisLong; 35 import android.annotation.ElapsedRealtimeLong; 36 import android.annotation.IntDef; 37 import android.annotation.NonNull; 38 import android.annotation.Nullable; 39 import android.annotation.UptimeMillisLong; 40 import android.app.ActivityManager.ProcessState; 41 import android.app.AppOpsManager; 42 import android.app.BackgroundStartPrivileges; 43 import android.app.BroadcastOptions; 44 import android.app.BroadcastOptions.DeliveryGroupPolicy; 45 import android.content.ComponentName; 46 import android.content.IIntentReceiver; 47 import android.content.Intent; 48 import android.content.IntentFilter; 49 import android.content.pm.ActivityInfo; 50 import android.content.pm.ResolveInfo; 51 import android.os.Binder; 52 import android.os.Bundle; 53 import android.os.SystemClock; 54 import android.os.UserHandle; 55 import android.util.ArrayMap; 56 import android.util.PrintWriterPrinter; 57 import android.util.TimeUtils; 58 import android.util.proto.ProtoOutputStream; 59 60 import com.android.internal.annotations.VisibleForTesting; 61 62 import dalvik.annotation.optimization.NeverCompile; 63 64 import java.io.PrintWriter; 65 import java.lang.annotation.Retention; 66 import java.lang.annotation.RetentionPolicy; 67 import java.text.SimpleDateFormat; 68 import java.util.Arrays; 69 import java.util.Date; 70 import java.util.List; 71 import java.util.Objects; 72 import java.util.Set; 73 import java.util.function.BiFunction; 74 75 /** 76 * An active intent broadcast. 77 */ 78 final class BroadcastRecord extends Binder { 79 final @NonNull Intent intent; // the original intent that generated us 80 final @Nullable ComponentName targetComp; // original component name set on the intent 81 final @Nullable ProcessRecord callerApp; // process that sent this 82 final @Nullable String callerPackage; // who sent this 83 final @Nullable String callerFeatureId; // which feature in the package sent this 84 final int callingPid; // the pid of who sent this 85 final int callingUid; // the uid of who sent this 86 final @ProcessState int callerProcState; // Procstate of the caller process at enqueue time. 87 88 final int originalStickyCallingUid; 89 // if this is a sticky broadcast, the Uid of the original sender 90 final boolean callerInstantApp; // caller is an Instant App? 91 final boolean callerInstrumented; // caller is being instrumented? 92 final boolean ordered; // serialize the send to receivers? 93 final boolean sticky; // originated from existing sticky data? 94 final boolean alarm; // originated from an alarm triggering? 95 final boolean pushMessage; // originated from a push message? 96 final boolean pushMessageOverQuota; // originated from a push message which was over quota? 97 final boolean interactive; // originated from user interaction? 98 final boolean initialSticky; // initial broadcast from register to sticky? 99 final boolean prioritized; // contains more than one priority tranche 100 final boolean deferUntilActive; // infinitely deferrable broadcast 101 final boolean shareIdentity; // whether the broadcaster's identity should be shared 102 final boolean urgent; // has been classified as "urgent" 103 final int userId; // user id this broadcast was for 104 final @Nullable String resolvedType; // the resolved data type 105 final @Nullable String[] requiredPermissions; // permissions the caller has required 106 final @Nullable String[] excludedPermissions; // permissions to exclude 107 final @Nullable String[] excludedPackages; // packages to exclude 108 final int appOp; // an app op that is associated with this broadcast 109 final @Nullable BroadcastOptions options; // BroadcastOptions supplied by caller 110 final @NonNull List<Object> receivers; // contains BroadcastFilter and ResolveInfo 111 final @DeliveryState int[] delivery; // delivery state of each receiver 112 final @NonNull String[] deliveryReasons; // reasons for delivery state of each receiver 113 final int[] blockedUntilBeyondCount; // blocked until count of each receiver 114 @Nullable ProcessRecord resultToApp; // who receives final result if non-null 115 @Nullable IIntentReceiver resultTo; // who receives final result if non-null 116 @UptimeMillisLong long enqueueTime; // when broadcast enqueued 117 @ElapsedRealtimeLong long enqueueRealTime; // when broadcast enqueued 118 @CurrentTimeMillisLong long enqueueClockTime; // when broadcast enqueued 119 // When broadcast is originally enqueued. Only used in case of replacing broadcasts 120 // with FLAG_RECEIVER_REPLACE_PENDING. If it is 0, then 'enqueueClockTime' is the original 121 // enqueue time. 122 @UptimeMillisLong long originalEnqueueClockTime; 123 @UptimeMillisLong long dispatchTime; // when broadcast dispatch started 124 @ElapsedRealtimeLong long dispatchRealTime; // when broadcast dispatch started 125 @CurrentTimeMillisLong long dispatchClockTime; // when broadcast dispatch started 126 @UptimeMillisLong long receiverTime; // when receiver started for timeouts 127 @UptimeMillisLong long finishTime; // when broadcast finished 128 final @UptimeMillisLong long[] scheduledTime; // when each receiver was scheduled 129 final @UptimeMillisLong long[] terminalTime; // when each receiver was terminal 130 final boolean timeoutExempt; // true if this broadcast is not subject to receiver timeouts 131 int resultCode; // current result code value. 132 @Nullable String resultData; // current result data value. 133 @Nullable Bundle resultExtras; // current result extra data values. 134 boolean resultAbort; // current result abortBroadcast value. 135 int nextReceiver; // next receiver to be executed. 136 int state; 137 int anrCount; // has this broadcast record hit any ANRs? 138 int manifestCount; // number of manifest receivers dispatched. 139 int manifestSkipCount; // number of manifest receivers skipped. 140 int terminalCount; // number of receivers in terminal state. 141 int deferredCount; // number of receivers in deferred state. 142 int beyondCount; // high-water number of receivers we've moved beyond. 143 @Nullable BroadcastQueue queue; // the outbound queue handling this broadcast 144 145 // Determines the privileges the app's process has in regard to background starts. 146 final BackgroundStartPrivileges mBackgroundStartPrivileges; 147 148 // Filter the intent extras by using the rules of the package visibility before broadcasting 149 // the intent to the receiver. 150 @Nullable 151 final BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver; 152 153 // Cache of records that are "matching" this. Only used at the time of enqueuing this record 154 // into the queue. 155 @Nullable 156 private ArrayMap<BroadcastRecord, Boolean> mMatchingRecordsCache; 157 158 private @Nullable String mCachedToString; 159 private @Nullable String mCachedToShortString; 160 161 /** 162 * When enabled, assume that {@link UserHandle#isCore(int)} apps should 163 * treat {@link BroadcastOptions#DEFERRAL_POLICY_DEFAULT} as 164 * {@link BroadcastOptions#DEFERRAL_POLICY_UNTIL_ACTIVE}. 165 */ 166 static boolean CORE_DEFER_UNTIL_ACTIVE = false; 167 168 /** Empty immutable list of receivers */ 169 static final List<Object> EMPTY_RECEIVERS = List.of(); 170 171 static final int IDLE = 0; 172 static final int APP_RECEIVE = 1; 173 static final int CALL_IN_RECEIVE = 2; 174 static final int CALL_DONE_RECEIVE = 3; 175 static final int WAITING_SERVICES = 4; 176 177 /** Initial state: waiting to run in future */ 178 static final int DELIVERY_PENDING = 0; 179 /** Terminal state: finished successfully */ 180 static final int DELIVERY_DELIVERED = 1; 181 /** Terminal state: skipped due to internal policy */ 182 static final int DELIVERY_SKIPPED = 2; 183 /** Terminal state: timed out during attempted delivery */ 184 static final int DELIVERY_TIMEOUT = 3; 185 /** Intermediate state: currently executing */ 186 static final int DELIVERY_SCHEDULED = 4; 187 /** Terminal state: failure to dispatch */ 188 static final int DELIVERY_FAILURE = 5; 189 /** Intermediate state: currently deferred while app is cached */ 190 static final int DELIVERY_DEFERRED = 6; 191 192 @IntDef(flag = false, prefix = { "DELIVERY_" }, value = { 193 DELIVERY_PENDING, 194 DELIVERY_DELIVERED, 195 DELIVERY_SKIPPED, 196 DELIVERY_TIMEOUT, 197 DELIVERY_SCHEDULED, 198 DELIVERY_FAILURE, 199 DELIVERY_DEFERRED, 200 }) 201 @Retention(RetentionPolicy.SOURCE) 202 public @interface DeliveryState {} 203 deliveryStateToString(@eliveryState int deliveryState)204 static @NonNull String deliveryStateToString(@DeliveryState int deliveryState) { 205 switch (deliveryState) { 206 case DELIVERY_PENDING: return "PENDING"; 207 case DELIVERY_DELIVERED: return "DELIVERED"; 208 case DELIVERY_SKIPPED: return "SKIPPED"; 209 case DELIVERY_TIMEOUT: return "TIMEOUT"; 210 case DELIVERY_SCHEDULED: return "SCHEDULED"; 211 case DELIVERY_FAILURE: return "FAILURE"; 212 case DELIVERY_DEFERRED: return "DEFERRED"; 213 default: return Integer.toString(deliveryState); 214 } 215 } 216 217 /** 218 * Return if the given delivery state is "terminal", where no additional 219 * delivery state changes will be made. 220 */ isDeliveryStateTerminal(@eliveryState int deliveryState)221 static boolean isDeliveryStateTerminal(@DeliveryState int deliveryState) { 222 switch (deliveryState) { 223 case DELIVERY_DELIVERED: 224 case DELIVERY_SKIPPED: 225 case DELIVERY_TIMEOUT: 226 case DELIVERY_FAILURE: 227 return true; 228 default: 229 return false; 230 } 231 } 232 233 /** 234 * Return if the given delivery state is "beyond", which means that we've 235 * moved beyond this receiver, and future receivers are now unblocked. 236 */ isDeliveryStateBeyond(@eliveryState int deliveryState)237 static boolean isDeliveryStateBeyond(@DeliveryState int deliveryState) { 238 switch (deliveryState) { 239 case DELIVERY_DELIVERED: 240 case DELIVERY_SKIPPED: 241 case DELIVERY_TIMEOUT: 242 case DELIVERY_FAILURE: 243 case DELIVERY_DEFERRED: 244 return true; 245 default: 246 return false; 247 } 248 } 249 250 /** 251 * Return true if this receiver should be assumed to have been delivered. 252 */ isAssumedDelivered(int index)253 boolean isAssumedDelivered(int index) { 254 return (receivers.get(index) instanceof BroadcastFilter) && !ordered 255 && (resultTo == null); 256 } 257 258 ProcessRecord curApp; // hosting application of current receiver. 259 ComponentName curComponent; // the receiver class that is currently running. 260 ActivityInfo curReceiver; // the manifest receiver that is currently running. 261 BroadcastFilter curFilter; // the registered receiver currently running. 262 Bundle curFilteredExtras; // the bundle that has been filtered by the package visibility rules 263 264 @NeverCompile dump(PrintWriter pw, String prefix, SimpleDateFormat sdf)265 void dump(PrintWriter pw, String prefix, SimpleDateFormat sdf) { 266 final long now = SystemClock.uptimeMillis(); 267 268 pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId); 269 pw.print(prefix); pw.println(intent.toInsecureString()); 270 if (targetComp != null && targetComp != intent.getComponent()) { 271 pw.print(prefix); pw.print(" targetComp: "); pw.println(targetComp.toShortString()); 272 } 273 Bundle bundle = intent.getExtras(); 274 if (bundle != null) { 275 pw.print(prefix); pw.print(" extras: "); pw.println(bundle.toString()); 276 } 277 pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" "); 278 pw.print(callerApp != null ? callerApp.toShortString() : "null"); 279 pw.print(" pid="); pw.print(callingPid); 280 pw.print(" uid="); pw.println(callingUid); 281 if ((requiredPermissions != null && requiredPermissions.length > 0) 282 || appOp != AppOpsManager.OP_NONE) { 283 pw.print(prefix); pw.print("requiredPermissions="); 284 pw.print(Arrays.toString(requiredPermissions)); 285 pw.print(" appOp="); pw.println(appOp); 286 } 287 if (excludedPermissions != null && excludedPermissions.length > 0) { 288 pw.print(prefix); pw.print("excludedPermissions="); 289 pw.print(Arrays.toString(excludedPermissions)); 290 } 291 if (excludedPackages != null && excludedPackages.length > 0) { 292 pw.print(prefix); pw.print("excludedPackages="); 293 pw.print(Arrays.toString(excludedPackages)); 294 } 295 if (options != null) { 296 pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); 297 } 298 pw.print(prefix); pw.print("enqueueClockTime="); 299 pw.print(sdf.format(new Date(enqueueClockTime))); 300 pw.print(" dispatchClockTime="); 301 pw.print(sdf.format(new Date(dispatchClockTime))); 302 if (originalEnqueueClockTime > 0) { 303 pw.print(" originalEnqueueClockTime="); 304 pw.print(sdf.format(new Date(originalEnqueueClockTime))); 305 } 306 pw.println(); 307 pw.print(prefix); pw.print("dispatchTime="); 308 TimeUtils.formatDuration(dispatchTime, now, pw); 309 pw.print(" ("); 310 TimeUtils.formatDuration(dispatchTime - enqueueTime, pw); 311 pw.print(" since enq)"); 312 if (finishTime != 0) { 313 pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw); 314 pw.print(" ("); 315 TimeUtils.formatDuration(finishTime-dispatchTime, pw); 316 pw.print(" since disp)"); 317 } else { 318 pw.print(" receiverTime="); TimeUtils.formatDuration(receiverTime, now, pw); 319 } 320 pw.println(""); 321 if (anrCount != 0) { 322 pw.print(prefix); pw.print("anrCount="); pw.println(anrCount); 323 } 324 if (resultTo != null || resultCode != -1 || resultData != null) { 325 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo); 326 pw.print(" resultCode="); pw.print(resultCode); 327 pw.print(" resultData="); pw.println(resultData); 328 } 329 if (resultExtras != null) { 330 pw.print(prefix); pw.print("resultExtras="); pw.println(resultExtras); 331 } 332 if (resultAbort || ordered || sticky || initialSticky) { 333 pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort); 334 pw.print(" ordered="); pw.print(ordered); 335 pw.print(" sticky="); pw.print(sticky); 336 pw.print(" initialSticky="); pw.print(initialSticky); 337 pw.print(" originalStickyCallingUid="); pw.println(originalStickyCallingUid); 338 } 339 if (nextReceiver != 0) { 340 pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver); 341 } 342 if (curFilter != null) { 343 pw.print(prefix); pw.print("curFilter="); pw.println(curFilter); 344 } 345 if (curReceiver != null) { 346 pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver); 347 } 348 if (curApp != null) { 349 pw.print(prefix); pw.print("curApp="); pw.println(curApp); 350 pw.print(prefix); pw.print("curComponent="); 351 pw.println((curComponent != null ? curComponent.toShortString() : "--")); 352 if (curReceiver != null && curReceiver.applicationInfo != null) { 353 pw.print(prefix); pw.print("curSourceDir="); 354 pw.println(curReceiver.applicationInfo.sourceDir); 355 } 356 } 357 if (curFilteredExtras != null) { 358 pw.print(" filtered extras: "); pw.println(curFilteredExtras); 359 } 360 if (state != IDLE) { 361 String stateStr = " (?)"; 362 switch (state) { 363 case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break; 364 case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break; 365 case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break; 366 case WAITING_SERVICES: stateStr=" (WAITING_SERVICES)"; break; 367 } 368 pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr); 369 } 370 pw.print(prefix); pw.print("terminalCount="); pw.println(terminalCount); 371 final int N = receivers != null ? receivers.size() : 0; 372 String p2 = prefix + " "; 373 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 374 for (int i = 0; i < N; i++) { 375 Object o = receivers.get(i); 376 pw.print(prefix); 377 pw.print(deliveryStateToString(delivery[i])); 378 pw.print(' '); 379 if (scheduledTime[i] != 0) { 380 pw.print("scheduled "); 381 TimeUtils.formatDuration(scheduledTime[i] - enqueueTime, pw); 382 pw.print(' '); 383 } 384 if (terminalTime[i] != 0) { 385 pw.print("terminal "); 386 TimeUtils.formatDuration(terminalTime[i] - scheduledTime[i], pw); 387 pw.print(' '); 388 } 389 pw.print("("); pw.print(blockedUntilBeyondCount[i]); pw.print(") "); 390 pw.print("#"); pw.print(i); pw.print(": "); 391 if (o instanceof BroadcastFilter) { 392 pw.println(o); 393 ((BroadcastFilter) o).dumpBrief(pw, p2); 394 } else if (o instanceof ResolveInfo) { 395 pw.println("(manifest)"); 396 ((ResolveInfo) o).dump(printer, p2, 0); 397 } else { 398 pw.println(o); 399 } 400 if (deliveryReasons[i] != null) { 401 pw.print(p2); pw.print("reason: "); pw.println(deliveryReasons[i]); 402 } 403 } 404 } 405 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, ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, boolean serialized, boolean sticky, boolean initialSticky, int userId, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, int callerAppProcessState)406 BroadcastRecord(BroadcastQueue queue, 407 Intent intent, ProcessRecord callerApp, String callerPackage, 408 @Nullable String callerFeatureId, int callingPid, int callingUid, 409 boolean callerInstantApp, String resolvedType, 410 String[] requiredPermissions, String[] excludedPermissions, 411 String[] excludedPackages, int appOp, 412 BroadcastOptions options, List receivers, 413 ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode, 414 String resultData, Bundle resultExtras, boolean serialized, boolean sticky, 415 boolean initialSticky, int userId, 416 @NonNull BackgroundStartPrivileges backgroundStartPrivileges, 417 boolean timeoutExempt, 418 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 419 int callerAppProcessState) { 420 this(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, 421 callingUid, callerInstantApp, resolvedType, requiredPermissions, 422 excludedPermissions, excludedPackages, appOp, options, receivers, resultToApp, 423 resultTo, resultCode, resultData, resultExtras, serialized, sticky, 424 initialSticky, userId, -1, backgroundStartPrivileges, timeoutExempt, 425 filterExtrasForReceiver, callerAppProcessState); 426 } 427 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, ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId, int originalStickyCallingUid, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, int callerAppProcessState)428 BroadcastRecord(BroadcastQueue _queue, 429 Intent _intent, ProcessRecord _callerApp, String _callerPackage, 430 @Nullable String _callerFeatureId, int _callingPid, int _callingUid, 431 boolean _callerInstantApp, String _resolvedType, 432 String[] _requiredPermissions, String[] _excludedPermissions, 433 String[] _excludedPackages, int _appOp, 434 BroadcastOptions _options, List _receivers, 435 ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode, 436 String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, 437 boolean _initialSticky, int _userId, int originalStickyCallingUid, 438 @NonNull BackgroundStartPrivileges backgroundStartPrivileges, 439 boolean timeoutExempt, 440 @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, 441 int callerAppProcessState) { 442 if (_intent == null) { 443 throw new NullPointerException("Can't construct with a null intent"); 444 } 445 queue = _queue; 446 intent = Objects.requireNonNull(_intent); 447 targetComp = _intent.getComponent(); 448 callerApp = _callerApp; 449 callerPackage = _callerPackage; 450 callerFeatureId = _callerFeatureId; 451 callingPid = _callingPid; 452 callingUid = _callingUid; 453 callerProcState = callerAppProcessState; 454 callerInstantApp = _callerInstantApp; 455 callerInstrumented = isCallerInstrumented(_callerApp, _callingUid); 456 resolvedType = _resolvedType; 457 requiredPermissions = _requiredPermissions; 458 excludedPermissions = _excludedPermissions; 459 excludedPackages = _excludedPackages; 460 appOp = _appOp; 461 options = _options; 462 receivers = (_receivers != null) ? _receivers : EMPTY_RECEIVERS; 463 delivery = new int[_receivers != null ? _receivers.size() : 0]; 464 deliveryReasons = new String[delivery.length]; 465 urgent = calculateUrgent(_intent, _options); 466 deferUntilActive = calculateDeferUntilActive(_callingUid, 467 _options, _resultTo, _serialized, urgent); 468 blockedUntilBeyondCount = calculateBlockedUntilBeyondCount(receivers, _serialized); 469 scheduledTime = new long[delivery.length]; 470 terminalTime = new long[delivery.length]; 471 resultToApp = _resultToApp; 472 resultTo = _resultTo; 473 resultCode = _resultCode; 474 resultData = _resultData; 475 resultExtras = _resultExtras; 476 ordered = _serialized; 477 sticky = _sticky; 478 initialSticky = _initialSticky; 479 prioritized = isPrioritized(blockedUntilBeyondCount, _serialized); 480 userId = _userId; 481 nextReceiver = 0; 482 state = IDLE; 483 mBackgroundStartPrivileges = backgroundStartPrivileges; 484 this.timeoutExempt = timeoutExempt; 485 alarm = options != null && options.isAlarmBroadcast(); 486 pushMessage = options != null && options.isPushMessagingBroadcast(); 487 pushMessageOverQuota = options != null && options.isPushMessagingOverQuotaBroadcast(); 488 interactive = options != null && options.isInteractive(); 489 shareIdentity = options != null && options.isShareIdentityEnabled(); 490 this.filterExtrasForReceiver = filterExtrasForReceiver; 491 this.originalStickyCallingUid = originalStickyCallingUid; 492 } 493 494 /** 495 * Copy constructor which takes a different intent. 496 * Only used by {@link #maybeStripForHistory}. 497 */ BroadcastRecord(BroadcastRecord from, Intent newIntent)498 private BroadcastRecord(BroadcastRecord from, Intent newIntent) { 499 intent = Objects.requireNonNull(newIntent); 500 targetComp = newIntent.getComponent(); 501 502 callerApp = from.callerApp; 503 callerPackage = from.callerPackage; 504 callerFeatureId = from.callerFeatureId; 505 callingPid = from.callingPid; 506 callingUid = from.callingUid; 507 callerProcState = from.callerProcState; 508 callerInstantApp = from.callerInstantApp; 509 callerInstrumented = from.callerInstrumented; 510 ordered = from.ordered; 511 sticky = from.sticky; 512 initialSticky = from.initialSticky; 513 prioritized = from.prioritized; 514 userId = from.userId; 515 resolvedType = from.resolvedType; 516 requiredPermissions = from.requiredPermissions; 517 excludedPermissions = from.excludedPermissions; 518 excludedPackages = from.excludedPackages; 519 appOp = from.appOp; 520 options = from.options; 521 receivers = from.receivers; 522 delivery = from.delivery; 523 deliveryReasons = from.deliveryReasons; 524 deferUntilActive = from.deferUntilActive; 525 blockedUntilBeyondCount = from.blockedUntilBeyondCount; 526 scheduledTime = from.scheduledTime; 527 terminalTime = from.terminalTime; 528 resultToApp = from.resultToApp; 529 resultTo = from.resultTo; 530 enqueueTime = from.enqueueTime; 531 enqueueRealTime = from.enqueueRealTime; 532 enqueueClockTime = from.enqueueClockTime; 533 dispatchTime = from.dispatchTime; 534 dispatchRealTime = from.dispatchRealTime; 535 dispatchClockTime = from.dispatchClockTime; 536 receiverTime = from.receiverTime; 537 finishTime = from.finishTime; 538 resultCode = from.resultCode; 539 resultData = from.resultData; 540 resultExtras = from.resultExtras; 541 resultAbort = from.resultAbort; 542 nextReceiver = from.nextReceiver; 543 state = from.state; 544 anrCount = from.anrCount; 545 manifestCount = from.manifestCount; 546 manifestSkipCount = from.manifestSkipCount; 547 queue = from.queue; 548 mBackgroundStartPrivileges = from.mBackgroundStartPrivileges; 549 timeoutExempt = from.timeoutExempt; 550 alarm = from.alarm; 551 pushMessage = from.pushMessage; 552 pushMessageOverQuota = from.pushMessageOverQuota; 553 interactive = from.interactive; 554 shareIdentity = from.shareIdentity; 555 urgent = from.urgent; 556 filterExtrasForReceiver = from.filterExtrasForReceiver; 557 originalStickyCallingUid = from.originalStickyCallingUid; 558 } 559 560 /** 561 * Update the delivery state of the given {@link #receivers} index. 562 * Automatically updates any time measurements related to state changes. 563 * 564 * @return if {@link #beyondCount} changed due to this state transition, 565 * indicating that other events may be unblocked. 566 */ 567 @CheckResult setDeliveryState(int index, @DeliveryState int newDeliveryState, @NonNull String reason)568 boolean setDeliveryState(int index, @DeliveryState int newDeliveryState, 569 @NonNull String reason) { 570 final int oldDeliveryState = delivery[index]; 571 if (isDeliveryStateTerminal(oldDeliveryState) 572 || newDeliveryState == oldDeliveryState) { 573 // We've already arrived in terminal or requested state, so leave 574 // any statistics and reasons intact from the first transition 575 return false; 576 } 577 578 switch (oldDeliveryState) { 579 case DELIVERY_DEFERRED: 580 deferredCount--; 581 break; 582 } 583 switch (newDeliveryState) { 584 case DELIVERY_PENDING: 585 scheduledTime[index] = 0; 586 break; 587 case DELIVERY_SCHEDULED: 588 scheduledTime[index] = SystemClock.uptimeMillis(); 589 break; 590 case DELIVERY_DEFERRED: 591 deferredCount++; 592 break; 593 case DELIVERY_DELIVERED: 594 case DELIVERY_SKIPPED: 595 case DELIVERY_TIMEOUT: 596 case DELIVERY_FAILURE: 597 terminalTime[index] = SystemClock.uptimeMillis(); 598 terminalCount++; 599 break; 600 } 601 602 delivery[index] = newDeliveryState; 603 deliveryReasons[index] = reason; 604 605 // If this state change might bring us to a new high-water mark, bring 606 // ourselves as high as we possibly can 607 final int oldBeyondCount = beyondCount; 608 if (index >= beyondCount) { 609 for (int i = beyondCount; i < delivery.length; i++) { 610 if (isDeliveryStateBeyond(getDeliveryState(i))) { 611 beyondCount = i + 1; 612 } else { 613 break; 614 } 615 } 616 } 617 return (beyondCount != oldBeyondCount); 618 } 619 getDeliveryState(int index)620 @DeliveryState int getDeliveryState(int index) { 621 return delivery[index]; 622 } 623 624 /** 625 * @return if the given {@link #receivers} index should be considered 626 * blocked based on the current status of the overall broadcast. 627 */ isBlocked(int index)628 boolean isBlocked(int index) { 629 return (beyondCount < blockedUntilBeyondCount[index]); 630 } 631 wasDeliveryAttempted(int index)632 boolean wasDeliveryAttempted(int index) { 633 final int deliveryState = getDeliveryState(index); 634 switch (deliveryState) { 635 case DELIVERY_DELIVERED: 636 case DELIVERY_TIMEOUT: 637 case DELIVERY_FAILURE: 638 return true; 639 default: 640 return false; 641 } 642 } 643 copyEnqueueTimeFrom(@onNull BroadcastRecord replacedBroadcast)644 void copyEnqueueTimeFrom(@NonNull BroadcastRecord replacedBroadcast) { 645 originalEnqueueClockTime = enqueueClockTime; 646 enqueueTime = replacedBroadcast.enqueueTime; 647 enqueueRealTime = replacedBroadcast.enqueueRealTime; 648 enqueueClockTime = replacedBroadcast.enqueueClockTime; 649 } 650 isForeground()651 boolean isForeground() { 652 return (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 653 } 654 isReplacePending()655 boolean isReplacePending() { 656 return (intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 657 } 658 isNoAbort()659 boolean isNoAbort() { 660 return (intent.getFlags() & Intent.FLAG_RECEIVER_NO_ABORT) != 0; 661 } 662 isOffload()663 boolean isOffload() { 664 return (intent.getFlags() & Intent.FLAG_RECEIVER_OFFLOAD) != 0; 665 } 666 isDeferUntilActive()667 boolean isDeferUntilActive() { 668 return deferUntilActive; 669 } 670 isUrgent()671 boolean isUrgent() { 672 return urgent; 673 } 674 getHostingRecordTriggerType()675 @NonNull String getHostingRecordTriggerType() { 676 if (alarm) { 677 return HostingRecord.TRIGGER_TYPE_ALARM; 678 } else if (pushMessage) { 679 return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE; 680 } else if (pushMessageOverQuota) { 681 return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA; 682 } 683 return HostingRecord.TRIGGER_TYPE_UNKNOWN; 684 } 685 686 /** 687 * Return an instance of {@link #intent} specialized for the given receiver. 688 * For example, this returns a new specialized instance if the extras need 689 * to be filtered, or a {@link ResolveInfo} needs to be configured. 690 * 691 * @return a specialized intent, otherwise {@code null} to indicate that the 692 * broadcast should not be delivered to this receiver, typically due 693 * to it being filtered away by {@link #filterExtrasForReceiver}. 694 */ getReceiverIntent(@onNull Object receiver)695 @Nullable Intent getReceiverIntent(@NonNull Object receiver) { 696 Intent newIntent = null; 697 if (filterExtrasForReceiver != null) { 698 final Bundle extras = intent.getExtras(); 699 if (extras != null) { 700 final int receiverUid = getReceiverUid(receiver); 701 final Bundle filteredExtras = filterExtrasForReceiver.apply(receiverUid, extras); 702 if (filteredExtras == null) { 703 // Completely filtered; skip the broadcast! 704 return null; 705 } else { 706 newIntent = new Intent(intent); 707 newIntent.replaceExtras(filteredExtras); 708 } 709 } 710 } 711 if (receiver instanceof ResolveInfo) { 712 if (newIntent == null) { 713 newIntent = new Intent(intent); 714 } 715 newIntent.setComponent(((ResolveInfo) receiver).activityInfo.getComponentName()); 716 } 717 return (newIntent != null) ? newIntent : intent; 718 } 719 isCallerInstrumented(@ullable ProcessRecord callerApp, int callingUid)720 static boolean isCallerInstrumented(@Nullable ProcessRecord callerApp, int callingUid) { 721 switch (UserHandle.getAppId(callingUid)) { 722 case android.os.Process.ROOT_UID: 723 case android.os.Process.SHELL_UID: 724 // Broadcasts sent via "shell" are typically invoked by test 725 // suites, so we treat them as if the caller was instrumented 726 return true; 727 } 728 return (callerApp != null) ? (callerApp.getActiveInstrumentation() != null) : false; 729 } 730 731 /** 732 * Determine if the result of {@link #calculateBlockedUntilBeyondCount(List, boolean)} 733 * has prioritized tranches of receivers. 734 */ 735 @VisibleForTesting isPrioritized(@onNull int[] blockedUntilBeyondCount, boolean ordered)736 static boolean isPrioritized(@NonNull int[] blockedUntilBeyondCount, 737 boolean ordered) { 738 return !ordered && (blockedUntilBeyondCount.length > 0) 739 && (blockedUntilBeyondCount[0] != -1); 740 } 741 742 /** 743 * Calculate the {@link #beyondCount} that each receiver should be 744 * considered blocked until. 745 * <p> 746 * For example, in an ordered broadcast, receiver {@code N} is blocked until 747 * receiver {@code N-1} reaches a terminal or deferred state. Similarly, in 748 * a prioritized broadcast, receiver {@code N} is blocked until all 749 * receivers of a higher priority reach a terminal or deferred state. 750 * <p> 751 * When there are no beyond count constraints, the blocked value for each 752 * receiver is {@code -1}. 753 */ 754 @VisibleForTesting calculateBlockedUntilBeyondCount( @onNull List<Object> receivers, boolean ordered)755 static @NonNull int[] calculateBlockedUntilBeyondCount( 756 @NonNull List<Object> receivers, boolean ordered) { 757 final int N = receivers.size(); 758 final int[] blockedUntilBeyondCount = new int[N]; 759 int lastPriority = 0; 760 int lastPriorityIndex = 0; 761 for (int i = 0; i < N; i++) { 762 if (ordered) { 763 // When sending an ordered broadcast, we need to block this 764 // receiver until all previous receivers have terminated 765 blockedUntilBeyondCount[i] = i; 766 } else { 767 // When sending a prioritized broadcast, we only need to wait 768 // for the previous tranche of receivers to be terminated 769 final int thisPriority = getReceiverPriority(receivers.get(i)); 770 if ((i == 0) || (thisPriority != lastPriority)) { 771 lastPriority = thisPriority; 772 lastPriorityIndex = i; 773 blockedUntilBeyondCount[i] = i; 774 } else { 775 blockedUntilBeyondCount[i] = lastPriorityIndex; 776 } 777 } 778 } 779 // If the entire list is in the same priority tranche, mark as -1 to 780 // indicate that none of them need to wait 781 if (N > 0 && blockedUntilBeyondCount[N - 1] == 0) { 782 Arrays.fill(blockedUntilBeyondCount, -1); 783 } 784 return blockedUntilBeyondCount; 785 } 786 getReceiverUid(@onNull Object receiver)787 static int getReceiverUid(@NonNull Object receiver) { 788 if (receiver instanceof BroadcastFilter) { 789 return ((BroadcastFilter) receiver).owningUid; 790 } else /* if (receiver instanceof ResolveInfo) */ { 791 return ((ResolveInfo) receiver).activityInfo.applicationInfo.uid; 792 } 793 } 794 getReceiverProcessName(@onNull Object receiver)795 static @NonNull String getReceiverProcessName(@NonNull Object receiver) { 796 if (receiver instanceof BroadcastFilter) { 797 return ((BroadcastFilter) receiver).receiverList.app.processName; 798 } else /* if (receiver instanceof ResolveInfo) */ { 799 return ((ResolveInfo) receiver).activityInfo.processName; 800 } 801 } 802 getReceiverPackageName(@onNull Object receiver)803 static @NonNull String getReceiverPackageName(@NonNull Object receiver) { 804 if (receiver instanceof BroadcastFilter) { 805 return ((BroadcastFilter) receiver).receiverList.app.info.packageName; 806 } else /* if (receiver instanceof ResolveInfo) */ { 807 return ((ResolveInfo) receiver).activityInfo.packageName; 808 } 809 } 810 getReceiverClassName(@onNull Object receiver)811 static @Nullable String getReceiverClassName(@NonNull Object receiver) { 812 if (receiver instanceof BroadcastFilter) { 813 return ((BroadcastFilter) receiver).getReceiverClassName(); 814 } else /* if (receiver instanceof ResolveInfo) */ { 815 return ((ResolveInfo) receiver).activityInfo.name; 816 } 817 } 818 getReceiverPriority(@onNull Object receiver)819 static int getReceiverPriority(@NonNull Object receiver) { 820 if (receiver instanceof BroadcastFilter) { 821 return ((BroadcastFilter) receiver).getPriority(); 822 } else /* if (receiver instanceof ResolveInfo) */ { 823 return ((ResolveInfo) receiver).priority; 824 } 825 } 826 isReceiverEquals(@onNull Object a, @NonNull Object b)827 static boolean isReceiverEquals(@NonNull Object a, @NonNull Object b) { 828 if (a == b) { 829 return true; 830 } else if (a instanceof ResolveInfo && b instanceof ResolveInfo) { 831 final ResolveInfo infoA = (ResolveInfo) a; 832 final ResolveInfo infoB = (ResolveInfo) b; 833 return Objects.equals(infoA.activityInfo.packageName, infoB.activityInfo.packageName) 834 && Objects.equals(infoA.activityInfo.name, infoB.activityInfo.name); 835 } else { 836 return false; 837 } 838 } 839 840 /** 841 * Core policy determination about this broadcast's delivery prioritization 842 */ 843 @VisibleForTesting calculateUrgent(@onNull Intent intent, @Nullable BroadcastOptions options)844 static boolean calculateUrgent(@NonNull Intent intent, @Nullable BroadcastOptions options) { 845 // TODO: flags for controlling policy 846 // TODO: migrate alarm-prioritization flag to BroadcastConstants 847 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0) { 848 return true; 849 } 850 if (options != null) { 851 if (options.isInteractive()) { 852 return true; 853 } 854 if (options.isAlarmBroadcast()) { 855 return true; 856 } 857 } 858 return false; 859 } 860 861 /** 862 * Resolve the requested {@link BroadcastOptions#setDeferralPolicy(int)} 863 * against this broadcast state to determine if it should be marked as 864 * "defer until active". 865 */ 866 @VisibleForTesting calculateDeferUntilActive(int callingUid, @Nullable BroadcastOptions options, @Nullable IIntentReceiver resultTo, boolean ordered, boolean urgent)867 static boolean calculateDeferUntilActive(int callingUid, @Nullable BroadcastOptions options, 868 @Nullable IIntentReceiver resultTo, boolean ordered, boolean urgent) { 869 // Ordered broadcasts can never be deferred until active 870 if (ordered) { 871 return false; 872 } 873 874 // Unordered resultTo broadcasts are always deferred until active 875 if (!ordered && resultTo != null) { 876 return true; 877 } 878 879 // Determine if a strong preference in either direction was expressed; 880 // a preference here overrides all remaining policies 881 if (options != null) { 882 switch (options.getDeferralPolicy()) { 883 case BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE: 884 return true; 885 case BroadcastOptions.DEFERRAL_POLICY_NONE: 886 return false; 887 } 888 } 889 890 // Urgent broadcasts aren't deferred until active 891 if (urgent) { 892 return false; 893 } 894 895 // Otherwise, choose a reasonable default 896 if (CORE_DEFER_UNTIL_ACTIVE && UserHandle.isCore(callingUid)) { 897 return true; 898 } else { 899 return false; 900 } 901 } 902 calculateTypeForLogging()903 int calculateTypeForLogging() { 904 int type = BROADCAST_TYPE_NONE; 905 if (isForeground()) { 906 type |= BROADCAST_TYPE_FOREGROUND; 907 } else { 908 type |= BROADCAST_TYPE_BACKGROUND; 909 } 910 if (alarm) { 911 type |= BROADCAST_TYPE_ALARM; 912 } 913 if (interactive) { 914 type |= BROADCAST_TYPE_INTERACTIVE; 915 } 916 if (ordered) { 917 type |= BROADCAST_TYPE_ORDERED; 918 } 919 if (prioritized) { 920 type |= BROADCAST_TYPE_PRIORITIZED; 921 } 922 if (resultTo != null) { 923 type |= BROADCAST_TYPE_RESULT_TO; 924 } 925 if (deferUntilActive) { 926 type |= BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE; 927 } 928 if (pushMessage) { 929 type |= BROADCAST_TYPE_PUSH_MESSAGE; 930 } 931 if (pushMessageOverQuota) { 932 type |= BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA; 933 } 934 if (sticky) { 935 type |= BROADCAST_TYPE_STICKY; 936 } 937 if (initialSticky) { 938 type |= BROADCAST_TYPE_INITIAL_STICKY; 939 } 940 return type; 941 } 942 maybeStripForHistory()943 public BroadcastRecord maybeStripForHistory() { 944 if (!intent.canStripForHistory()) { 945 return this; 946 } 947 return new BroadcastRecord(this, intent.maybeStripForHistory()); 948 } 949 950 @VisibleForTesting cleanupDisabledPackageReceiversLocked( String packageName, Set<String> filterByClasses, int userId, boolean doit)951 boolean cleanupDisabledPackageReceiversLocked( 952 String packageName, Set<String> filterByClasses, int userId, boolean doit) { 953 if (receivers == null) { 954 return false; 955 } 956 957 final boolean cleanupAllUsers = userId == UserHandle.USER_ALL; 958 final boolean sendToAllUsers = this.userId == UserHandle.USER_ALL; 959 if (this.userId != userId && !cleanupAllUsers && !sendToAllUsers) { 960 return false; 961 } 962 963 boolean didSomething = false; 964 Object o; 965 for (int i = receivers.size() - 1; i >= 0; i--) { 966 o = receivers.get(i); 967 if (!(o instanceof ResolveInfo)) { 968 continue; 969 } 970 ActivityInfo info = ((ResolveInfo)o).activityInfo; 971 972 final boolean sameComponent = packageName == null 973 || (info.applicationInfo.packageName.equals(packageName) 974 && (filterByClasses == null || filterByClasses.contains(info.name))); 975 if (sameComponent && (cleanupAllUsers 976 || UserHandle.getUserId(info.applicationInfo.uid) == userId)) { 977 if (!doit) { 978 return true; 979 } 980 didSomething = true; 981 receivers.remove(i); 982 if (i < nextReceiver) { 983 nextReceiver--; 984 } 985 } 986 } 987 nextReceiver = Math.min(nextReceiver, receivers.size()); 988 989 return didSomething; 990 } 991 992 /** 993 * Apply special treatment to manifest receivers hosted by a singleton 994 * process, by re-targeting them at {@link UserHandle#USER_SYSTEM}. 995 */ applySingletonPolicy(@onNull ActivityManagerService service)996 void applySingletonPolicy(@NonNull ActivityManagerService service) { 997 if (receivers == null) return; 998 for (int i = 0; i < receivers.size(); i++) { 999 final Object receiver = receivers.get(i); 1000 if (receiver instanceof ResolveInfo) { 1001 final ResolveInfo info = (ResolveInfo) receiver; 1002 boolean isSingleton = false; 1003 try { 1004 isSingleton = service.isSingleton(info.activityInfo.processName, 1005 info.activityInfo.applicationInfo, 1006 info.activityInfo.name, info.activityInfo.flags); 1007 } catch (SecurityException e) { 1008 BroadcastQueue.logw(e.getMessage()); 1009 } 1010 final int receiverUid = info.activityInfo.applicationInfo.uid; 1011 if (callingUid != android.os.Process.SYSTEM_UID && isSingleton 1012 && service.isValidSingletonCall(callingUid, receiverUid)) { 1013 info.activityInfo = service.getActivityInfoForUser(info.activityInfo, 1014 UserHandle.USER_SYSTEM); 1015 } 1016 } 1017 } 1018 } 1019 containsReceiver(@onNull Object receiver)1020 boolean containsReceiver(@NonNull Object receiver) { 1021 for (int i = receivers.size() - 1; i >= 0; --i) { 1022 if (isReceiverEquals(receiver, receivers.get(i))) { 1023 return true; 1024 } 1025 } 1026 return false; 1027 } 1028 containsAllReceivers(@onNull List<Object> otherReceivers)1029 boolean containsAllReceivers(@NonNull List<Object> otherReceivers) { 1030 for (int i = otherReceivers.size() - 1; i >= 0; --i) { 1031 if (!containsReceiver(otherReceivers.get(i))) { 1032 return false; 1033 } 1034 } 1035 return true; 1036 } 1037 1038 @DeliveryGroupPolicy getDeliveryGroupPolicy()1039 int getDeliveryGroupPolicy() { 1040 return (options != null) ? options.getDeliveryGroupPolicy() 1041 : BroadcastOptions.DELIVERY_GROUP_POLICY_ALL; 1042 } 1043 matchesDeliveryGroup(@onNull BroadcastRecord other)1044 boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) { 1045 return matchesDeliveryGroup(this, other); 1046 } 1047 matchesDeliveryGroup(@onNull BroadcastRecord newRecord, @NonNull BroadcastRecord oldRecord)1048 private static boolean matchesDeliveryGroup(@NonNull BroadcastRecord newRecord, 1049 @NonNull BroadcastRecord oldRecord) { 1050 final IntentFilter newMatchingFilter = getDeliveryGroupMatchingFilter(newRecord); 1051 // If neither delivery group key nor matching filter is specified, then use 1052 // Intent.filterEquals() to identify the delivery group. 1053 if (isMatchingKeyNull(newRecord) && isMatchingKeyNull(oldRecord) 1054 && newMatchingFilter == null) { 1055 return newRecord.intent.filterEquals(oldRecord.intent); 1056 } 1057 if (newMatchingFilter != null && !newMatchingFilter.asPredicate().test(oldRecord.intent)) { 1058 return false; 1059 } 1060 return areMatchingKeysEqual(newRecord, oldRecord); 1061 } 1062 isMatchingKeyNull(@onNull BroadcastRecord record)1063 private static boolean isMatchingKeyNull(@NonNull BroadcastRecord record) { 1064 final String namespace = getDeliveryGroupMatchingNamespaceFragment(record); 1065 final String key = getDeliveryGroupMatchingKeyFragment(record); 1066 // If either namespace or key part is null, then treat the entire matching key as null. 1067 return namespace == null || key == null; 1068 } 1069 areMatchingKeysEqual(@onNull BroadcastRecord newRecord, @NonNull BroadcastRecord oldRecord)1070 private static boolean areMatchingKeysEqual(@NonNull BroadcastRecord newRecord, 1071 @NonNull BroadcastRecord oldRecord) { 1072 final String newNamespaceFragment = getDeliveryGroupMatchingNamespaceFragment(newRecord); 1073 final String oldNamespaceFragment = getDeliveryGroupMatchingNamespaceFragment(oldRecord); 1074 if (!Objects.equals(newNamespaceFragment, oldNamespaceFragment)) { 1075 return false; 1076 } 1077 1078 final String newKeyFragment = getDeliveryGroupMatchingKeyFragment(newRecord); 1079 final String oldKeyFragment = getDeliveryGroupMatchingKeyFragment(oldRecord); 1080 return Objects.equals(newKeyFragment, oldKeyFragment); 1081 } 1082 1083 @Nullable getDeliveryGroupMatchingNamespaceFragment( @onNull BroadcastRecord record)1084 private static String getDeliveryGroupMatchingNamespaceFragment( 1085 @NonNull BroadcastRecord record) { 1086 return record.options == null 1087 ? null : record.options.getDeliveryGroupMatchingNamespaceFragment(); 1088 } 1089 1090 @Nullable getDeliveryGroupMatchingKeyFragment(@onNull BroadcastRecord record)1091 private static String getDeliveryGroupMatchingKeyFragment(@NonNull BroadcastRecord record) { 1092 return record.options == null 1093 ? null : record.options.getDeliveryGroupMatchingKeyFragment(); 1094 } 1095 1096 @Nullable getDeliveryGroupMatchingFilter(@onNull BroadcastRecord record)1097 private static IntentFilter getDeliveryGroupMatchingFilter(@NonNull BroadcastRecord record) { 1098 return record.options == null ? null : record.options.getDeliveryGroupMatchingFilter(); 1099 } 1100 1101 /** 1102 * Returns {@code true} if all the receivers are still waiting to receive the broadcast. 1103 * Otherwise {@code false}. 1104 */ allReceiversPending()1105 boolean allReceiversPending() { 1106 // We could also count the number of receivers with deliver state DELIVERY_PENDING, but 1107 // checking how many receivers have finished (either skipped or cancelled) and whether or 1108 // not the dispatch has been started should be sufficient. 1109 return (terminalCount == 0 && dispatchTime <= 0); 1110 } 1111 isMatchingRecord(@onNull BroadcastRecord record)1112 boolean isMatchingRecord(@NonNull BroadcastRecord record) { 1113 final int idx = mMatchingRecordsCache.indexOfKey(record); 1114 if (idx > 0) { 1115 return mMatchingRecordsCache.valueAt(idx); 1116 } 1117 // Consider a record to be matching if has the same receivers in the same order. 1118 boolean matches = (receivers.size() == record.receivers.size()); 1119 if (matches) { 1120 for (int i = receivers.size() - 1; i >= 0; --i) { 1121 if (!isReceiverEquals(receivers.get(i), record.receivers.get(i))) { 1122 matches = false; 1123 break; 1124 } 1125 } 1126 } 1127 mMatchingRecordsCache.put(record, matches); 1128 return matches; 1129 } 1130 setMatchingRecordsCache(@onNull ArrayMap<BroadcastRecord, Boolean> matchingRecordsCache)1131 void setMatchingRecordsCache(@NonNull ArrayMap<BroadcastRecord, Boolean> matchingRecordsCache) { 1132 mMatchingRecordsCache = matchingRecordsCache; 1133 } 1134 clearMatchingRecordsCache()1135 void clearMatchingRecordsCache() { 1136 mMatchingRecordsCache = null; 1137 } 1138 1139 @Override toString()1140 public String toString() { 1141 if (mCachedToString == null) { 1142 String label = intent.getAction(); 1143 if (label == null) { 1144 label = intent.toString(); 1145 } 1146 mCachedToString = "BroadcastRecord{" + toShortString() + "}"; 1147 } 1148 return mCachedToString; 1149 } 1150 toShortString()1151 public String toShortString() { 1152 if (mCachedToShortString == null) { 1153 String label = intent.getAction(); 1154 if (label == null) { 1155 label = intent.toString(); 1156 } 1157 mCachedToShortString = Integer.toHexString(System.identityHashCode(this)) 1158 + " " + label + "/u" + userId; 1159 } 1160 return mCachedToShortString; 1161 } 1162 1163 @NeverCompile dumpDebug(ProtoOutputStream proto, long fieldId)1164 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1165 long token = proto.start(fieldId); 1166 proto.write(BroadcastRecordProto.USER_ID, userId); 1167 proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction()); 1168 proto.end(token); 1169 } 1170 } 1171