• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.app.AppProtoEnums.BROADCAST_TYPE_ALARM;
20 import static android.app.AppProtoEnums.BROADCAST_TYPE_BACKGROUND;
21 import static android.app.AppProtoEnums.BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE;
22 import static android.app.AppProtoEnums.BROADCAST_TYPE_FOREGROUND;
23 import static android.app.AppProtoEnums.BROADCAST_TYPE_INITIAL_STICKY;
24 import static android.app.AppProtoEnums.BROADCAST_TYPE_INTERACTIVE;
25 import static android.app.AppProtoEnums.BROADCAST_TYPE_NONE;
26 import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED;
27 import static android.app.AppProtoEnums.BROADCAST_TYPE_PRIORITIZED;
28 import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE;
29 import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA;
30 import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO;
31 import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY;
32 
33 import android.annotation.CheckResult;
34 import android.annotation.CurrentTimeMillisLong;
35 import android.annotation.ElapsedRealtimeLong;
36 import android.annotation.IntDef;
37 import android.annotation.NonNull;
38 import android.annotation.Nullable;
39 import android.annotation.UptimeMillisLong;
40 import android.app.ActivityManager.ProcessState;
41 import android.app.AppOpsManager;
42 import android.app.BackgroundStartPrivileges;
43 import android.app.BroadcastOptions;
44 import android.app.BroadcastOptions.DeliveryGroupPolicy;
45 import android.compat.annotation.ChangeId;
46 import android.content.ComponentName;
47 import android.content.IIntentReceiver;
48 import android.content.Intent;
49 import android.content.IntentFilter;
50 import android.content.pm.ActivityInfo;
51 import android.content.pm.ApplicationInfo;
52 import android.content.pm.ResolveInfo;
53 import android.os.Binder;
54 import android.os.Bundle;
55 import android.os.SystemClock;
56 import android.os.UserHandle;
57 import android.util.ArrayMap;
58 import android.util.IntArray;
59 import android.util.PrintWriterPrinter;
60 import android.util.TimeUtils;
61 import android.util.proto.ProtoOutputStream;
62 
63 import com.android.internal.annotations.VisibleForTesting;
64 import com.android.server.compat.PlatformCompat;
65 
66 import dalvik.annotation.optimization.NeverCompile;
67 
68 import java.io.PrintWriter;
69 import java.lang.annotation.Retention;
70 import java.lang.annotation.RetentionPolicy;
71 import java.text.SimpleDateFormat;
72 import java.util.Arrays;
73 import java.util.Date;
74 import java.util.List;
75 import java.util.Objects;
76 import java.util.Set;
77 import java.util.function.BiFunction;
78 
79 /**
80  * An active intent broadcast.
81  */
82 final class BroadcastRecord extends Binder {
83     /**
84      * Limit the scope of the priority values to the process level. This means that priority values
85      * will only influence the order of broadcast delivery within the same process.
86      */
87     @ChangeId
88     @VisibleForTesting
89     static final long LIMIT_PRIORITY_SCOPE = 371307720L;
90 
91     final @NonNull Intent intent;    // the original intent that generated us
92     final @Nullable ComponentName targetComp; // original component name set on the intent
93     final @Nullable ProcessRecord callerApp; // process that sent this
94     final @Nullable String callerPackage; // who sent this
95     final @Nullable String callerFeatureId; // which feature in the package sent this
96     final int callingPid;   // the pid of who sent this
97     final int callingUid;   // the uid of who sent this
98     final @ProcessState int callerProcState; // Procstate of the caller process at enqueue time.
99 
100     final int originalStickyCallingUid;
101             // if this is a sticky broadcast, the Uid of the original sender
102     final boolean callerInstantApp; // caller is an Instant App?
103     final boolean callerInstrumented; // caller is being instrumented?
104     final boolean ordered;  // serialize the send to receivers?
105     final boolean sticky;   // originated from existing sticky data?
106     final boolean alarm;    // originated from an alarm triggering?
107     final boolean pushMessage; // originated from a push message?
108     final boolean pushMessageOverQuota; // originated from a push message which was over quota?
109     final boolean interactive; // originated from user interaction?
110     final boolean initialSticky; // initial broadcast from register to sticky?
111     final boolean prioritized; // contains more than one priority tranche
112     final boolean deferUntilActive; // infinitely deferrable broadcast
113     final boolean shareIdentity;  // whether the broadcaster's identity should be shared
114     final boolean urgent;    // has been classified as "urgent"
115     final int userId;       // user id this broadcast was for
116     final @Nullable String resolvedType; // the resolved data type
117     final @Nullable String[] requiredPermissions; // permissions the caller has required
118     final @Nullable String[] excludedPermissions; // permissions to exclude
119     final @Nullable String[] excludedPackages; // packages to exclude
120     final int appOp;        // an app op that is associated with this broadcast
121     final @Nullable BroadcastOptions options; // BroadcastOptions supplied by caller
122     final @NonNull List<Object> receivers;   // contains BroadcastFilter and ResolveInfo
123     final @DeliveryState int[] delivery;   // delivery state of each receiver
124     final @NonNull String[] deliveryReasons; // reasons for delivery state of each receiver
125     final int[] blockedUntilBeyondCount; // blocked until count of each receiver
126     @Nullable ProcessRecord resultToApp; // who receives final result if non-null
127     @Nullable IIntentReceiver resultTo; // who receives final result if non-null
128     @UptimeMillisLong       long enqueueTime;        // when broadcast enqueued
129     @ElapsedRealtimeLong    long enqueueRealTime;    // when broadcast enqueued
130     @CurrentTimeMillisLong  long enqueueClockTime;   // when broadcast enqueued
131     // When broadcast is originally enqueued. Only used in case of replacing broadcasts
132     // with FLAG_RECEIVER_REPLACE_PENDING. If it is 0, then 'enqueueClockTime' is the original
133     // enqueue time.
134     @UptimeMillisLong       long originalEnqueueClockTime;
135     @UptimeMillisLong       long dispatchTime;       // when broadcast dispatch started
136     @ElapsedRealtimeLong    long dispatchRealTime;   // when broadcast dispatch started
137     @CurrentTimeMillisLong  long dispatchClockTime;  // when broadcast dispatch started
138     @UptimeMillisLong       long receiverTime;       // when receiver started for timeouts
139     @UptimeMillisLong       long finishTime;         // when broadcast finished
140     final @UptimeMillisLong long[] scheduledTime;    // when each receiver was scheduled
141     final @UptimeMillisLong long[] terminalTime;     // when each receiver was terminal
142     final boolean timeoutExempt;  // true if this broadcast is not subject to receiver timeouts
143     int resultCode;         // current result code value.
144     @Nullable String resultData;      // current result data value.
145     @Nullable Bundle resultExtras;    // current result extra data values.
146     boolean resultAbort;    // current result abortBroadcast value.
147     int nextReceiver;       // next receiver to be executed.
148     int state;
149     int anrCount;           // has this broadcast record hit any ANRs?
150     int manifestCount;      // number of manifest receivers dispatched.
151     int manifestSkipCount;  // number of manifest receivers skipped.
152     int terminalCount;      // number of receivers in terminal state.
153     int deferredCount;      // number of receivers in deferred state.
154     int beyondCount;        // high-water number of receivers we've moved beyond.
155     @Nullable BroadcastQueue queue;   // the outbound queue handling this broadcast
156 
157     // Determines the privileges the app's process has in regard to background starts.
158     final BackgroundStartPrivileges mBackgroundStartPrivileges;
159 
160     // Filter the intent extras by using the rules of the package visibility before broadcasting
161     // the intent to the receiver.
162     @Nullable
163     final BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver;
164 
165     // Cache of records that are "matching" this. Only used at the time of enqueuing this record
166     // into the queue.
167     @Nullable
168     private ArrayMap<BroadcastRecord, Boolean> mMatchingRecordsCache;
169 
170     // Stores the {@link BroadcastProcessedEventRecord} for each process associated with this
171     // record.
172     @NonNull
173     private ArrayMap<String, BroadcastProcessedEventRecord> mBroadcastProcessedRecords =
174             new ArrayMap<>();
175 
176     private @Nullable String mCachedToString;
177     private @Nullable String mCachedToShortString;
178 
179     /**
180      * When enabled, assume that {@link UserHandle#isCore(int)} apps should
181      * treat {@link BroadcastOptions#DEFERRAL_POLICY_DEFAULT} as
182      * {@link BroadcastOptions#DEFERRAL_POLICY_UNTIL_ACTIVE}.
183      */
184     static boolean CORE_DEFER_UNTIL_ACTIVE = false;
185 
186     /** Empty immutable list of receivers */
187     static final List<Object> EMPTY_RECEIVERS = List.of();
188 
189     static final int IDLE = 0;
190     static final int APP_RECEIVE = 1;
191     static final int CALL_IN_RECEIVE = 2;
192     static final int CALL_DONE_RECEIVE = 3;
193     static final int WAITING_SERVICES = 4;
194 
195     /** Initial state: waiting to run in future */
196     static final int DELIVERY_PENDING = 0;
197     /** Terminal state: finished successfully */
198     static final int DELIVERY_DELIVERED = 1;
199     /** Terminal state: skipped due to internal policy */
200     static final int DELIVERY_SKIPPED = 2;
201     /** Terminal state: timed out during attempted delivery */
202     static final int DELIVERY_TIMEOUT = 3;
203     /** Intermediate state: currently executing */
204     static final int DELIVERY_SCHEDULED = 4;
205     /** Terminal state: failure to dispatch */
206     static final int DELIVERY_FAILURE = 5;
207     /** Intermediate state: currently deferred while app is cached */
208     static final int DELIVERY_DEFERRED = 6;
209 
210     @IntDef(flag = false, prefix = { "DELIVERY_" }, value = {
211             DELIVERY_PENDING,
212             DELIVERY_DELIVERED,
213             DELIVERY_SKIPPED,
214             DELIVERY_TIMEOUT,
215             DELIVERY_SCHEDULED,
216             DELIVERY_FAILURE,
217             DELIVERY_DEFERRED,
218     })
219     @Retention(RetentionPolicy.SOURCE)
220     public @interface DeliveryState {}
221 
deliveryStateToString(@eliveryState int deliveryState)222     static @NonNull String deliveryStateToString(@DeliveryState int deliveryState) {
223         switch (deliveryState) {
224             case DELIVERY_PENDING: return "PENDING";
225             case DELIVERY_DELIVERED: return "DELIVERED";
226             case DELIVERY_SKIPPED: return "SKIPPED";
227             case DELIVERY_TIMEOUT: return "TIMEOUT";
228             case DELIVERY_SCHEDULED: return "SCHEDULED";
229             case DELIVERY_FAILURE: return "FAILURE";
230             case DELIVERY_DEFERRED: return "DEFERRED";
231             default: return Integer.toString(deliveryState);
232         }
233     }
234 
235     /**
236      * Return if the given delivery state is "terminal", where no additional
237      * delivery state changes will be made.
238      */
isDeliveryStateTerminal(@eliveryState int deliveryState)239     static boolean isDeliveryStateTerminal(@DeliveryState int deliveryState) {
240         switch (deliveryState) {
241             case DELIVERY_DELIVERED:
242             case DELIVERY_SKIPPED:
243             case DELIVERY_TIMEOUT:
244             case DELIVERY_FAILURE:
245                 return true;
246             default:
247                 return false;
248         }
249     }
250 
251     /**
252      * Return if the given delivery state is "beyond", which means that we've
253      * moved beyond this receiver, and future receivers are now unblocked.
254      */
isDeliveryStateBeyond(@eliveryState int deliveryState)255     static boolean isDeliveryStateBeyond(@DeliveryState int deliveryState) {
256         switch (deliveryState) {
257             case DELIVERY_DELIVERED:
258             case DELIVERY_SKIPPED:
259             case DELIVERY_TIMEOUT:
260             case DELIVERY_FAILURE:
261             case DELIVERY_DEFERRED:
262                 return true;
263             default:
264                 return false;
265         }
266     }
267 
268     /**
269      * Return true if this receiver should be assumed to have been delivered.
270      */
isAssumedDelivered(int index)271     boolean isAssumedDelivered(int index) {
272         return (receivers.get(index) instanceof BroadcastFilter) && !ordered
273                 && (resultTo == null);
274     }
275 
276     ProcessRecord curApp;       // hosting application of current receiver.
277     ComponentName curComponent; // the receiver class that is currently running.
278     ActivityInfo curReceiver;   // the manifest receiver that is currently running.
279     BroadcastFilter curFilter;  // the registered receiver currently running.
280     Bundle curFilteredExtras;   // the bundle that has been filtered by the package visibility rules
281 
282     @NeverCompile
dump(PrintWriter pw, String prefix, SimpleDateFormat sdf)283     void dump(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
284         final long now = SystemClock.uptimeMillis();
285 
286         pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId);
287         pw.print(prefix); pw.println(intent.toInsecureString());
288         if (targetComp != null && targetComp != intent.getComponent()) {
289             pw.print(prefix); pw.print("  targetComp: "); pw.println(targetComp.toShortString());
290         }
291         Bundle bundle = intent.getExtras();
292         if (bundle != null) {
293             pw.print(prefix); pw.print("  extras: "); pw.println(bundle.toString());
294         }
295         pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" ");
296                 pw.print(callerApp != null ? callerApp.toShortString() : "null");
297                 pw.print(" pid="); pw.print(callingPid);
298                 pw.print(" uid="); pw.println(callingUid);
299         if ((requiredPermissions != null && requiredPermissions.length > 0)
300                 || appOp != AppOpsManager.OP_NONE) {
301             pw.print(prefix); pw.print("requiredPermissions=");
302             pw.print(Arrays.toString(requiredPermissions));
303             pw.print("  appOp="); pw.println(appOp);
304         }
305         if (excludedPermissions != null && excludedPermissions.length > 0) {
306             pw.print(prefix); pw.print("excludedPermissions=");
307             pw.print(Arrays.toString(excludedPermissions));
308         }
309         if (excludedPackages != null && excludedPackages.length > 0) {
310             pw.print(prefix); pw.print("excludedPackages=");
311             pw.print(Arrays.toString(excludedPackages));
312         }
313         if (options != null) {
314             pw.print(prefix); pw.print("options="); pw.println(options.toBundle());
315         }
316         pw.print(prefix); pw.print("enqueueClockTime=");
317                 pw.print(sdf.format(new Date(enqueueClockTime)));
318                 pw.print(" dispatchClockTime=");
319                 pw.print(sdf.format(new Date(dispatchClockTime)));
320         if (originalEnqueueClockTime > 0) {
321             pw.print(" originalEnqueueClockTime=");
322             pw.print(sdf.format(new Date(originalEnqueueClockTime)));
323         }
324         pw.println();
325         pw.print(prefix); pw.print("dispatchTime=");
326                 TimeUtils.formatDuration(dispatchTime, now, pw);
327                 pw.print(" (");
328                 TimeUtils.formatDuration(dispatchTime - enqueueTime, pw);
329                 pw.print(" since enq)");
330         if (finishTime != 0) {
331             pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw);
332             pw.print(" (");
333             TimeUtils.formatDuration(finishTime-dispatchTime, pw);
334             pw.print(" since disp)");
335         } else {
336             pw.print(" receiverTime="); TimeUtils.formatDuration(receiverTime, now, pw);
337         }
338         pw.println("");
339         if (anrCount != 0) {
340             pw.print(prefix); pw.print("anrCount="); pw.println(anrCount);
341         }
342         if (resultTo != null || resultCode != -1 || resultData != null) {
343             pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
344                     pw.print(" resultCode="); pw.print(resultCode);
345                     pw.print(" resultData="); pw.println(resultData);
346         }
347         if (resultExtras != null) {
348             pw.print(prefix); pw.print("resultExtras="); pw.println(resultExtras);
349         }
350         if (resultAbort || ordered || sticky || initialSticky) {
351             pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort);
352                     pw.print(" ordered="); pw.print(ordered);
353                     pw.print(" sticky="); pw.print(sticky);
354                     pw.print(" initialSticky="); pw.print(initialSticky);
355                     pw.print(" originalStickyCallingUid="); pw.println(originalStickyCallingUid);
356         }
357         if (nextReceiver != 0) {
358             pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
359         }
360         if (curFilter != null) {
361             pw.print(prefix); pw.print("curFilter="); pw.println(curFilter);
362         }
363         if (curReceiver != null) {
364             pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver);
365         }
366         if (curApp != null) {
367             pw.print(prefix); pw.print("curApp="); pw.println(curApp);
368             pw.print(prefix); pw.print("curComponent=");
369                     pw.println((curComponent != null ? curComponent.toShortString() : "--"));
370             if (curReceiver != null && curReceiver.applicationInfo != null) {
371                 pw.print(prefix); pw.print("curSourceDir=");
372                         pw.println(curReceiver.applicationInfo.sourceDir);
373             }
374         }
375         if (curFilteredExtras != null) {
376             pw.print(" filtered extras: "); pw.println(curFilteredExtras);
377         }
378         if (state != IDLE) {
379             String stateStr = " (?)";
380             switch (state) {
381                 case APP_RECEIVE:       stateStr=" (APP_RECEIVE)"; break;
382                 case CALL_IN_RECEIVE:   stateStr=" (CALL_IN_RECEIVE)"; break;
383                 case CALL_DONE_RECEIVE: stateStr=" (CALL_DONE_RECEIVE)"; break;
384                 case WAITING_SERVICES:  stateStr=" (WAITING_SERVICES)"; break;
385             }
386             pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr);
387         }
388         pw.print(prefix); pw.print("terminalCount="); pw.println(terminalCount);
389         final int N = receivers != null ? receivers.size() : 0;
390         String p2 = prefix + "  ";
391         PrintWriterPrinter printer = new PrintWriterPrinter(pw);
392         for (int i = 0; i < N; i++) {
393             Object o = receivers.get(i);
394             pw.print(prefix);
395             pw.print(deliveryStateToString(delivery[i]));
396             pw.print(' ');
397             if (scheduledTime[i] != 0) {
398                 pw.print("scheduled ");
399                 TimeUtils.formatDuration(scheduledTime[i] - enqueueTime, pw);
400                 pw.print(' ');
401             }
402             if (terminalTime[i] != 0) {
403                 pw.print("terminal ");
404                 TimeUtils.formatDuration(terminalTime[i] - scheduledTime[i], pw);
405                 pw.print(' ');
406             }
407             pw.print("("); pw.print(blockedUntilBeyondCount[i]); pw.print(") ");
408             pw.print("#"); pw.print(i); pw.print(": ");
409             if (o instanceof BroadcastFilter) {
410                 pw.println(o);
411                 ((BroadcastFilter) o).dumpBrief(pw, p2);
412             } else if (o instanceof ResolveInfo) {
413                 pw.println("(manifest)");
414                 ((ResolveInfo) o).dump(printer, p2, 0);
415             } else {
416                 pw.println(o);
417             }
418             if (deliveryReasons[i] != null) {
419                 pw.print(p2); pw.print("reason: "); pw.println(deliveryReasons[i]);
420             }
421         }
422     }
423 
BroadcastRecord(BroadcastQueue queue, Intent intent, ProcessRecord callerApp, String callerPackage, @Nullable String callerFeatureId, int callingPid, int callingUid, boolean callerInstantApp, String resolvedType, String[] requiredPermissions, String[] excludedPermissions, String[] excludedPackages, int appOp, BroadcastOptions options, List receivers, ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, boolean serialized, boolean sticky, boolean initialSticky, int userId, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, int callerAppProcessState, PlatformCompat platformCompat)424     BroadcastRecord(BroadcastQueue queue,
425             Intent intent, ProcessRecord callerApp, String callerPackage,
426             @Nullable String callerFeatureId, int callingPid, int callingUid,
427             boolean callerInstantApp, String resolvedType,
428             String[] requiredPermissions, String[] excludedPermissions,
429             String[] excludedPackages, int appOp,
430             BroadcastOptions options, List receivers,
431             ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode,
432             String resultData, Bundle resultExtras, boolean serialized, boolean sticky,
433             boolean initialSticky, int userId,
434             @NonNull BackgroundStartPrivileges backgroundStartPrivileges,
435             boolean timeoutExempt,
436             @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
437             int callerAppProcessState, PlatformCompat platformCompat) {
438         this(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid,
439                 callingUid, callerInstantApp, resolvedType, requiredPermissions,
440                 excludedPermissions, excludedPackages, appOp, options, receivers, resultToApp,
441                 resultTo, resultCode, resultData, resultExtras, serialized, sticky,
442                 initialSticky, userId, -1, backgroundStartPrivileges, timeoutExempt,
443                 filterExtrasForReceiver, callerAppProcessState, platformCompat);
444     }
445 
BroadcastRecord(BroadcastQueue _queue, Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType, String[] _requiredPermissions, String[] _excludedPermissions, String[] _excludedPackages, int _appOp, BroadcastOptions _options, List _receivers, ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId, int originalStickyCallingUid, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, int callerAppProcessState, PlatformCompat platformCompat)446     BroadcastRecord(BroadcastQueue _queue,
447             Intent _intent, ProcessRecord _callerApp, String _callerPackage,
448             @Nullable String _callerFeatureId, int _callingPid, int _callingUid,
449             boolean _callerInstantApp, String _resolvedType,
450             String[] _requiredPermissions, String[] _excludedPermissions,
451             String[] _excludedPackages, int _appOp,
452             BroadcastOptions _options, List _receivers,
453             ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode,
454             String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
455             boolean _initialSticky, int _userId, int originalStickyCallingUid,
456             @NonNull BackgroundStartPrivileges backgroundStartPrivileges,
457             boolean timeoutExempt,
458             @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
459             int callerAppProcessState, PlatformCompat platformCompat) {
460         if (_intent == null) {
461             throw new NullPointerException("Can't construct with a null intent");
462         }
463         queue = _queue;
464         intent = Objects.requireNonNull(_intent);
465         targetComp = _intent.getComponent();
466         callerApp = _callerApp;
467         callerPackage = _callerPackage;
468         callerFeatureId = _callerFeatureId;
469         callingPid = _callingPid;
470         callingUid = _callingUid;
471         callerProcState = callerAppProcessState;
472         callerInstantApp = _callerInstantApp;
473         callerInstrumented = isCallerInstrumented(_callerApp, _callingUid);
474         resolvedType = _resolvedType;
475         requiredPermissions = _requiredPermissions;
476         excludedPermissions = _excludedPermissions;
477         excludedPackages = _excludedPackages;
478         appOp = _appOp;
479         options = _options;
480         receivers = (_receivers != null) ? _receivers : EMPTY_RECEIVERS;
481         delivery = new int[_receivers != null ? _receivers.size() : 0];
482         deliveryReasons = new String[delivery.length];
483         urgent = calculateUrgent(_intent, _options);
484         deferUntilActive = calculateDeferUntilActive(_callingUid,
485                 _options, _resultTo, _serialized, urgent);
486         blockedUntilBeyondCount = calculateBlockedUntilBeyondCount(
487                 receivers, _serialized, platformCompat);
488         scheduledTime = new long[delivery.length];
489         terminalTime = new long[delivery.length];
490         resultToApp = _resultToApp;
491         resultTo = _resultTo;
492         resultCode = _resultCode;
493         resultData = _resultData;
494         resultExtras = _resultExtras;
495         ordered = _serialized;
496         sticky = _sticky;
497         initialSticky = _initialSticky;
498         prioritized = isPrioritized(blockedUntilBeyondCount, _serialized);
499         userId = _userId;
500         nextReceiver = 0;
501         state = IDLE;
502         mBackgroundStartPrivileges = backgroundStartPrivileges;
503         this.timeoutExempt = timeoutExempt;
504         alarm = options != null && options.isAlarmBroadcast();
505         pushMessage = options != null && options.isPushMessagingBroadcast();
506         pushMessageOverQuota = options != null && options.isPushMessagingOverQuotaBroadcast();
507         interactive = options != null && options.isInteractive();
508         shareIdentity = options != null && options.isShareIdentityEnabled();
509         this.filterExtrasForReceiver = filterExtrasForReceiver;
510         this.originalStickyCallingUid = originalStickyCallingUid;
511     }
512 
513     /**
514      * Copy constructor which takes a different intent.
515      * Only used by {@link #maybeStripForHistory}.
516      */
BroadcastRecord(BroadcastRecord from, Intent newIntent)517     private BroadcastRecord(BroadcastRecord from, Intent newIntent) {
518         intent = Objects.requireNonNull(newIntent);
519         targetComp = newIntent.getComponent();
520 
521         callerApp = from.callerApp;
522         callerPackage = from.callerPackage;
523         callerFeatureId = from.callerFeatureId;
524         callingPid = from.callingPid;
525         callingUid = from.callingUid;
526         callerProcState = from.callerProcState;
527         callerInstantApp = from.callerInstantApp;
528         callerInstrumented = from.callerInstrumented;
529         ordered = from.ordered;
530         sticky = from.sticky;
531         initialSticky = from.initialSticky;
532         prioritized = from.prioritized;
533         userId = from.userId;
534         resolvedType = from.resolvedType;
535         requiredPermissions = from.requiredPermissions;
536         excludedPermissions = from.excludedPermissions;
537         excludedPackages = from.excludedPackages;
538         appOp = from.appOp;
539         options = from.options;
540         receivers = from.receivers;
541         delivery = from.delivery;
542         deliveryReasons = from.deliveryReasons;
543         deferUntilActive = from.deferUntilActive;
544         blockedUntilBeyondCount = from.blockedUntilBeyondCount;
545         scheduledTime = from.scheduledTime;
546         terminalTime = from.terminalTime;
547         resultToApp = from.resultToApp;
548         resultTo = from.resultTo;
549         enqueueTime = from.enqueueTime;
550         enqueueRealTime = from.enqueueRealTime;
551         enqueueClockTime = from.enqueueClockTime;
552         dispatchTime = from.dispatchTime;
553         dispatchRealTime = from.dispatchRealTime;
554         dispatchClockTime = from.dispatchClockTime;
555         receiverTime = from.receiverTime;
556         finishTime = from.finishTime;
557         resultCode = from.resultCode;
558         resultData = from.resultData;
559         resultExtras = from.resultExtras;
560         resultAbort = from.resultAbort;
561         nextReceiver = from.nextReceiver;
562         state = from.state;
563         anrCount = from.anrCount;
564         manifestCount = from.manifestCount;
565         manifestSkipCount = from.manifestSkipCount;
566         queue = from.queue;
567         mBackgroundStartPrivileges = from.mBackgroundStartPrivileges;
568         timeoutExempt = from.timeoutExempt;
569         alarm = from.alarm;
570         pushMessage = from.pushMessage;
571         pushMessageOverQuota = from.pushMessageOverQuota;
572         interactive = from.interactive;
573         shareIdentity = from.shareIdentity;
574         urgent = from.urgent;
575         filterExtrasForReceiver = from.filterExtrasForReceiver;
576         originalStickyCallingUid = from.originalStickyCallingUid;
577     }
578 
579     /**
580      * Update the delivery state of the given {@link #receivers} index.
581      * Automatically updates any time measurements related to state changes.
582      *
583      * @return if {@link #beyondCount} changed due to this state transition,
584      *         indicating that other events may be unblocked.
585      */
586     @CheckResult
setDeliveryState(int index, @DeliveryState int newDeliveryState, @NonNull String reason)587     boolean setDeliveryState(int index, @DeliveryState int newDeliveryState,
588             @NonNull String reason) {
589         final int oldDeliveryState = delivery[index];
590         if (isDeliveryStateTerminal(oldDeliveryState)
591                 || newDeliveryState == oldDeliveryState) {
592             // We've already arrived in terminal or requested state, so leave
593             // any statistics and reasons intact from the first transition
594             return false;
595         }
596 
597         switch (oldDeliveryState) {
598             case DELIVERY_DEFERRED:
599                 deferredCount--;
600                 break;
601         }
602         switch (newDeliveryState) {
603             case DELIVERY_PENDING:
604                 scheduledTime[index] = 0;
605                 break;
606             case DELIVERY_SCHEDULED:
607                 scheduledTime[index] = SystemClock.uptimeMillis();
608                 break;
609             case DELIVERY_DEFERRED:
610                 deferredCount++;
611                 break;
612             case DELIVERY_DELIVERED:
613             case DELIVERY_SKIPPED:
614             case DELIVERY_TIMEOUT:
615             case DELIVERY_FAILURE:
616                 terminalTime[index] = SystemClock.uptimeMillis();
617                 terminalCount++;
618                 break;
619         }
620 
621         delivery[index] = newDeliveryState;
622         deliveryReasons[index] = reason;
623 
624         // If this state change might bring us to a new high-water mark, bring
625         // ourselves as high as we possibly can
626         final int oldBeyondCount = beyondCount;
627         if (index >= beyondCount) {
628             for (int i = beyondCount; i < delivery.length; i++) {
629                 if (isDeliveryStateBeyond(getDeliveryState(i))) {
630                     beyondCount = i + 1;
631                 } else {
632                     break;
633                 }
634             }
635         }
636         return (beyondCount != oldBeyondCount);
637     }
638 
getDeliveryState(int index)639     @DeliveryState int getDeliveryState(int index) {
640         return delivery[index];
641     }
642 
643     /**
644      * @return if the given {@link #receivers} index should be considered
645      *         blocked based on the current status of the overall broadcast.
646      */
isBlocked(int index)647     boolean isBlocked(int index) {
648         return (beyondCount < blockedUntilBeyondCount[index]);
649     }
650 
wasDeliveryAttempted(int index)651     boolean wasDeliveryAttempted(int index) {
652         final int deliveryState = getDeliveryState(index);
653         switch (deliveryState) {
654             case DELIVERY_DELIVERED:
655             case DELIVERY_TIMEOUT:
656             case DELIVERY_FAILURE:
657                 return true;
658             default:
659                 return false;
660         }
661     }
662 
wasDelivered(int index)663     boolean wasDelivered(int index) {
664         final int deliveryState = getDeliveryState(index);
665         switch (deliveryState) {
666             case DELIVERY_DELIVERED:
667             case DELIVERY_TIMEOUT:
668                 return true;
669             default:
670                 return false;
671         }
672     }
673 
copyEnqueueTimeFrom(@onNull BroadcastRecord replacedBroadcast)674     void copyEnqueueTimeFrom(@NonNull BroadcastRecord replacedBroadcast) {
675         originalEnqueueClockTime = enqueueClockTime;
676         enqueueTime = replacedBroadcast.enqueueTime;
677         enqueueRealTime = replacedBroadcast.enqueueRealTime;
678         enqueueClockTime = replacedBroadcast.enqueueClockTime;
679     }
680 
isForeground()681     boolean isForeground() {
682         return (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
683     }
684 
isReplacePending()685     boolean isReplacePending() {
686         return (intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
687     }
688 
isNoAbort()689     boolean isNoAbort() {
690         return (intent.getFlags() & Intent.FLAG_RECEIVER_NO_ABORT) != 0;
691     }
692 
isOffload()693     boolean isOffload() {
694         return (intent.getFlags() & Intent.FLAG_RECEIVER_OFFLOAD) != 0;
695     }
696 
isDeferUntilActive()697     boolean isDeferUntilActive() {
698         return deferUntilActive;
699     }
700 
isUrgent()701     boolean isUrgent() {
702         return urgent;
703     }
704 
getHostingRecordTriggerType()705     @NonNull String getHostingRecordTriggerType() {
706         if (alarm) {
707             return HostingRecord.TRIGGER_TYPE_ALARM;
708         } else if (pushMessage) {
709             return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE;
710         } else if (pushMessageOverQuota) {
711             return HostingRecord.TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
712         }
713         return HostingRecord.TRIGGER_TYPE_UNKNOWN;
714     }
715 
716     /**
717      * Return an instance of {@link #intent} specialized for the given receiver.
718      * For example, this returns a new specialized instance if the extras need
719      * to be filtered, or a {@link ResolveInfo} needs to be configured.
720      *
721      * @return a specialized intent, otherwise {@code null} to indicate that the
722      *         broadcast should not be delivered to this receiver, typically due
723      *         to it being filtered away by {@link #filterExtrasForReceiver}.
724      */
getReceiverIntent(@onNull Object receiver)725     @Nullable Intent getReceiverIntent(@NonNull Object receiver) {
726         Intent newIntent = null;
727         if (filterExtrasForReceiver != null) {
728             final Bundle extras = intent.getExtras();
729             if (extras != null) {
730                 final int receiverUid = getReceiverUid(receiver);
731                 final Bundle filteredExtras = filterExtrasForReceiver.apply(receiverUid, extras);
732                 if (filteredExtras == null) {
733                     // Completely filtered; skip the broadcast!
734                     return null;
735                 } else {
736                     newIntent = new Intent(intent);
737                     newIntent.replaceExtras(filteredExtras);
738                 }
739             }
740         }
741         if (receiver instanceof ResolveInfo) {
742             if (newIntent == null) {
743                 newIntent = new Intent(intent);
744             }
745             newIntent.setComponent(((ResolveInfo) receiver).activityInfo.getComponentName());
746         }
747         return (newIntent != null) ? newIntent : intent;
748     }
749 
isCallerInstrumented(@ullable ProcessRecord callerApp, int callingUid)750     static boolean isCallerInstrumented(@Nullable ProcessRecord callerApp, int callingUid) {
751         switch (UserHandle.getAppId(callingUid)) {
752             case android.os.Process.ROOT_UID:
753             case android.os.Process.SHELL_UID:
754                 // Broadcasts sent via "shell" are typically invoked by test
755                 // suites, so we treat them as if the caller was instrumented
756                 return true;
757         }
758         return (callerApp != null) ? (callerApp.getActiveInstrumentation() != null) : false;
759     }
760 
761     /**
762      * Determine if the result of
763      * {@link #calculateBlockedUntilBeyondCount(List, boolean, PlatformCompat)}
764      * has prioritized tranches of receivers.
765      */
766     @VisibleForTesting
isPrioritized(@onNull int[] blockedUntilBeyondCount, boolean ordered)767     static boolean isPrioritized(@NonNull int[] blockedUntilBeyondCount,
768             boolean ordered) {
769         return !ordered && (blockedUntilBeyondCount.length > 0)
770                 && (blockedUntilBeyondCount[0] != -1);
771     }
772 
773     /**
774      * Calculate the {@link #beyondCount} that each receiver should be
775      * considered blocked until.
776      * <p>
777      * For example, in an ordered broadcast, receiver {@code N} is blocked until
778      * receiver {@code N-1} reaches a terminal or deferred state. Similarly, in
779      * a prioritized broadcast, receiver {@code N} is blocked until all
780      * receivers of a higher priority reach a terminal or deferred state.
781      * <p>
782      * When there are no beyond count constraints, the blocked value for each
783      * receiver is {@code -1}.
784      */
785     @VisibleForTesting
calculateBlockedUntilBeyondCount( @onNull List<Object> receivers, boolean ordered, PlatformCompat platformCompat)786     static @NonNull int[] calculateBlockedUntilBeyondCount(
787             @NonNull List<Object> receivers, boolean ordered, PlatformCompat platformCompat) {
788         final int N = receivers.size();
789         final int[] blockedUntilBeyondCount = new int[N];
790         if (ordered) {
791             // When sending an ordered broadcast, we need to block this
792             // receiver until all previous receivers have terminated
793             for (int i = 0; i < N; i++) {
794                 blockedUntilBeyondCount[i] = i;
795             }
796         } else {
797             if (Flags.limitPriorityScope()) {
798                 final boolean[] changeEnabled = calculateChangeStateForReceivers(
799                         receivers, LIMIT_PRIORITY_SCOPE, platformCompat);
800 
801                 // Priority of the previous tranche
802                 int lastTranchePriority = 0;
803                 // Priority of the current tranche
804                 int currentTranchePriority = 0;
805                 // Index of the last receiver in the previous tranche
806                 int lastTranchePriorityIndex = -1;
807                 // Index of the last receiver with change disabled in the previous tranche
808                 int lastTrancheChangeDisabledIndex = -1;
809                 // Index of the last receiver with change disabled in the current tranche
810                 int currentTrancheChangeDisabledIndex = -1;
811 
812                 for (int i = 0; i < N; i++) {
813                     final int thisPriority = getReceiverPriority(receivers.get(i));
814                     if (i == 0) {
815                         currentTranchePriority = thisPriority;
816                         if (!changeEnabled[i]) {
817                             currentTrancheChangeDisabledIndex = i;
818                         }
819                         continue;
820                     }
821 
822                     // Check if a new priority tranche has started
823                     if (thisPriority != currentTranchePriority) {
824                         // Update tranche boundaries and reset the disabled index.
825                         if (currentTrancheChangeDisabledIndex != -1) {
826                             lastTrancheChangeDisabledIndex = currentTrancheChangeDisabledIndex;
827                         }
828                         lastTranchePriority = currentTranchePriority;
829                         lastTranchePriorityIndex = i - 1;
830                         currentTranchePriority = thisPriority;
831                         currentTrancheChangeDisabledIndex = -1;
832                     }
833                     if (!changeEnabled[i]) {
834                         currentTrancheChangeDisabledIndex = i;
835 
836                         // Since the change is disabled, block the current receiver until the
837                         // last receiver in the previous tranche.
838                         blockedUntilBeyondCount[i] = lastTranchePriorityIndex + 1;
839                     } else if (thisPriority != lastTranchePriority) {
840                         // If the changeId was disabled for an earlier receiver and the current
841                         // receiver has a different priority, block the current receiver
842                         // until that earlier receiver.
843                         if (lastTrancheChangeDisabledIndex != -1) {
844                             blockedUntilBeyondCount[i] = lastTrancheChangeDisabledIndex + 1;
845                         }
846                     }
847                 }
848                 // If the entire list is in the same priority tranche or no receivers had
849                 // changeId disabled, mark as -1 to indicate that none of them need to wait
850                 if (N > 0 && (lastTranchePriorityIndex == -1
851                         || (lastTrancheChangeDisabledIndex == -1
852                                 && currentTrancheChangeDisabledIndex == -1))) {
853                     Arrays.fill(blockedUntilBeyondCount, -1);
854                 }
855             } else {
856                 // When sending a prioritized broadcast, we only need to wait
857                 // for the previous tranche of receivers to be terminated
858                 int lastPriority = 0;
859                 int lastPriorityIndex = 0;
860                 for (int i = 0; i < N; i++) {
861                     final int thisPriority = getReceiverPriority(receivers.get(i));
862                     if ((i == 0) || (thisPriority != lastPriority)) {
863                         lastPriority = thisPriority;
864                         lastPriorityIndex = i;
865                         blockedUntilBeyondCount[i] = i;
866                     } else {
867                         blockedUntilBeyondCount[i] = lastPriorityIndex;
868                     }
869                 }
870                 // If the entire list is in the same priority tranche, mark as -1 to
871                 // indicate that none of them need to wait
872                 if (N > 0 && blockedUntilBeyondCount[N - 1] == 0) {
873                     Arrays.fill(blockedUntilBeyondCount, -1);
874                 }
875             }
876         }
877         return blockedUntilBeyondCount;
878     }
879 
880     @VisibleForTesting
calculateChangeStateForReceivers(@onNull List<Object> receivers, long changeId, PlatformCompat platformCompat)881     static @NonNull boolean[] calculateChangeStateForReceivers(@NonNull List<Object> receivers,
882             long changeId, PlatformCompat platformCompat) {
883         // TODO: b/371307720 - Remove this method as we are already avoiding the packagemanager
884         // calls by checking the changeId state using ApplicationInfos.
885         final ArrayMap<String, Boolean> changeStates = new ArrayMap<>();
886         final int count = receivers.size();
887         final boolean[] changeStateForReceivers = new boolean[count];
888         for (int i = 0; i < count; ++i) {
889             final ApplicationInfo receiverAppInfo = getReceiverAppInfo(receivers.get(i));
890             final boolean isChangeEnabled;
891             final int idx = changeStates.indexOfKey(receiverAppInfo.packageName);
892             if (idx >= 0) {
893                 isChangeEnabled = changeStates.valueAt(idx);
894             } else {
895                 isChangeEnabled = platformCompat.isChangeEnabledInternalNoLogging(
896                         changeId, receiverAppInfo);
897                 changeStates.put(receiverAppInfo.packageName, isChangeEnabled);
898             }
899             changeStateForReceivers[i] = isChangeEnabled;
900         }
901         return changeStateForReceivers;
902     }
903 
getReceiverAppInfo(@onNull Object receiver)904     static ApplicationInfo getReceiverAppInfo(@NonNull Object receiver) {
905         if (receiver instanceof BroadcastFilter) {
906             return ((BroadcastFilter) receiver).getApplicationInfo();
907         } else {
908             return ((ResolveInfo) receiver).activityInfo.applicationInfo;
909         }
910     }
911 
getReceiverUid(@onNull Object receiver)912     static int getReceiverUid(@NonNull Object receiver) {
913         if (receiver instanceof BroadcastFilter) {
914             return ((BroadcastFilter) receiver).owningUid;
915         } else /* if (receiver instanceof ResolveInfo) */ {
916             return ((ResolveInfo) receiver).activityInfo.applicationInfo.uid;
917         }
918     }
919 
getReceiverProcessName(@onNull Object receiver)920     static @NonNull String getReceiverProcessName(@NonNull Object receiver) {
921         if (receiver instanceof BroadcastFilter) {
922             return ((BroadcastFilter) receiver).receiverList.app.processName;
923         } else /* if (receiver instanceof ResolveInfo) */ {
924             return ((ResolveInfo) receiver).activityInfo.processName;
925         }
926     }
927 
getReceiverPackageName(@onNull Object receiver)928     static @NonNull String getReceiverPackageName(@NonNull Object receiver) {
929         if (receiver instanceof BroadcastFilter) {
930             return ((BroadcastFilter) receiver).receiverList.app.info.packageName;
931         } else /* if (receiver instanceof ResolveInfo) */ {
932             return ((ResolveInfo) receiver).activityInfo.packageName;
933         }
934     }
935 
getReceiverClassName(@onNull Object receiver)936     static @Nullable String getReceiverClassName(@NonNull Object receiver) {
937         if (receiver instanceof BroadcastFilter) {
938             return ((BroadcastFilter) receiver).getReceiverClassName();
939         } else /* if (receiver instanceof ResolveInfo) */ {
940             return ((ResolveInfo) receiver).activityInfo.name;
941         }
942     }
943 
getReceiverPriority(@onNull Object receiver)944     static int getReceiverPriority(@NonNull Object receiver) {
945         if (receiver instanceof BroadcastFilter) {
946             return ((BroadcastFilter) receiver).getPriority();
947         } else /* if (receiver instanceof ResolveInfo) */ {
948             return ((ResolveInfo) receiver).priority;
949         }
950     }
951 
isReceiverEquals(@onNull Object a, @NonNull Object b)952     static boolean isReceiverEquals(@NonNull Object a, @NonNull Object b) {
953         if (a == b) {
954             return true;
955         } else if (a instanceof ResolveInfo && b instanceof ResolveInfo) {
956             final ResolveInfo infoA = (ResolveInfo) a;
957             final ResolveInfo infoB = (ResolveInfo) b;
958             return Objects.equals(infoA.activityInfo.packageName, infoB.activityInfo.packageName)
959                     && Objects.equals(infoA.activityInfo.name, infoB.activityInfo.name);
960         } else {
961             return false;
962         }
963     }
964 
965     /**
966      * Core policy determination about this broadcast's delivery prioritization
967      */
968     @VisibleForTesting
calculateUrgent(@onNull Intent intent, @Nullable BroadcastOptions options)969     static boolean calculateUrgent(@NonNull Intent intent, @Nullable BroadcastOptions options) {
970         // TODO: flags for controlling policy
971         // TODO: migrate alarm-prioritization flag to BroadcastConstants
972         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0) {
973             return true;
974         }
975         if (options != null) {
976             if (options.isInteractive()) {
977                 return true;
978             }
979             if (options.isAlarmBroadcast()) {
980                 return true;
981             }
982         }
983         return false;
984     }
985 
986     /**
987      * Resolve the requested {@link BroadcastOptions#setDeferralPolicy(int)}
988      * against this broadcast state to determine if it should be marked as
989      * "defer until active".
990      */
991     @VisibleForTesting
calculateDeferUntilActive(int callingUid, @Nullable BroadcastOptions options, @Nullable IIntentReceiver resultTo, boolean ordered, boolean urgent)992     static boolean calculateDeferUntilActive(int callingUid, @Nullable BroadcastOptions options,
993             @Nullable IIntentReceiver resultTo, boolean ordered, boolean urgent) {
994         // Ordered broadcasts can never be deferred until active
995         if (ordered) {
996             return false;
997         }
998 
999         // Unordered resultTo broadcasts are always deferred until active
1000         if (!ordered && resultTo != null) {
1001             return true;
1002         }
1003 
1004         // Determine if a strong preference in either direction was expressed;
1005         // a preference here overrides all remaining policies
1006         if (options != null) {
1007             switch (options.getDeferralPolicy()) {
1008                 case BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE:
1009                     return true;
1010                 case BroadcastOptions.DEFERRAL_POLICY_NONE:
1011                     return false;
1012             }
1013         }
1014 
1015         // Urgent broadcasts aren't deferred until active
1016         if (urgent) {
1017             return false;
1018         }
1019 
1020         // Otherwise, choose a reasonable default
1021         if (CORE_DEFER_UNTIL_ACTIVE && UserHandle.isCore(callingUid)) {
1022             return true;
1023         } else {
1024             return false;
1025         }
1026     }
1027 
calculateTypeForLogging()1028     int calculateTypeForLogging() {
1029         int type = BROADCAST_TYPE_NONE;
1030         if (isForeground()) {
1031             type |= BROADCAST_TYPE_FOREGROUND;
1032         } else {
1033             type |= BROADCAST_TYPE_BACKGROUND;
1034         }
1035         if (alarm) {
1036             type |= BROADCAST_TYPE_ALARM;
1037         }
1038         if (interactive) {
1039             type |= BROADCAST_TYPE_INTERACTIVE;
1040         }
1041         if (ordered) {
1042             type |= BROADCAST_TYPE_ORDERED;
1043         }
1044         if (prioritized) {
1045             type |= BROADCAST_TYPE_PRIORITIZED;
1046         }
1047         if (resultTo != null) {
1048             type |= BROADCAST_TYPE_RESULT_TO;
1049         }
1050         if (deferUntilActive) {
1051             type |= BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE;
1052         }
1053         if (pushMessage) {
1054             type |= BROADCAST_TYPE_PUSH_MESSAGE;
1055         }
1056         if (pushMessageOverQuota) {
1057             type |= BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA;
1058         }
1059         if (sticky) {
1060             type |= BROADCAST_TYPE_STICKY;
1061         }
1062         if (initialSticky) {
1063             type |= BROADCAST_TYPE_INITIAL_STICKY;
1064         }
1065         return type;
1066     }
1067 
calculateTypesForLogging()1068     int[] calculateTypesForLogging() {
1069         final IntArray types = new IntArray();
1070         if (isForeground()) {
1071             types.add(BROADCAST_TYPE_FOREGROUND);
1072         } else {
1073             types.add(BROADCAST_TYPE_BACKGROUND);
1074         }
1075         if (alarm) {
1076             types.add(BROADCAST_TYPE_ALARM);
1077         }
1078         if (interactive) {
1079             types.add(BROADCAST_TYPE_INTERACTIVE);
1080         }
1081         if (ordered) {
1082             types.add(BROADCAST_TYPE_ORDERED);
1083         }
1084         if (prioritized) {
1085             types.add(BROADCAST_TYPE_PRIORITIZED);
1086         }
1087         if (resultTo != null) {
1088             types.add(BROADCAST_TYPE_RESULT_TO);
1089         }
1090         if (deferUntilActive) {
1091             types.add(BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE);
1092         }
1093         if (pushMessage) {
1094             types.add(BROADCAST_TYPE_PUSH_MESSAGE);
1095         }
1096         if (pushMessageOverQuota) {
1097             types.add(BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA);
1098         }
1099         if (sticky) {
1100             types.add(BROADCAST_TYPE_STICKY);
1101         }
1102         if (initialSticky) {
1103             types.add(BROADCAST_TYPE_INITIAL_STICKY);
1104         }
1105         return types.toArray();
1106     }
1107 
maybeStripForHistory()1108     public BroadcastRecord maybeStripForHistory() {
1109         if (!intent.canStripForHistory()) {
1110             return this;
1111         }
1112         return new BroadcastRecord(this, intent.maybeStripForHistory());
1113     }
1114 
1115     @VisibleForTesting
cleanupDisabledPackageReceiversLocked( String packageName, Set<String> filterByClasses, int userId, boolean doit)1116     boolean cleanupDisabledPackageReceiversLocked(
1117             String packageName, Set<String> filterByClasses, int userId, boolean doit) {
1118         if (receivers == null) {
1119             return false;
1120         }
1121 
1122         final boolean cleanupAllUsers = userId == UserHandle.USER_ALL;
1123         final boolean sendToAllUsers = this.userId == UserHandle.USER_ALL;
1124         if (this.userId != userId && !cleanupAllUsers && !sendToAllUsers) {
1125             return false;
1126         }
1127 
1128         boolean didSomething = false;
1129         Object o;
1130         for (int i = receivers.size() - 1; i >= 0; i--) {
1131             o = receivers.get(i);
1132             if (!(o instanceof ResolveInfo)) {
1133                 continue;
1134             }
1135             ActivityInfo info = ((ResolveInfo)o).activityInfo;
1136 
1137             final boolean sameComponent = packageName == null
1138                     || (info.applicationInfo.packageName.equals(packageName)
1139                     && (filterByClasses == null || filterByClasses.contains(info.name)));
1140             if (sameComponent && (cleanupAllUsers
1141                     || UserHandle.getUserId(info.applicationInfo.uid) == userId)) {
1142                 if (!doit) {
1143                     return true;
1144                 }
1145                 didSomething = true;
1146                 receivers.remove(i);
1147                 if (i < nextReceiver) {
1148                     nextReceiver--;
1149                 }
1150             }
1151         }
1152         nextReceiver = Math.min(nextReceiver, receivers.size());
1153 
1154         return didSomething;
1155     }
1156 
1157     /**
1158      * Apply special treatment to manifest receivers hosted by a singleton
1159      * process, by re-targeting them at {@link UserHandle#USER_SYSTEM}.
1160      */
applySingletonPolicy(@onNull ActivityManagerService service)1161     void applySingletonPolicy(@NonNull ActivityManagerService service) {
1162         if (receivers == null) return;
1163         for (int i = 0; i < receivers.size(); i++) {
1164             final Object receiver = receivers.get(i);
1165             if (receiver instanceof ResolveInfo) {
1166                 final ResolveInfo info = (ResolveInfo) receiver;
1167                 boolean isSingleton = false;
1168                 try {
1169                     isSingleton = service.isSingleton(info.activityInfo.processName,
1170                             info.activityInfo.applicationInfo,
1171                             info.activityInfo.name, info.activityInfo.flags);
1172                 } catch (SecurityException e) {
1173                     BroadcastQueue.logw(e.getMessage());
1174                 }
1175                 final int receiverUid = info.activityInfo.applicationInfo.uid;
1176                 if (callingUid != android.os.Process.SYSTEM_UID && isSingleton
1177                         && service.isValidSingletonCall(callingUid, receiverUid)) {
1178                     info.activityInfo = service.getActivityInfoForUser(info.activityInfo,
1179                             UserHandle.USER_SYSTEM);
1180                 }
1181             }
1182         }
1183     }
1184 
containsReceiver(@onNull Object receiver)1185     boolean containsReceiver(@NonNull Object receiver) {
1186         for (int i = receivers.size() - 1; i >= 0; --i) {
1187             if (isReceiverEquals(receiver, receivers.get(i))) {
1188                 return true;
1189             }
1190         }
1191         return false;
1192     }
1193 
containsAllReceivers(@onNull List<Object> otherReceivers)1194     boolean containsAllReceivers(@NonNull List<Object> otherReceivers) {
1195         for (int i = otherReceivers.size() - 1; i >= 0; --i) {
1196             if (!containsReceiver(otherReceivers.get(i))) {
1197                 return false;
1198             }
1199         }
1200         return true;
1201     }
1202 
1203     @DeliveryGroupPolicy
getDeliveryGroupPolicy()1204     int getDeliveryGroupPolicy() {
1205         return (options != null) ? options.getDeliveryGroupPolicy()
1206                 : BroadcastOptions.DELIVERY_GROUP_POLICY_ALL;
1207     }
1208 
matchesDeliveryGroup(@onNull BroadcastRecord other)1209     boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
1210         return matchesDeliveryGroup(this, other);
1211     }
1212 
matchesDeliveryGroup(@onNull BroadcastRecord newRecord, @NonNull BroadcastRecord oldRecord)1213     private static boolean matchesDeliveryGroup(@NonNull BroadcastRecord newRecord,
1214             @NonNull BroadcastRecord oldRecord) {
1215         final IntentFilter newMatchingFilter = getDeliveryGroupMatchingFilter(newRecord);
1216         // If neither delivery group key nor matching filter is specified, then use
1217         // Intent.filterEquals() to identify the delivery group.
1218         if (isMatchingKeyNull(newRecord) && isMatchingKeyNull(oldRecord)
1219                 && newMatchingFilter == null) {
1220             return newRecord.intent.filterEquals(oldRecord.intent);
1221         }
1222         if (newMatchingFilter != null && !newMatchingFilter.asPredicate().test(oldRecord.intent)) {
1223             return false;
1224         }
1225         return areMatchingKeysEqual(newRecord, oldRecord);
1226     }
1227 
isMatchingKeyNull(@onNull BroadcastRecord record)1228     private static boolean isMatchingKeyNull(@NonNull BroadcastRecord record) {
1229         final String namespace = getDeliveryGroupMatchingNamespaceFragment(record);
1230         final String key = getDeliveryGroupMatchingKeyFragment(record);
1231         // If either namespace or key part is null, then treat the entire matching key as null.
1232         return namespace == null || key == null;
1233     }
1234 
areMatchingKeysEqual(@onNull BroadcastRecord newRecord, @NonNull BroadcastRecord oldRecord)1235     private static boolean areMatchingKeysEqual(@NonNull BroadcastRecord newRecord,
1236             @NonNull BroadcastRecord oldRecord) {
1237         final String newNamespaceFragment = getDeliveryGroupMatchingNamespaceFragment(newRecord);
1238         final String oldNamespaceFragment = getDeliveryGroupMatchingNamespaceFragment(oldRecord);
1239         if (!Objects.equals(newNamespaceFragment, oldNamespaceFragment)) {
1240             return false;
1241         }
1242 
1243         final String newKeyFragment = getDeliveryGroupMatchingKeyFragment(newRecord);
1244         final String oldKeyFragment = getDeliveryGroupMatchingKeyFragment(oldRecord);
1245         return Objects.equals(newKeyFragment, oldKeyFragment);
1246     }
1247 
1248     @Nullable
getDeliveryGroupMatchingNamespaceFragment( @onNull BroadcastRecord record)1249     private static String getDeliveryGroupMatchingNamespaceFragment(
1250             @NonNull BroadcastRecord record) {
1251         return record.options == null
1252                 ? null : record.options.getDeliveryGroupMatchingNamespaceFragment();
1253     }
1254 
1255     @Nullable
getDeliveryGroupMatchingKeyFragment(@onNull BroadcastRecord record)1256     private static String getDeliveryGroupMatchingKeyFragment(@NonNull BroadcastRecord record) {
1257         return record.options == null
1258                 ? null : record.options.getDeliveryGroupMatchingKeyFragment();
1259     }
1260 
1261     @Nullable
getDeliveryGroupMatchingFilter(@onNull BroadcastRecord record)1262     private static IntentFilter getDeliveryGroupMatchingFilter(@NonNull BroadcastRecord record) {
1263         return record.options == null ? null : record.options.getDeliveryGroupMatchingFilter();
1264     }
1265 
1266     /**
1267      * Returns {@code true} if all the receivers are still waiting to receive the broadcast.
1268      * Otherwise {@code false}.
1269      */
allReceiversPending()1270     boolean allReceiversPending() {
1271         // We could also count the number of receivers with deliver state DELIVERY_PENDING, but
1272         // checking how many receivers have finished (either skipped or cancelled) and whether or
1273         // not the dispatch has been started should be sufficient.
1274         return (terminalCount == 0 && dispatchTime <= 0);
1275     }
1276 
isMatchingRecord(@onNull BroadcastRecord record)1277     boolean isMatchingRecord(@NonNull BroadcastRecord record) {
1278         final int idx = mMatchingRecordsCache.indexOfKey(record);
1279         if (idx > 0) {
1280             return mMatchingRecordsCache.valueAt(idx);
1281         }
1282         // Consider a record to be matching if has the same receivers in the same order.
1283         boolean matches = (receivers.size() == record.receivers.size());
1284         if (matches) {
1285             for (int i = receivers.size() - 1; i >= 0; --i) {
1286                 if (!isReceiverEquals(receivers.get(i), record.receivers.get(i))) {
1287                     matches = false;
1288                     break;
1289                 }
1290             }
1291         }
1292         mMatchingRecordsCache.put(record, matches);
1293         return matches;
1294     }
1295 
setMatchingRecordsCache(@onNull ArrayMap<BroadcastRecord, Boolean> matchingRecordsCache)1296     void setMatchingRecordsCache(@NonNull ArrayMap<BroadcastRecord, Boolean> matchingRecordsCache) {
1297         mMatchingRecordsCache = matchingRecordsCache;
1298     }
1299 
clearMatchingRecordsCache()1300     void clearMatchingRecordsCache() {
1301         mMatchingRecordsCache = null;
1302     }
1303 
1304     @Override
1305     @NonNull
toString()1306     public String toString() {
1307         if (mCachedToString == null) {
1308             mCachedToString = "BroadcastRecord{" + toShortString() + "}";
1309         }
1310         return mCachedToString;
1311     }
1312 
1313     @NonNull
toShortString()1314     public String toShortString() {
1315         if (mCachedToShortString == null) {
1316             final String label = intentToString(intent);
1317             mCachedToShortString = Integer.toHexString(System.identityHashCode(this))
1318                     + " " + label + "/u" + userId;
1319         }
1320         return mCachedToShortString;
1321     }
1322 
1323     @NonNull
intentToString(@onNull Intent intent)1324     public static String intentToString(@NonNull Intent intent) {
1325         String label = intent.getAction();
1326         if (label == null) {
1327             label = intent.toString();
1328         }
1329         return label;
1330     }
1331 
debugLog()1332     public boolean debugLog() {
1333         return debugLog(options);
1334     }
1335 
debugLog(@ullable BroadcastOptions options)1336     public static boolean debugLog(@Nullable BroadcastOptions options) {
1337         return options != null && options.isDebugLogEnabled();
1338     }
1339 
1340     @NeverCompile
dumpDebug(@onNull ProtoOutputStream proto, long fieldId)1341     public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
1342         long token = proto.start(fieldId);
1343         proto.write(BroadcastRecordProto.USER_ID, userId);
1344         proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
1345         proto.end(token);
1346     }
1347 
1348     /**
1349      * Uses the {@link BroadcastProcessedEventRecord} pojo to store the logging information related
1350      * to {@param receiver} object.
1351      */
updateBroadcastProcessedEventRecord(@onNull Object receiver, long timeMillis)1352     public void updateBroadcastProcessedEventRecord(@NonNull Object receiver, long timeMillis) {
1353         if (!Flags.logBroadcastProcessedEvent()) {
1354             return;
1355         }
1356 
1357         final String receiverProcessName = getReceiverProcessName(receiver);
1358         BroadcastProcessedEventRecord broadcastProcessedEventRecord =
1359                 mBroadcastProcessedRecords.get(receiverProcessName);
1360         if (broadcastProcessedEventRecord == null) {
1361             broadcastProcessedEventRecord = new BroadcastProcessedEventRecord()
1362                     .setBroadcastTypes(calculateTypesForLogging())
1363                     .setIntentAction(intent.getAction())
1364                     .setReceiverProcessName(receiverProcessName)
1365                     .setReceiverUid(getReceiverUid(receiver))
1366                     .setSenderUid(callingUid);
1367 
1368             mBroadcastProcessedRecords.put(receiverProcessName, broadcastProcessedEventRecord);
1369         }
1370 
1371         broadcastProcessedEventRecord.addReceiverFinishTime(timeMillis);
1372     }
1373 
logBroadcastProcessedEventRecord()1374     public void logBroadcastProcessedEventRecord() {
1375         if (!Flags.logBroadcastProcessedEvent()) {
1376             return;
1377         }
1378 
1379         int size = mBroadcastProcessedRecords.size();
1380         for (int i = 0; i < size; i++) {
1381             mBroadcastProcessedRecords.valueAt(i).logToStatsD();
1382         }
1383         mBroadcastProcessedRecords.clear();
1384     }
1385 
1386     @VisibleForTesting
1387     @NonNull
getBroadcastProcessedRecordsForTest()1388     ArrayMap<String, BroadcastProcessedEventRecord> getBroadcastProcessedRecordsForTest() {
1389         return mBroadcastProcessedRecords;
1390     }
1391 }
1392