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