Merge "Add BroadcastOptions.setDeferUntilActive() API."
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8a1d6f2..1d39931 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -760,10 +760,12 @@
 
   public class BroadcastOptions {
     method public void clearRequireCompatChange();
+    method public boolean isDeferUntilActive();
     method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
     method public static android.app.BroadcastOptions makeBasic();
     method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
     method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
+    method @NonNull public android.app.BroadcastOptions setDeferUntilActive(boolean);
     method public void setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
     method public void setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
     method public void setDeliveryGroupPolicy(int);
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 8b7b7eb..16c5b08 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -66,6 +66,7 @@
     private @DeliveryGroupPolicy int mDeliveryGroupPolicy;
     private @Nullable String mDeliveryGroupMatchingKey;
     private @Nullable IntentFilter mDeliveryGroupMatchingFilter;
+    private boolean mIsDeferUntilActive = false;
 
     /**
      * Change ID which is invalid.
@@ -688,6 +689,41 @@
     }
 
     /**
+     * Sets whether the broadcast should not run until the process is in an active process state
+     * (ie, a process exists for the app and the app is not in a cached process state).
+     *
+     * Whether an app's process state is considered active is independent of its standby bucket.
+     *
+     * A broadcast that is deferred until the process is active will not execute until the process
+     * is brought to an active state by some other action, like a job, alarm, or service binding. As
+     * a result, the broadcast may be delayed indefinitely. This deferral only applies to runtime
+     * registered receivers of a broadcast. Any manifest receivers will run immediately, similar to
+     * how a manifest receiver would start a new process in order to run a broadcast receiver.
+     *
+     * Ordered broadcasts, alarm broadcasts, interactive broadcasts, and manifest broadcasts are
+     * never deferred.
+     *
+     * Unordered broadcasts and unordered broadcasts with completion callbacks may be
+     * deferred. Completion callbacks for broadcasts deferred until active are
+     * best-effort. Completion callbacks will run when all eligible processes have finished
+     * executing the broadcast. Processes in inactive process states that defer the broadcast are
+     * not considered eligible and may not execute the broadcast prior to the completion callback.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) {
+        mIsDeferUntilActive = shouldDefer;
+        return this;
+    }
+
+    /** @hide */
+    @SystemApi
+    public boolean isDeferUntilActive() {
+        return mIsDeferUntilActive;
+    }
+
+    /**
      * Returns the created options as a Bundle, which can be passed to
      * {@link android.content.Context#sendBroadcast(android.content.Intent)
      * Context.sendBroadcast(Intent)} and related methods.