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.IIntentReceiver; 22 import android.content.ComponentName; 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 34 import java.io.PrintWriter; 35 import java.util.Arrays; 36 import java.util.Date; 37 import java.util.List; 38 import java.util.Set; 39 40 /** 41 * An active intent broadcast. 42 */ 43 final class BroadcastRecord extends Binder { 44 final Intent intent; // the original intent that generated us 45 final ComponentName targetComp; // original component name set on the intent 46 final ProcessRecord callerApp; // process that sent this 47 final String callerPackage; // who sent this 48 final int callingPid; // the pid of who sent this 49 final int callingUid; // the uid of who sent this 50 final boolean ordered; // serialize the send to receivers? 51 final boolean sticky; // originated from existing sticky data? 52 final boolean initialSticky; // initial broadcast from register to sticky? 53 final int userId; // user id this broadcast was for 54 final String resolvedType; // the resolved data type 55 final String[] requiredPermissions; // permissions the caller has required 56 final int appOp; // an app op that is associated with this broadcast 57 final BroadcastOptions options; // BroadcastOptions supplied by caller 58 final List receivers; // contains BroadcastFilter and ResolveInfo 59 IIntentReceiver resultTo; // who receives final result if non-null 60 long enqueueClockTime; // the clock time the broadcast was enqueued 61 long dispatchTime; // when dispatch started on this set of receivers 62 long dispatchClockTime; // the clock time the dispatch started 63 long receiverTime; // when current receiver started for timeouts. 64 long finishTime; // when we finished the broadcast. 65 int resultCode; // current result code value. 66 String resultData; // current result data value. 67 Bundle resultExtras; // current result extra data values. 68 boolean resultAbort; // current result abortBroadcast value. 69 int nextReceiver; // next receiver to be executed. 70 IBinder receiver; // who is currently running, null if none. 71 int state; 72 int anrCount; // has this broadcast record hit any ANRs? 73 BroadcastQueue queue; // the outbound queue handling this broadcast 74 75 static final int IDLE = 0; 76 static final int APP_RECEIVE = 1; 77 static final int CALL_IN_RECEIVE = 2; 78 static final int CALL_DONE_RECEIVE = 3; 79 static final int WAITING_SERVICES = 4; 80 81 // The following are set when we are calling a receiver (one that 82 // was found in our list of registered receivers). 83 BroadcastFilter curFilter; 84 85 // The following are set only when we are launching a receiver (one 86 // that was found by querying the package manager). 87 ProcessRecord curApp; // hosting application of current receiver. 88 ComponentName curComponent; // the receiver class that is currently running. 89 ActivityInfo curReceiver; // info about the receiver that is currently running. 90 dump(PrintWriter pw, String prefix)91 void dump(PrintWriter pw, String prefix) { 92 final long now = SystemClock.uptimeMillis(); 93 94 pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId); 95 pw.print(prefix); pw.println(intent.toInsecureString()); 96 if (targetComp != null && targetComp != intent.getComponent()) { 97 pw.print(prefix); pw.print(" targetComp: "); pw.println(targetComp.toShortString()); 98 } 99 Bundle bundle = intent.getExtras(); 100 if (bundle != null) { 101 pw.print(prefix); pw.print(" extras: "); pw.println(bundle.toString()); 102 } 103 pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" "); 104 pw.print(callerApp != null ? callerApp.toShortString() : "null"); 105 pw.print(" pid="); pw.print(callingPid); 106 pw.print(" uid="); pw.println(callingUid); 107 if ((requiredPermissions != null && requiredPermissions.length > 0) 108 || appOp != AppOpsManager.OP_NONE) { 109 pw.print(prefix); pw.print("requiredPermissions="); 110 pw.print(Arrays.toString(requiredPermissions)); 111 pw.print(" appOp="); pw.println(appOp); 112 } 113 if (options != null) { 114 pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); 115 } 116 pw.print(prefix); pw.print("enqueueClockTime="); 117 pw.print(new Date(enqueueClockTime)); 118 pw.print(" dispatchClockTime="); 119 pw.println(new Date(dispatchClockTime)); 120 pw.print(prefix); pw.print("dispatchTime="); 121 TimeUtils.formatDuration(dispatchTime, now, pw); 122 if (finishTime != 0) { 123 pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw); 124 } else { 125 pw.print(" receiverTime="); TimeUtils.formatDuration(receiverTime, now, pw); 126 } 127 pw.println(""); 128 if (anrCount != 0) { 129 pw.print(prefix); pw.print("anrCount="); pw.println(anrCount); 130 } 131 if (resultTo != null || resultCode != -1 || resultData != null) { 132 pw.print(prefix); pw.print("resultTo="); pw.print(resultTo); 133 pw.print(" resultCode="); pw.print(resultCode); 134 pw.print(" resultData="); pw.println(resultData); 135 } 136 if (resultExtras != null) { 137 pw.print(prefix); pw.print("resultExtras="); pw.println(resultExtras); 138 } 139 if (resultAbort || ordered || sticky || initialSticky) { 140 pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort); 141 pw.print(" ordered="); pw.print(ordered); 142 pw.print(" sticky="); pw.print(sticky); 143 pw.print(" initialSticky="); pw.println(initialSticky); 144 } 145 if (nextReceiver != 0 || receiver != null) { 146 pw.print(prefix); pw.print("nextReceiver="); pw.print(nextReceiver); 147 pw.print(" receiver="); pw.println(receiver); 148 } 149 if (curFilter != null) { 150 pw.print(prefix); pw.print("curFilter="); pw.println(curFilter); 151 } 152 if (curReceiver != null) { 153 pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver); 154 } 155 if (curApp != null) { 156 pw.print(prefix); pw.print("curApp="); pw.println(curApp); 157 pw.print(prefix); pw.print("curComponent="); 158 pw.println((curComponent != null ? curComponent.toShortString() : "--")); 159 if (curReceiver != null && curReceiver.applicationInfo != null) { 160 pw.print(prefix); pw.print("curSourceDir="); 161 pw.println(curReceiver.applicationInfo.sourceDir); 162 } 163 } 164 if (state != IDLE) { 165 String stateStr = " (?)"; 166 switch (state) { 167 case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break; 168 case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break; 169 case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break; 170 case WAITING_SERVICES: stateStr=" (WAITING_SERVICES)"; break; 171 } 172 pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr); 173 } 174 final int N = receivers != null ? receivers.size() : 0; 175 String p2 = prefix + " "; 176 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 177 for (int i = 0; i < N; i++) { 178 Object o = receivers.get(i); 179 pw.print(prefix); pw.print("Receiver #"); pw.print(i); 180 pw.print(": "); pw.println(o); 181 if (o instanceof BroadcastFilter) 182 ((BroadcastFilter)o).dumpBrief(pw, p2); 183 else if (o instanceof ResolveInfo) 184 ((ResolveInfo)o).dump(printer, p2); 185 } 186 } 187 BroadcastRecord(BroadcastQueue _queue, Intent _intent, ProcessRecord _callerApp, String _callerPackage, int _callingPid, int _callingUid, 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)188 BroadcastRecord(BroadcastQueue _queue, 189 Intent _intent, ProcessRecord _callerApp, String _callerPackage, 190 int _callingPid, int _callingUid, String _resolvedType, String[] _requiredPermissions, 191 int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, 192 int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, 193 boolean _sticky, boolean _initialSticky, 194 int _userId) { 195 queue = _queue; 196 intent = _intent; 197 targetComp = _intent.getComponent(); 198 callerApp = _callerApp; 199 callerPackage = _callerPackage; 200 callingPid = _callingPid; 201 callingUid = _callingUid; 202 resolvedType = _resolvedType; 203 requiredPermissions = _requiredPermissions; 204 appOp = _appOp; 205 options = _options; 206 receivers = _receivers; 207 resultTo = _resultTo; 208 resultCode = _resultCode; 209 resultData = _resultData; 210 resultExtras = _resultExtras; 211 ordered = _serialized; 212 sticky = _sticky; 213 initialSticky = _initialSticky; 214 userId = _userId; 215 nextReceiver = 0; 216 state = IDLE; 217 } 218 cleanupDisabledPackageReceiversLocked( String packageName, Set<String> filterByClasses, int userId, boolean doit)219 boolean cleanupDisabledPackageReceiversLocked( 220 String packageName, Set<String> filterByClasses, int userId, boolean doit) { 221 if ((userId != UserHandle.USER_ALL && this.userId != userId) || receivers == null) { 222 return false; 223 } 224 225 boolean didSomething = false; 226 Object o; 227 for (int i = receivers.size() - 1; i >= 0; i--) { 228 o = receivers.get(i); 229 if (!(o instanceof ResolveInfo)) { 230 continue; 231 } 232 ActivityInfo info = ((ResolveInfo)o).activityInfo; 233 234 final boolean sameComponent = packageName == null 235 || (info.applicationInfo.packageName.equals(packageName) 236 && (filterByClasses == null || filterByClasses.contains(info.name))); 237 if (sameComponent) { 238 if (!doit) { 239 return true; 240 } 241 didSomething = true; 242 receivers.remove(i); 243 if (i < nextReceiver) { 244 nextReceiver--; 245 } 246 } 247 } 248 nextReceiver = Math.min(nextReceiver, receivers.size()); 249 250 return didSomething; 251 } 252 toString()253 public String toString() { 254 return "BroadcastRecord{" 255 + Integer.toHexString(System.identityHashCode(this)) 256 + " u" + userId + " " + intent.getAction() + "}"; 257 } 258 } 259