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