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.content.IIntentReceiver; 20 import android.content.ComponentName; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.content.pm.ResolveInfo; 24 import android.os.Binder; 25 import android.os.Bundle; 26 import android.os.IBinder; 27 import android.os.SystemClock; 28 import android.util.PrintWriterPrinter; 29 30 import java.io.PrintWriter; 31 import java.util.List; 32 33 /** 34 * An active intent broadcast. 35 */ 36 class BroadcastRecord extends Binder { 37 final Intent intent; // the original intent that generated us 38 final ProcessRecord callerApp; // process that sent this 39 final String callerPackage; // who sent this 40 final int callingPid; // the pid of who sent this 41 final int callingUid; // the uid of who sent this 42 final boolean ordered; // serialize the send to receivers? 43 final boolean sticky; // originated from existing sticky data? 44 final boolean initialSticky; // initial broadcast from register to sticky? 45 final String requiredPermission; // a permission the caller has required 46 final List receivers; // contains BroadcastFilter and ResolveInfo 47 final IIntentReceiver resultTo; // who receives final result if non-null 48 long dispatchTime; // when dispatch started on this set of receivers 49 long receiverTime; // when current receiver started for timeouts. 50 long finishTime; // when we finished the broadcast. 51 int resultCode; // current result code value. 52 String resultData; // current result data value. 53 Bundle resultExtras; // current result extra data values. 54 boolean resultAbort; // current result abortBroadcast value. 55 int nextReceiver; // next receiver to be executed. 56 IBinder receiver; // who is currently running, null if none. 57 int state; 58 int anrCount; // has this broadcast record hit any ANRs? 59 60 static final int IDLE = 0; 61 static final int APP_RECEIVE = 1; 62 static final int CALL_IN_RECEIVE = 2; 63 static final int CALL_DONE_RECEIVE = 3; 64 65 // The following are set when we are calling a receiver (one that 66 // was found in our list of registered receivers). 67 BroadcastFilter curFilter; 68 69 // The following are set only when we are launching a receiver (one 70 // that was found by querying the package manager). 71 ProcessRecord curApp; // hosting application of current receiver. 72 ComponentName curComponent; // the receiver class that is currently running. 73 ActivityInfo curReceiver; // info about the receiver that is currently running. 74 75 void dump(PrintWriter pw, String prefix) { 76 pw.println(prefix + this); 77 pw.println(prefix + intent); 78 if (sticky) { 79 Bundle bundle = intent.getExtras(); 80 if (bundle != null) { 81 pw.println(prefix + "extras: " + bundle.toString()); 82 } 83 } 84 pw.println(prefix + "proc=" + callerApp); 85 pw.println(prefix + "caller=" + callerPackage 86 + " callingPid=" + callingPid 87 + " callingUid=" + callingUid); 88 if (requiredPermission != null) { 89 pw.println(prefix + "requiredPermission=" + requiredPermission); 90 } 91 pw.println(prefix + "dispatchTime=" + dispatchTime + " (" 92 + (SystemClock.uptimeMillis()-dispatchTime) + "ms since now)"); 93 if (finishTime != 0) { 94 pw.println(prefix + "finishTime=" + finishTime + " (" 95 + (SystemClock.uptimeMillis()-finishTime) + "ms since now)"); 96 } else { 97 pw.println(prefix + "receiverTime=" + receiverTime + " (" 98 + (SystemClock.uptimeMillis()-receiverTime) + "ms since now)"); 99 } 100 if (anrCount != 0) { 101 pw.println(prefix + "anrCount=" + anrCount); 102 } 103 if (resultTo != null || resultCode != -1 || resultData != null) { 104 pw.println(prefix + "resultTo=" + resultTo 105 + " resultCode=" + resultCode + " resultData=" + resultData); 106 } 107 if (resultExtras != null) { 108 pw.println(prefix + "resultExtras=" + resultExtras); 109 } 110 if (resultAbort || ordered || sticky || initialSticky) { 111 pw.println(prefix + "resultAbort=" + resultAbort 112 + " ordered=" + ordered + " sticky=" + sticky 113 + " initialSticky=" + initialSticky); 114 } 115 if (nextReceiver != 0 || receiver != null) { 116 pw.println(prefix + "nextReceiver=" + nextReceiver 117 + " receiver=" + receiver); 118 } 119 if (curFilter != null) { 120 pw.println(prefix + "curFilter=" + curFilter); 121 } 122 if (curReceiver != null) { 123 pw.println(prefix + "curReceiver=" + curReceiver); 124 } 125 if (curApp != null) { 126 pw.println(prefix + "curApp=" + curApp); 127 pw.println(prefix + "curComponent=" 128 + (curComponent != null ? curComponent.toShortString() : "--")); 129 if (curReceiver != null && curReceiver.applicationInfo != null) { 130 pw.println(prefix + "curSourceDir=" + curReceiver.applicationInfo.sourceDir); 131 } 132 } 133 String stateStr = " (?)"; 134 switch (state) { 135 case IDLE: stateStr=" (IDLE)"; break; 136 case APP_RECEIVE: stateStr=" (APP_RECEIVE)"; break; 137 case CALL_IN_RECEIVE: stateStr=" (CALL_IN_RECEIVE)"; break; 138 case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break; 139 } 140 pw.println(prefix + "state=" + state + stateStr); 141 final int N = receivers != null ? receivers.size() : 0; 142 String p2 = prefix + " "; 143 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 144 for (int i=0; i<N; i++) { 145 Object o = receivers.get(i); 146 pw.println(prefix + "Receiver #" + i + ": " + o); 147 if (o instanceof BroadcastFilter) 148 ((BroadcastFilter)o).dumpBrief(pw, p2); 149 else if (o instanceof ResolveInfo) 150 ((ResolveInfo)o).dump(printer, p2); 151 } 152 } 153 154 BroadcastRecord(Intent _intent, ProcessRecord _callerApp, String _callerPackage, 155 int _callingPid, int _callingUid, String _requiredPermission, 156 List _receivers, IIntentReceiver _resultTo, int _resultCode, 157 String _resultData, Bundle _resultExtras, boolean _serialized, 158 boolean _sticky, boolean _initialSticky) { 159 intent = _intent; 160 callerApp = _callerApp; 161 callerPackage = _callerPackage; 162 callingPid = _callingPid; 163 callingUid = _callingUid; 164 requiredPermission = _requiredPermission; 165 receivers = _receivers; 166 resultTo = _resultTo; 167 resultCode = _resultCode; 168 resultData = _resultData; 169 resultExtras = _resultExtras; 170 ordered = _serialized; 171 sticky = _sticky; 172 initialSticky = _initialSticky; 173 nextReceiver = 0; 174 state = IDLE; 175 } 176 177 public String toString() { 178 return "BroadcastRecord{" 179 + Integer.toHexString(System.identityHashCode(this)) 180 + " " + intent.getAction() + "}"; 181 } 182 } 183