Merge "Prefer GCM to CBC or CTR in documentation." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 2094c7c..3c1612d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30625,6 +30625,7 @@
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
     field public static final java.lang.String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
     field public static final java.lang.String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
     field public static final java.lang.String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
diff --git a/api/system-current.txt b/api/system-current.txt
index 9386c50..90d5ad3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -32845,6 +32845,7 @@
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
     field public static final java.lang.String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
     field public static final java.lang.String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
     field public static final java.lang.String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index d461bca..1aee794 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -138,8 +138,8 @@
          * errors, then add them to the top switch statement
          */
         if (errorFlag < 0) {
-            throw new UnsupportedOperationException(String.format("Unknown error %d",
-                    errorFlag));
+            throw new CameraRuntimeException(CAMERA_ERROR,
+                    String.format("Unknown camera device error %d", errorFlag));
         }
     }
 
diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd
index fca958e..52cb13e 100644
--- a/docs/html/training/articles/keystore.jd
+++ b/docs/html/training/articles/keystore.jd
@@ -32,7 +32,7 @@
   keystore, they can be used for cryptographic operations with the key material
   remaining non-exportable. Moreover, it offers facilities to restrict when and
   how keys can be used, such as requiring user authentication for key use or
-  restricting encryption keys to be used only in certain block modes. See
+  restricting keys to be used only in certain cryptographic modes. See
   <a href="#SecurityFeatures">Security Features</a> section for more information.</p>
 
 <p>The Keystore system is used by the {@link
@@ -48,7 +48,8 @@
 mitigates unauthorized use of key material outside of the Android device by preventing extraction of
 the key material from application processes and from the Android device as a whole. Secondly,
 Android KeyStore mitigates unauthorized use of key material on the Android device by making apps
-specify authorized uses of their keys and then enforcing these restrictions.
+specify authorized uses of their keys and then enforcing these restrictions outside of the apps'
+processes.
 
 <h3 id="ExtractionPrevention">Extraction Prevention</h3>
 
@@ -78,14 +79,16 @@
 To mitigate unauthorized use of keys on the Android device, Android Keystore lets apps specify
 authorized uses of their keys when generating or importing the keys. Once a key is generated or
 imported, its authorizations can not be changed. Authorizations are then enforced by the Android
-Keystore whenever the key is used.
+Keystore whenever the key is used. This is an advanced security feature which is generally useful
+only if your requirements are that a compromise of your application process after key
+generation/import (but not before or during) cannot lead to unauthorized uses of the key.
 
 <p>Supported key use authorizations fall into the following categories:
 <ul>
 <li><em>cryptography</em>: authorized key algorithm, operations or purposes (encrypt, decrypt, sign,
-  verify), padding schemes, block modes, digests with which the key can be used</li>
+  verify), padding schemes, block modes, digests with which the key can be used;</li>
 <li><em>temporal validity interval</em>: interval of time during which the key is authorized for
-  use</li>
+  use;</li>
 <li><em>user authentication</em>: the key can only be used if the user has been authenticated
   recently enough. See <a href="#UserAuthentication">Requiring User Authentication For Key Use</a>.
   </li>
@@ -181,23 +184,33 @@
 <h3 id="UserAuthentication">Requiring User Authentication For Key Use</h3>
 
 <p>When generating or importing a key into the {@code AndroidKeyStore} you can specify that the key
-can only be used if user has been authenticated. The user is authenticated using a subset of their
-secure lock screen credentials. This is a security measure which makes it possible to generate
-cryptographic assertions about the user having been authenticated.
+is only authorized to be used if the user has been authenticated. The user is authenticated using a
+subset of their secure lock screen credentials (pattern/PIN/password, fingerprint).
 
-<p>When a key is configured to require user authentication, it is also configured to operate in one
-of the two modes:
+<p>This is an advanced security feature which is generally useful only if your requirements are that
+a compromise of your application process after key generation/import (but not before or during)
+cannot bypass the requirement for the user to be authenticated to use the key.
+
+<p>When a key is authorized to be used only if the user has been authenticated, it is configured to
+operate in one of the two modes:
 <ul>
-<li>User authentication is valid for a duration of time. All keys in this mode are authorized
-  for use as soon as the user unlocks the secure lock screen or confirms their secure lock screen
-  credentials using the {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
-  flow. Each key specifies for how long the authorization remains valid for that key. Such keys
-  can only be generated or imported if the secure lock screen is enabled (see {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}).
-  These keys become permanently invalidated once the secure lock screen is disabled or forcibly
-  reset (e.g. by a Device Admin).</li>
-<li>User authentication is required for every use of the key. In this mode, a specific operation
-  involving a specific key is authorized by the user. Currently, the only means of such
-  authorization is fingerprint authentication: {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
-  Such keys can only be generated or imported if at least one fingerprint is enrolled (see {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
-  These keys become permanently invalidated once all fingerprints are unenrolled.</li>
-</ul>
+<li>User authentication authorizes the use of keys for a duration of time. All keys in this mode are
+  authorized for use as soon as the user unlocks the secure lock screen or confirms their secure
+  lock screen credential using the
+  {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
+  flow. The duration for which the authorization remains valid is specific to each key, as specified
+  using {@code setUserAuthenticationValidityDurationSeconds} during key generation or import. Such
+  keys can only be generated or imported if the secure lock screen is enabled (see
+  {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}). These keys
+  become permanently invalidated once the secure lock screen is disabled (reconfigured to None,
+  Swipe or other mode which does not authenticate the user) or forcibly reset (e.g. by a Device
+  Administrator).</li>
+<li>User authentication authorizes a specific cryptographic operation associated with one key. In
+  this mode, each operation involving such a key must be individually authorized by the user.
+  Currently, the only means of such authorization is fingerprint authentication:
+  {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
+  Such keys can only be generated or imported if at least one fingerprint is enrolled (see
+  {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
+  These keys become permanently invalidated once a new fingerprint is enrolled or all fingerprints
+  are unenrolled.</li>
+</ul>
\ No newline at end of file
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 944757c..1732db9 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -19,16 +19,20 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.text.TextUtils;
 
 import java.math.BigInteger;
 import java.security.KeyPairGenerator;
+import java.security.Signature;
 import java.security.cert.Certificate;
 import java.security.spec.AlgorithmParameterSpec;
 import java.util.Date;
 
 import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
 import javax.security.auth.x500.X500Principal;
 
 /**
@@ -62,10 +66,15 @@
  * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
  * certificate will be created with an invalid signature which will not verify. Such a certificate
  * is still useful because it provides access to the public key. To generate a valid
- * signature for the certificate the key needs to be authorized for
- * {@link KeyProperties#PURPOSE_SIGN}, a suitable digest or {@link KeyProperties#DIGEST_NONE}, and
- * {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
- * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.
+ * signature for the certificate the key needs to be authorized for all of the following:
+ * <ul>
+ * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
+ * <li>operation without requiring the user to be authenticated (see
+ * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
+ * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
+ * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
+ * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
+ * </ul>
  *
  * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
  * material of the public keys is accessible.
@@ -393,28 +402,32 @@
     }
 
     /**
-     * Returns {@code true} if user authentication is required for this key to be used.
+     * Returns {@code true} if the key is authorized to be used only if the user has been
+     * authenticated.
      *
-     * <p>This restriction applies only to private key operations. Public key operations are not
-     * restricted.
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @see #getUserAuthenticationValidityDurationSeconds()
+     * @see Builder#setUserAuthenticationRequired(boolean)
      */
     public boolean isUserAuthenticationRequired() {
         return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the duration of time (seconds) for which this key can be used after the user is
-     * successfully authenticated. This has effect only if user authentication is required.
+     * Gets the duration of time (seconds) for which this key is authorized to be used after the
+     * user is successfully authenticated. This has effect only if user authentication is required
+     * (see {@link #isUserAuthenticationRequired()}).
      *
-     * <p>This restriction applies only to private key operations. Public key operations are not
-     * restricted.
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @return duration in seconds or {@code -1} if authentication is required for every use of the
-     * key.
+     *         key.
      *
      * @see #isUserAuthenticationRequired()
+     * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
      */
     public int getUserAuthenticationValidityDurationSeconds() {
         return mUserAuthenticationValidityDurationSeconds;
@@ -738,22 +751,38 @@
         }
 
         /**
-         * Sets whether user authentication is required to use this key.
+         * Sets whether this key is authorized to be used only if the user has been authenticated.
          *
-         * <p>By default, the key can be used without user authentication.
+         * <p>By default, the key is authorized to be used regardless of whether the user has been
+         * authenticated.
          *
-         * <p>When user authentication is required, the user authorizes the use of the key by
-         * authenticating to this Android device using a subset of their secure lock screen
-         * credentials. Different authentication methods are used depending on whether the every
-         * use of the key must be authenticated (as specified by
-         * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+         * <p>When user authentication is required:
+         * <ul>
+         * <li>The key can only be generated if secure lock screen is set up (see
+         * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
+         * authentication takes place for every use of the key (see
+         * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
+         * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+         * <li>The use of the key must be authorized by the user by authenticating to this Android
+         * device using a subset of their secure lock screen credentials such as
+         * password/PIN/pattern or fingerprint.
          * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
          * information</a>.
+         * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
+         * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
+         * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
+         * Additionally, if the key requires that user authentication takes place for every use of
+         * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
+         * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
+         * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
+         * </ul>
          *
-         * <p>This restriction applies only to private key operations. Public key operations are not
-         * restricted.
+         * <p>This authorization applies only to secret key and private key operations. Public key
+         * operations are not restricted.
          *
          * @see #setUserAuthenticationValidityDurationSeconds(int)
+         * @see KeyguardManager#isDeviceSecure()
+         * @see FingerprintManager#hasEnrolledFingerprints()
          */
         @NonNull
         public Builder setUserAuthenticationRequired(boolean required) {
@@ -762,15 +791,39 @@
         }
 
         /**
-         * Sets the duration of time (seconds) for which this key can be used after the user is
-         * successfully authenticated. This has effect only if user authentication is required.
+         * Sets the duration of time (seconds) for which this key is authorized to be used after the
+         * user is successfully authenticated. This has effect if the key requires user
+         * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
          *
-         * <p>By default, the user needs to authenticate for every use of the key.
+         * <p>By default, if user authentication is required, it must take place for every use of
+         * the key.
          *
-         * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
-         *        every use of the key.
+         * <p>Cryptographic operations involving keys which require user authentication to take
+         * place for every operation can only use fingerprint authentication. This is achieved by
+         * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
+         * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
+         * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+         * the cryptographic operation only if the authentication flow succeeds.
+         *
+         * <p>Cryptographic operations involving keys which are authorized to be used for a duration
+         * of time after a successful user authentication event can only use secure lock screen
+         * authentication. These cryptographic operations will throw
+         * {@link UserNotAuthenticatedException} during initialization if the user needs to be
+         * authenticated to proceed. This situation can be resolved by the user unlocking the secure
+         * lock screen of the Android or by going through the confirm credential flow initiated by
+         * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
+         * Once resolved, initializing a new cryptographic operation using this key (or any other
+         * key which is authorized to be used for a fixed duration of time after user
+         * authentication) should succeed provided the user authentication flow completed
+         * successfully.
+         *
+         * @param seconds duration in seconds or {@code -1} if user authentication must take place
+         *        for every use of the key.
          *
          * @see #setUserAuthenticationRequired(boolean)
+         * @see FingerprintManager
+         * @see FingerprintManager.CryptoObject
+         * @see KeyguardManager
          */
         @NonNull
         public Builder setUserAuthenticationValidityDurationSeconds(
diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java
index 0016e5f..785ec15 100644
--- a/keystore/java/android/security/keystore/KeyInfo.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -238,17 +238,27 @@
     }
 
     /**
-     * Returns {@code true} if user authentication is required for this key to be used.
+     * Returns {@code true} if the key is authorized to be used only if the user has been
+     * authenticated.
+     *
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @see #getUserAuthenticationValidityDurationSeconds()
+     * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)
+     * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean)
      */
     public boolean isUserAuthenticationRequired() {
         return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the duration of time (seconds) for which this key can be used after the user is
-     * successfully authenticated. This has effect only if user authentication is required.
+     * Gets the duration of time (seconds) for which this key is authorized to be used after the
+     * user is successfully authenticated. This has effect only if user authentication is required
+     * (see {@link #isUserAuthenticationRequired()}).
+     *
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @return duration in seconds or {@code -1} if authentication is required for every use of the
      *         key.
diff --git a/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
index e320c9c..9e82fc0 100644
--- a/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
+++ b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
@@ -21,12 +21,13 @@
 /**
  * Indicates that the key can no longer be used because it has been permanently invalidated.
  *
- * <p>This can currently occur only for keys that require user authentication. Such keys are
- * permanently invalidated once the secure lock screen is disabled (i.e., reconfigured to None,
- * Swipe or other mode which does not authenticate the user) or when the secure lock screen is
- * forcibly reset (e.g., by Device Admin). Additionally, keys configured to require user
- * authentication for every use of the key are also permanently invalidated once a new fingerprint
- * is enrolled or once no more fingerprints are enrolled.
+ * <p>This only occurs for keys which are authorized to be used only if the user has been
+ * authenticated. Such keys are permanently and irreversibly invalidated once the secure lock screen
+ * is disabled (i.e., reconfigured to None, Swipe or other mode which does not authenticate the
+ * user) or when the secure lock screen is forcibly reset (e.g., by Device Admin). Additionally,
+ * keys configured to require user authentication to take place for every of the keys, are also
+ * permanently invalidated once a new fingerprint is enrolled or once no more fingerprints are
+ * enrolled.
  */
 public class KeyPermanentlyInvalidatedException extends InvalidKeyException {
 
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index f11b773..b7a2a0b 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -19,13 +19,17 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
+import android.hardware.fingerprint.FingerprintManager;
 
 import java.security.Key;
+import java.security.Signature;
 import java.security.KeyStore.ProtectionParameter;
 import java.security.cert.Certificate;
 import java.util.Date;
 
 import javax.crypto.Cipher;
+import javax.crypto.Mac;
 
 /**
  * Specification of how a key or key pair is secured when imported into the
@@ -257,22 +261,32 @@
     }
 
     /**
-     * Returns {@code true} if user authentication is required for this key to be used.
+     * Returns {@code true} if the key is authorized to be used only if the user has been
+     * authenticated.
+     *
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @see #getUserAuthenticationValidityDurationSeconds()
+     * @see Builder#setUserAuthenticationRequired(boolean)
      */
     public boolean isUserAuthenticationRequired() {
         return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the duration of time (seconds) for which this key can be used after the user is
-     * successfully authenticated. This has effect only if user authentication is required.
+     * Gets the duration of time (seconds) for which this key is authorized to be used after the
+     * user is successfully authenticated. This has effect only if user authentication is required
+     * (see {@link #isUserAuthenticationRequired()}).
+     *
+     * <p>This authorization applies only to secret key and private key operations. Public key
+     * operations are not restricted.
      *
      * @return duration in seconds or {@code -1} if authentication is required for every use of the
      *         key.
      *
      * @see #isUserAuthenticationRequired()
+     * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
      */
     public int getUserAuthenticationValidityDurationSeconds() {
         return mUserAuthenticationValidityDurationSeconds;
@@ -479,19 +493,38 @@
         }
 
         /**
-         * Sets whether user authentication is required to use this key.
+         * Sets whether this key is authorized to be used only if the user has been authenticated.
          *
-         * <p>By default, the key can be used without user authentication.
+         * <p>By default, the key is authorized to be used regardless of whether the user has been
+         * authenticated.
          *
-         * <p>When user authentication is required, the user authorizes the use of the key by
-         * authenticating to this Android device using a subset of their secure lock screen
-         * credentials. Different authentication methods are used depending on whether the every
-         * use of the key must be authenticated (as specified by
-         * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+         * <p>When user authentication is required:
+         * <ul>
+         * <li>The key can only be import if secure lock screen is set up (see
+         * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
+         * authentication takes place for every use of the key (see
+         * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
+         * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
+         * <li>The use of the key must be authorized by the user by authenticating to this Android
+         * device using a subset of their secure lock screen credentials such as
+         * password/PIN/pattern or fingerprint.
          * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
          * information</a>.
+         * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
+         * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
+         * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
+         * Additionally, if the key requires that user authentication takes place for every use of
+         * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
+         * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
+         * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
+         * </ul>
+         *
+         * <p>This authorization applies only to secret key and private key operations. Public key
+         * operations are not restricted.
          *
          * @see #setUserAuthenticationValidityDurationSeconds(int)
+         * @see KeyguardManager#isDeviceSecure()
+         * @see FingerprintManager#hasEnrolledFingerprints()
          */
         @NonNull
         public Builder setUserAuthenticationRequired(boolean required) {
@@ -500,15 +533,39 @@
         }
 
         /**
-         * Sets the duration of time (seconds) for which this key can be used after the user is
-         * successfully authenticated. This has effect only if user authentication is required.
+         * Sets the duration of time (seconds) for which this key is authorized to be used after the
+         * user is successfully authenticated. This has effect if the key requires user
+         * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
          *
-         * <p>By default, the user needs to authenticate for every use of the key.
+         * <p>By default, if user authentication is required, it must take place for every use of
+         * the key.
          *
-         * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
-         *        every use of the key.
+         * <p>Cryptographic operations involving keys which require user authentication to take
+         * place for every operation can only use fingerprint authentication. This is achieved by
+         * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
+         * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
+         * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
+         * the cryptographic operation only if the authentication flow succeeds.
+         *
+         * <p>Cryptographic operations involving keys which are authorized to be used for a duration
+         * of time after a successful user authentication event can only use secure lock screen
+         * authentication. These cryptographic operations will throw
+         * {@link UserNotAuthenticatedException} during initialization if the user needs to be
+         * authenticated to proceed. This situation can be resolved by the user unlocking the secure
+         * lock screen of the Android or by going through the confirm credential flow initiated by
+         * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
+         * Once resolved, initializing a new cryptographic operation using this key (or any other
+         * key which is authorized to be used for a fixed duration of time after user
+         * authentication) should succeed provided the user authentication flow completed
+         * successfully.
+         *
+         * @param seconds duration in seconds or {@code -1} if user authentication must take place
+         *        for every use of the key.
          *
          * @see #setUserAuthenticationRequired(boolean)
+         * @see FingerprintManager
+         * @see FingerprintManager.CryptoObject
+         * @see KeyguardManager
          */
         @NonNull
         public Builder setUserAuthenticationValidityDurationSeconds(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 9e0b08b..5a4acb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -251,6 +251,9 @@
 
     @Override
     public void setSubs(List<SubscriptionInfo> subs) {
+        if (hasCorrectSubs(subs)) {
+            return;
+        }
         // Clear out all old subIds.
         mPhoneStates.clear();
         if (mMobileSignalGroup != null) {
@@ -265,6 +268,19 @@
         }
     }
 
+    private boolean hasCorrectSubs(List<SubscriptionInfo> subs) {
+        final int N = subs.size();
+        if (N != mPhoneStates.size()) {
+            return false;
+        }
+        for (int i = 0; i < N; i++) {
+            if (mPhoneStates.get(i).mSubId != subs.get(i).getSubscriptionId()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private PhoneState getOrInflateState(int subId) {
         for (PhoneState state : mPhoneStates) {
             if (state.mSubId == subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index f57575d..10c35af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -110,6 +110,8 @@
                     mInitialTouchX = x;
                     mInitialTouchY = y;
                     int expandedHeight = mPickedChild.getActualHeight();
+                    mPanel.setPanelScrimMinFraction((float) expandedHeight
+                            / mPanel.getMaxPanelHeight());
                     mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight
                             + mNotificationsTopPadding);
                     mHeadsUpManager.unpinAll();
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 5ac436a..495f0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1767,6 +1767,7 @@
         mIsExpansionFromHeadsUp = false;
         mNotificationStackScroller.setTrackingHeadsUp(false);
         mExpandingFromHeadsUp = false;
+        setPanelScrimMinFraction(0.0f);
     }
 
     private void setListening(boolean listening) {
@@ -2317,7 +2318,7 @@
         }
         x = Math.min(rightMost, Math.max(leftMost, x));
         setVerticalPanelTranslation(x -
-                (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth()/2));
+                (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth() / 2));
      }
 
     private void resetVerticalPanelPosition() {
@@ -2334,4 +2335,8 @@
         mNotificationStackScroller.setStackHeight(stackHeight);
         updateKeyguardBottomAreaAlpha();
     }
+
+    public void setPanelScrimMinFraction(float minFraction) {
+        mBar.panelScrimMinFractionChanged(minFraction);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 552a0b2..cf553ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -25,7 +25,7 @@
 
 import java.util.ArrayList;
 
-public class PanelBar extends FrameLayout {
+public abstract class PanelBar extends FrameLayout {
     public static final boolean DEBUG = false;
     public static final String TAG = PanelBar.class.getSimpleName();
     public static final void LOG(String fmt, Object... args) {
@@ -156,6 +156,8 @@
         }
     }
 
+    public abstract void panelScrimMinFractionChanged(float minFraction);
+
     /**
      * @param panel the panel which changed its expansion state
      * @param frac the fraction from the expansion in [0, 1]
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index b7e675d..dfd280a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -40,6 +40,8 @@
     PanelView mNotificationPanel;
     private final PhoneStatusBarTransitions mBarTransitions;
     private ScrimController mScrimController;
+    private float mMinFraction;
+    private float mPanelFraction;
 
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -180,8 +182,22 @@
     }
 
     @Override
+    public void panelScrimMinFractionChanged(float minFraction) {
+        if (mMinFraction != minFraction) {
+            mMinFraction = minFraction;
+            updateScrimFraction();
+        }
+    }
+
+    @Override
     public void panelExpansionChanged(PanelView panel, float frac, boolean expanded) {
         super.panelExpansionChanged(panel, frac, expanded);
-        mScrimController.setPanelExpansion(frac);
+        mPanelFraction = frac;
+        updateScrimFraction();
+    }
+
+    private void updateScrimFraction() {
+        float scrimFraction = Math.max(mPanelFraction - mMinFraction / (1.0f - mMinFraction), 0);
+        mScrimController.setPanelExpansion(scrimFraction);
     }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index bcfee30..3f78497 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -125,6 +125,10 @@
     public static final String
             KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
 
+    /** Control whether users can reach the SIM lock settings. */
+    public static final String
+            KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
+
     /** Control whether users can edit APNs in Settings. */
     public static final String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
 
@@ -328,6 +332,7 @@
         sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
         sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false);
+        sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false);
         sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false);
         sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
         sDefaults.putBoolean(KEY_PREFER_2G_BOOL, true);