• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 android.app;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresPermission;
23 import android.annotation.SystemApi;
24 import android.annotation.TestApi;
25 import android.app.compat.CompatChanges;
26 import android.compat.annotation.ChangeId;
27 import android.compat.annotation.Disabled;
28 import android.compat.annotation.EnabledSince;
29 import android.content.Intent;
30 import android.os.Build;
31 import android.os.Bundle;
32 import android.os.PowerExemptionManager;
33 import android.os.PowerExemptionManager.ReasonCode;
34 import android.os.PowerExemptionManager.TempAllowListType;
35 
36 /**
37  * Helper class for building an options Bundle that can be used with
38  * {@link android.content.Context#sendBroadcast(android.content.Intent)
39  * Context.sendBroadcast(Intent)} and related methods.
40  * {@hide}
41  */
42 @SystemApi
43 public class BroadcastOptions extends ComponentOptions {
44     private long mTemporaryAppAllowlistDuration;
45     private @TempAllowListType int mTemporaryAppAllowlistType;
46     private @ReasonCode int mTemporaryAppAllowlistReasonCode;
47     private @Nullable String mTemporaryAppAllowlistReason;
48     private int mMinManifestReceiverApiLevel = 0;
49     private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
50     private boolean mDontSendToRestrictedApps = false;
51     private boolean mAllowBackgroundActivityStarts;
52     private String[] mRequireAllOfPermissions;
53     private String[] mRequireNoneOfPermissions;
54     private long mRequireCompatChangeId = CHANGE_INVALID;
55     private boolean mRequireCompatChangeEnabled = true;
56     private boolean mIsAlarmBroadcast = false;
57     private long mIdForResponseEvent;
58 
59     /**
60      * Change ID which is invalid.
61      *
62      * @hide
63      */
64     public static final long CHANGE_INVALID = Long.MIN_VALUE;
65 
66     /**
67      * Change ID which is always enabled, for testing purposes.
68      *
69      * @hide
70      */
71     @TestApi
72     @ChangeId
73     @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
74     public static final long CHANGE_ALWAYS_ENABLED = 209888056L;
75 
76     /**
77      * Change ID which is always disabled, for testing purposes.
78      *
79      * @hide
80      */
81     @TestApi
82     @ChangeId
83     @Disabled
84     public static final long CHANGE_ALWAYS_DISABLED = 210856463L;
85 
86     /**
87      * How long to temporarily put an app on the power allowlist when executing this broadcast
88      * to it.
89      */
90     private static final String KEY_TEMPORARY_APP_ALLOWLIST_DURATION
91             = "android:broadcast.temporaryAppAllowlistDuration";
92 
93     private static final String KEY_TEMPORARY_APP_ALLOWLIST_TYPE
94             = "android:broadcast.temporaryAppAllowlistType";
95 
96     private static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE =
97             "android:broadcast.temporaryAppAllowlistReasonCode";
98 
99     private static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON =
100             "android:broadcast.temporaryAppAllowlistReason";
101 
102     /**
103      * Corresponds to {@link #setMinManifestReceiverApiLevel}.
104      */
105     private static final String KEY_MIN_MANIFEST_RECEIVER_API_LEVEL
106             = "android:broadcast.minManifestReceiverApiLevel";
107 
108     /**
109      * Corresponds to {@link #setMaxManifestReceiverApiLevel}.
110      */
111     private static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL
112             = "android:broadcast.maxManifestReceiverApiLevel";
113 
114     /**
115      * Corresponds to {@link #setDontSendToRestrictedApps}.
116      */
117     private static final String KEY_DONT_SEND_TO_RESTRICTED_APPS =
118             "android:broadcast.dontSendToRestrictedApps";
119 
120     /**
121      * Corresponds to {@link #setBackgroundActivityStartsAllowed}.
122      */
123     private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
124             "android:broadcast.allowBackgroundActivityStarts";
125 
126     /**
127      * Corresponds to {@link #setRequireAllOfPermissions}
128      * @hide
129      */
130     public static final String KEY_REQUIRE_ALL_OF_PERMISSIONS =
131             "android:broadcast.requireAllOfPermissions";
132 
133     /**
134      * Corresponds to {@link #setRequireNoneOfPermissions}
135      * @hide
136      */
137     public static final String KEY_REQUIRE_NONE_OF_PERMISSIONS =
138             "android:broadcast.requireNoneOfPermissions";
139 
140     /**
141      * Corresponds to {@link #setRequireCompatChange(long, boolean)}
142      */
143     private static final String KEY_REQUIRE_COMPAT_CHANGE_ID =
144             "android:broadcast.requireCompatChangeId";
145 
146     /**
147      * Corresponds to {@link #setRequireCompatChange(long, boolean)}
148      */
149     private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED =
150             "android:broadcast.requireCompatChangeEnabled";
151 
152     /**
153      * Corresponds to {@link #setAlarmBroadcast(boolean)}
154      * @hide
155      */
156     public static final String KEY_ALARM_BROADCAST =
157             "android:broadcast.is_alarm";
158 
159     /**
160      * @hide
161      * @deprecated Use {@link android.os.PowerExemptionManager#
162      * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED} instead.
163      */
164     @Deprecated
165     public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED =
166             PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
167 
168     /**
169      * @hide
170      * @deprecated Use {@link android.os.PowerExemptionManager#
171      * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} instead.
172      */
173     @Deprecated
174     public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED =
175             PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
176 
177     /**
178      * Corresponds to {@link #recordResponseEventWhileInBackground(long)}.
179      */
180     private static final String KEY_ID_FOR_RESPONSE_EVENT =
181             "android:broadcast.idForResponseEvent";
182 
makeBasic()183     public static BroadcastOptions makeBasic() {
184         BroadcastOptions opts = new BroadcastOptions();
185         return opts;
186     }
187 
BroadcastOptions()188     private BroadcastOptions() {
189         super();
190         resetTemporaryAppAllowlist();
191     }
192 
193     /** @hide */
194     @TestApi
BroadcastOptions(@onNull Bundle opts)195     public BroadcastOptions(@NonNull Bundle opts) {
196         super(opts);
197         // Match the logic in toBundle().
198         if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) {
199             mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION);
200             mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE);
201             mTemporaryAppAllowlistReasonCode = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE,
202                     PowerExemptionManager.REASON_UNKNOWN);
203             mTemporaryAppAllowlistReason = opts.getString(KEY_TEMPORARY_APP_ALLOWLIST_REASON);
204         } else {
205             resetTemporaryAppAllowlist();
206         }
207         mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0);
208         mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL,
209                 Build.VERSION_CODES.CUR_DEVELOPMENT);
210         mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false);
211         mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS,
212                 false);
213         mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS);
214         mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS);
215         mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID);
216         mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true);
217         mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT);
218         mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false);
219     }
220 
221     /**
222      * Set a duration for which the system should temporary place an application on the
223      * power allowlist when this broadcast is being delivered to it.
224      * @param duration The duration in milliseconds; 0 means to not place on allowlist.
225      * @deprecated use {@link #setTemporaryAppAllowlist(long, int, int,  String)} instead.
226      */
227     @Deprecated
228     @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
229             android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
230             android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
setTemporaryAppWhitelistDuration(long duration)231     public void setTemporaryAppWhitelistDuration(long duration) {
232         setTemporaryAppAllowlist(duration,
233                 PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
234                 PowerExemptionManager.REASON_UNKNOWN, null);
235     }
236 
237     /**
238      * Set a duration for which the system should temporary place an application on the
239      * power allowlist when this broadcast is being delivered to it, specify the temp allowlist
240      * type.
241      * @param duration the duration in milliseconds.
242      *                 0 means to not place on allowlist, and clears previous call to this method.
243      * @param type one of {@link TempAllowListType}.
244      *             {@link PowerExemptionManager#TEMPORARY_ALLOW_LIST_TYPE_NONE} means
245      *             to not place on allowlist, and clears previous call to this method.
246      * @param reasonCode one of {@link ReasonCode}, use
247      *                  {@link PowerExemptionManager#REASON_UNKNOWN} if not sure.
248      * @param reason A human-readable reason explaining why the app is temp allowlisted. Only
249      *               used for logging purposes. Could be null or empty string.
250      */
251     @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
252             android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
253             android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
setTemporaryAppAllowlist(long duration, @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason)254     public void setTemporaryAppAllowlist(long duration, @TempAllowListType int type,
255             @ReasonCode int reasonCode, @Nullable String reason) {
256         mTemporaryAppAllowlistDuration = duration;
257         mTemporaryAppAllowlistType = type;
258         mTemporaryAppAllowlistReasonCode = reasonCode;
259         mTemporaryAppAllowlistReason = reason;
260 
261         if (!isTemporaryAppAllowlistSet()) {
262             resetTemporaryAppAllowlist();
263         }
264     }
265 
isTemporaryAppAllowlistSet()266     private boolean isTemporaryAppAllowlistSet() {
267         return mTemporaryAppAllowlistDuration > 0
268                 && mTemporaryAppAllowlistType
269                     != PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
270     }
271 
resetTemporaryAppAllowlist()272     private void resetTemporaryAppAllowlist() {
273         mTemporaryAppAllowlistDuration = 0;
274         mTemporaryAppAllowlistType = PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
275         mTemporaryAppAllowlistReasonCode = PowerExemptionManager.REASON_UNKNOWN;
276         mTemporaryAppAllowlistReason = null;
277     }
278 
279     /**
280      * Set PendingIntent activity is allowed to be started in the background if the caller
281      * can start background activities.
282      * @hide
283      */
284     @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed)285     public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
286         super.setPendingIntentBackgroundActivityLaunchAllowed(allowed);
287     }
288 
289     /**
290      * Get PendingIntent activity is allowed to be started in the background if the caller
291      * can start background activities.
292      * @hide
293      */
294     @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
isPendingIntentBackgroundActivityLaunchAllowed()295     public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
296         return super.isPendingIntentBackgroundActivityLaunchAllowed();
297     }
298 
299     /**
300      * Return {@link #setTemporaryAppAllowlist}.
301      * @hide
302      */
303     @TestApi
getTemporaryAppAllowlistDuration()304     public long getTemporaryAppAllowlistDuration() {
305         return mTemporaryAppAllowlistDuration;
306     }
307 
308     /**
309      * Return {@link #mTemporaryAppAllowlistType}.
310      * @hide
311      */
312     @TestApi
getTemporaryAppAllowlistType()313     public @TempAllowListType int getTemporaryAppAllowlistType() {
314         return mTemporaryAppAllowlistType;
315     }
316 
317     /**
318      * Return {@link #mTemporaryAppAllowlistReasonCode}.
319      * @hide
320      */
321     @TestApi
getTemporaryAppAllowlistReasonCode()322     public @ReasonCode int getTemporaryAppAllowlistReasonCode() {
323         return mTemporaryAppAllowlistReasonCode;
324     }
325 
326     /**
327      * Return {@link #mTemporaryAppAllowlistReason}.
328      * @hide
329      */
330     @TestApi
getTemporaryAppAllowlistReason()331     public @Nullable String getTemporaryAppAllowlistReason() {
332         return mTemporaryAppAllowlistReason;
333     }
334 
335     /**
336      * Set the minimum target API level of receivers of the broadcast.  If an application
337      * is targeting an API level less than this, the broadcast will not be delivered to
338      * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
339      *
340      * @deprecated to give developers the most flexibility during beta releases,
341      *             we strongly encourage using {@link ChangeId} instead of
342      *             target SDK checks; callers should use
343      *             {@link #setRequireCompatChange(long, boolean)} instead,
344      *             possibly combined with
345      *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
346      * @hide
347      */
348     @Deprecated
setMinManifestReceiverApiLevel(int apiLevel)349     public void setMinManifestReceiverApiLevel(int apiLevel) {
350         mMinManifestReceiverApiLevel = apiLevel;
351     }
352 
353     /**
354      * Return {@link #setMinManifestReceiverApiLevel}.
355      *
356      * @deprecated to give developers the most flexibility during beta releases,
357      *             we strongly encourage using {@link ChangeId} instead of
358      *             target SDK checks; callers should use
359      *             {@link #setRequireCompatChange(long, boolean)} instead,
360      *             possibly combined with
361      *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
362      * @hide
363      */
364     @Deprecated
getMinManifestReceiverApiLevel()365     public int getMinManifestReceiverApiLevel() {
366         return mMinManifestReceiverApiLevel;
367     }
368 
369     /**
370      * Set the maximum target API level of receivers of the broadcast.  If an application
371      * is targeting an API level greater than this, the broadcast will not be delivered to
372      * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
373      *
374      * @deprecated to give developers the most flexibility during beta releases,
375      *             we strongly encourage using {@link ChangeId} instead of
376      *             target SDK checks; callers should use
377      *             {@link #setRequireCompatChange(long, boolean)} instead,
378      *             possibly combined with
379      *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
380      * @hide
381      */
382     @TestApi
383     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
384     @Deprecated
setMaxManifestReceiverApiLevel(int apiLevel)385     public void setMaxManifestReceiverApiLevel(int apiLevel) {
386         mMaxManifestReceiverApiLevel = apiLevel;
387     }
388 
389     /**
390      * Return {@link #setMaxManifestReceiverApiLevel}.
391      *
392      * @deprecated to give developers the most flexibility during beta releases,
393      *             we strongly encourage using {@link ChangeId} instead of
394      *             target SDK checks; callers should use
395      *             {@link #setRequireCompatChange(long, boolean)} instead,
396      *             possibly combined with
397      *             {@link Intent#FLAG_RECEIVER_REGISTERED_ONLY}.
398      * @hide
399      */
400     @TestApi
401     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
402     @Deprecated
getMaxManifestReceiverApiLevel()403     public int getMaxManifestReceiverApiLevel() {
404         return mMaxManifestReceiverApiLevel;
405     }
406 
407     /**
408      * Sets whether pending intent can be sent for an application with background restrictions
409      * @param dontSendToRestrictedApps if true, pending intent will not be sent for an application
410      * with background restrictions. Default value is {@code false}
411      */
setDontSendToRestrictedApps(boolean dontSendToRestrictedApps)412     public void setDontSendToRestrictedApps(boolean dontSendToRestrictedApps) {
413         mDontSendToRestrictedApps = dontSendToRestrictedApps;
414     }
415 
416     /**
417      * @hide
418      * @return #setDontSendToRestrictedApps
419      */
isDontSendToRestrictedApps()420     public boolean isDontSendToRestrictedApps() {
421         return mDontSendToRestrictedApps;
422     }
423 
424     /**
425      * Sets the process will be able to start activities from background for the duration of
426      * the broadcast dispatch. Default value is {@code false}
427      */
428     @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND)
setBackgroundActivityStartsAllowed(boolean allowBackgroundActivityStarts)429     public void setBackgroundActivityStartsAllowed(boolean allowBackgroundActivityStarts) {
430         mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
431     }
432 
433     /**
434      * @hide
435      * @return #setAllowBackgroundActivityStarts
436      */
allowsBackgroundActivityStarts()437     public boolean allowsBackgroundActivityStarts() {
438         return mAllowBackgroundActivityStarts;
439     }
440 
441     /**
442      * Use this to configure a broadcast to be sent to apps that hold all permissions in
443      * the list. This is only for use with the {@link Context#sendBroadcast(Intent intent,
444      * @Nullable String receiverPermission, @Nullable Bundle options)}.
445      *
446      * <p> If both {@link #setRequireAllOfPermissions(String[])} and
447      * {@link #setRequireNoneOfPermissions(String[])} are used, then receivers must have all of the
448      * permissions set by {@link #setRequireAllOfPermissions(String[])}, and none of the
449      * permissions set by {@link #setRequireNoneOfPermissions(String[])} to get the broadcast.
450      *
451      * @param requiredPermissions a list of Strings of permission the receiver must have. Set to
452      *                            null or an empty array to clear any previously set value.
453      * @hide
454      */
455     @SystemApi
setRequireAllOfPermissions(@ullable String[] requiredPermissions)456     public void setRequireAllOfPermissions(@Nullable String[] requiredPermissions) {
457         mRequireAllOfPermissions = requiredPermissions;
458     }
459 
460     /**
461      * Use this to configure a broadcast to be sent to apps that don't hold any permissions in
462      * list. This is only for use with the {@link Context#sendBroadcast(Intent intent,
463      * @Nullable String receiverPermission, @Nullable Bundle options)}.
464      *
465      * <p> If both {@link #setRequireAllOfPermissions(String[])} and
466      * {@link #setRequireNoneOfPermissions(String[])} are used, then receivers must have all of the
467      * permissions set by {@link #setRequireAllOfPermissions(String[])}, and none of the
468      * permissions set by {@link #setRequireNoneOfPermissions(String[])} to get the broadcast.
469      *
470      * @param excludedPermissions a list of Strings of permission the receiver must not have. Set to
471      *                            null or an empty array to clear any previously set value.
472      * @hide
473      */
474     @SystemApi
setRequireNoneOfPermissions(@ullable String[] excludedPermissions)475     public void setRequireNoneOfPermissions(@Nullable String[] excludedPermissions) {
476         mRequireNoneOfPermissions = excludedPermissions;
477     }
478 
479     /**
480      * When set, this broadcast will only be delivered to apps which have the
481      * given {@link ChangeId} in the given state.
482      * <p>
483      * Each {@link BroadcastOptions} instance supports only a single
484      * {@link ChangeId} requirement, so any subsequent calls will override any
485      * previously defined requirement.
486      * <p>
487      * This requirement applies to both manifest registered and runtime
488      * registered receivers.
489      *
490      * @param changeId the {@link ChangeId} to inspect
491      * @param enabled the required enabled state of the inspected
492      *            {@link ChangeId} for this broadcast to be delivered
493      * @see CompatChanges#isChangeEnabled
494      * @see #clearRequireCompatChange()
495      */
setRequireCompatChange(long changeId, boolean enabled)496     public void setRequireCompatChange(long changeId, boolean enabled) {
497         mRequireCompatChangeId = changeId;
498         mRequireCompatChangeEnabled = enabled;
499     }
500 
501     /**
502      * Clear any previously defined requirement for this broadcast requested via
503      * {@link #setRequireCompatChange(long, boolean)}.
504      */
clearRequireCompatChange()505     public void clearRequireCompatChange() {
506         mRequireCompatChangeId = CHANGE_INVALID;
507         mRequireCompatChangeEnabled = true;
508     }
509 
510     /**
511      * When set, this broadcast will be understood as having originated from an
512      * alarm going off.  Only the OS itself can use this option; uses by other
513      * senders will be ignored.
514      * @hide
515      *
516      * @param senderIsAlarm Whether the broadcast is alarm-triggered.
517      */
setAlarmBroadcast(boolean senderIsAlarm)518     public void setAlarmBroadcast(boolean senderIsAlarm) {
519         mIsAlarmBroadcast = senderIsAlarm;
520     }
521 
522     /**
523      * Did this broadcast originate from an alarm triggering?
524      * @return true if this broadcast is an alarm message, false otherwise
525      * @hide
526      */
isAlarmBroadcast()527     public boolean isAlarmBroadcast() {
528         return mIsAlarmBroadcast;
529     }
530 
531     /**
532      * Did this broadcast originate from a push message from the server?
533      *
534      * @return true if this broadcast is a push message, false otherwise.
535      * @hide
536      */
isPushMessagingBroadcast()537     public boolean isPushMessagingBroadcast() {
538         return mTemporaryAppAllowlistReasonCode == PowerExemptionManager.REASON_PUSH_MESSAGING;
539     }
540 
541     /**
542      * Did this broadcast originate from a push message from the server which was over the allowed
543      * quota?
544      *
545      * @return true if this broadcast is a push message over quota, false otherwise.
546      * @hide
547      */
isPushMessagingOverQuotaBroadcast()548     public boolean isPushMessagingOverQuotaBroadcast() {
549         return mTemporaryAppAllowlistReasonCode
550                 == PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA;
551     }
552 
553     /** {@hide} */
getRequireCompatChangeId()554     public long getRequireCompatChangeId() {
555         return mRequireCompatChangeId;
556     }
557 
558     /**
559      * Test if the given app meets the {@link ChangeId} state required by this
560      * broadcast, if any.
561      *
562      * @hide
563      */
564     @TestApi
testRequireCompatChange(int uid)565     public boolean testRequireCompatChange(int uid) {
566         if (mRequireCompatChangeId != CHANGE_INVALID) {
567             return CompatChanges.isChangeEnabled(mRequireCompatChangeId,
568                     uid) == mRequireCompatChangeEnabled;
569         } else {
570             return true;
571         }
572     }
573 
574     /**
575      * Sets whether events (such as posting a notification) originating from an app after it
576      * receives the broadcast while in background should be recorded as responses to the broadcast.
577      *
578      * <p> Note that this will only be considered when sending explicit broadcast intents.
579      *
580      * @param id ID to be used for the response events corresponding to this broadcast. If the
581      *           value is {@code 0} (default), then response events will not be recorded. Otherwise,
582      *           they will be recorded with the ID provided.
583      *
584      * @hide
585      */
586     @SystemApi
587     @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS)
recordResponseEventWhileInBackground(@ntRangefrom = 0) long id)588     public void recordResponseEventWhileInBackground(@IntRange(from = 0) long id) {
589         mIdForResponseEvent = id;
590     }
591 
592     /** @hide */
593     @IntRange(from = 0)
getIdForResponseEvent()594     public long getIdForResponseEvent() {
595         return mIdForResponseEvent;
596     }
597 
598     /**
599      * Returns the created options as a Bundle, which can be passed to
600      * {@link android.content.Context#sendBroadcast(android.content.Intent)
601      * Context.sendBroadcast(Intent)} and related methods.
602      * Note that the returned Bundle is still owned by the BroadcastOptions
603      * object; you must not modify it, but can supply it to the sendBroadcast
604      * methods that take an options Bundle.
605      */
606     @Override
toBundle()607     public Bundle toBundle() {
608         Bundle b = super.toBundle();
609         if (isTemporaryAppAllowlistSet()) {
610             b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration);
611             b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType);
612             b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode);
613             b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason);
614         }
615         if (mIsAlarmBroadcast) {
616             b.putBoolean(KEY_ALARM_BROADCAST, true);
617         }
618         if (mMinManifestReceiverApiLevel != 0) {
619             b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel);
620         }
621         if (mMaxManifestReceiverApiLevel != Build.VERSION_CODES.CUR_DEVELOPMENT) {
622             b.putInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, mMaxManifestReceiverApiLevel);
623         }
624         if (mDontSendToRestrictedApps) {
625             b.putBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, true);
626         }
627         if (mAllowBackgroundActivityStarts) {
628             b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true);
629         }
630         if (mRequireAllOfPermissions != null) {
631             b.putStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS, mRequireAllOfPermissions);
632         }
633         if (mRequireNoneOfPermissions != null) {
634             b.putStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS, mRequireNoneOfPermissions);
635         }
636         if (mRequireCompatChangeId != CHANGE_INVALID) {
637             b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId);
638             b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled);
639         }
640         if (mIdForResponseEvent != 0) {
641             b.putLong(KEY_ID_FOR_RESPONSE_EVENT, mIdForResponseEvent);
642         }
643         return b.isEmpty() ? null : b;
644     }
645 }
646