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