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