Merge "Fix tuner for secondary users" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 4b36adc..cb63aaa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33958,6 +33958,7 @@
     field public static final int DENSITY_280 = 280; // 0x118
     field public static final int DENSITY_360 = 360; // 0x168
     field public static final int DENSITY_400 = 400; // 0x190
+    field public static final int DENSITY_420 = 420; // 0x1a4
     field public static final int DENSITY_560 = 560; // 0x230
     field public static final int DENSITY_DEFAULT = 160; // 0xa0
     field public static final int DENSITY_HIGH = 240; // 0xf0
diff --git a/api/system-current.txt b/api/system-current.txt
index 36cd869..a9bc944 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -36250,6 +36250,7 @@
     field public static final int DENSITY_280 = 280; // 0x118
     field public static final int DENSITY_360 = 360; // 0x168
     field public static final int DENSITY_400 = 400; // 0x190
+    field public static final int DENSITY_420 = 420; // 0x1a4
     field public static final int DENSITY_560 = 560; // 0x230
     field public static final int DENSITY_DEFAULT = 160; // 0xa0
     field public static final int DENSITY_HIGH = 240; // 0xf0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fd88a05..da21eaf 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4235,11 +4235,6 @@
 
             configDiff = mConfiguration.updateFrom(config);
             config = applyCompatConfiguration(mCurDefaultDisplayDpi);
-
-            final Theme systemTheme = getSystemContext().getTheme();
-            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
-                systemTheme.rebase();
-            }
         }
 
         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index abe12dc..7824072 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -1082,7 +1082,8 @@
          * create and display the dialog.
          */
         public AlertDialog create() {
-            final AlertDialog dialog = new AlertDialog(P.mContext);
+            // Context has already been wrapped with the appropriate theme.
+            final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
             P.apply(dialog.mAlert);
             dialog.setCancelable(P.mCancelable);
             if (P.mCancelable) {
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index a36e66c..9a69600 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -90,6 +90,14 @@
     public static final int DENSITY_400 = 400;
 
     /**
+     * Intermediate density for screens that sit somewhere between
+     * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+     * This is not a density that applications should target, instead relying
+     * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+     */
+    public static final int DENSITY_420 = 420;
+
+    /**
      * Standard quantized DPI for extra-extra-high-density screens.
      */
     public static final int DENSITY_XXHIGH = 480;
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index bae2cde..a3d5b8a 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -43,6 +43,9 @@
 #include <dirent.h>
 #include <assert.h>
 
+#include <string>
+#include <vector>
+
 
 using namespace android;
 
@@ -357,38 +360,66 @@
     return false;
 }
 
+// Convenience wrapper over the property API that returns an
+// std::string.
+std::string getProperty(const char* key, const char* defaultValue) {
+    std::vector<char> temp(PROPERTY_VALUE_MAX);
+    const int len = property_get(key, &temp[0], defaultValue);
+    if (len < 0) {
+        return "";
+    }
+    return std::string(&temp[0], len);
+}
+
 /*
- * Read the persistent locale. Attempts to read to persist.sys.locale
- * and falls back to the default locale (ro.product.locale) if
- * persist.sys.locale is empty.
+ * Read the persistent locale. Inspects the following system properties
+ * (in order) and returns the first non-empty property in the list :
+ *
+ * (1) persist.sys.locale
+ * (2) persist.sys.language/country/localevar (country and localevar are
+ * inspected iff. language is non-empty.
+ * (3) ro.product.locale
+ * (4) ro.product.locale.language/region
+ *
+ * Note that we need to inspect persist.sys.language/country/localevar to
+ * preserve language settings for devices that are upgrading from Lollipop
+ * to M. The same goes for ro.product.locale.language/region as well.
  */
-static void readLocale(char* locale)
+const std::string readLocale()
 {
-    // Allocate 4 extra bytes because we might read a property into
-    // this array at offset 4.
-    char propLocale[PROPERTY_VALUE_MAX + 4];
-
-    property_get("persist.sys.locale", propLocale, "");
-    if (propLocale[0] == 0) {
-        property_get("ro.product.locale", propLocale, "");
-
-        if (propLocale[0] == 0) {
-            // If persist.sys.locale and ro.product.locale are missing,
-            // construct a locale value from the individual locale components.
-            property_get("ro.product.locale.language", propLocale, "en");
-
-            // The language code is either two or three chars in length. If it
-            // isn't 2 chars long, assume three. Anything else is an error
-            // anyway.
-            const int offset = (propLocale[2] == 0) ? 2 : 3;
-            propLocale[offset] = '-';
-
-            property_get("ro.product.locale.region", propLocale + offset + 1, "US");
-        }
+    const std::string locale = getProperty("persist.sys.locale", "");
+    if (!locale.empty()) {
+        return locale;
     }
 
-    strncat(locale, propLocale, PROPERTY_VALUE_MAX);
-    // ALOGD("[DEBUG] locale=%s", locale);
+    const std::string language = getProperty("persist.sys.language", "");
+    if (!language.empty()) {
+        const std::string country = getProperty("persist.sys.country", "");
+        const std::string variant = getProperty("persist.sys.localevar", "");
+
+        std::string out = language;
+        if (!country.empty()) {
+            out = out + "-" + country;
+        }
+
+        if (!variant.empty()) {
+            out = out + "-" + variant;
+        }
+
+        return out;
+    }
+
+    const std::string productLocale = getProperty("ro.product.locale", "");
+    if (!productLocale.empty()) {
+        return productLocale;
+    }
+
+    // If persist.sys.locale and ro.product.locale are missing,
+    // construct a locale value from the individual locale components.
+    const std::string productLanguage = getProperty("ro.product.locale.language", "en");
+    const std::string productRegion = getProperty("ro.product.locale.region", "US");
+
+    return productLanguage + "-" + productRegion;
 }
 
 void AndroidRuntime::addOption(const char* optionString, void* extraInfo)
@@ -793,7 +824,8 @@
     /* Set the properties for locale */
     {
         strcpy(localeOption, "-Duser.locale=");
-        readLocale(localeOption);
+        const std::string locale = readLocale();
+        strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX);
         addOption(localeOption);
     }
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cf28490..ae8cae8 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1267,7 +1267,7 @@
 
          If this string is empty or the specified package does not exist, then
          the platform will search for an SMS app and use that (if there is one)-->
-    <string name="default_sms_application" translatable="false"></string>
+    <string name="default_sms_application" translatable="false">com.android.messaging</string>
 
     <!-- Default web browser.  This is the package name of the application that will
          be the default browser when the device first boots.  Afterwards the user
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index bf069d3..32f6a89 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -786,12 +786,16 @@
             mMaskColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_IN);
         }
 
-        // Draw the appropriate mask.
+        // Draw the appropriate mask anchored to (0,0).
+        final int left = bounds.left;
+        final int top = bounds.top;
+        mMaskCanvas.translate(-left, -top);
         if (maskType == MASK_EXPLICIT) {
             drawMask(mMaskCanvas);
         } else if (maskType == MASK_CONTENT) {
             drawContent(mMaskCanvas);
         }
+        mMaskCanvas.translate(left, top);
     }
 
     private int getMaskType() {
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 7605231..f42d750 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -38,27 +38,35 @@
 /**
  * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a
  * {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore
- * system</a>. The spec determines whether user authentication is required for using the key, what
- * uses the key is authorized for (e.g., only for signing -- decryption not permitted), the key's
- * validity start and end dates.
+ * system</a>. The spec determines authorized uses of the key, such as whether user authentication
+ * is required for using the key, what operations are authorized (e.g., signing, but not
+ * decryption) and with what parameters (e.g., only with a particular padding scheme or digest), the
+ * key's validity start and end dates. Key use authorizations expressed in the spec apply only to
+ * secret keys and private keys -- public keys can be used for any supported operations.
  *
  * <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using
  * the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the
  * desired key type (e.g., {@code EC} or {@code AES} -- see
  * {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider
- * with the {@code KeyPairGeneratorSpec} instance, and then generate a key or key pair using
- * {@link KeyPairGenerator#generateKeyPair()}.
+ * with the {@code KeyGenParameterSpec} instance, and then generate a key or key pair using
+ * {@link KeyGenerator#generateKey()} or {@link KeyPairGenerator#generateKeyPair()}.
  *
  * <p>The generated key pair or key will be returned by the generator and also stored in the Android
- * Keystore system under the alias specified in this spec. To obtain the secret or private key from
- * the Android KeyStore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
+ * Keystore under the alias specified in this spec. To obtain the secret or private key from the
+ * Android Keystore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
  * or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- * To obtain the public key from the Android Keystore system use
+ * To obtain the public key from the Android Keystore use
  * {@link java.security.KeyStore#getCertificate(String)} and then
  * {@link Certificate#getPublicKey()}.
  *
+ * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
+ * Keystore, generated private keys implement {@link java.security.interfaces.ECKey} or
+ * {@link java.security.interfaces.RSAKey} interfaces whereas public keys implement
+ * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
+ * interfaces.
+ *
  * <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in
- * the Android KeyStore. This is because the {@link java.security.KeyStore} abstraction does not
+ * the Android Keystore. This is because the {@link java.security.KeyStore} abstraction does not
  * support storing key pairs without a certificate. The subject, serial number, and validity dates
  * of the certificate can be customized in this spec. The self-signed certificate may be replaced at
  * a later time by a certificate signed by a Certificate Authority (CA).
@@ -82,27 +90,33 @@
  *
  * <p>Instances of this class are immutable.
  *
- * <p><h3>Example: Asymmetric key pair</h3>
- * The following example illustrates how to generate an EC key pair in the Android KeyStore system
- * under alias {@code key1} authorized to be used only for signing using SHA-256, SHA-384,
- * or SHA-512 digest and only if the user has been authenticated within the last five minutes.
+ * <p><h3>Example: NIST P-256 EC key pair for signing/verification using ECDSA</h3>
+ * This example illustrates how to generate a NIST P-256 (aka secp256r1 aka prime256v1) EC key pair
+ * in the Android KeyStore system under alias {@code key1} where the private key is authorized to be
+ * used only for signing using SHA-256, SHA-384, or SHA-512 digest and only if the user has been
+ * authenticated within the last five minutes. The use of public key is unrestricted, thus
+ * permitting signature verification using any padding schemes and digests, and without user
+ * authentication.
  * <pre> {@code
  * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
- *         KeyProperties.KEY_ALGORITHM_EC,
- *         "AndroidKeyStore");
+ *         KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
  * keyPairGenerator.initialize(
  *         new KeyGenParameterSpec.Builder(
  *                 "key1",
- *                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+ *                 KeyProperties.PURPOSE_SIGN)
+ *                 .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
  *                 .setDigests(KeyProperties.DIGEST_SHA256,
  *                         KeyProperties.DIGEST_SHA384,
  *                         KeyProperties.DIGEST_SHA512)
- *                 // Only permit this key to be used if the user authenticated
+ *                 // Only permit the private key to be used if the user authenticated
  *                 // within the last five minutes.
  *                 .setUserAuthenticationRequired(true)
  *                 .setUserAuthenticationValidityDurationSeconds(5 * 60)
  *                 .build());
  * KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ * Signature signature = Signature.getInstance("SHA256withECDSA");
+ * signature.initSign(keyPair.getPrivate());
+ * ...
  *
  * // The key pair can also be obtained from the Android Keystore any time as follows:
  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
@@ -111,14 +125,67 @@
  * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
  * }</pre>
  *
- * <p><h3>Example: Symmetric key</h3>
+ * <p><h3>Example: RSA key pair for signing/verification using RSA-PSS</h3>
+ * This example illustrates how to generate an RSA key pair in the Android KeyStore system under
+ * alias {@code key1} authorized to be used only for signing using the RSA-PSS signature padding
+ * scheme with SHA-256 or SHA-512 digests. The use of public key is unrestricted, thus permitting
+ * signature verification using any padding schemes and digests.
+ * <pre> {@code
+ * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ *         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
+ * keyPairGenerator.initialize(
+ *         new KeyGenParameterSpec.Builder(
+ *                 "key1",
+ *                 KeyProperties.PURPOSE_SIGN)
+ *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ *                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+ *                 .build());
+ * KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ * Signature signature = Signature.getInstance("SHA256withRSA/PSS");
+ * signature.initSign(keyPair.getPrivate());
+ * ...
+ *
+ * // The key pair can also be obtained from the Android Keystore any time as follows:
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
+ * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
+ * }</pre>
+ *
+ * <p><h3>Example: RSA key pair for encryption/decryption using RSA OAEP</h3>
+ * This example illustrates how to generate an RSA key pair in the Android KeyStore system under
+ * alias {@code key1} where the private key is authorized to be used only for decryption using RSA
+ * OAEP encryption padding scheme with SHA-256 or SHA-512 digests. The use of public key is
+ * unrestricted, thus permitting encryption using any padding schemes and digests.
+ * <pre> {@code
+ * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ *         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
+ * keyPairGenerator.initialize(
+ *         new KeyGenParameterSpec.Builder(
+ *                 "key1",
+ *                 KeyProperties.PURPOSE_DECRYPT)
+ *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
+ *                 .build());
+ * KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ * Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+ * cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
+ * ...
+ *
+ * // The key pair can also be obtained from the Android Keystore any time as follows:
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
+ * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
+ * }</pre>
+ *
+ * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3>
  * The following example illustrates how to generate an AES key in the Android KeyStore system under
  * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no
  * padding.
  * <pre> {@code
  * KeyGenerator keyGenerator = KeyGenerator.getInstance(
- *         KeyProperties.KEY_ALGORITHM_AES,
- *         "AndroidKeyStore");
+ *         KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
  * keyGenerator.initialize(
  *         new KeyGenParameterSpec.Builder("key2",
  *                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
@@ -127,6 +194,29 @@
  *                 .build());
  * SecretKey key = keyGenerator.generateKey();
  *
+ * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ * cipher.init(Cipher.ENCRYPT_MODE, key);
+ * ...
+ *
+ * // The key can also be obtained from the Android Keystore any time as follows:
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * key = (SecretKey) keyStore.getKey("key2", null);
+ * }</pre>
+ *
+ * <p><h3>Example: HMAC key for generating a MAC using SHA-256</h3>
+ * This example illustrates how to generate an HMAC key in the Android KeyStore system under alias
+ * {@code key2} authorized to be used only for generating an HMAC using SHA-256.
+ * <pre> {@code
+ * KeyGenerator keyGenerator = KeyGenerator.getInstance(
+ *         KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
+ * keyGenerator.initialize(
+ *         new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build());
+ * SecretKey key = keyGenerator.generateKey();
+ * Mac mac = Mac.getInstance("HmacSHA256");
+ * mac.init(key);
+ * ...
+ *
  * // The key can also be obtained from the Android Keystore any time as follows:
  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
  * keyStore.load(null);
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index b71dc82..c984439 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -33,28 +33,36 @@
 
 /**
  * Specification of how a key or key pair is secured when imported into the
- * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
- * specifies parameters such as whether user authentication is required for using the key, what uses
- * the key is authorized for (e.g., only in {@code GCM} mode, or only for signing -- decryption not
- * permitted), the key's and validity start and end dates.
+ * <a href="{@docRoot}training/articles/keystore.html">Android Keystore system</a>. This class
+ * specifies authorized uses of the imported key, such as whether user authentication is required
+ * for using the key, what operations the key is authorized for (e.g., decryption, but not signing)
+ * and with what parameters (e.g., only with a particular padding scheme or digest), the key's and
+ * validity start and end dates. Key use authorizations expressed in this class apply only to secret
+ * keys and private keys -- public keys can be used for any supported operations.
  *
- * <p>To import a key or key pair into the Android KeyStore, create an instance of this class using
+ * <p>To import a key or key pair into the Android Keystore, create an instance of this class using
  * the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry}
  * with the key or key pair being imported.
  *
- * <p>To obtain the secret/symmetric or private key from the Android KeyStore use
+ * <p>To obtain the secret/symmetric or private key from the Android Keystore use
  * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
  * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- * To obtain the public key from the Android KeyStore use
+ * To obtain the public key from the Android Keystore use
  * {@link java.security.KeyStore#getCertificate(String)} and then
  * {@link Certificate#getPublicKey()}.
  *
- * <p>NOTE: The key material of keys stored in the Android KeyStore is not accessible.
+ * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
+ * Keystore, its private keys implement {@link java.security.interfaces.ECKey} or
+ * {@link java.security.interfaces.RSAKey} interfaces whereas its public keys implement
+ * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
+ * interfaces.
+ *
+ * <p>NOTE: The key material of keys stored in the Android Keystore is not accessible.
  *
  * <p>Instances of this class are immutable.
  *
- * <p><h3>Example: Symmetric Key</h3>
- * The following example illustrates how to import an AES key into the Android KeyStore under alias
+ * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3>
+ * This example illustrates how to import an AES key into the Android KeyStore under alias
  * {@code key1} authorized to be used only for encryption/decryption in GCM mode with no padding.
  * The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
  * <pre> {@code
@@ -71,15 +79,41 @@
  *                 .build());
  * // Key imported, obtain a reference to it.
  * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
- * // The original key can now be thrown away.
+ * // The original key can now be discarded.
+ *
+ * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ * cipher.init(Cipher.ENCRYPT_MODE, keyStoreKey);
+ * ...
  * }</pre>
  *
- * <p><h3>Example: Asymmetric Key Pair</h3>
- * The following example illustrates how to import an EC key pair into the Android KeyStore under
- * alias {@code key2} authorized to be used only for signing with SHA-256 digest and only if
- * the user has been authenticated within the last ten minutes. Both the private and the public key
- * must export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509}
- * format respectively.
+ * <p><h3>Example: HMAC key for generating MACs using SHA-512</h3>
+ * This example illustrates how to import an HMAC key into the Android KeyStore under alias
+ * {@code key1} authorized to be used only for generating MACs using SHA-512 digest. The key must
+ * export its key material via {@link Key#getEncoded()} in {@code RAW} format.
+ * <pre> {@code
+ * SecretKey key = ...; // HMAC key of algorithm "HmacSHA512".
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ *         "key1",
+ *         new KeyStore.SecretKeyEntry(key),
+ *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
+ * // Key imported, obtain a reference to it.
+ * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
+ * // The original key can now be discarded.
+ *
+ * Mac mac = Mac.getInstance("HmacSHA512");
+ * mac.init(keyStoreKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: EC key pair for signing/verification using ECDSA</h3>
+ * This example illustrates how to import an EC key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for signing with SHA-256 or SHA-512
+ * digests. The use of public key is unrestricted, thus permitting signature verification using any
+ * digests. Both the private and the public key must export their key material via
+ * {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format respectively.
  * <pre> {@code
  * PrivateKey privateKey = ...;   // EC private key
  * Certificate[] certChain = ...; // Certificate chain with the first certificate
@@ -91,7 +125,39 @@
  *         "key2",
  *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
  *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
+ *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ *                 .build());
+ * // Key pair imported, obtain a reference to it.
+ * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
+ * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
+ * // The original private key can now be discarded.
+ *
+ * Signature signature = Signature.getInstance("SHA256withECDSA");
+ * signature.initSign(keyStorePrivateKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: RSA key pair for signing/verification using PKCS#1 padding</h3>
+ * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for signing using the PKCS#1
+ * signature padding scheme with SHA-256 digest and only if the user has been authenticated within
+ * the last ten minutes. The use of public key is unrestricted, thus permitting signature
+ * verification using any padding schemes and digests, and without user authentication. Both the
+ * private and the public key must export their key material via {@link Key#getEncoded()} in
+ * {@code PKCS#8} and {@code X.509} format respectively.
+ * <pre> {@code
+ * PrivateKey privateKey = ...;   // RSA private key
+ * Certificate[] certChain = ...; // Certificate chain with the first certificate
+ *                                // containing the corresponding RSA public key.
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ *         "key2",
+ *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
+ *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
  *                 .setDigests(KeyProperties.DIGEST_SHA256)
+ *                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
  *                 // Only permit this key to be used if the user
  *                 // authenticated within the last ten minutes.
  *                 .setUserAuthenticationRequired(true)
@@ -100,7 +166,40 @@
  * // Key pair imported, obtain a reference to it.
  * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
  * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * // The original private key can now be thrown away.
+ * // The original private key can now be discarded.
+ *
+ * Signature signature = Signature.getInstance("SHA256withRSA");
+ * signature.initSign(keyStorePrivateKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: RSA key pair for encryption/decryption using PKCS#1 padding</h3>
+ * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for decryption using the PKCS#1
+ * encryption padding scheme. The use of public key is unrestricted, thus permitting encryption
+ * using any padding schemes and digests. Both the private and the public key must export their key
+ * material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format respectively.
+ * <pre> {@code
+ * PrivateKey privateKey = ...;   // RSA private key
+ * Certificate[] certChain = ...; // Certificate chain with the first certificate
+ *                                // containing the corresponding RSA public key.
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ *         "key2",
+ *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
+ *         new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+ *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+ *                 .build());
+ * // Key pair imported, obtain a reference to it.
+ * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
+ * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
+ * // The original private key can now be discarded.
+ *
+ * Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ * cipher.init(Cipher.DECRYPT_MODE, keyStorePrivateKey);
+ * ...
  * }</pre>
  */
 public final class KeyProtection implements ProtectionParameter {
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..165ef4f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index d6e2065..f95f09f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index 6be4161..860a906 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index b031273..bab268e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..0feb405
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 12ceb90..cabab0d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index dc8809e..16e1bf5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index 5178ac5..40375de 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..b7b8f98
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index 98be526..69b7449 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index eed3f54..57d243c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index 22ae09d..e53eaff 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..695e7a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
index c819545..88294c0 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
index 6075caf..09d684a 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
index bccda1b..e31ea32 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png
new file mode 100644
index 0000000..24f12d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..51482f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..46c7b18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..396ad7d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 59cf2bf..059ecee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -258,7 +258,7 @@
         mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
         mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
         mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
-        mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
+        mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime_land);
         mRecentIcon = res.getDrawable(R.drawable.ic_sysbar_recent);
         mRecentLandIcon = res.getDrawable(R.drawable.ic_sysbar_recent_land);
     }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 30680ed..fa87270 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -2905,9 +2905,9 @@
                             }
                             // Now that we've told the host, push out an update.
                             sendUpdateIntentLocked(provider, appWidgetIds);
-                            providersUpdated = true;
                         }
                     }
+                    providersUpdated = true;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index aab6374..8b0e6f2 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -283,7 +283,22 @@
                 // Don't delete accounts when updating a authenticator's
                 // package.
                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                    purgeOldGrantsAll();
+                    /* Purging data requires file io, don't block the main thread. This is probably
+                     * less than ideal because we are introducing a race condition where old grants
+                     * could be exercised until they are purged. But that race condition existed
+                     * anyway with the broadcast receiver.
+                     *
+                     * Ideally, we would completely clear the cache, purge data from the database,
+                     * and then rebuild the cache. All under the cache lock. But that change is too
+                     * large at this point.
+                     */
+                    Runnable r = new Runnable() {
+                        @Override
+                        public void run() {
+                            purgeOldGrantsAll();
+                        }
+                    };
+                    new Thread(r).start();
                 }
             }
         }, intentFilter);
@@ -329,52 +344,6 @@
         return mUserManager;
     }
 
-    /* Caller should lock mUsers */
-    private UserAccounts initUserLocked(int userId) {
-        UserAccounts accounts = mUsers.get(userId);
-        if (accounts == null) {
-            accounts = new UserAccounts(mContext, userId);
-            initializeDebugDbSizeAndCompileSqlStatementForLogging(
-                    accounts.openHelper.getWritableDatabase(), accounts);
-            mUsers.append(userId, accounts);
-            purgeOldGrants(accounts);
-            validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
-        }
-        return accounts;
-    }
-
-    private void purgeOldGrantsAll() {
-        synchronized (mUsers) {
-            for (int i = 0; i < mUsers.size(); i++) {
-                purgeOldGrants(mUsers.valueAt(i));
-            }
-        }
-    }
-
-    private void purgeOldGrants(UserAccounts accounts) {
-        synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-            final Cursor cursor = db.query(TABLE_GRANTS,
-                    new String[]{GRANTS_GRANTEE_UID},
-                    null, null, GRANTS_GRANTEE_UID, null, null);
-            try {
-                while (cursor.moveToNext()) {
-                    final int uid = cursor.getInt(0);
-                    final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
-                    if (packageExists) {
-                        continue;
-                    }
-                    Log.d(TAG, "deleting grants for UID " + uid
-                            + " because its package is no longer installed");
-                    db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?",
-                            new String[]{Integer.toString(uid)});
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
     /**
      * Validate internal set of accounts against installed authenticators for
      * given user. Clears cached authenticators before validating.
@@ -469,13 +438,49 @@
         synchronized (mUsers) {
             UserAccounts accounts = mUsers.get(userId);
             if (accounts == null) {
-                accounts = initUserLocked(userId);
+                accounts = new UserAccounts(mContext, userId);
+                initializeDebugDbSizeAndCompileSqlStatementForLogging(
+                        accounts.openHelper.getWritableDatabase(), accounts);
                 mUsers.append(userId, accounts);
+                purgeOldGrants(accounts);
+                validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
             }
             return accounts;
         }
     }
 
+    private void purgeOldGrantsAll() {
+        synchronized (mUsers) {
+            for (int i = 0; i < mUsers.size(); i++) {
+                purgeOldGrants(mUsers.valueAt(i));
+            }
+        }
+    }
+
+    private void purgeOldGrants(UserAccounts accounts) {
+        synchronized (accounts.cacheLock) {
+            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+            final Cursor cursor = db.query(TABLE_GRANTS,
+                    new String[]{GRANTS_GRANTEE_UID},
+                    null, null, GRANTS_GRANTEE_UID, null, null);
+            try {
+                while (cursor.moveToNext()) {
+                    final int uid = cursor.getInt(0);
+                    final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
+                    if (packageExists) {
+                        continue;
+                    }
+                    Log.d(TAG, "deleting grants for UID " + uid
+                            + " because its package is no longer installed");
+                    db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?",
+                            new String[]{Integer.toString(uid)});
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
     private void onUserRemoved(Intent intent) {
         int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
         if (userId < 1) return;
@@ -2510,8 +2515,9 @@
         }
         long identityToken = clearCallingIdentity();
         try {
+            UserAccounts accounts = getUserAccounts(userId);
             return getAccountsInternal(
-                    userId,
+                    accounts,
                     callingUid,
                     null,  // packageName
                     visibleAccountTypes);
@@ -2609,8 +2615,9 @@
 
         long identityToken = clearCallingIdentity();
         try {
+            UserAccounts accounts = getUserAccounts(userId);
             return getAccountsInternal(
-                    userId,
+                    accounts,
                     callingUid,
                     callingPackage,
                     visibleAccountTypes);
@@ -2620,13 +2627,11 @@
     }
 
     private Account[] getAccountsInternal(
-            int userId,
+            UserAccounts userAccounts,
             int callingUid,
             String callingPackage,
             List<String> visibleAccountTypes) {
-        UserAccounts accounts = getUserAccounts(userId);
-        synchronized (accounts.cacheLock) {
-            UserAccounts userAccounts = getUserAccounts(userId);
+        synchronized (userAccounts.cacheLock) {
             ArrayList<Account> visibleAccounts = new ArrayList<>();
             for (String visibleType : visibleAccountTypes) {
                 Account[] accountsForType = getAccountsFromCacheLocked(
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index a75cc48..6e34876 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3740,7 +3740,12 @@
         if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
 
         boolean prevIsHome = false;
-        if (tr.isOverHomeStack()) {
+
+        // If true, we should resume the home activity next if the task we are moving to the
+        // back is over the home stack. We force to false if the task we are moving to back
+        // is the home task and we don't want it resumed after moving to the back.
+        final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
+        if (canGoHome) {
             final TaskRecord nextTask = getNextTask(tr);
             if (nextTask != null) {
                 nextTask.setTaskToReturnTo(tr.getTaskToReturnTo());
@@ -3774,8 +3779,7 @@
         }
 
         final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
-        if (prevIsHome || task == tr && tr.isOverHomeStack()
-                || numTasks <= 1 && isOnHomeDisplay()) {
+        if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) {
             if (!mService.mBooting && !mService.mBooted) {
                 // Not ready yet!
                 return false;
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c705fbf..2c9d82b 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -454,6 +454,18 @@
                 "Must have " + permission + " permission.");
     }
 
+    int getEffectiveUserId(int userId) {
+        UserManager um = UserManager.get(mContext);
+        if (um != null) {
+            final long callingIdentity = Binder.clearCallingIdentity();
+            userId = um.getCredentialOwnerProfile(userId);
+            Binder.restoreCallingIdentity(callingIdentity);
+        } else {
+            Slog.e(TAG, "Unable to acquire UserManager");
+        }
+        return userId;
+    }
+
     boolean isCurrentUserOrProfile(int userId) {
         UserManager um = UserManager.get(mContext);
 
@@ -686,11 +698,15 @@
             }
             final byte [] cryptoClone = Arrays.copyOf(cryptoToken, cryptoToken.length);
 
+            // Group ID is arbitrarily set to parent profile user ID. It just represents
+            // the default fingerprints for the user.
+            final int effectiveGroupId = getEffectiveUserId(groupId);
+
             final boolean restricted = isRestricted();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    startEnrollment(token, cryptoClone, groupId, receiver, flags, restricted);
+                    startEnrollment(token, cryptoClone, effectiveGroupId, receiver, flags, restricted);
                 }
             });
         }
@@ -724,11 +740,16 @@
                 Slog.w(TAG, "Calling not granted permission to use fingerprint");
                 return;
             }
+
+            // Group ID is arbitrarily set to parent profile user ID. It just represents
+            // the default fingerprints for the user.
+            final int effectiveGroupId = getEffectiveUserId(groupId);
+
             final boolean restricted = isRestricted();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    startAuthentication(token, opId, groupId, receiver, flags, restricted);
+                    startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted);
                 }
             });
         }
@@ -751,10 +772,14 @@
                 final IFingerprintServiceReceiver receiver) {
             checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
             final boolean restricted = isRestricted();
+
+            // Group ID is arbitrarily set to parent profile user ID. It just represents
+            // the default fingerprints for the user.
+            final int effectiveGroupId = getEffectiveUserId(groupId);
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    startRemove(token, fingerId, groupId, receiver, restricted);
+                    startRemove(token, fingerId, effectiveGroupId, receiver, restricted);
                 }
             });
 
@@ -771,10 +796,15 @@
         @Override // Binder call
         public void rename(final int fingerId, final int groupId, final String name) {
             checkPermission(MANAGE_FINGERPRINT);
+
+            // Group ID is arbitrarily set to parent profile user ID. It just represents
+            // the default fingerprints for the user.
+            final int effectiveGroupId = getEffectiveUserId(groupId);
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, groupId, name);
+                    mFingerprintUtils.renameFingerprintForUser(mContext, fingerId,
+                            effectiveGroupId, name);
                 }
             });
         }
@@ -784,15 +814,19 @@
             if (!canUseFingerprint(opPackageName)) {
                 return Collections.emptyList();
             }
-            return FingerprintService.this.getEnrolledFingerprints(userId);
+            int effectiveUserId = getEffectiveUserId(userId);
+
+            return FingerprintService.this.getEnrolledFingerprints(effectiveUserId);
         }
 
         @Override // Binder call
-        public boolean hasEnrolledFingerprints(int groupId, String opPackageName) {
+        public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
             if (!canUseFingerprint(opPackageName)) {
                 return false;
             }
-            return FingerprintService.this.hasEnrolledFingerprints(groupId);
+
+            int effectiveUserId  = getEffectiveUserId(userId);
+            return FingerprintService.this.hasEnrolledFingerprints(effectiveUserId);
         }
 
         @Override // Binder call
@@ -829,8 +863,7 @@
         IFingerprintDaemon daemon = getFingerprintDaemon();
         if (daemon != null) {
             try {
-                // TODO: if this is a managed profile, use the profile parent's directory for
-                // storage.
+                userId = getEffectiveUserId(userId);
                 final File systemDir = Environment.getUserSystemDirectory(userId);
                 final File fpDir = new File(systemDir, FP_DATA_DIR);
                 if (!fpDir.exists()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6a4ae3d..21e256e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -481,12 +481,21 @@
         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
 
     /**
-     * Tracks new system packages [receiving in an OTA] that we expect to
+     * Tracks new system packages [received in an OTA] that we expect to
      * find updated user-installed versions. Keys are package name, values
      * are package location.
      */
     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
 
+    /**
+     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
+     */
+    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
+    /**
+     * Whether or not system app permissions should be promoted from install to runtime.
+     */
+    boolean mPromoteSystemApps;
+
     final Settings mSettings;
     boolean mRestoredSettings;
 
@@ -2028,6 +2037,24 @@
                 }
             }
 
+            final VersionInfo ver = mSettings.getInternalVersion();
+            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+            // when upgrading from pre-M, promote system app permissions from install to runtime
+            mPromoteSystemApps =
+                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
+
+            // save off the names of pre-existing system packages prior to scanning; we don't
+            // want to automatically grant runtime permissions for new system apps
+            if (mPromoteSystemApps) {
+                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
+                while (pkgSettingIter.hasNext()) {
+                    PackageSetting ps = pkgSettingIter.next();
+                    if (isSystemApp(ps)) {
+                        mExistingSystemPackages.add(ps.name);
+                    }
+                }
+            }
+
             // Collect vendor overlay packages.
             // (Do this before scanning any apps.)
             // For security and version matching reason, only consider
@@ -2247,8 +2274,6 @@
             // cases get permissions that the user didn't initially explicitly
             // allow...  it would be nice to have some better way to handle
             // this situation.
-            final VersionInfo ver = mSettings.getInternalVersion();
-
             int updateFlags = UPDATE_PERMISSIONS_ALL;
             if (ver.sdkVersion != mSdkVersion) {
                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
@@ -2257,6 +2282,9 @@
             }
             updatePermissionsLPw(null, null, updateFlags);
             ver.sdkVersion = mSdkVersion;
+            // clear only after permissions have been updated
+            mExistingSystemPackages.clear();
+            mPromoteSystemApps = false;
 
             // If this is the first boot, and it is a normal boot, then
             // we need to initialize the default preferred apps.
@@ -2268,7 +2296,6 @@
 
             // If this is first boot after an OTA, and a normal boot, then
             // we need to clear code cache directories.
-            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
             if (mIsUpgrade && !onlyCore) {
                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
@@ -8356,6 +8383,13 @@
                     } else if (origPermissions.hasInstallPermission(bp.name)) {
                         // For legacy apps that became modern, install becomes runtime.
                         grant = GRANT_UPGRADE;
+                    } else if (mPromoteSystemApps
+                            && isSystemApp(ps)
+                            && mExistingSystemPackages.contains(ps.name)) {
+                        // For legacy system apps, install becomes runtime.
+                        // We cannot check hasInstallPermission() for system apps since those
+                        // permissions were granted implicitly and not persisted pre-M.
+                        grant = GRANT_UPGRADE;
                     } else {
                         // For modern apps keep runtime permissions unchanged.
                         grant = GRANT_RUNTIME;
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 147efdd..c71b48f 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -465,6 +465,9 @@
             pw.println(prefix + "mLastFilteredX=" + mLastFilteredX);
             pw.println(prefix + "mLastFilteredY=" + mLastFilteredY);
             pw.println(prefix + "mLastFilteredZ=" + mLastFilteredZ);
+            final long delta = SystemClock.elapsedRealtimeNanos() - mLastFilteredTimestampNanos;
+            pw.println(prefix + "mLastFilteredTimestampNanos=" + mLastFilteredTimestampNanos
+                    + " (" + (delta * 0.000001f) + "ms ago)");
             pw.println(prefix + "mTiltHistory={last: " + getLastTiltLocked() + "}");
             pw.println(prefix + "mFlat=" + mFlat);
             pw.println(prefix + "mSwinging=" + mSwinging);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5d6df26..4db0b1e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -203,7 +203,9 @@
     }
 
     void moveStack(TaskStack stack, boolean toTop) {
-        mStacks.remove(stack);
+        if (!mStacks.remove(stack)) {
+            Slog.wtf(TAG, "moving stack that was not added: " + stack, new Throwable());
+        }
         mStacks.add(toTop ? mStacks.size() : 0, stack);
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 4545032..794b49c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -385,8 +385,6 @@
         }
 
         close();
-
-        mDisplayContent = null;
     }
 
     void resetAnimationBackgroundAnimator() {
@@ -518,6 +516,7 @@
             mDimLayer.destroySurface();
             mDimLayer = null;
         }
+        mDisplayContent = null;
     }
 
     public void dump(String prefix, PrintWriter pw) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 014527b..bd72860 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -95,6 +95,7 @@
 import dalvik.system.VMRuntime;
 
 import java.io.File;
+import java.util.Locale;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -182,6 +183,23 @@
             SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
         }
 
+        // If the system has "persist.sys.language" and friends set, replace them with
+        // "persist.sys.locale". Note that the default locale at this point is calculated
+        // using the "-Duser.locale" command line flag. That flag is usually populated by
+        // AndroidRuntime using the same set of system properties, but only the system_server
+        // and system apps are allowed to set them.
+        //
+        // NOTE: Most changes made here will need an equivalent change to
+        // core/jni/AndroidRuntime.cpp
+        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
+            final String languageTag = Locale.getDefault().toLanguageTag();
+
+            SystemProperties.set("persist.sys.locale", languageTag);
+            SystemProperties.set("persist.sys.language", "");
+            SystemProperties.set("persist.sys.country", "");
+            SystemProperties.set("persist.sys.localevar", "");
+        }
+
         // Here we go!
         Slog.i(TAG, "Entered the Android system server!");
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
@@ -1024,12 +1042,6 @@
         w.getDefaultDisplay().getMetrics(metrics);
         context.getResources().updateConfiguration(config, metrics);
 
-        // The system context's theme may be configuration-dependent.
-        final Theme systemTheme = context.getTheme();
-        if (systemTheme.getChangingConfigurations() != 0) {
-            systemTheme.rebase();
-        }
-
         try {
             // TODO: use boot phase
             mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index 2d40291..9ee9cf4 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -603,7 +603,10 @@
         @Override
         public void exit() {
             cancelOneshotTimeout();
-            mReceiveThread.halt();  // Also closes sockets.
+            if (mReceiveThread != null) {
+                mReceiveThread.halt();  // Also closes sockets.
+                mReceiveThread = null;
+            }
             clearDhcpState();
         }
 
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 303a492..80515cf 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -220,6 +220,8 @@
     private int mCdmaEriIconIndex;
     private int mCdmaEriIconMode;
 
+    private boolean mIsDataRoamingFromRegistration;
+
     /**
      * get String description of roaming type
      * @hide
@@ -297,6 +299,7 @@
         mCdmaEriIconIndex = s.mCdmaEriIconIndex;
         mCdmaEriIconMode = s.mCdmaEriIconMode;
         mIsEmergencyOnly = s.mIsEmergencyOnly;
+        mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
     }
 
     /**
@@ -324,6 +327,7 @@
         mCdmaEriIconIndex = in.readInt();
         mCdmaEriIconMode = in.readInt();
         mIsEmergencyOnly = in.readInt() != 0;
+        mIsDataRoamingFromRegistration = in.readInt() != 0;
     }
 
     public void writeToParcel(Parcel out, int flags) {
@@ -348,6 +352,7 @@
         out.writeInt(mCdmaEriIconIndex);
         out.writeInt(mCdmaEriIconMode);
         out.writeInt(mIsEmergencyOnly ? 1 : 0);
+        out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
     }
 
     public int describeContents() {
@@ -439,6 +444,26 @@
     }
 
     /**
+     * Set whether data network registration state is roaming
+     *
+     * This should only be set to the roaming value received
+     * once the data registration phase has completed.
+     * @hide
+     */
+    public void setDataRoamingFromRegistration(boolean dataRoaming) {
+        mIsDataRoamingFromRegistration = dataRoaming;
+    }
+
+    /**
+     * Get whether data network registration state is roaming
+     * @return true if registration indicates roaming, false otherwise
+     * @hide
+     */
+    public boolean getDataRoamingFromRegistration() {
+        return mIsDataRoamingFromRegistration;
+    }
+
+    /**
      * Get current data network roaming type
      * @return roaming type
      * @hide
@@ -599,7 +624,8 @@
                 + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
                 + mCdmaRoamingIndicator
                 + mCdmaDefaultRoamingIndicator
-                + (mIsEmergencyOnly ? 1 : 0));
+                + (mIsEmergencyOnly ? 1 : 0)
+                + (mIsDataRoamingFromRegistration ? 1 : 0));
     }
 
     @Override
@@ -635,7 +661,8 @@
                 && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
                 && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
                         s.mCdmaDefaultRoamingIndicator)
-                && mIsEmergencyOnly == s.mIsEmergencyOnly);
+                && mIsEmergencyOnly == s.mIsEmergencyOnly
+                && mIsDataRoamingFromRegistration == s.mIsDataRoamingFromRegistration);
     }
 
     /**
@@ -736,7 +763,8 @@
                 + " " + mSystemId
                 + " RoamInd=" + mCdmaRoamingIndicator
                 + " DefRoamInd=" + mCdmaDefaultRoamingIndicator
-                + " EmergOnly=" + mIsEmergencyOnly);
+                + " EmergOnly=" + mIsEmergencyOnly
+                + " IsDataRoamingFromRegistration=" + mIsDataRoamingFromRegistration);
     }
 
     private void setNullState(int state) {
@@ -762,6 +790,7 @@
         mCdmaEriIconIndex = -1;
         mCdmaEriIconMode = -1;
         mIsEmergencyOnly = false;
+        mIsDataRoamingFromRegistration = false;
     }
 
     public void setStateOutOfService() {
@@ -934,6 +963,7 @@
         mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
         mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
         mIsEmergencyOnly = m.getBoolean("emergencyOnly");
+        mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
     }
 
     /**
@@ -962,6 +992,7 @@
         m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
         m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
         m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
+        m.putBoolean("isDataRoamingFromRegistration", Boolean.valueOf(mIsDataRoamingFromRegistration));
     }
 
     /** @hide */
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 47258b6..baf2e2e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -97,13 +97,13 @@
      * @return the delegate or null if not found.
      */
     @Nullable
-    public T getDelegate(long native_object) {
+    public synchronized T getDelegate(long native_object) {
         if (native_object > 0) {
-            T delegate =  mDelegates.get(native_object);
+            T delegate = mDelegates.get(native_object);
 
             if (Debug.DEBUG) {
                 if (delegate == null) {
-                    System.out.println("Unknown " + mClass.getSimpleName() + " with int " +
+                    System.err.println("Unknown " + mClass.getSimpleName() + " with int " +
                             native_object);
                 }
             }
@@ -119,14 +119,18 @@
      * @param newDelegate the delegate to add
      * @return a unique native int to identify the delegate
      */
-    public long addNewDelegate(T newDelegate) {
+    public synchronized long addNewDelegate(T newDelegate) {
         long native_object = ++mDelegateCounter;
+
         mDelegates.put(native_object, newDelegate);
         assert !mJavaReferences.contains(newDelegate);
         mJavaReferences.add(newDelegate);
 
         if (Debug.DEBUG) {
-            System.out.println("New " + mClass.getSimpleName() + " with int " + native_object);
+            System.out.println(
+                    "New " + mClass.getSimpleName() + " " +
+                            "with int " +
+                            native_object);
         }
 
         return native_object;
@@ -136,7 +140,7 @@
      * Removes the main reference on the given delegate.
      * @param native_object the native integer representing the delegate.
      */
-    public void removeJavaReferenceFor(long native_object) {
+    public synchronized void removeJavaReferenceFor(long native_object) {
         T delegate = getDelegate(native_object);
 
         if (Debug.DEBUG) {