Fix issue #21814207 and issue #21814212 (alarm manager)

Issue #21814207: AlarmManager.setAndAllowWhileIdle should also allow wake locks.

Introduce a whole new infrastructure for providing options when
sending broadcasts, much like ActivityOptions.  There is a single
option right now, asking the activity manager to apply a tempory
whitelist to each receiver of the broadcast.

Issue #21814212: Need to allow configuration of alarm manager parameters

The various alarm manager timing configurations are not modifiable
through settings, much like DeviceIdleController.  Also did a few
tweaks in the existing DeviceIdleController impl.

Change-Id: Ifd01013185acc4de668617b1e46e78e30ebed041
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6ae21eb..680feae 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -108,7 +108,7 @@
         try {
             getDefault().broadcastIntent(
                 null, intent, null, null, Activity.RESULT_OK, null, null,
-                null /*permission*/, appOp, false, true, userId);
+                null /*permission*/, appOp, null, false, true, userId);
         } catch (RemoteException ex) {
         }
     }
@@ -458,12 +458,13 @@
             Bundle resultExtras = data.readBundle();
             String perm = data.readString();
             int appOp = data.readInt();
+            Bundle options = data.readBundle();
             boolean serialized = data.readInt() != 0;
             boolean sticky = data.readInt() != 0;
             int userId = data.readInt();
             int res = broadcastIntent(app, intent, resolvedType, resultTo,
                     resultCode, resultData, resultExtras, perm, appOp,
-                    serialized, sticky, userId);
+                    options, serialized, sticky, userId);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -2991,9 +2992,9 @@
         reply.recycle();
     }
     public int broadcastIntent(IApplicationThread caller,
-            Intent intent, String resolvedType,  IIntentReceiver resultTo,
+            Intent intent, String resolvedType, IIntentReceiver resultTo,
             int resultCode, String resultData, Bundle map,
-            String requiredPermission, int appOp, boolean serialized,
+            String requiredPermission, int appOp, Bundle options, boolean serialized,
             boolean sticky, int userId) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -3008,6 +3009,7 @@
         data.writeBundle(map);
         data.writeString(requiredPermission);
         data.writeInt(appOp);
+        data.writeBundle(options);
         data.writeInt(serialized ? 1 : 0);
         data.writeInt(sticky ? 1 : 0);
         data.writeInt(userId);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 6fb997e..2406985 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -43,7 +43,7 @@
      * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
      * the total time (in ms) the user spent in the app flow.
      */
-    public static final String EXTRA_USAGE_TIME_REPORT = "android.usage_time";
+    public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
 
     /**
      * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
@@ -56,67 +56,67 @@
      * The package name that created the options.
      * @hide
      */
-    public static final String KEY_PACKAGE_NAME = "android:packageName";
+    public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
 
     /**
      * Type of animation that arguments specify.
      * @hide
      */
-    public static final String KEY_ANIM_TYPE = "android:animType";
+    public static final String KEY_ANIM_TYPE = "android:activity.animType";
 
     /**
      * Custom enter animation resource ID.
      * @hide
      */
-    public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes";
+    public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
 
     /**
      * Custom exit animation resource ID.
      * @hide
      */
-    public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
+    public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
 
     /**
      * Custom in-place animation resource ID.
      * @hide
      */
-    public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes";
+    public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
 
     /**
      * Bitmap for thumbnail animation.
      * @hide
      */
-    public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail";
+    public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
 
     /**
      * Start X position of thumbnail animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_X = "android:animStartX";
+    public static final String KEY_ANIM_START_X = "android:activity.animStartX";
 
     /**
      * Start Y position of thumbnail animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_Y = "android:animStartY";
+    public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
 
     /**
      * Initial width of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_WIDTH = "android:animWidth";
+    public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
 
     /**
      * Initial height of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_HEIGHT = "android:animHeight";
+    public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
 
     /**
      * Callback for when animation is started.
      * @hide
      */
-    public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
+    public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
 
     /**
      * For Activity transitions, the calling Activity's TransitionListener used to
@@ -124,15 +124,18 @@
      * complete.
      */
     private static final String KEY_TRANSITION_COMPLETE_LISTENER
-            = "android:transitionCompleteListener";
+            = "android:activity.transitionCompleteListener";
 
-    private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning";
-    private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames";
-    private static final String KEY_RESULT_DATA = "android:resultData";
-    private static final String KEY_RESULT_CODE = "android:resultCode";
-    private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex";
+    private static final String KEY_TRANSITION_IS_RETURNING
+            = "android:activity.transitionIsReturning";
+    private static final String KEY_TRANSITION_SHARED_ELEMENTS
+            = "android:activity.sharedElementNames";
+    private static final String KEY_RESULT_DATA = "android:activity.resultData";
+    private static final String KEY_RESULT_CODE = "android:activity.resultCode";
+    private static final String KEY_EXIT_COORDINATOR_INDEX
+            = "android:activity.exitCoordinatorIndex";
 
-    private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport";
+    private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
 
     /** @hide */
     public static final int ANIM_NONE = 0;
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
new file mode 100644
index 0000000..1f378da
--- /dev/null
+++ b/core/java/android/app/BroadcastOptions.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.SystemApi;
+import android.os.Bundle;
+
+/**
+ * Helper class for building an options Bundle that can be used with
+ * {@link android.content.Context#sendBroadcast(android.content.Intent)
+ * Context.sendBroadcast(Intent)} and related methods.
+ * {@hide}
+ */
+@SystemApi
+public class BroadcastOptions {
+    private long mTemporaryAppWhitelistDuration;
+
+    /**
+     * How long to temporarily put an app on the power whitelist when executing this broadcast
+     * to it.
+     * @hide
+     */
+    public static final String KEY_TEMPORARY_APP_WHITELIST_DURATION
+            = "android:broadcast.temporaryAppWhitelistDuration";
+
+    public static BroadcastOptions makeBasic() {
+        BroadcastOptions opts = new BroadcastOptions();
+        return opts;
+    }
+
+    private BroadcastOptions() {
+    }
+
+    /** @hide */
+    public BroadcastOptions(Bundle opts) {
+        mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION);
+    }
+
+    /**
+     * Set a duration for which the system should temporary place an application on the
+     * power whitelist when this broadcast is being delivered to it.
+     * @param duration The duration in milliseconds; 0 means to not place on whitelist.
+     */
+    public void setTemporaryAppWhitelistDuration(long duration) {
+        mTemporaryAppWhitelistDuration = duration;
+    }
+
+    /**
+     * Return {@link #setTemporaryAppWhitelistDuration}.
+     * @hide
+     */
+    public long getTemporaryAppWhitelistDuration() {
+        return mTemporaryAppWhitelistDuration;
+    }
+
+    /**
+     * 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.
+     * Note that the returned Bundle is still owned by the ActivityOptions
+     * object; you must not modify it, but can supply it to the sendBroadcast
+     * methods that take an options Bundle.
+     */
+    public Bundle toBundle() {
+        Bundle b = new Bundle();
+        if (mTemporaryAppWhitelistDuration > 0) {
+            b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration);
+        }
+        return b.isEmpty() ? null : b;
+    }
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index be36af7..0420fb6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -46,7 +46,6 @@
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -676,8 +675,8 @@
                     + " Is this really what you want?");
         }
         mMainThread.getInstrumentation().execStartActivity(
-            getOuterContext(), mMainThread.getApplicationThread(), null,
-            (Activity)null, intent, -1, options);
+                getOuterContext(), mMainThread.getApplicationThread(), null,
+                (Activity) null, intent, -1, options);
     }
 
     /** @hide */
@@ -710,8 +709,8 @@
                     + " Is this really what you want?");
         }
         mMainThread.getInstrumentation().execStartActivitiesAsUser(
-            getOuterContext(), mMainThread.getApplicationThread(), null,
-            (Activity)null, intents, options, userHandle.getIdentifier());
+                getOuterContext(), mMainThread.getApplicationThread(), null,
+                (Activity) null, intents, options, userHandle.getIdentifier());
     }
 
     @Override
@@ -724,8 +723,8 @@
                     + " Is this really what you want?");
         }
         mMainThread.getInstrumentation().execStartActivities(
-            getOuterContext(), mMainThread.getApplicationThread(), null,
-            (Activity)null, intents, options);
+                getOuterContext(), mMainThread.getApplicationThread(), null,
+                (Activity) null, intents, options);
     }
 
     @Override
@@ -766,9 +765,9 @@
         try {
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
-                mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
-                getUserId());
+                    mMainThread.getApplicationThread(), intent, resolvedType, null,
+                    Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
+                    getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -781,9 +780,24 @@
         try {
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
-                mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
-                false, false, getUserId());
+                    mMainThread.getApplicationThread(), intent, resolvedType, null,
+                    Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+                    null, false, false, getUserId());
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failure from system", e);
+        }
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+        warnIfCallingFromSystemProcess();
+        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+        try {
+            intent.prepareToLeaveProcess();
+            ActivityManagerNative.getDefault().broadcastIntent(
+                    mMainThread.getApplicationThread(), intent, resolvedType, null,
+                    Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+                    options, false, false, getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -796,25 +810,24 @@
         try {
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
-                mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
-                getUserId());
+                    mMainThread.getApplicationThread(), intent, resolvedType, null,
+                    Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
+                    getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
     }
 
     @Override
-    public void sendOrderedBroadcast(Intent intent,
-            String receiverPermission) {
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
         warnIfCallingFromSystemProcess();
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
-                mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false,
-                getUserId());
+                    mMainThread.getApplicationThread(), intent, resolvedType, null,
+                    Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
+                    null, true, false, getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -826,7 +839,16 @@
             Handler scheduler, int initialCode, String initialData,
             Bundle initialExtras) {
         sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
-                resultReceiver, scheduler, initialCode, initialData, initialExtras);
+                resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent,
+            String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
+                resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
     }
 
     @Override
@@ -834,6 +856,14 @@
             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
             Handler scheduler, int initialCode, String initialData,
             Bundle initialExtras) {
+        sendOrderedBroadcast(intent, receiverPermission, appOp,
+                resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
+    }
+
+    void sendOrderedBroadcast(Intent intent,
+            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras, Bundle options) {
         warnIfCallingFromSystemProcess();
         IIntentReceiver rd = null;
         if (resultReceiver != null) {
@@ -858,7 +888,7 @@
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermission, appOp,
-                    true, false, getUserId());
+                    options, true, false, getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -871,7 +901,7 @@
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
                     intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
-                    AppOpsManager.OP_NONE, false, false, user.getIdentifier());
+                    AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -891,7 +921,7 @@
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
-                    Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
+                    Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false,
                     user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -934,7 +964,7 @@
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermission,
-                    appOp, true, false, user.getIdentifier());
+                    appOp, null, true, false, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -949,7 +979,7 @@
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true,
+                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
                 getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
@@ -986,7 +1016,7 @@
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
-                    AppOpsManager.OP_NONE, true, true, getUserId());
+                    AppOpsManager.OP_NONE, null, true, true, getUserId());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -1017,7 +1047,7 @@
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier());
+                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -1052,7 +1082,7 @@
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
-                    AppOpsManager.OP_NONE, true, true, user.getIdentifier());
+                    AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9311e5e..e7f7e13 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -107,7 +107,7 @@
     public int broadcastIntent(IApplicationThread caller, Intent intent,
             String resolvedType, IIntentReceiver resultTo, int resultCode,
             String resultData, Bundle map, String requiredPermission,
-            int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException;
+            int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
     public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
     public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
             boolean abortBroadcast, int flags) throws RemoteException;
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 031854a..c42ba65 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -613,7 +613,7 @@
      * is no longer allowing more intents to be sent through it.
      */
     public void send() throws CanceledException {
-        send(null, 0, null, null, null, null);
+        send(null, 0, null, null, null, null, null);
     }
 
     /**
@@ -627,7 +627,7 @@
      * is no longer allowing more intents to be sent through it.
      */
     public void send(int code) throws CanceledException {
-        send(null, code, null, null, null, null);
+        send(null, code, null, null, null, null, null);
     }
 
     /**
@@ -646,9 +646,9 @@
      * @throws CanceledException Throws CanceledException if the PendingIntent
      * is no longer allowing more intents to be sent through it.
      */
-    public void send(Context context, int code, Intent intent)
+    public void send(Context context, int code, @Nullable Intent intent)
             throws CanceledException {
-        send(context, code, intent, null, null, null);
+        send(context, code, intent, null, null, null, null);
     }
 
     /**
@@ -667,9 +667,9 @@
      * @throws CanceledException Throws CanceledException if the PendingIntent
      * is no longer allowing more intents to be sent through it.
      */
-    public void send(int code, OnFinished onFinished, Handler handler)
+    public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)
             throws CanceledException {
-        send(null, code, null, onFinished, handler, null);
+        send(null, code, null, onFinished, handler, null, null);
     }
 
     /**
@@ -705,9 +705,9 @@
      * @throws CanceledException Throws CanceledException if the PendingIntent
      * is no longer allowing more intents to be sent through it.
      */
-    public void send(Context context, int code, Intent intent,
-            OnFinished onFinished, Handler handler) throws CanceledException {
-        send(context, code, intent, onFinished, handler, null);
+    public void send(Context context, int code, @Nullable Intent intent,
+            @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException {
+        send(context, code, intent, onFinished, handler, null, null);
     }
 
     /**
@@ -748,8 +748,56 @@
      * @throws CanceledException Throws CanceledException if the PendingIntent
      * is no longer allowing more intents to be sent through it.
      */
-    public void send(Context context, int code, Intent intent,
-            OnFinished onFinished, Handler handler, String requiredPermission)
+    public void send(Context context, int code, @Nullable Intent intent,
+            @Nullable OnFinished onFinished, @Nullable Handler handler,
+            @Nullable String requiredPermission)
+            throws CanceledException {
+        send(context, code, intent, onFinished, handler, requiredPermission, null);
+    }
+
+    /**
+     * Perform the operation associated with this PendingIntent, allowing the
+     * caller to specify information about the Intent to use and be notified
+     * when the send has completed.
+     *
+     * <p>For the intent parameter, a PendingIntent
+     * often has restrictions on which fields can be supplied here, based on
+     * how the PendingIntent was retrieved in {@link #getActivity},
+     * {@link #getBroadcast}, or {@link #getService}.
+     *
+     * @param context The Context of the caller.  This may be null if
+     * <var>intent</var> is also null.
+     * @param code Result code to supply back to the PendingIntent's target.
+     * @param intent Additional Intent data.  See {@link Intent#fillIn
+     * Intent.fillIn()} for information on how this is applied to the
+     * original Intent.  Use null to not modify the original Intent.
+     * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was
+     * created, this argument will be ignored.
+     * @param onFinished The object to call back on when the send has
+     * completed, or null for no callback.
+     * @param handler Handler identifying the thread on which the callback
+     * should happen.  If null, the callback will happen from the thread
+     * pool of the process.
+     * @param requiredPermission Name of permission that a recipient of the PendingIntent
+     * is required to hold.  This is only valid for broadcast intents, and
+     * corresponds to the permission argument in
+     * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
+     * If null, no permission is required.
+     * @param options Additional options the caller would like to provide to modify the sending
+     * behavior.  May be built from an {@link ActivityOptions} to apply to an activity start.
+     *
+     * @see #send()
+     * @see #send(int)
+     * @see #send(Context, int, Intent)
+     * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
+     * @see #send(Context, int, Intent, OnFinished, Handler)
+     *
+     * @throws CanceledException Throws CanceledException if the PendingIntent
+     * is no longer allowing more intents to be sent through it.
+     */
+    public void send(Context context, int code, @Nullable Intent intent,
+            @Nullable OnFinished onFinished, @Nullable Handler handler,
+            @Nullable String requiredPermission, @Nullable Bundle options)
             throws CanceledException {
         try {
             String resolvedType = intent != null ?
@@ -759,7 +807,7 @@
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
                             : null,
-                    requiredPermission);
+                    requiredPermission, options);
             if (res < 0) {
                 throw new CanceledException();
             }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 83ce087..675515b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1517,6 +1517,38 @@
             @Nullable String receiverPermission);
 
     /**
+     * Broadcast the given intent to all interested BroadcastReceivers, allowing
+     * an optional required permission to be enforced.  This
+     * call is asynchronous; it returns immediately, and you will continue
+     * executing while the receivers are run.  No results are propagated from
+     * receivers and receivers can not abort the broadcast. If you want
+     * to allow receivers to propagate results or abort the broadcast, you must
+     * send an ordered broadcast using
+     * {@link #sendOrderedBroadcast(Intent, String)}.
+     *
+     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+     *
+     * @param intent The Intent to broadcast; all receivers matching this
+     *               Intent will receive the broadcast.
+     * @param receiverPermission (optional) String naming a permission that
+     *               a receiver must hold in order to receive your broadcast.
+     *               If null, no permission is required.
+     * @param options (optional) Additional sending options, generated from a
+     * {@link android.app.BroadcastOptions}.
+     *
+     * @see android.content.BroadcastReceiver
+     * @see #registerReceiver
+     * @see #sendBroadcast(Intent)
+     * @see #sendOrderedBroadcast(Intent, String)
+     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
+     * @hide
+     */
+    @SystemApi
+    public abstract void sendBroadcast(Intent intent,
+            @Nullable String receiverPermission,
+            @Nullable Bundle options);
+
+    /**
      * Like {@link #sendBroadcast(Intent, String)}, but also allows specification
      * of an associated app op as per {@link android.app.AppOpsManager}.
      * @hide
@@ -1588,11 +1620,60 @@
      * @see android.app.Activity#RESULT_OK
      */
     public abstract void sendOrderedBroadcast(@NonNull Intent intent,
-            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+            @Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver,
             @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
             @Nullable Bundle initialExtras);
 
     /**
+     * Version of {@link #sendBroadcast(Intent)} that allows you to
+     * receive data back from the broadcast.  This is accomplished by
+     * supplying your own BroadcastReceiver when calling, which will be
+     * treated as a final receiver at the end of the broadcast -- its
+     * {@link BroadcastReceiver#onReceive} method will be called with
+     * the result values collected from the other receivers.  The broadcast will
+     * be serialized in the same way as calling
+     * {@link #sendOrderedBroadcast(Intent, String)}.
+     *
+     * <p>Like {@link #sendBroadcast(Intent)}, this method is
+     * asynchronous; it will return before
+     * resultReceiver.onReceive() is called.
+     *
+     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+     *
+     *
+     * @param intent The Intent to broadcast; all receivers matching this
+     *               Intent will receive the broadcast.
+     * @param receiverPermission String naming a permissions that
+     *               a receiver must hold in order to receive your broadcast.
+     *               If null, no permission is required.
+     * @param options (optional) Additional sending options, generated from a
+     * {@link android.app.BroadcastOptions}.
+     * @param resultReceiver Your own BroadcastReceiver to treat as the final
+     *                       receiver of the broadcast.
+     * @param scheduler A custom Handler with which to schedule the
+     *                  resultReceiver callback; if null it will be
+     *                  scheduled in the Context's main thread.
+     * @param initialCode An initial value for the result code.  Often
+     *                    Activity.RESULT_OK.
+     * @param initialData An initial value for the result data.  Often
+     *                    null.
+     * @param initialExtras An initial value for the result extras.  Often
+     *                      null.
+     * @see #sendBroadcast(Intent)
+     * @see #sendBroadcast(Intent, String)
+     * @see #sendOrderedBroadcast(Intent, String)
+     * @see android.content.BroadcastReceiver
+     * @see #registerReceiver
+     * @see android.app.Activity#RESULT_OK
+     * @hide
+     */
+    @SystemApi
+    public abstract void sendOrderedBroadcast(@NonNull Intent intent,
+            @Nullable String receiverPermission, @Nullable Bundle options,
+            @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
+            int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras);
+
+    /**
      * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler,
      * int, String, android.os.Bundle)}, but also allows specification
      * of an associated app op as per {@link android.app.AppOpsManager}.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index fb9e194..4e7c832 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.SystemApi;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -401,6 +402,13 @@
     }
 
     /** @hide */
+    @SystemApi
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+        mBase.sendBroadcast(intent, receiverPermission, options);
+    }
+
+    /** @hide */
     @Override
     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
         mBase.sendBroadcast(intent, receiverPermission, appOp);
@@ -423,6 +431,18 @@
     }
 
     /** @hide */
+    @SystemApi
+    @Override
+    public void sendOrderedBroadcast(
+            Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        mBase.sendOrderedBroadcast(intent, receiverPermission,
+                options, resultReceiver, scheduler, initialCode,
+                initialData, initialExtras);
+    }
+
+    /** @hide */
     @Override
     public void sendOrderedBroadcast(
         Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl
index 7dbd6f2..f3affa7 100644
--- a/core/java/android/content/IIntentSender.aidl
+++ b/core/java/android/content/IIntentSender.aidl
@@ -18,9 +18,10 @@
 
 import android.content.IIntentReceiver;
 import android.content.Intent;
+import android.os.Bundle;
 
 /** @hide */
 interface IIntentSender {
     int send(int code, in Intent intent, String resolvedType,
-            IIntentReceiver finishedReceiver, String requiredPermission);
+            IIntentReceiver finishedReceiver, String requiredPermission, in Bundle options);
 }
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 166495b..13a767e 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -195,7 +195,7 @@
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
                             : null,
-                    requiredPermission);
+                    requiredPermission, null);
             if (res < 0) {
                 throw new SendIntentException();
             }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3e9c9de..56cd1a7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7133,6 +7133,29 @@
         public static final String APP_IDLE_CONSTANTS = "app_idle_constants";
 
         /**
+         * Alarm manager specific settings.
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * "min_futurity=5000,allow_while_idle_short_time=4500"
+         *
+         * The following keys are supported:
+         *
+         * <pre>
+         * min_futurity                         (long)
+         * min_interval                         (long)
+         * allow_while_idle_short_time          (long)
+         * allow_while_idle_long_time           (long)
+         * allow_while_idle_whitelist_duration  (long)
+         * </pre>
+         *
+         * <p>
+         * Type: string
+         * @hide
+         * @see com.android.server.AlarmManagerService.Constants
+         */
+        public static final String ALARM_MANAGER_CONSTANTS = "alarm_manager_constants";
+
+        /**
          * Get the key that retrieves a bluetooth headset's priority.
          * @hide
          */