Merge "power: throttle interaction hints" into oc-dev
diff --git a/Android.mk b/Android.mk
index 3f2ae83..3f059ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -950,7 +950,7 @@
     -since $(SRC_API_DIR)/23.txt 23 \
     -since $(SRC_API_DIR)/24.txt 24 \
     -since $(SRC_API_DIR)/25.txt 25 \
-    -since ./frameworks/base/api/current.txt O \
+    -since $(SRC_API_DIR)/26.txt 26 \
     -werror -hide 111 -hide 113 -hide 121 \
     -overview $(LOCAL_PATH)/core/java/overview.html \
 
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index e4a22c4..95ec24c 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -43,6 +43,13 @@
  * long as necessary (and will not block the application's main loop), but
  * only one request will be processed at a time.
  *
+ * <p class="note"><b>Note:</b> IntentService is subject to all the
+ * <a href="/preview/features/background.html">background execution limits</a>
+ * imposed with Android 8.0 (API level 26). In most cases, you are better off
+ * using {@link android.support.v4.app.JobIntentService}, which uses jobs
+ * instead of services when running on Android 8.0 or higher.
+ * </p>
+ *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For a detailed discussion about how to create services, read the
@@ -50,6 +57,7 @@
  * guide.</p>
  * </div>
  *
+ * @see android.support.v4.app.JobIntentService
  * @see android.os.AsyncTask
  */
 public abstract class IntentService extends Service {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 1eac395..e3bc78e 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -205,7 +205,8 @@
         }
         synchronized (mLeScanClients) {
             if (callback != null && mLeScanClients.containsKey(callback)) {
-                postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+                return postCallbackErrorOrReturn(callback,
+                            ScanCallback.SCAN_FAILED_ALREADY_STARTED);
             }
             IBluetoothGatt gatt;
             try {
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index c0b82b4..61b0eb0 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -36,161 +36,72 @@
 import java.util.List;
 
 /**
- * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users
- * with quick access to activities other than an app's main activity in the currently-active
- * launcher.  For example,
- * an email app may publish the "compose new email" action, which will directly open the
- * compose activity.  The {@link ShortcutInfo} class contains information about each of the
- * shortcuts themselves.
+ * The ShortcutManager manages an app's <em>shortcuts</em>. Shortcuts provide users with quick
+ * access to activities other than an app's main activity in the currently-active launcher, provided
+ * that the launcher supports app shortcuts.  For example, an email app may publish the "compose new
+ * email" action, which will directly open the compose activity.  The {@link ShortcutInfo} class
+ * contains information about each of the shortcuts themselves.
  *
- * <h3>Static Shortcuts and Dynamic Shortcuts</h3>
+ * <p>This page discusses the implementation details of the <code>ShortcutManager</code> class. For
+ * guidance on performing operations on app shortcuts within your app, see the
+ * <a href="/guide/topics/ui/shortcuts.html">App Shortcuts</a> feature guide.
  *
- * <p>
- * There are several different types of shortcuts:
+ * <h3>Shortcut characteristics</h3>
  *
- * <ul>
- * <li><p>Static shortcuts are declared in a resource XML file, which is referenced in the publisher
- * app's <code>AndroidManifest.xml</code> file. These shortcuts are visually associated with an
- * app's launcher icon.
- * <p>Static shortcuts are published when an app is installed, and the details of these shortcuts
- * change when an app is upgraded with an updated XML file. Static shortcuts are immutable, and
- * their definitions, such as icons and labels, cannot be changed dynamically without upgrading the
- * publisher app.</li>
+ * This section describes in-depth details about each shortcut type's usage and availability.
  *
- * <li>Dynamic shortcuts are published at runtime using this class's APIs. These shortcuts are
- * visually associated with an app's launcher icon. Apps can publish, update, and remove dynamic
- * shortcuts at runtime.
- * </ul>
+ * <p class="note"><b>Important security note:</b> All shortcut information is stored in
+ * <a href="/training/articles/direct-boot.html">credential encrypted storage</a>, so your app
+ * cannot access a user's shortcuts until after they've unlocked the device.
  *
- * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
- * {@code LAUNCHER} category&mdash;can have shortcuts.
- * If an app has multiple main activities, these activities have different sets
- * of shortcuts.
+ * <h4>Static and dynamic shortcuts</h4>
  *
  * <p>Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user
- * long-presses on an app's launcher icon. Note that the actual gesture may be different
- * depending on the launcher app.
+ * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the
+ * app's launcher icon, but the actual gesture may be different on other launcher apps.
  *
- * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
- * static and dynamic shortcuts combined.
+ * <p>The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
  *
+ * <h4>Pinned shortcuts</h4>
  *
- * <h3>Pinning Shortcuts</h3>
+ * <p>Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned
+ * shortcut is removed from the launcher only in the following situations:
+ * <ul>
+ *     <li>The user removes it.
+ *     <li>The publisher app associated with the shortcut is uninstalled.
+ *     <li>The user performs the clear data action on the publisher app from the device's
+ *     <b>Settings</b> app.
+ * </ul>
  *
- * <p>Apps running in the foreground can also <em>pin</em> shortcuts at runtime, subject to user
- * permission, using this class's APIs. Each pinned shortcut is a copy of a static shortcut or a
- * dynamic shortcut. Although users can pin a shortcut multiple times, the system calls the pinning
- * API only once to complete the pinning process. Unlike static and dynamic shortcuts, pinned
- * shortcuts appear as separate icons, visually distinct from the app's launcher icon, in the
- * launcher. There is no limit to the number of pinned shortcuts that an app can create.
+ * <p>Because the system performs
+ * <a href="/guide/topics/ui/shortcuts.html#backup-and-restore">backup and restore</a> on pinned
+ * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or
+ * server-side identifiers, rather than identifiers generated locally that might not make sense on
+ * other devices.
  *
- * <p>Pinned shortcuts <strong>cannot</strong> be removed by publisher apps. They're removed only
- * when the user removes them, when the publisher app is uninstalled, or when the user performs the
- * clear data action on the publisher app from the device's <b>Settings</b> app.
+ * <h3>Shortcut display order</h3>
  *
- * <p>However, the publisher app can <em>disable</em> pinned shortcuts so they cannot be started.
- * See the following sections for details.
+ * <p>When the launcher displays an app's shortcuts, they should appear in the following order:
  *
- * <h3>Updating and Disabling Shortcuts</h3>
+ * <ul>
+ *   <li>Static shortcuts (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
+ *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
+ *   <li>Within each shortcut type (static and dynamic), sort the shortcuts in order of increasing
+ *   rank according to {@link ShortcutInfo#getRank()}.
+ * </ul>
  *
- * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
- * the pinned shortcut will still be visible and launchable.  This allows an app to have
- * more than {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
+ * <p>Shortcut ranks are non-negative, sequential integers that determine the order in which
+ * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks
+ * of existing shortcuts when you call {@link #updateShortcuts(List)},
+ * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}.
  *
- * <p>For example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
- * <ol>
- *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
- *     conversations (c1, c2, ..., c5).
+ * <p class="note"><b>Note:</b> Ranks are auto-adjusted so that they're unique for each type of
+ * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and
+ * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut
+ * at the second position. In response, the third and fourth shortcuts move closer to the bottom of
+ * the shortcut list, with their ranks changing to 2 and 3, respectively.
  *
- *     <li>The user pins all 5 of the shortcuts.
- *
- *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
- *     so the publisher app
- *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
- *     c4, c5, ..., c8.
- *     The publisher app has to remove c1, c2, and c3 because it can't have more than
- *     5 dynamic shortcuts.
- *
- *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
- *     shortcuts for these conversations are still available and launchable.
- *
- *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
- *     the publisher app, including the 3 pinned
- *     shortcuts, even though an app can have at most 5 dynamic shortcuts.
- *
- *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
- *     8 shortcuts, when, for example, the chat peers' icons have changed.
- * </ol>
- * The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
- * can also be used
- * to update existing shortcuts with the same IDs, but they <b>cannot</b> be used
- * for updating non-dynamic, pinned shortcuts because these two methods try to convert the given
- * lists of shortcuts to dynamic shortcuts.
- *
- *
- * <h4>Disabling Static Shortcuts</h4>
- * <p>When an app is upgraded and the new version
- * no longer uses a static shortcut that appeared in the previous version, this deprecated
- * shortcut isn't published as a static shortcut.
- *
- * <p>If the deprecated shortcut is pinned, then the pinned shortcut will remain on the launcher,
- * but it's disabled automatically. When a pinned shortcut is disabled, this class's APIs cannot
- * update it.
- *
- * <h4>Disabling Dynamic Shortcuts</h4>
- * Sometimes pinned shortcuts become obsolete and may not be usable.  For example, a pinned shortcut
- * to a group chat becomes unusable when the associated group chat is deleted.  In cases like this,
- * apps should use {@link #disableShortcuts(List)}, which removes the specified dynamic
- * shortcuts and also makes any specified pinned shortcuts un-launchable.
- * The {@link #disableShortcuts(List, CharSequence)} method can also be used to disable shortcuts
- * and show users a custom error message when they attempt to launch the disabled shortcuts.
- *
- *
- * <h3>Publishing Static Shortcuts</h3>
- *
- * <p>
- * In order to add static shortcuts to your app, first add
- * {@code <meta-data android:name="android.app.shortcuts" />} to your main activity in
- * AndroidManifest.xml:
- * <pre>
- *&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- *             package="com.example.myapplication"&gt;
- *  &lt;application ... &gt;
- *    &lt;activity android:name="Main"&gt;
- *      &lt;intent-filter&gt;
- *        &lt;action android:name="android.intent.action.MAIN" /&gt;
- *        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
- *      &lt;/intent-filter&gt;
- *      <strong>&lt;meta-data android:name="android.app.shortcuts"
- *                 android:resource="@xml/shortcuts" /&gt;</strong>
- *    &lt;/activity&gt;
- *  &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * Then, define your app's static shortcuts in the <code>res/xml/shortcuts.xml</code>
- * file:
- * <pre>
- *&lt;shortcuts xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- *  &lt;shortcut
- *    android:shortcutId="compose"
- *    android:enabled="true"
- *    android:icon="@drawable/compose_icon"
- *    android:shortcutShortLabel="@string/compose_shortcut_short_label1"
- *    android:shortcutLongLabel="@string/compose_shortcut_long_label1"
- *    android:shortcutDisabledMessage="@string/compose_disabled_message1"&gt;
- *    &lt;intent
- *      android:action="android.intent.action.VIEW"
- *      android:targetPackage="com.example.myapplication"
- *      android:targetClass="com.example.myapplication.ComposeActivity" /&gt;
- *    &lt;!-- If your shortcut is associated with multiple intents, include them
- *         here. The last intent in the list is what the user sees when they
- *         launch this shortcut. --&gt;
- *    &lt;categories android:name="android.shortcut.conversation" /&gt;
- *  &lt;/shortcut&gt;
- *  &lt;!-- Specify more shortcuts here. --&gt;
- *&lt;/shortcuts&gt;
- * </pre>
+ * <h3>Options for static shortcuts</h3>
  *
  * The following list includes descriptions for the different attributes within a static shortcut:
  * <dl>
@@ -236,9 +147,10 @@
  *   {@code android:action} is mandatory.
  *   See <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a> for the
  *   other supported tags.
- *   You can provide multiple intents for a single shortcut so that the last defined activity is launched
- *   with the other activities in the <a href="/guide/components/tasks-and-back-stack.html">back stack</a>.
- *   See {@link android.app.TaskStackBuilder} for details.
+ *   <p>You can provide multiple intents for a single shortcut so that the last defined activity is
+ *   launched with the other activities in the
+ *   <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See
+ *   {@link android.app.TaskStackBuilder} for details.
  *   <p><b>Note:</b> String resources may not be used within an {@code <intent>} element.
  *   </dd>
  *   <dt>{@code categories}</dt>
@@ -247,337 +159,92 @@
  *   </dd>
  * </dl>
  *
- * <h3>Publishing Dynamic Shortcuts</h3>
+ * <h3>Updating shortcuts</h3>
  *
- * <p>
- * Apps can publish dynamic shortcuts with {@link #setDynamicShortcuts(List)}
- * or {@link #addDynamicShortcuts(List)}.  The {@link #updateShortcuts(List)} method can also be
- * used to update existing, mutable shortcuts.
- * Use {@link #removeDynamicShortcuts(List)} or {@link #removeAllDynamicShortcuts()} to remove
- * dynamic shortcuts.
- *
- * <p>The following code snippet shows how to create a single dynamic shortcut:
- * <pre>
- *ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
- *
- *ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
- *    .setShortLabel("Web site")
- *    .setLongLabel("Open the web site")
- *    .setIcon(Icon.createWithResource(context, R.drawable.icon_website))
- *    .setIntent(new Intent(Intent.ACTION_VIEW,
- *                   Uri.parse("https://www.mysite.example.com/")))
- *    .build();
- *
- *shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
- * </pre>
- *
- * <h3>Publishing Pinned Shortcuts</h3>
- *
- * <p>Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a
- * supported launcher programatically using {@link #requestPinShortcut(ShortcutInfo, IntentSender)}.
- * You pass two arguments into this method:
- *
- * <ul>
- *   <li>A {@link ShortcutInfo} object &ndash; If the shortcut already exists, this object should
- *   contain only the shortcut's ID. Otherwise, the new {@link ShortcutInfo} object must contain an
- *   ID, an intent, and a short label for the new shortcut.
- *   <li><p>A {@link android.app.PendingIntent} object &ndash; This intent represents the callback
- *   that your app receives if the shortcut is successfully pinned to the device's launcher.
- *   <p><b>Note:</b> If the user doesn't allow the shortcut to be pinned to the launcher, the
- *   pinning process fails, and the {@link Intent} object that is passed into this
- *   {@link android.app.PendingIntent} object isn't executed.
- *   <div class="note"><p><b>Note:</b> Due to background execution limits introduced in Android
- *   {@link VERSION_CODES#O}, it's best to use a
- *   <a href="{@docRoot}guide/components/broadcasts.html#manifest-declared_receivers">
- *   manifest-declared receiver</a> to receive a callback.
- *   <p>Also, to prevent other apps from invoking the receiver, add the attribute assignment
- *   <code>android:exported="false"</code> to the receiver's manifest entry.</p></div>
- * </ul>
- *
- * The following code snippet shows how to pin a single shortcut that already exists and is enabled:
- *
- * <pre>
- *ShortcutManager mShortcutManager =
- *        context.getSystemService(ShortcutManager.class);
- *
- *if (mShortcutManager.isRequestPinShortcutSupported()) {
- *
- *    // This example defines a new shortcut; that is, this shortcut hasn't
- *    // been published before.
- *    ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder()
- *            .setIcon(myIcon)
- *            .setShortLabel("My awesome shortcut")
- *            .setIntent(myIntent)
- *            .build();
- *
- *    PendingIntent resultPendingIntent = null;
- *
- *    // Create the following Intent and PendingIntent objects only if your app
- *    // needs to be notified that the user allowed the shortcut to be pinned.
- *    // Use a boolean value, such as "appNeedsNotifying", to define this behavior.
- *    if (appNeedsNotifying) {
- *        // We assume here the app has a manifest-declared receiver "MyReceiver".
- *        Intent pinnedShortcutCallbackIntent = new Intent(context, MyReceiver.class);
- *
- *        // Configure the intent so that your app's broadcast receiver gets
- *        // the callback successfully.
- *        PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,
- *                pinnedShortcutCallbackIntent);
- *
- *        resultPendingIntent = successCallback.getIntentSender();
- *    }
- *
- *    mShortcutManager.requestPinShortcut(pinShortcutInfo, resultPendingIntent);
- *}
- * </pre>
- *
- * <p class="note"><strong>Note:</strong> As you add logic in your app to make requests to pin
- * shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether
- * your app can complete this process on a particular device, check the return value of
- * {@link #isRequestPinShortcutSupported()}. Based on this return value, you might decide to hide
- * the option in your app that allows users to pin a shortcut.
- *
- * <p class="note"><strong>Note:</strong> See also the support library APIs
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#isRequestPinShortcutSupported(
- * Context)} and
- * {@link android.support.v4.content.pm.ShortcutManagerCompat#requestPinShortcut(
- * Context, ShortcutInfoCompat, IntentSender)}, which works on Android versions lower than
- * {@link VERSION_CODES#O} by falling back to the deprecated private intent
- * {@code com.android.launcher.action.INSTALL_SHORTCUT}.
- *
- * <h4>Custom Activity for Pinning Shortcuts</h4>
- *
- * <p>You can also create a specialized activity that helps users create shortcuts, complete with
- * custom options and a confirmation button. In your app's manifest file, add
- * {@link Intent#ACTION_CREATE_SHORTCUT} to the activity's <code>&lt;intent-filter&gt;</code>
- * element, as shown in the following snippet:
- *
- * <pre>
- *&lt;manifest&gt;
- *    ...
- *    &lt;application&gt;
- *        &lt;activity android:name="com.example.MyCustomPromptToPinShortcut" ... &gt;
- *            &lt;intent-filter
- *                    action android:name="android.intent.action.ACTION_CREATE_SHORTCUT"&gt;
- *            ...
- *            &lt;/intent-filter&gt;
- *        &lt;/activity&gt;
- *        ...
- *    &lt;/application&gt;
- *&lt;/manifest&gt;
- * </pre>
- *
- * <p>When you use this specialized activity in your app, the following sequence of steps takes
- * place:</p>
- *
+ * <p>As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
  * <ol>
- *   <li>The user attempts to create a shortcut, triggering the system to start the specialized
- *   activity.</li>
- *   <li>The user sets options for the shortcut.</li>
- *   <li>The user selects the confirmation button, allowing your app to create the shortcut using
- *   the {@link #createShortcutResultIntent(ShortcutInfo)} method. This method returns an
- *   {@link Intent}, which your app relays back to the previously-executing activity using
- *   {@link Activity#setResult(int)}.</li>
- *   <li>Your app calls {@link Activity#finish()} on the activity used for creating the customized
- *   shortcut.</li>
+ *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
+ *     conversations (c1, c2, ..., c5).
+ *
+ *     <li>The user pins all 5 of the shortcuts.
+ *
+ *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8),
+ *     so the publisher app
+ *     re-publishes its dynamic shortcuts.  The new dynamic shortcut list is:
+ *     c4, c5, ..., c8.
+ *     The publisher app has to remove c1, c2, and c3 because it can't have more than
+ *     5 dynamic shortcuts.
+ *
+ *     <li>However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned
+ *     shortcuts for these conversations are still available and launchable.
+ *
+ *     <li>At this point, the user can access a total of 8 shortcuts that link to activities in
+ *     the publisher app, including the 3 pinned shortcuts, even though an app can have at most 5
+ *     dynamic shortcuts.
+ *
+ *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
+ *     8 shortcuts, when, for example, the chat peers' icons have changed.
+ *     <p>The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
+ *     can also be used to update existing shortcuts with the same IDs, but they <b>cannot</b> be
+ *     used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the
+ *     given lists of shortcuts to dynamic shortcuts.
  * </ol>
  *
- * <h3>Shortcut Intents</h3>
+ * <h3>Shortcut intents</h3>
+ *
  * <p>
  * Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags.
  * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other
  * flags; otherwise, if the app is already running, the app is simply brought to
  * the foreground, and the target activity may not appear.
  *
- * <p>The {@link ShortcutInfo.Builder#setIntents(Intent[])} method can be used instead of
- * {@link ShortcutInfo.Builder#setIntent(Intent)} with {@link android.app.TaskStackBuilder}
- * in order to launch an activity with other activities in the back stack.
- * When the user selects a shortcut to load an activity with a back stack,
- * then presses the back key, a parent activity from the same app will be shown
- * instead of the user being navigated back to the launcher.
- *
- * <p>Static shortcuts can also have multiple intents to achieve the same effect.
- * In order to associate multiple {@link Intent} objects with a shortcut, simply list multiple
- * <code>&lt;intent&gt;</code> elements within a single <code>&lt;shortcut&gt;</code> element.
- * The last intent specifies what the user sees when they launch a shortcut.
- *
  * <p>Static shortcuts <b>cannot</b> have custom intent flags.
  * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK}
- * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set.
- * This means, when the app is already running, all the existing activities will be
- * destroyed when a static shortcut is launched.
- * If this behavior is not desirable, you can use a <em>trampoline activity</em>,
- * or an invisible activity that starts another activity in {@link Activity#onCreate},
- * then calls {@link Activity#finish()}.
- * The first activity should include an attribute setting
- * of {@code android:taskAffinity=""} in the app's <code>AndroidManifest.xml</code>
- * file, and the intent within the static shortcut should point at this first activity.
+ * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all
+ * the existing activities in your app will be destroyed when a static shortcut is launched.
+ * If this behavior is not desirable, you can use a <em>trampoline activity</em>, or an invisible
+ * activity that starts another activity in {@link Activity#onCreate}, then calls
+ * {@link Activity#finish()}:
+ * <ol>
+ *     <li>In the <code>AndroidManifest.xml</code> file, the trampoline activity should include the
+ *     attribute assignment {@code android:taskAffinity=""}.
+ *     <li>In the shortcuts resource file, the intent within the static shortcut should point at
+ *     the trampoline activity.
+ * </ol>
  *
+ * <h3>Handling system locale changes</h3>
  *
- * <h3>Showing New Information in a Shortcut</h3>
- * <p>
- * In order to avoid confusion, you should not use {@link #updateShortcuts(List)} to update
- * a shortcut so that it contains conceptually different information.
+ * <p>Apps should update dynamic and pinned shortcuts when the system locale changes using the
+ * {@link Intent#ACTION_LOCALE_CHANGED} broadcast. When the system locale changes,
+ * <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is reset, so even
+ * background apps can add and update dynamic shortcuts until the rate limit is reached again.
  *
- * <p>For example, a phone app may publish the most frequently called contact as a dynamic
- * shortcut.  Over time, this contact may change. When it does, the app should
- * represent the changed contact with a new shortcut that contains a different ID, using either
- * {@link #setDynamicShortcuts(List)} or {@link #addDynamicShortcuts(List)}, rather than updating
- * the existing shortcut with {@link #updateShortcuts(List)}.
- * This is because when the shortcut is pinned, changing
- * it to reference a different contact will likely confuse the user.
+ * <h3>Shortcut limits</h3>
  *
- * <p>On the other hand, when the
- * contact's information has changed, such as the name or picture, the app should
- * use {@link #updateShortcuts(List)} so that the pinned shortcut is updated too.
+ * <p>Only main activities&mdash;activities that handle the {@code MAIN} action and the
+ * {@code LAUNCHER} category&mdash;can have shortcuts. If an app has multiple main activities, you
+ * need to define the set of shortcuts for <em>each</em> activity.
  *
+ * <p>Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of
+ * static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts that
+ * an app can create.
  *
- * <h3>Shortcut Display Order</h3>
- * When the launcher displays the shortcuts that are associated with a particular launcher icon,
- * the shortcuts should appear in the following order:
- * <ul>
- *   <li>First show static shortcuts
- *   (if {@link ShortcutInfo#isDeclaredInManifest()} is {@code true}),
- *   and then show dynamic shortcuts (if {@link ShortcutInfo#isDynamic()} is {@code true}).
- *   <li>Within each category of shortcuts (static and dynamic), sort the shortcuts in order
- *   of increasing rank according to {@link ShortcutInfo#getRank()}.
- * </ul>
- * <p>Shortcut ranks are non-negative, sequential integers
- * that determine the order in which shortcuts appear, assuming that the shortcuts are all in
- * the same category.
- * Ranks of existing shortcuts can be updated with
- * {@link #updateShortcuts(List)}. You can also use {@link #addDynamicShortcuts(List)} and
- * {@link #setDynamicShortcuts(List)}.
+ * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
+ * the pinned shortcut is still visible and launchable.  This allows an app to have more than
+ * {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
  *
- * <p>Ranks are auto-adjusted so that they're unique for each target activity in each category
- * (static or dynamic).  For example, if there are 3 dynamic shortcuts with ranks 0, 1 and 2,
- * adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut at
- * the second position.
- * In response, the third and fourth shortcuts move closer to the bottom of the shortcut list,
- * with their ranks changing to 2 and 3, respectively.
+ * <h4>Rate limiting</h4>
  *
- * <h3>Rate Limiting</h3>
+ * <p>When <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is active,
+ * {@link #isRateLimitingActive()} returns {@code true}.
  *
- * <p>
- * Calls to {@link #setDynamicShortcuts(List)}, {@link #addDynamicShortcuts(List)}, and
- * {@link #updateShortcuts(List)} may be rate-limited when called by <em>background apps</em>, or
- * apps with no foreground activity or service.  When you attempt to call these methods
- * from a background app after exceeding the rate limit, these APIs return {@code false}.
- *
- * <p>Apps with a foreground activity or service are not rate-limited.
- *
- * <p>Rate-limiting is reset upon certain events, so that even background apps
- * can call these APIs until the rate limit is reached again.
- * These events include the following:
+ * <p>Rate limiting is reset upon certain events, so even background apps can call these APIs until
+ * the rate limit is reached again. These events include the following:
  * <ul>
  *   <li>An app comes to the foreground.
  *   <li>The system locale changes.
  *   <li>The user performs the <strong>inline reply</strong> action on a notification.
  * </ul>
- *
- * <p>When rate-limiting is active, {@link #isRateLimitingActive()} returns {@code true}.
- *
- * <h4>Resetting rate-limiting for testing</h4>
- *
- * <p>
- * If your app is rate-limited during development or testing, you can use the
- * <strong>Reset ShortcutManager rate-limiting</strong> development option or
- * the following {@code adb} command to reset it:
- * <pre class="no-pretty-print">
- *$ adb shell cmd shortcut reset-throttling [ --user USER-ID ]
- * </pre>
- *
- * <h3>Handling System Locale Changes</h3>
- *
- * <p>
- * Apps should update dynamic and pinned shortcuts when the system locale changes
- * using the {@link Intent#ACTION_LOCALE_CHANGED} broadcast.
- *
- * <p>When the system locale changes, rate-limiting is reset, so even background apps
- * can add and update dynamic shortcuts until the rate limit is reached again.
- *
- *
- * <h3>Backup and Restore</h3>
- *
- * <p>
- * When an app has the {@code android:allowBackup="true"} attribute assignment included
- * in its <code>AndroidManifest.xml</code> file, pinned shortcuts are
- * backed up automatically and are restored when the user sets up a new device.
- *
- * <h4>Categories of shortcuts that are backed up</h4>
- *
- * <ul>
- *  <li>Pinned shortcuts are backed up.  Bitmap icons are not backed up by the system,
- *  so launcher apps should back them up and restore them so that the user still sees icons
- *  for pinned shortcuts on the launcher.  Apps can always use
- *  {@link #updateShortcuts(List)} to re-publish icons.
- *
- *  <li>Static shortcuts aren't backed up, but when an app is re-installed on a new
- *  device, they are re-published from the <code>AndroidManifest.xml</code> file.
- *
- *  <li>Dynamic shortcuts <b>aren't</b> backed up.
- * </ul>
- *
- * <p>Because dynamic shortcuts are not restored, it is recommended that apps check
- * currently-published dynamic shortcuts using {@link #getDynamicShortcuts()}
- * each time they are launched, and they should re-publish
- * dynamic shortcuts when necessary.
- *
- * <pre>
- *public class MainActivity extends Activity {
- *    public void onCreate(Bundle savedInstanceState) {
- *        super.onCreate(savedInstanceState);
- *        ShortcutManager shortcutManager =
- *                getSystemService(ShortcutManager.class);
- *
- *        if (shortcutManager.getDynamicShortcuts().size() == 0) {
- *            // Application restored. Need to re-publish dynamic shortcuts.
- *            if (shortcutManager.getPinnedShortcuts().size() > 0) {
- *                // Pinned shortcuts have been restored. Use
- *                // updateShortcuts() to make sure they contain
- *                // up-to-date information.
- *            }
- *        }
- *    }
- *    // ...
- *}
- * </pre>
- *
- *
- * <h4>Backup/restore and shortcut IDs</h4>
- * <p>
- * Because pinned shortcuts are backed up and restored on new devices, shortcut IDs
- * should contain either stable, constant strings or server-side identifiers,
- * rather than identifiers generated locally that might not make sense on other devices.
- *
- *
- * <h3>Report Shortcut Usage and Prediction</h3>
- * <p>
- * Launcher apps may be capable of predicting which shortcuts will most likely be
- * used at a given time by examining the shortcut usage history data.
- *
- * <p>In order to provide launchers with such data, publisher apps should
- * report the shortcuts that are used with {@link #reportShortcutUsed(String)}
- * when a shortcut is selected,
- * <b>or when an action equivalent to a shortcut is taken by the user even if it wasn't started
- * with the shortcut</b>.
- *
- * <p>For example, suppose a navigation app supports "navigate to work" as a shortcut.
- * It should then report when the user selects this shortcut <b>and</b> when the user chooses
- * to navigate to work within the app itself.
- * This helps the launcher app
- * learn that the user wants to navigate to work at a certain time every
- * weekday, and it can then show this shortcut in a suggestion list at the right time.
- *
- * <h3>Launcher API</h3>
- *
- * The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
- *
- *
- * <h3>Direct Boot and Shortcuts</h3>
- *
- * All shortcut information is stored in credential encrypted storage, so no shortcuts can be
- * accessed when the user is locked.
  */
 @SystemService(Context.SHORTCUT_SERVICE)
 public class ShortcutManager {
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 63eedf5..55343a2 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -73,8 +73,10 @@
      * Create a request suitable for still image capture. Specifically, this
      * means prioritizing image quality over frame rate. These requests would
      * commonly be used with the {@link CameraCaptureSession#capture} method.
-     * This template is guaranteed to be supported on all camera devices.
-     *
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      * @see #createCaptureRequest
      */
     public static final int TEMPLATE_STILL_CAPTURE = 2;
@@ -84,7 +86,10 @@
      * that a stable frame rate is used, and post-processing is set for
      * recording quality. These requests would commonly be used with the
      * {@link CameraCaptureSession#setRepeatingRequest} method.
-     * This template is guaranteed to be supported on all camera devices.
+     * This template is guaranteed to be supported on all camera devices except
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
@@ -98,7 +103,10 @@
      * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
      * This template is guaranteed to be supported on all camera devices except
      * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
-     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}) and
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT} devices
+     * that are not {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * BACKWARD_COMPATIBLE}.
      *
      * @see #createCaptureRequest
      */
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index a80ef03..53b49f0 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -179,11 +179,18 @@
  * should not contain fields for username, password, and credit card information. The reason for
  * this rule is that a malicious app could draft a view structure where the credit card fields
  * are not visible, so when the user selects a dataset from the username UI, the credit card info is
- * released to the application without the user knowledge. Similar, it's recommended to always
+ * released to the application without the user knowledge. Similarly, it's recommended to always
  * protect a dataset that contains sensitive information by requiring dataset authentication
- * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}).
+ * (see {@link Dataset.Builder#setAuthentication(android.content.IntentSender)}), and to include
+ * info about the "primary" field of the partition in the custom presentation for "secondary"
+ * fields &mdash; that would prevent a malicious app from getting the "primary" fields without the
+ * user realizing they're being released (for example, a malicious app could have fields for a
+ * credit card number, verification code, and expiration date crafted in a way that just the latter
+ * is visible; by explicitly indicating the expiration date is related to a given credit card
+ * number, the service would be providing a visual clue for the users to check what would be
+ * released upon selecting that field).
  *
- * <p>When the service detects that a screen have multiple partitions, it should return a
+ * <p>When the service detects that a screen has multiple partitions, it should return a
  * {@link FillResponse} with just the datasets for the partition that originated the request (i.e.,
  * the partition that has the {@link android.app.assist.AssistStructure.ViewNode} whose
  * {@link android.app.assist.AssistStructure.ViewNode#isFocused()} returns {@code true}); then if
@@ -236,6 +243,36 @@
  * <p>When the service returns multiple {@link FillResponse}, the last one overrides the previous;
  * that's why the {@link SaveInfo} in the 2nd request above has the info for both partitions.
  *
+ * <h3>Package verification</h3>
+ *
+ * <p>When autofilling app-specific data (like username and password), the service must verify
+ * the authenticity of the request by obtaining all signing certificates of the app being
+ * autofilled, and only fulfilling the request when they match the values that were
+ * obtained when the data was first saved &mdash; such verification is necessary to avoid phishing
+ * attempts by apps that were sideloaded in the device with the same package name of another app.
+ * Here's an example on how to achieve that by hashing the signing certificates:
+ *
+ * <pre class="prettyprint">
+ * private String getCertificatesHash(String packageName) throws Exception {
+ *   PackageManager pm = mContext.getPackageManager();
+ *   PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ *   ArrayList<String> hashes = new ArrayList<>(info.signatures.length);
+ *   for (Signature sig : info.signatures) {
+ *     byte[] cert = sig.toByteArray();
+ *     MessageDigest md = MessageDigest.getInstance("SHA-256");
+ *     md.update(cert);
+ *     hashes.add(toHexString(md.digest()));
+ *   }
+ *   Collections.sort(hashes);
+ *   StringBuilder hash = new StringBuilder();
+ *   for (int i = 0; i < hashes.size(); i++) {
+ *     hash.append(hashes.get(i));
+ *   }
+ *   return hash.toString();
+ * }
+ *
+ * </pre>
+ *
  * <h3>Ignoring views</h3>
  *
  * <p>If the service find views that cannot be autofilled (for example, a text field representing
@@ -243,6 +280,76 @@
  * calling {@link FillResponse.Builder#setIgnoredIds(AutofillId...)} so the system does not trigger
  * a new {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} when these views are
  * focused.
+ *
+ * <h3>Web security</h3>
+ *
+ * <p>When handling autofill requests that represent web pages (typically
+ * view structures whose root's {@link android.app.assist.AssistStructure.ViewNode#getClassName()}
+ * is a {@link android.webkit.WebView}), the service should take the following steps to verify if
+ * the structure can be autofilled with the data associated with the app requesting it:
+ *
+ * <ol>
+ *   <li>Use the {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()} to get the
+ *       source of the document.
+ *   <li>Get the canonical domain using the
+ *       <a href="https://publicsuffix.org/>Public Suffix List</a> (see example below).
+ *   <li>Use <a href="https://developers.google.com/digital-asset-links/">Digital Asset Links</a>
+ *       to obtain the package name and certificate fingerprint of the package corresponding to
+ *       the canonical domain.
+ *   <li>Make sure the certificate fingerprint matches the value returned by Package Manager
+ *       (see "Package verification" section above).
+ * </ol>
+ *
+ * <p>Here's an example on how to get the canonical domain using
+ * <a href="https://github.com/google/guava">Guava</a>:
+ *
+ * <pre class="prettyprint">
+ * private static String getCanonicalDomain(String domain) {
+ *   InternetDomainName idn = InternetDomainName.from(domain);
+ *   while (!idn.isTopPrivateDomain() && idn != null) {
+ *     idn = idn.parent();
+ *   }
+ *   return idn == null ? null : idn.toString();
+ * }
+ * </pre>
+ *
+ * <p>If the association between the web domain and app package cannot be verified through the steps
+ * above, the service can still autofill the app, but it should warn the user about the potential
+ * data leakage first, and askfor the user to confirm. For example, the service could:
+ *
+ * <ol>
+ *   <li>Create a dataset that requires
+ *       {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authentication} to
+ *       unlock.
+ *   <li>Include the web domain in the custom presentation for the
+ *       {@link Dataset.Builder#setValue(AutofillId, AutofillValue, android.widget.RemoteViews)
+ *       dataset value}.
+ *   <li>When the user select that dataset, show a disclaimer dialog explaining that the app is
+ *       requesting credentials for a web domain, but the service could not verify if the app owns
+ *       that domain. If the user agrees, then the service can unlock the dataset.
+ *   <li>Similarly, when adding a {@link SaveInfo} object for the request, the service should
+ *       include the above disclaimer in the {@link SaveInfo.Builder#setDescription(CharSequence)}.
+ * </ol>
+ *
+ * <p>This same procedure could also be used when the autofillable data is contained inside an
+ * {@code IFRAME}, in which case the WebView generates a new autofill context when a node inside
+ * the {@code IFRAME} is focused, which the root node containing the {@code IFRAME}'s {@code src}
+ * attribute on {@link android.app.assist.AssistStructure.ViewNode#getWebDomain()}. A typical and
+ * legitimate use case for this scenario is a financial app that allows the user
+ * to login on different bank accounts. For example, a financial app {@code my_financial_app} could
+ * use a WebView that loads contents from {@code banklogin.my_financial_app.com}, which contains an
+ * {@code IFRAME} node whose {@code src} attribute is {@code login.some_bank.com}. When fulfilling
+ * that request, the service could add an
+ * {@link Dataset.Builder#setAuthentication(android.content.IntentSender) authenticated dataset}
+ * whose presentation displays "Username for some_bank.com" and
+ * "Password for some_bank.com". Then when the user taps one of these options, the service
+ * shows the disclaimer dialog explaining that selecting that option would release the
+ * {@code login.some_bank.com} credentials to the {@code my_financial_app}; if the user agrees,
+ * then the service returns an unlocked dataset with the {@code some_bank.com} credentials.
+ *
+ * <p><b>Note:</b> The autofill service could also whitelist well-known browser apps and skip the
+ * verifications above, as long as the service can verify the authenticity of the browser app by
+ * checking its signing certificate.
  */
 public abstract class AutofillService extends Service {
     private static final String TAG = "AutofillService";
@@ -387,7 +494,7 @@
      * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
      * to notify the result of the request.
      *
-     * <p><b>NOTE: </b>to retrieve the actual value of the field, the service should call
+     * <p><b>Note:</b> To retrieve the actual value of the field, the service should call
      * {@link android.app.assist.AssistStructure.ViewNode#getAutofillValue()}; if it calls
      * {@link android.app.assist.AssistStructure.ViewNode#getText()} or other methods, there is no
      * guarantee such method will return the most recent value of the field.
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index e13fdf6..80ef3aa 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -205,6 +205,13 @@
         /**
          * Adds a new {@link Dataset} to this response.
          *
+         * <p><b>Note: </b> the total number of datasets is limited by the Binder transaction size,
+         * so it's recommended to keep it small (in the range of 10-20 at most) and use pagination
+         * by adding a fake
+         * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated dataset}
+         * at the end with a presentation string like "Next 10" that would return a new
+         * {@link FillResponse} with the next 10 datasets, and so on.
+         *
          * @return This builder.
          */
         public @NonNull Builder addDataset(@Nullable Dataset dataset) {
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
index 287dc76..9b52934 100644
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.java
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
@@ -106,6 +106,8 @@
             if (mPayload != null) {
                 dest.writeInt(mPayload.length);
                 dest.writeByteArray(mPayload);
+            } else {
+                dest.writeInt(0);
             }
         }
     }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index 722b659..73733a0 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -76,7 +76,7 @@
 
     /**
      * Returns an {@link AccessibilityNodeInfo} representing a virtual view,
-     * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
+     * such as a descendant of the host View, with the given <code>virtualViewId</code>
      * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      * <p>
      * A virtual descendant is an imaginary View that is reported as a part of the view
@@ -123,7 +123,7 @@
     }
 
     /**
-     * Performs an accessibility action on a virtual view, i.e. a descendant of the
+     * Performs an accessibility action on a virtual view, such as a descendant of the
      * host View, with the given <code>virtualViewId</code> or the host View itself
      * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      *
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Find the virtual view, i.e. a descendant of the host View, that has the
+     * Find the virtual view, such as a descendant of the host View, that has the
      * specified focus type.
      *
      * @param focus The focus to find. One of
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index e1e8317..c123a80 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -52,9 +52,64 @@
 import java.util.Objects;
 
 /**
- * App entry point to the Autofill Framework.
+ * The {@link AutofillManager} provides ways for apps and custom views to integrate with the
+ * Autofill Framework lifecycle.
  *
- * <p>It is safe to call into this from any thread.
+ * <p>The autofill lifecycle starts with the creation of an autofill context associated with an
+ * activity context; the autofill context is created when one of the following methods is called for
+ * the first time in an activity context, and the current user has an enabled autofill service:
+ *
+ * <ul>
+ *   <li>{@link #notifyViewEntered(View)}
+ *   <li>{@link #notifyViewEntered(View, int, Rect)}
+ *   <li>{@link #requestAutofill(View)}
+ * </ul>
+ *
+ * <p>Tipically, the context is automatically created when the first view of the activity is
+ * focused because {@code View.onFocusChanged()} indirectly calls
+ * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to
+ * explicitly create it (for example, a custom view developer could offer a contextual menu action
+ * in a text-field view to let users manually request autofill).
+ *
+ * <p>After the context is created, the Android System creates a {@link android.view.ViewStructure}
+ * that represents the view hierarchy by calling
+ * {@link View#dispatchProvideAutofillStructure(android.view.ViewStructure, int)} in the root views
+ * of all application windows. By default, {@code dispatchProvideAutofillStructure()} results in
+ * subsequent calls to {@link View#onProvideAutofillStructure(android.view.ViewStructure, int)} and
+ * {@link View#onProvideAutofillVirtualStructure(android.view.ViewStructure, int)} for each view in
+ * the hierarchy.
+ *
+ * <p>The resulting {@link android.view.ViewStructure} is then passed to the autofill service, which
+ * parses it looking for views that can be autofilled. If the service finds such views, it returns
+ * a data structure to the Android System containing the following optional info:
+ *
+ * <ul>
+ *   <li>Datasets used to autofill subsets of views in the activity.
+ *   <li>Id of views that the service can save their values for future autofilling.
+ * </ul>
+ *
+ * <p>When the service returns datasets, the Android System displays an autofill dataset picker
+ * UI affordance associated with the view, when the view is focused on and is part of a dataset.
+ * The application can be notified when the affordance is shown by registering an
+ * {@link AutofillCallback} through {@link #registerCallback(AutofillCallback)}. When the user
+ * selects a dataset from the affordance, all views present in the dataset are autofilled, through
+ * calls to {@link View#autofill(AutofillValue)} or {@link View#autofill(SparseArray)}.
+ *
+ * <p>When the service returns ids of savable views, the Android System keeps track of changes
+ * made to these views, so they can be used to determine if the autofill save UI is shown later.
+ *
+ * <p>The context is then finished when one of the following occurs:
+ *
+ * <ul>
+ *   <li>{@link #commit()} is called or all savable views are gone.
+ *   <li>{@link #cancel()} is called.
+ * </ul>
+ *
+ * <p>Finally, after the autofill context is commited (i.e., not cancelled), the Android System
+ * shows a save UI affordance if the value of savable views have changed. If the user selects the
+ * option to Save, the current value of the views is then sent to the autofill service.
+ *
+ * <p>It is safe to call into its methods from any thread.
  */
 @SystemService(Context.AUTOFILL_MANAGER_SERVICE)
 public final class AutofillManager {
@@ -671,8 +726,13 @@
     /**
      * Called to indicate the current autofill context should be commited.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method after the form is submitted and another page is rendered.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method after the form is submitted and
+     * another page is rendered.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void commit() {
         if (!hasAutofillFeature()) {
@@ -690,8 +750,13 @@
     /**
      * Called to indicate the current autofill context should be cancelled.
      *
-     * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
-     * call this method if the user does not post the form but moves to another form in this page.
+     * <p>This method is typically called by {@link View Views} that manage virtual views; for
+     * example, when the view is rendering an {@code HTML} page with a form and virtual views
+     * that represent the HTML elements, it should call this method if the user does not post the
+     * form but moves to another form in this page.
+     *
+     * <p><b>Note:</b> This method does not need to be called on regular application lifecycle
+     * methods such as {@link android.app.Activity#finish()}.
      */
     public void cancel() {
         if (!hasAutofillFeature()) {
@@ -1462,10 +1527,10 @@
     }
 
     /**
-     * Callback for auto-fill related events.
+     * Callback for autofill related events.
      *
      * <p>Typically used for applications that display their own "auto-complete" views, so they can
-     * enable / disable such views when the auto-fill UI affordance is shown / hidden.
+     * enable / disable such views when the autofill UI affordance is shown / hidden.
      */
     public abstract static class AutofillCallback {
 
@@ -1475,7 +1540,7 @@
         public @interface AutofillEventType {}
 
         /**
-         * The auto-fill input UI affordance associated with the view was shown.
+         * The autofill input UI affordance associated with the view was shown.
          *
          * <p>If the view provides its own auto-complete UI affordance and its currently shown, it
          * should be hidden upon receiving this event.
@@ -1483,7 +1548,7 @@
         public static final int EVENT_INPUT_SHOWN = 1;
 
         /**
-         * The auto-fill input UI affordance associated with the view was hidden.
+         * The autofill input UI affordance associated with the view was hidden.
          *
          * <p>If the view provides its own auto-complete UI affordance that was hidden upon a
          * {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
@@ -1491,7 +1556,7 @@
         public static final int EVENT_INPUT_HIDDEN = 2;
 
         /**
-         * The auto-fill input UI affordance associated with the view won't be shown because
+         * The autofill input UI affordance associated with the view isn't shown because
          * autofill is not available.
          *
          * <p>If the view provides its own auto-complete UI affordance but was not displaying it
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index dda5df6..ce0a288 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2648,6 +2648,18 @@
      * understood by the {@link android.service.autofill.AutofillService} implementations:
      *
      * <ol>
+     *   <li>Only the HTML nodes inside a {@code FORM} are generated.
+     *   <li>The source of the HTML is set using {@link ViewStructure#setWebDomain(String)} in the
+     *   node representing the WebView.
+     *   <li>If a web page has multiple {@code FORM}s, only the data for the current form is
+     *   represented&mdash;if the user taps a field from another form, then the current autofill
+     *   context is canceled (by calling {@link android.view.autofill.AutofillManager#cancel()} and
+     *   a new context is created for that {@code FORM}.
+     *   <li>Similarly, if the page has {@code IFRAME} nodes, they are not initially represented in
+     *   the view structure until the user taps a field from a {@code FORM} inside the
+     *   {@code IFRAME}, in which case it would be treated the same way as multiple forms described
+     *   above, except that the {@link ViewStructure#setWebDomain(String) web domain} of the
+     *   {@code FORM} contains the {@code src} attribute from the {@code IFRAME} node.
      *   <li>If the Android SDK provides a similar View, then should be set with the
      *   fully-qualified class name of such view.
      *   <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index d023866..d5b34c4 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -260,13 +260,13 @@
      * Example:
      *
      * <pre class="prettyprint">
-     * Calendar start = new Calendar();
-     * Calendar end = new Calendar();
-     * end.add(1, Calendar.YEAR);
+     * Calendar start = Calendar.getInstance();
+     * Calendar end = Calendar.getInstance();
+     * end.add(Calendar.YEAR, 1);
      *
      * KeyPairGeneratorSpec spec =
      *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
-     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
+     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerialNumber(BigInteger.valueOf(1337))
      *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
      * </pre>
      *
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index dbbbfc6..26e65dd 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -57,10 +57,10 @@
  * SoundPool will automatically stop a previously playing stream based first
  * on priority and then by age within that priority. Limiting the maximum
  * number of streams helps to cap CPU loading and reducing the likelihood that
- * audio mixing will impact visuals or UI performance.</p> 
+ * audio mixing will impact visuals or UI performance.</p>
  *
  * <p>Sounds can be looped by setting a non-zero loop value. A value of -1
- * causes the sound to loop forever. In this case, the application must 
+ * causes the sound to loop forever. In this case, the application must
  * explicitly call the stop() function to stop the sound. Any other non-zero
  * value will cause the sound to repeat the specified number of times, e.g.
  * a value of 3 causes the sound to play a total of 4 times.</p>
@@ -101,7 +101,7 @@
  * <p>Note that since streams can be stopped due to resource constraints, the
  * streamID is a reference to a particular instance of a stream. If the stream
  * is stopped to allow a higher priority stream to play, the stream is no
- * longer be valid. However, the application is allowed to call methods on
+ * longer valid. However, the application is allowed to call methods on
  * the streamID without error. This may help simplify program logic since
  * the application need not concern itself with the stream lifecycle.</p>
  *
@@ -137,7 +137,7 @@
      *
      * @param maxStreams the maximum number of simultaneous streams for this
      *                   SoundPool object
-     * @param streamType the audio stream type as described in AudioManager 
+     * @param streamType the audio stream type as described in AudioManager
      *                   For example, game applications will normally use
      *                   {@link AudioManager#STREAM_MUSIC}.
      * @param srcQuality the sample-rate converter quality. Currently has no
@@ -213,7 +213,7 @@
      * "R.raw.explosion" as the resource ID. Note that this means you cannot
      * have both an "explosion.wav" and an "explosion.mp3" in the res/raw
      * directory.
-     * 
+     *
      * @param context the application context
      * @param resId the resource ID
      * @param priority the priority of the sound. Currently has no effect. Use
@@ -287,7 +287,7 @@
     /**
      * Play a sound from a sound ID.
      *
-     * Play the sound specified by the soundID. This is the value 
+     * Play the sound specified by the soundID. This is the value
      * returned by the load() function. Returns a non-zero streamID
      * if successful, zero if it fails. The streamID can be used to
      * further control playback. Note that calling play() may cause
@@ -509,7 +509,7 @@
         }
     }
 
-    private native final int _load(FileDescriptor fd, long offset, long length, int priority); 
+    private native final int _load(FileDescriptor fd, long offset, long length, int priority);
 
     private native final int native_setup(Object weakRef, int maxStreams,
             Object/*AudioAttributes*/ attributes);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f5d7dd8..973d21c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2895,7 +2895,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 145;
+            private static final int SETTINGS_VERSION = 146;
 
             private final int mUserId;
 
@@ -3421,22 +3421,11 @@
                 }
 
                 if (currentVersion == 141) {
-                    // Version 142: We added the notion of a default and whether the system set
-                    // the setting. This is used for resetting the internal state and we need
-                    // to make sure this value is updated for the existing settings, otherwise
-                    // we would delete system set settings while they should stay unmodified.
-                    SettingsState globalSettings = getGlobalSettingsLocked();
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings);
-                    globalSettings.persistSyncLocked();
-
-                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings);
-                    secureSettings.persistSyncLocked();
-
-                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
-                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings);
-                    systemSettings.persistSyncLocked();
-
+                    // This implementation was incorrectly setting the current value of
+                    // settings changed by non-system packages as the default which default
+                    // is set by the system. We add a new upgrade step at the end to properly
+                    // handle this case which would also fix incorrect changes made by the
+                    // old implementation of this step.
                     currentVersion = 142;
                 }
 
@@ -3496,6 +3485,31 @@
                     currentVersion = 145;
                 }
 
+                if (currentVersion == 145) {
+                    // Version 146: In step 142 we had a bug where incorrectly
+                    // some settings were considered system set and as a result
+                    // made the default and marked as the default being set by
+                    // the system. Here reevaluate the default and default system
+                    // set flags. This would both fix corruption by the old impl
+                    // of step 142 and also properly handle devices which never
+                    // run 142.
+                    if (userId == UserHandle.USER_SYSTEM) {
+                        SettingsState globalSettings = getGlobalSettingsLocked();
+                        ensureLegacyDefaultValueAndSystemSetUpdatedLocked(globalSettings, userId);
+                        globalSettings.persistSyncLocked();
+                    }
+
+                    SettingsState secureSettings = getSecureSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(secureSettings, userId);
+                    secureSettings.persistSyncLocked();
+
+                    SettingsState systemSettings = getSystemSettingsLocked(mUserId);
+                    ensureLegacyDefaultValueAndSystemSetUpdatedLocked(systemSettings, userId);
+                    systemSettings.persistSyncLocked();
+
+                    currentVersion = 146;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
@@ -3514,19 +3528,46 @@
             }
         }
 
-        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings) {
+        private void ensureLegacyDefaultValueAndSystemSetUpdatedLocked(SettingsState settings,
+                int userId) {
             List<String> names = settings.getSettingNamesLocked();
             final int nameCount = names.size();
             for (int i = 0; i < nameCount; i++) {
                 String name = names.get(i);
                 Setting setting = settings.getSettingLocked(name);
-                if (setting.getDefaultValue() == null) {
-                    boolean systemSet = SettingsState.isSystemPackage(getContext(),
-                            setting.getPackageName());
+
+                // In the upgrade case we pretend the call is made from the app
+                // that made the last change to the setting to properly determine
+                // whether the call has been made by a system component.
+                int callingUid = -1;
+                try {
+                    callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
+                } catch (RemoteException e) {
+                    /* ignore - handled below */
+                }
+                if (callingUid < 0) {
+                    Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
+                    continue;
+                }
+                try {
+                    final boolean systemSet = SettingsState.isSystemPackage(getContext(),
+                            setting.getPackageName(), callingUid);
                     if (systemSet) {
                         settings.insertSettingLocked(name, setting.getValue(),
                                 setting.getTag(), true, setting.getPackageName());
+                    } else if (setting.getDefaultValue() != null && setting.isDefaultFromSystem()) {
+                        // We had a bug where changes by non-system packages were marked
+                        // as system made and as a result set as the default. Therefore, if
+                        // the package changed the setting last is not a system one but the
+                        // setting is marked as its default coming from the system we clear
+                        // the default and clear the system set flag.
+                        settings.resetSettingDefaultValueLocked(name);
                     }
+                } catch (IllegalStateException e) {
+                    // If the package goes over its quota during the upgrade, don't
+                    // crash but just log the error as the system does the upgrade.
+                    Slog.e(LOG_TAG, "Error upgrading setting: " + setting.getName(), e);
+
                 }
             }
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 5f4b239..6c98360 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -298,6 +298,22 @@
     }
 
     // The settings provider must hold its lock when calling here.
+    public void resetSettingDefaultValueLocked(String name) {
+        Setting oldSetting = getSettingLocked(name);
+        if (oldSetting != null && !oldSetting.isNull() && oldSetting.getDefaultValue() != null) {
+            String oldValue = oldSetting.getValue();
+            String oldDefaultValue = oldSetting.getDefaultValue();
+            Setting newSetting = new Setting(name, oldSetting.getValue(), null,
+                    oldSetting.getPackageName(), oldSetting.getTag(), false,
+                    oldSetting.getId());
+            mSettings.put(name, newSetting);
+            updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
+                    newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
+            scheduleWriteIfNeededLocked();
+        }
+    }
+
+    // The settings provider must hold its lock when calling here.
     public boolean insertSettingLocked(String name, String value, String tag,
             boolean makeDefault, String packageName) {
         if (TextUtils.isEmpty(name)) {
@@ -1003,6 +1019,10 @@
     }
 
     public static boolean isSystemPackage(Context context, String packageName) {
+        return isSystemPackage(context, packageName, Binder.getCallingUid());
+    }
+
+    public static boolean isSystemPackage(Context context, String packageName, int callingUid) {
         synchronized (sLock) {
             if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
                 return true;
@@ -1015,7 +1035,7 @@
             }
 
             // Native services running as a special UID get a pass
-            final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
+            final int callingAppId = UserHandle.getAppId(callingUid);
             if (callingAppId < FIRST_APPLICATION_UID) {
                 sSystemUids.put(callingAppId, callingAppId);
                 return true;
@@ -1026,7 +1046,7 @@
             // profile for the purpose of determining whether the other end is a
             // system component we need to use the user id of the caller for
             // pulling information about the caller from the package manager.
-            final int callingUserId = UserHandle.getCallingUserId();
+            final int callingUserId = UserHandle.getUserId(callingUid);
 
             final long identity = Binder.clearCallingIdentity();
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 6fe8827..e9f6e95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -397,24 +397,6 @@
                 && pm.resolveActivity(PHONE_INTENT, 0) != null;
     }
 
-    private boolean isCameraDisabledByDpm() {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (dpm != null && mStatusBar != null) {
-            try {
-                final int userId = ActivityManager.getService().getCurrentUser().id;
-                final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
-                final  boolean disabledBecauseKeyguardSecure =
-                        (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
-                                && mStatusBar.isKeyguardSecure();
-                return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Can't get userId", e);
-            }
-        }
-        return false;
-    }
-
     private void watchForCameraPolicyChanges() {
         final IntentFilter filter = new IntentFilter();
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -865,7 +847,8 @@
         @Override
         public IconState getIcon() {
             ResolveInfo resolved = resolveCameraIntent();
-            mIconState.isVisible = !isCameraDisabledByDpm() && resolved != null
+            boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
+            mIconState.isVisible = !isCameraDisabled && resolved != null
                     && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                     && mUserSetupComplete;
             mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6aab8e1..54c12a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -31,6 +31,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.EventLog;
 import android.util.FloatProperty;
 import android.util.MathUtils;
 import android.view.MotionEvent;
@@ -2440,6 +2441,11 @@
      * @param keyguardIsShowing whether keyguard is being shown
      */
     public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) {
+        if (!mStatusBar.isCameraAllowedByAdmin()) {
+            EventLog.writeEvent(0x534e4554, "63787722", -1, "");
+            return false;
+        }
+
         ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
         String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
                 ? null : resolveInfo.activityInfo.packageName;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index f58fe82..d2994bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1,5 +1,3 @@
-
-
 /*
  * Copyright (C) 2010 The Android Open Source Project
  *
@@ -5040,6 +5038,18 @@
         }
     }
 
+    boolean isCameraAllowedByAdmin() {
+        if (mDevicePolicyManager.getCameraDisabled(null, mCurrentUserId)) {
+            return false;
+        } else if (isKeyguardShowing() && isKeyguardSecure()) {
+            // Check if the admin has disabled the camera specifically for the keyguard
+            return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mCurrentUserId)
+                    & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+        }
+
+        return true;
+    }
+
     public void notifyFpAuthModeChanged() {
         updateDozing();
     }
@@ -5062,6 +5072,10 @@
     }
 
     public boolean isKeyguardShowing() {
+        if (mStatusBarKeyguardViewManager == null) {
+            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
+            return true;
+        }
         return mStatusBarKeyguardViewManager.isShowing();
     }
 
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 62332c9..c012ee4 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -41,6 +41,7 @@
     private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000;  // 1MB.
     private static final String DEFAULT_USER_AGENT = "Android";
     private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
+    private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(60);
 
     private final String[] mXtraServers;
     // to load balance our server requests
@@ -123,6 +124,7 @@
                     "x-wap-profile",
                     "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
             connection.setConnectTimeout(CONNECTION_TIMEOUT_MS);
+            connection.setReadTimeout(READ_TIMEOUT_MS);
 
             connection.connect();
             int statusCode = connection.getResponseCode();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c1b98f5..f36b762 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4004,10 +4004,15 @@
         // reader
         synchronized (mPackages) {
             final BasePermission p = mSettings.mPermissions.get(name);
+            if (p == null) {
+                return null;
+            }
             // If the caller is an app that targets pre 26 SDK drop protection flags.
             final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
-            permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
-                    permissionInfo.protectionLevel, packageName, callingUid);
+            if (permissionInfo != null) {
+                permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
+                        permissionInfo.protectionLevel, packageName, callingUid);
+            }
             return permissionInfo;
         }
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 4e4398e..741161b 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -115,41 +115,6 @@
         mListener.onWindowsGone();
     };
 
-    private final Runnable mRemoveStartingWindow = () -> {
-        StartingSurface surface = null;
-        synchronized (mWindowMap) {
-            if (mContainer == null) {
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
-                        + " remove starting window");
-                return;
-            }
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting " + mContainer
-                    + ": startingWindow=" + mContainer.startingWindow
-                    + " startingView=" + mContainer.startingSurface);
-            if (mContainer.startingData != null) {
-                surface = mContainer.startingSurface;
-                mContainer.startingData = null;
-                mContainer.startingSurface = null;
-                mContainer.startingWindow = null;
-                mContainer.startingDisplayed = false;
-                if (surface == null && DEBUG_STARTING_WINDOW) {
-                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
-                            + "remove");
-                }
-            } else if (DEBUG_STARTING_WINDOW) {
-                Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
-                        + mContainer);
-            }
-        }
-        if (surface != null) {
-            try {
-                surface.remove();
-            } catch (Exception e) {
-                Slog.w(TAG_WM, "Exception when removing starting window", e);
-            }
-        }
-    };
-
     private final Runnable mAddStartingWindow = () -> {
         final StartingData startingData;
         final AppWindowToken container;
@@ -649,13 +614,6 @@
 
     public void removeStartingWindow() {
         synchronized (mWindowMap) {
-            if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
-                // Already scheduled.
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Trying to remove starting window but "
-                        + "already scheduled");
-                return;
-            }
-
             if (mContainer.startingWindow == null) {
                 if (mContainer.startingData != null) {
                     // Starting window has not been added yet, but it is scheduled to be added.
@@ -667,9 +625,36 @@
                 return;
             }
 
+            final StartingSurface surface;
+            if (mContainer.startingData != null) {
+                surface = mContainer.startingSurface;
+                mContainer.startingData = null;
+                mContainer.startingSurface = null;
+                mContainer.startingWindow = null;
+                mContainer.startingDisplayed = false;
+                if (surface == null && DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
+                            + "remove");
+                }
+            } else {
+                if (DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
+                            + mContainer);
+                }
+                return;
+            }
+
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer
-                    + " startingWindow=" + mContainer.startingWindow);
-            mHandler.post(mRemoveStartingWindow);
+                    + " startingWindow=" + mContainer.startingWindow
+                    + " startingView=" + mContainer.startingSurface);
+            mHandler.post(() -> {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
+                try {
+                    surface.remove();
+                } catch (Exception e) {
+                    Slog.w(TAG_WM, "Exception when removing starting window", e);
+                }
+            });
         }
     }