Merge "Add use fingerprint app op - framework" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 0aeda1c..1ffa5aa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2733,7 +2733,6 @@
   }
 
   public class AccountManager {
-    method public boolean accountAuthenticated(android.accounts.Account);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
@@ -2757,6 +2756,7 @@
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
     method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
+    method public boolean notifyAccountAuthenticated(android.accounts.Account);
     method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
     method public deprecated android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
@@ -2794,7 +2794,7 @@
     field public static final java.lang.String KEY_ERROR_CODE = "errorCode";
     field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage";
     field public static final java.lang.String KEY_INTENT = "intent";
-    field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch";
+    field public static final java.lang.String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime";
     field public static final java.lang.String KEY_PASSWORD = "password";
     field public static final java.lang.String KEY_USERDATA = "userdata";
     field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
@@ -13918,7 +13918,9 @@
   public static class FingerprintManager.CryptoObject {
     ctor public FingerprintManager.CryptoObject(java.security.Signature);
     ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
+    ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
     method public javax.crypto.Cipher getCipher();
+    method public javax.crypto.Mac getMac();
     method public java.security.Signature getSignature();
   }
 
@@ -28169,36 +28171,102 @@
 
   public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
     method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+    method public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
     method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
-    method public void CHEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
     method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
     method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
-    method public void CSYRK(int, int, float, float, android.renderscript.Allocation, float, float, android.renderscript.Allocation);
+    method public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
     method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
     method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
     method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
     method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
     method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
-    method public void ZHEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
     method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
     method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
-    method public void ZSYRK(int, int, double, double, android.renderscript.Allocation, double, double, android.renderscript.Allocation);
+    method public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
     field public static final int CONJ_TRANSPOSE = 113; // 0x71
     field public static final int LEFT = 141; // 0x8d
@@ -28616,6 +28684,12 @@
     method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
   }
 
+  public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
+    ctor public KeyPermanentlyInvalidatedException();
+    ctor public KeyPermanentlyInvalidatedException(java.lang.String);
+    ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
+  }
+
   public abstract class KeyStoreKeyProperties {
   }
 
@@ -28696,11 +28770,6 @@
     method public boolean isCleartextTrafficPermitted();
   }
 
-  public class NewFingerprintEnrolledException extends java.security.InvalidKeyException {
-    ctor public NewFingerprintEnrolledException();
-    ctor public NewFingerprintEnrolledException(java.lang.String);
-  }
-
   public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
     ctor public UserNotAuthenticatedException();
     ctor public UserNotAuthenticatedException(java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 0b887d5..15989b3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2811,7 +2811,6 @@
   }
 
   public class AccountManager {
-    method public boolean accountAuthenticated(android.accounts.Account);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
@@ -2835,6 +2834,7 @@
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
     method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
+    method public boolean notifyAccountAuthenticated(android.accounts.Account);
     method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
     method public deprecated android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
@@ -2872,7 +2872,7 @@
     field public static final java.lang.String KEY_ERROR_CODE = "errorCode";
     field public static final java.lang.String KEY_ERROR_MESSAGE = "errorMessage";
     field public static final java.lang.String KEY_INTENT = "intent";
-    field public static final java.lang.String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH = "lastAuthenticatedTimeMillisEpoch";
+    field public static final java.lang.String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime";
     field public static final java.lang.String KEY_PASSWORD = "password";
     field public static final java.lang.String KEY_USERDATA = "userdata";
     field public static final java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
@@ -14217,7 +14217,9 @@
   public static class FingerprintManager.CryptoObject {
     ctor public FingerprintManager.CryptoObject(java.security.Signature);
     ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
+    ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
     method public javax.crypto.Cipher getCipher();
+    method public javax.crypto.Mac getMac();
     method public java.security.Signature getSignature();
   }
 
@@ -30182,36 +30184,102 @@
 
   public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
     method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+    method public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
     method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
-    method public void CHEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
     method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+    method public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
     method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
-    method public void CSYRK(int, int, float, float, android.renderscript.Allocation, float, float, android.renderscript.Allocation);
+    method public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+    method public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
     method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+    method public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
     method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
     method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+    method public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
     method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+    method public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
     method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
-    method public void ZHEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
     method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+    method public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+    method public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+    method public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
     method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
     method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
-    method public void ZSYRK(int, int, double, double, android.renderscript.Allocation, double, double, android.renderscript.Allocation);
+    method public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+    method public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+    method public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
     method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
     field public static final int CONJ_TRANSPOSE = 113; // 0x71
     field public static final int LEFT = 141; // 0x8d
@@ -30629,6 +30697,12 @@
     method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
   }
 
+  public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
+    ctor public KeyPermanentlyInvalidatedException();
+    ctor public KeyPermanentlyInvalidatedException(java.lang.String);
+    ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
+  }
+
   public abstract class KeyStoreKeyProperties {
   }
 
@@ -30709,11 +30783,6 @@
     method public boolean isCleartextTrafficPermitted();
   }
 
-  public class NewFingerprintEnrolledException extends java.security.InvalidKeyException {
-    ctor public NewFingerprintEnrolledException();
-    ctor public NewFingerprintEnrolledException(java.lang.String);
-  }
-
   public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
     ctor public UserNotAuthenticatedException();
     ctor public UserNotAuthenticatedException(java.lang.String);
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 480d171..ffa36d6 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -207,8 +207,7 @@
      * were authenticated successfully. Time is specified in milliseconds since
      * epoch.
      */
-    public static final String KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH =
-            "lastAuthenticatedTimeMillisEpoch";
+    public static final String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime";
 
     /**
      * Authenticators using 'customTokens' option will also get the UID of the
@@ -671,8 +670,8 @@
     }
 
     /**
-     * Informs the system that the account has been authenticated recently. This
-     * recency may be used by other applications to verify the account. This
+     * Notifies the system that the account has just been authenticated. This
+     * information may be used by other applications to verify the account. This
      * should be called only when the user has entered correct credentials for
      * the account.
      * <p>
@@ -685,7 +684,7 @@
      *
      * @param account The {@link Account} to be updated.
      */
-    public boolean accountAuthenticated(Account account) {
+    public boolean notifyAccountAuthenticated(Account account) {
         if (account == null)
             throw new IllegalArgumentException("account is null");
         try {
@@ -1587,7 +1586,7 @@
      * password prompt.
      * 
      * <p>Also the returning Bundle may contain {@link
-     * #KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH} indicating the last time the
+     * #KEY_LAST_AUTHENTICATED_TIME} indicating the last time the
      * credential was validated/created.
      * 
      * If an error occurred,{@link AccountManagerFuture#getResult()} throws:
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9bad9bb..2e45b79 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -114,7 +114,6 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.net.InetAddress;
-import java.security.Security;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
@@ -5338,7 +5337,7 @@
         // Set the reporter for event logging in libcore
         EventLogger.setReporter(new EventLoggingReporter());
 
-        Security.addProvider(new AndroidKeyStoreProvider());
+        AndroidKeyStoreProvider.install();
 
         // Make sure TrustedCertificateStore looks in the right place for CA certificates
         final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 4d487b16..8a3c9c8 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -227,8 +227,7 @@
     public static final int _NUM_OP = 56;
 
     /** Access to coarse location information. */
-    public static final String OPSTR_COARSE_LOCATION =
-            "android:coarse_location";
+    public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
     /** Access to fine location information. */
     public static final String OPSTR_FINE_LOCATION =
             "android:fine_location";
@@ -243,7 +242,59 @@
             = "android:get_usage_stats";
     /** Activate a VPN connection without user intervention. @hide */
     @SystemApi
-    public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
+    public static final String OPSTR_ACTIVATE_VPN
+            = "android:activate_vpn";
+    /** @hide Allows an application to read the user's contacts data. */
+    public static final String OPSTR_READ_CONTACTS
+            = "android:read_contacts";
+    /** @hide Allows an application to write to the user's contacts data. */
+    public static final String OPSTR_WRITE_CONTACTS
+            = "android:write_contacts";
+    /** @hide Allows an application to read the user's call log. */
+    public static final String OPSTR_READ_CALL_LOG
+            = "android:read_call_log";
+    /** @hide Allows an application to write to the user's call log. */
+    public static final String OPSTR_WRITE_CALL_LOG
+            = "android:write_call_log";
+    /** @hide Allows an application to read the user's calendar data. */
+    public static final String OPSTR_READ_CALENDAR
+            = "android:read_calendar";
+    /** @hide Allows an application to write to the user's calendar data. */
+    public static final String OPSTR_WRITE_CALENDAR
+            = "android:write_calendar";
+    /** @hide Allows an application to initiate a phone call. */
+    public static final String OPSTR_CALL_PHONE
+            = "android:call_phone";
+    /** @hide Allows an application to read SMS messages. */
+    public static final String OPSTR_READ_SMS
+            = "android:read_sms";
+    /** @hide Allows an application to receive SMS messages. */
+    public static final String OPSTR_RECEIVE_SMS
+            = "android:receive_sms";
+    /** @hide Allows an application to receive MMS messages. */
+    public static final String OPSTR_RECEIVE_MMS
+            = "android:receive_mms";
+    /** @hide Allows an application to receive WAP push messages. */
+    public static final String OPSTR_RECEIVE_WAP_PUSH
+            = "android:receive_wap_push";
+    /** @hide Allows an application to send SMS messages. */
+    public static final String OPSTR_SEND_SMS
+            = "android:send_sms";
+    /** @hide Allows an application to add system alert windows. */
+    public static final String OPSTR_SYSTEM_ALERT_WINDOW
+            = "android:system_alert_window";
+    /** @hide Required to be able to access the camera device. */
+    public static final String OPSTR_CAMERA
+            = "android:camera";
+    /** @hide Required to be able to access the microphone device. */
+    public static final String OPSTR_RECORD_AUDIO
+            = "android:record_audio";
+    /** @hide Required to access phone state related information. */
+    public static final String OPSTR_READ_PHONE_STATE
+            = "android:read_phone_state";
+    /** @hide Required to access phone state related information. */
+    public static final String OPSTR_ADD_VOICEMAIL
+            = "android:add_voicemail";
 
     /**
      * This maps each operation to the operation that serves as the
@@ -764,6 +815,23 @@
         sPermToOp.put(Manifest.permission.ACCESS_COARSE_LOCATION, OPSTR_COARSE_LOCATION);
         sPermToOp.put(Manifest.permission.ACCESS_FINE_LOCATION, OPSTR_FINE_LOCATION);
         sPermToOp.put(Manifest.permission.PACKAGE_USAGE_STATS, OPSTR_GET_USAGE_STATS);
+        sPermToOp.put(Manifest.permission.READ_CONTACTS, OPSTR_READ_CONTACTS);
+        sPermToOp.put(Manifest.permission.WRITE_CONTACTS, OPSTR_WRITE_CONTACTS);
+        sPermToOp.put(Manifest.permission.READ_CALL_LOG, OPSTR_READ_CALL_LOG);
+        sPermToOp.put(Manifest.permission.WRITE_CALL_LOG, OPSTR_WRITE_CALL_LOG);
+        sPermToOp.put(Manifest.permission.READ_CALENDAR, OPSTR_READ_CALENDAR);
+        sPermToOp.put(Manifest.permission.WRITE_CALENDAR, OPSTR_WRITE_CALENDAR);
+        sPermToOp.put(Manifest.permission.CALL_PHONE, OPSTR_CALL_PHONE);
+        sPermToOp.put(Manifest.permission.READ_SMS, OPSTR_READ_SMS);
+        sPermToOp.put(Manifest.permission.RECEIVE_SMS, OPSTR_RECEIVE_SMS);
+        sPermToOp.put(Manifest.permission.RECEIVE_MMS, OPSTR_RECEIVE_MMS);
+        sPermToOp.put(Manifest.permission.RECEIVE_WAP_PUSH, OPSTR_RECEIVE_WAP_PUSH);
+        sPermToOp.put(Manifest.permission.SEND_SMS, OPSTR_SEND_SMS);
+        sPermToOp.put(Manifest.permission.SYSTEM_ALERT_WINDOW, OPSTR_SYSTEM_ALERT_WINDOW);
+        sPermToOp.put(Manifest.permission.CAMERA, OPSTR_CAMERA);
+        sPermToOp.put(Manifest.permission.RECORD_AUDIO, OPSTR_RECORD_AUDIO);
+        sPermToOp.put(Manifest.permission.READ_PHONE_STATE, OPSTR_READ_PHONE_STATE);
+        sPermToOp.put(Manifest.permission.ADD_VOICEMAIL, OPSTR_ADD_VOICEMAIL);
     }
 
     private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6e511f3..90293a4 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -62,6 +62,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -1561,13 +1562,7 @@
     public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final String volumeUuid = storage.getPrimaryStorageUuid();
-        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
-            return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
-        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
-            return storage.getPrimaryPhysicalVolume();
-        } else {
-            return storage.findVolumeByUuid(volumeUuid);
-        }
+        return storage.findVolumeByQualifiedUuid(volumeUuid);
     }
 
     @Override
@@ -2055,7 +2050,8 @@
     /** {@hide} */
     private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
             Handler.Callback {
-        private static final int MSG_STATUS_CHANGED = 1;
+        private static final int MSG_CREATED = 1;
+        private static final int MSG_STATUS_CHANGED = 2;
 
         final MoveCallback mCallback;
         final Handler mHandler;
@@ -2068,23 +2064,36 @@
         @Override
         public boolean handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_STATUS_CHANGED:
+                case MSG_CREATED: {
                     final SomeArgs args = (SomeArgs) msg.obj;
-                    mCallback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
-                            (long) args.arg4);
+                    mCallback.onCreated(args.argi1, (Bundle) args.arg2);
                     args.recycle();
                     return true;
+                }
+                case MSG_STATUS_CHANGED: {
+                    final SomeArgs args = (SomeArgs) msg.obj;
+                    mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
+                    args.recycle();
+                    return true;
+                }
             }
             return false;
         }
 
         @Override
-        public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+        public void onCreated(int moveId, Bundle extras) {
             final SomeArgs args = SomeArgs.obtain();
             args.argi1 = moveId;
-            args.arg2 = moveTitle;
-            args.argi3 = status;
-            args.arg4 = estMillis;
+            args.arg2 = extras;
+            mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
+        }
+
+        @Override
+        public void onStatusChanged(int moveId, int status, long estMillis) {
+            final SomeArgs args = SomeArgs.obtain();
+            args.argi1 = moveId;
+            args.argi2 = status;
+            args.arg3 = estMillis;
             mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
         }
     }
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index f103cae..123514e 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -236,7 +236,7 @@
         private int mScanResultType = SCAN_RESULT_TYPE_FULL;
         private long mReportDelayMillis = 0;
         private int mMatchMode = MATCH_MODE_AGGRESSIVE;
-        private int mNumOfMatchesPerFilter  = MATCH_NUM_ONE_ADVERTISEMENT;
+        private int mNumOfMatchesPerFilter  = MATCH_NUM_MAX_ADVERTISEMENT;
         /**
          * Set scan mode for Bluetooth LE scan.
          *
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5eacce3..8687c6b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -252,6 +252,21 @@
     public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
 
     /**
+     * @hide Flag for {@link #bindService}: Like {@link #BIND_FOREGROUND_SERVICE},
+     * but only applies while the device is awake.
+     */
+    public static final int BIND_FOREGROUND_SERVICE_WHILE_AWAKE = 0x02000000;
+
+    /**
+     * @hide Flag for {@link #bindService}: For only the case where the binding
+     * is coming from the system, set the process state to FOREGROUND_SERVICE
+     * instead of the normal maximum of IMPORTANT_FOREGROUND.  That is, this is
+     * saying that the process shouldn't participate in the normal power reduction
+     * modes (removing network access etc).
+     */
+    public static final int BIND_FOREGROUND_SERVICE = 0x04000000;
+
+    /**
      * @hide Flag for {@link #bindService}: Treat the binding as hosting
      * an activity, an unbinding as the activity going in the background.
      * That is, when unbinding, the process when empty will go on the activity
@@ -374,24 +389,30 @@
     }
 
     /**
-     * Return a localized string from the application's package's
+     * Returns a localized string from the application's package's
      * default string table.
      *
      * @param resId Resource id for the string
+     * @return The string data associated with the resource, stripped of styled
+     *         text information.
      */
+    @NonNull
     public final String getString(@StringRes int resId) {
         return getResources().getString(resId);
     }
 
     /**
-     * Return a localized formatted string from the application's package's
+     * Returns a localized formatted string from the application's package's
      * default string table, substituting the format arguments as defined in
      * {@link java.util.Formatter} and {@link java.lang.String#format}.
      *
      * @param resId Resource id for the format string
-     * @param formatArgs The format arguments that will be used for substitution.
+     * @param formatArgs The format arguments that will be used for
+     *                   substitution.
+     * @return The string data associated with the resource, formatted and
+     *         stripped of styled text information.
      */
-
+    @NonNull
     public final String getString(@StringRes int resId, Object... formatArgs) {
         return getResources().getString(resId, formatArgs);
     }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index ae59bfc..0b24594 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -58,6 +58,7 @@
  *  {@hide}
  */
 interface IPackageManager {
+    boolean isPackageFrozen(String packageName);
     boolean isPackageAvailable(String packageName, int userId);
     PackageInfo getPackageInfo(String packageName, int flags, int userId);
     int getPackageUid(String packageName, int userId);
diff --git a/core/java/android/content/pm/IPackageMoveObserver.aidl b/core/java/android/content/pm/IPackageMoveObserver.aidl
index 155ed0b..86189fc 100644
--- a/core/java/android/content/pm/IPackageMoveObserver.aidl
+++ b/core/java/android/content/pm/IPackageMoveObserver.aidl
@@ -17,10 +17,13 @@
 
 package android.content.pm;
 
+import android.os.Bundle;
+
 /**
  * Callback for moving package resources from the Package Manager.
  * @hide
  */
 oneway interface IPackageMoveObserver {
-    void onStatusChanged(int moveId, String moveTitle, int status, long estMillis);
+    void onCreated(int moveId, in Bundle extras);
+    void onStatusChanged(int moveId, int status, long estMillis);
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a1ee7fc..7ff6ec3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4212,8 +4212,8 @@
 
     /** {@hide} */
     public static abstract class MoveCallback {
-        public abstract void onStatusChanged(int moveId, String moveTitle, int status,
-                long estMillis);
+        public void onCreated(int moveId, Bundle extras) {}
+        public abstract void onStatusChanged(int moveId, int status, long estMillis);
     }
 
     /** {@hide} */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index fed9261..9596c42 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4315,9 +4315,6 @@
         // Additional data supplied by callers.
         public Object mExtras;
 
-        // Whether an operation is currently pending on this package
-        public boolean mOperationPending;
-
         // Applications hardware preferences
         public ArrayList<ConfigurationInfo> configPreferences = null;
 
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index fdafb04..14bfac5 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -271,7 +271,7 @@
             final TypedArray a = Resources.obtainAttributes(r, theme, attrs,
                     R.styleable.ColorStateListItem);
             final int[] themeAttrs = a.extractThemeAttrs();
-            final int baseColor = a.getColor(R.styleable.ColorStateListItem_color, 0);
+            final int baseColor = a.getColor(R.styleable.ColorStateListItem_color, Color.MAGENTA);
             final float alphaMod = a.getFloat(R.styleable.ColorStateListItem_alpha, 1.0f);
 
             changingConfigurations |= a.getChangingConfigurations();
@@ -296,7 +296,9 @@
             }
             stateSpec = StateSet.trimStateSet(stateSpec, j);
 
-            // Apply alpha modulation.
+            // Apply alpha modulation. If we couldn't resolve the color or
+            // alpha yet, the default values leave us enough information to
+            // modulate again during applyTheme().
             final int color = modulateColorAlpha(baseColor, alphaMod);
             if (listSize == 0 || stateSpec.length == 0) {
                 defaultColor = color;
@@ -365,14 +367,31 @@
             if (themeAttrsList[i] != null) {
                 final TypedArray a = t.resolveAttributes(themeAttrsList[i],
                         R.styleable.ColorStateListItem);
+
+                final float defaultAlphaMod;
+                if (themeAttrsList[i][R.styleable.ColorStateListItem_color] != 0) {
+                    // If the base color hasn't been resolved yet, the current
+                    // color's alpha channel is either full-opacity (if we
+                    // haven't resolved the alpha modulation yet) or
+                    // pre-modulated. Either is okay as a default value.
+                    defaultAlphaMod = Color.alpha(mColors[i]) / 255.0f;
+                } else {
+                    // Otherwise, the only correct default value is 1. Even if
+                    // nothing is resolved during this call, we can apply this
+                    // multiple times without losing of information.
+                    defaultAlphaMod = 1.0f;
+                }
+
                 final int baseColor = a.getColor(
                         R.styleable.ColorStateListItem_color, mColors[i]);
                 final float alphaMod = a.getFloat(
-                        R.styleable.ColorStateListItem_alpha, 1.0f);
-
+                        R.styleable.ColorStateListItem_alpha, defaultAlphaMod);
                 mColors[i] = modulateColorAlpha(baseColor, alphaMod);
+
+                // Account for any configuration changes.
                 mChangingConfigurations |= a.getChangingConfigurations();
 
+                // Extract the theme attributes, if any.
                 themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]);
                 if (themeAttrsList[i] != null) {
                     hasUnresolvedAttrs = true;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 334d180..6e77e33 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -393,10 +393,11 @@
      * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
      *
      * @return String The string data associated with the resource,
-     * stripped of styled text information.
+     *         stripped of styled text information.
      */
+    @NonNull
     public String getString(@StringRes int id) throws NotFoundException {
-        CharSequence res = getText(id);
+        final CharSequence res = getText(id);
         if (res != null) {
             return res.toString();
         }
@@ -421,11 +422,11 @@
      * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
      *
      * @return String The string data associated with the resource,
-     * stripped of styled text information.
+     *         stripped of styled text information.
      */
-    public String getString(@StringRes int id, Object... formatArgs)
-            throws NotFoundException {
-        String raw = getString(id);
+    @NonNull
+    public String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
+        final String raw = getString(id);
         return String.format(mConfiguration.locale, raw, formatArgs);
     }
 
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 7abe2df..779448b 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -42,6 +42,7 @@
 import java.util.List;
 
 import javax.crypto.Cipher;
+import javax.crypto.Mac;
 
 /**
  * A class that coordinates access to the fingerprint hardware.
@@ -195,18 +196,26 @@
 
     /**
      * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
-     * framework supports {@link Signature} and {@link Cipher} objects.
+     * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
      */
     public static class CryptoObject {
 
-        public CryptoObject(Signature signature) {
+        public CryptoObject(@NonNull Signature signature) {
             mSignature = signature;
             mCipher = null;
+            mMac = null;
         }
 
-        public CryptoObject(Cipher cipher) {
+        public CryptoObject(@NonNull Cipher cipher) {
             mCipher = cipher;
             mSignature = null;
+            mMac = null;
+        }
+
+        public CryptoObject(@NonNull Mac mac) {
+            mMac = mac;
+            mCipher = null;
+            mSignature = null;
         }
 
         /**
@@ -222,6 +231,12 @@
         public Cipher getCipher() { return mCipher; }
 
         /**
+         * Get {@link Mac} object.
+         * @return {@link Mac} object or null if this doesn't contain one.
+         */
+        public Mac getMac() { return mMac; }
+
+        /**
          * @hide
          * @return the opId associated with this object or 0 if none
          */
@@ -230,12 +245,15 @@
                 return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mSignature);
             } else if (mCipher != null) {
                 return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCipher);
+            } else if (mMac != null) {
+                return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mMac);
             }
             return 0;
         }
 
         private final Signature mSignature;
         private final Cipher mCipher;
+        private final Mac mMac;
     };
 
     /**
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index f305b2a..4a8dfbc 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1657,7 +1657,7 @@
     /**
      * Searches the query string for the first value with the given key.
      *
-     * <p><strong>Warning:</strong> Prior to Ice Cream Sandwich, this decoded
+     * <p><strong>Warning:</strong> Prior to Jelly Bean, this decoded
      * the '+' character as '+' rather than ' '.
      *
      * @param key which will be encoded
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 2eb97f1..e3e16eb 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -758,7 +758,6 @@
      * @hide
      */
     public static File maybeTranslateEmulatedPathToInternal(File path) {
-        // TODO: bring back this optimization
-        return path;
+        return StorageManager.maybeTranslateEmulatedPathToInternal(path);
     }
 }
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 931cd3e..021e5e4 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -390,7 +390,7 @@
      * attacks.
      */
     public static boolean contains(File dir, File file) {
-        if (file == null) return false;
+        if (dir == null || file == null) return false;
 
         String dirPath = dir.getAbsolutePath();
         String filePath = file.getAbsolutePath();
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 355ec8c..009649f 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -634,6 +634,9 @@
             if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
                 argsForZygote.add("--enable-jit");
             }
+            if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) {
+                argsForZygote.add("--generate-cfi");
+            }
             if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                 argsForZygote.add("--enable-assert");
             }
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
index 2d13e49..c958fb0 100644
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ b/core/java/android/os/storage/IMountServiceListener.java
@@ -91,10 +91,17 @@
                     reply.writeNoException();
                     return true;
                 }
-                case TRANSACTION_onVolumeMetadataChanged: {
+                case TRANSACTION_onVolumeRecordChanged: {
+                    data.enforceInterface(DESCRIPTOR);
+                    final VolumeRecord rec = (VolumeRecord) data.readParcelable(null);
+                    onVolumeRecordChanged(rec);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_onVolumeForgotten: {
                     data.enforceInterface(DESCRIPTOR);
                     final String fsUuid = data.readString();
-                    onVolumeMetadataChanged(fsUuid);
+                    onVolumeForgotten(fsUuid);
                     reply.writeNoException();
                     return true;
                 }
@@ -192,13 +199,29 @@
             }
 
             @Override
-            public void onVolumeMetadataChanged(String fsUuid) throws RemoteException {
+            public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeParcelable(rec, 0);
+                    mRemote.transact(Stub.TRANSACTION_onVolumeRecordChanged, _data, _reply,
+                            android.os.IBinder.FLAG_ONEWAY);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public void onVolumeForgotten(String fsUuid) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
                     _data.writeString(fsUuid);
-                    mRemote.transact(Stub.TRANSACTION_onVolumeMetadataChanged, _data, _reply,
+                    mRemote.transact(Stub.TRANSACTION_onVolumeForgotten, _data, _reply,
                             android.os.IBinder.FLAG_ONEWAY);
                     _reply.readException();
                 } finally {
@@ -228,8 +251,9 @@
         static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
         static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1);
         static final int TRANSACTION_onVolumeStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 2);
-        static final int TRANSACTION_onVolumeMetadataChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
-        static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 4);
+        static final int TRANSACTION_onVolumeRecordChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
+        static final int TRANSACTION_onVolumeForgotten = (IBinder.FIRST_CALL_TRANSACTION + 4);
+        static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 5);
     }
 
     /**
@@ -252,8 +276,8 @@
 
     public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
             throws RemoteException;
-
-    public void onVolumeMetadataChanged(String fsUuid) throws RemoteException;
+    public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException;
+    public void onVolumeForgotten(String fsUuid) throws RemoteException;
 
     public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java
index 536aca9..214c60d 100644
--- a/core/java/android/os/storage/StorageEventListener.java
+++ b/core/java/android/os/storage/StorageEventListener.java
@@ -41,7 +41,10 @@
     public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
     }
 
-    public void onVolumeMetadataChanged(String fsUuid) {
+    public void onVolumeRecordChanged(VolumeRecord rec) {
+    }
+
+    public void onVolumeForgotten(String fsUuid) {
     }
 
     public void onDiskScanned(DiskInfo disk, int volumeCount) {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 29da4f1..50e7d1c4 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -93,8 +93,9 @@
             Handler.Callback {
         private static final int MSG_STORAGE_STATE_CHANGED = 1;
         private static final int MSG_VOLUME_STATE_CHANGED = 2;
-        private static final int MSG_VOLUME_METADATA_CHANGED = 3;
-        private static final int MSG_DISK_SCANNED = 4;
+        private static final int MSG_VOLUME_RECORD_CHANGED = 3;
+        private static final int MSG_VOLUME_FORGOTTEN = 4;
+        private static final int MSG_DISK_SCANNED = 5;
 
         final StorageEventListener mCallback;
         final Handler mHandler;
@@ -117,8 +118,12 @@
                     mCallback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
                     args.recycle();
                     return true;
-                case MSG_VOLUME_METADATA_CHANGED:
-                    mCallback.onVolumeMetadataChanged((String) args.arg1);
+                case MSG_VOLUME_RECORD_CHANGED:
+                    mCallback.onVolumeRecordChanged((VolumeRecord) args.arg1);
+                    args.recycle();
+                    return true;
+                case MSG_VOLUME_FORGOTTEN:
+                    mCallback.onVolumeForgotten((String) args.arg1);
                     args.recycle();
                     return true;
                 case MSG_DISK_SCANNED:
@@ -154,10 +159,17 @@
         }
 
         @Override
-        public void onVolumeMetadataChanged(String fsUuid) {
+        public void onVolumeRecordChanged(VolumeRecord rec) {
+            final SomeArgs args = SomeArgs.obtain();
+            args.arg1 = rec;
+            mHandler.obtainMessage(MSG_VOLUME_RECORD_CHANGED, args).sendToTarget();
+        }
+
+        @Override
+        public void onVolumeForgotten(String fsUuid) {
             final SomeArgs args = SomeArgs.obtain();
             args.arg1 = fsUuid;
-            mHandler.obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
+            mHandler.obtainMessage(MSG_VOLUME_FORGOTTEN, args).sendToTarget();
         }
 
         @Override
@@ -246,8 +258,9 @@
     }
 
     /** {@hide} */
+    @Deprecated
     public static StorageManager from(Context context) {
-        return (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+        return context.getSystemService(StorageManager.class);
     }
 
     /**
@@ -536,6 +549,17 @@
     }
 
     /** {@hide} */
+    public @Nullable VolumeInfo findVolumeByQualifiedUuid(String volumeUuid) {
+        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
+            return findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
+        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
+            return getPrimaryPhysicalVolume();
+        } else {
+            return findVolumeByUuid(volumeUuid);
+        }
+    }
+
+    /** {@hide} */
     public @NonNull List<VolumeInfo> getVolumes() {
         try {
             return Arrays.asList(mMountService.getVolumes(0));
@@ -555,6 +579,8 @@
 
     /** {@hide} */
     public @Nullable String getBestVolumeDescription(VolumeInfo vol) {
+        if (vol == null) return null;
+
         // Nickname always takes precedence when defined
         if (!TextUtils.isEmpty(vol.fsUuid)) {
             final VolumeRecord rec = findRecordByUuid(vol.fsUuid);
@@ -861,6 +887,27 @@
                 DEFAULT_FULL_THRESHOLD_BYTES);
     }
 
+    /** {@hide} */
+    public static File maybeTranslateEmulatedPathToInternal(File path) {
+        final IMountService mountService = IMountService.Stub.asInterface(
+                ServiceManager.getService("mount"));
+        try {
+            final VolumeInfo[] vols = mountService.getVolumes(0);
+            for (VolumeInfo vol : vols) {
+                if ((vol.getType() == VolumeInfo.TYPE_EMULATED
+                        || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
+                    final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
+                            vol.getInternalPath(), path);
+                    if (internalPath != null) {
+                        return internalPath;
+                    }
+                }
+            }
+        } catch (RemoteException ignored) {
+        }
+        return path;
+    }
+
     /// Consts to match the password types in cryptfs.h
     /** @hide */
     public static final int CRYPT_TYPE_PASSWORD = 0;
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index fd10cae..2622ee0 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -129,6 +129,7 @@
     public String fsUuid;
     public String fsLabel;
     public String path;
+    public String internalPath;
 
     /** Framework state */
     public final int mtpIndex;
@@ -155,6 +156,7 @@
         fsUuid = parcel.readString();
         fsLabel = parcel.readString();
         path = parcel.readString();
+        internalPath = parcel.readString();
         mtpIndex = parcel.readInt();
     }
 
@@ -248,7 +250,11 @@
     }
 
     public File getPath() {
-        return new File(path);
+        return (path != null) ? new File(path) : null;
+    }
+
+    public File getInternalPath() {
+        return (internalPath != null) ? new File(internalPath) : null;
     }
 
     public File getPathForUser(int userId) {
@@ -335,14 +341,11 @@
         final Uri uri;
         if (type == VolumeInfo.TYPE_PUBLIC) {
             uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid);
-        } else if (VolumeInfo.ID_EMULATED_INTERNAL.equals(id)) {
+        } else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) {
             uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
                     DOCUMENT_ROOT_PRIMARY_EMULATED);
-        } else if (type == VolumeInfo.TYPE_EMULATED) {
-            // TODO: build intent once supported
-            uri = null;
         } else {
-            throw new IllegalArgumentException();
+            return null;
         }
 
         final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
@@ -372,6 +375,7 @@
         pw.printPair("fsLabel", fsLabel);
         pw.println();
         pw.printPair("path", path);
+        pw.printPair("internalPath", internalPath);
         pw.printPair("mtpIndex", mtpIndex);
         pw.decreaseIndent();
         pw.println();
@@ -437,6 +441,7 @@
         parcel.writeString(fsUuid);
         parcel.writeString(fsLabel);
         parcel.writeString(path);
+        parcel.writeString(internalPath);
         parcel.writeInt(mtpIndex);
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 00c851b..293cf6f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -919,6 +919,15 @@
             = "android.settings.ZEN_MODE_SCHEDULE_RULE_SETTINGS";
 
     /**
+     * Activity Action: Show Zen Mode event rule configuration settings.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ZEN_MODE_EVENT_RULE_SETTINGS
+            = "android.settings.ZEN_MODE_EVENT_RULE_SETTINGS";
+
+    /**
      * Activity Action: Show Zen Mode external rule configuration settings.
      *
      * @hide
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index 458f153..03248e5 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -87,6 +87,28 @@
         return result;
     }
 
+    public Long getLong(int tag) {
+        if (hwEnforced.containsTag(tag)) {
+            return hwEnforced.getLong(tag, -1);
+        } else if (swEnforced.containsTag(tag)) {
+            return swEnforced.getLong(tag, -1);
+        } else {
+            return null;
+        }
+    }
+
+    public long getLong(int tag, long defaultValue) {
+        Long result = getLong(tag);
+        return (result != null) ? result : defaultValue;
+    }
+
+    public List<Long> getLongs(int tag) {
+        List<Long> result = new ArrayList<Long>();
+        result.addAll(hwEnforced.getLongs(tag));
+        result.addAll(swEnforced.getLongs(tag));
+        return result;
+    }
+
     public Date getDate(int tag) {
         Date result = hwEnforced.getDate(tag, null);
         if (result == null) {
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 40baf9c..d8834fe 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -194,6 +194,9 @@
     public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50;
     public static final int KM_ERROR_MISSING_NONCE = -51;
     public static final int KM_ERROR_INVALID_NONCE = -52;
+    public static final int KM_ERROR_UNSUPPORTED_CHUNK_LENGTH = -53;
+    public static final int KM_ERROR_RESCOPABLE_KEY_NOT_USABLE = -54;
+    public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index dc8f3ea..f09f4d2 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -95,7 +95,7 @@
     private static final String MANUAL_TAG = "manual";
     private static final String AUTOMATIC_TAG = "automatic";
 
-    private static final String RULE_ATT_ID = "id";
+    private static final String RULE_ATT_ID = "ruleId";
     private static final String RULE_ATT_ENABLED = "enabled";
     private static final String RULE_ATT_SNOOZING = "snoozing";
     private static final String RULE_ATT_NAME = "name";
@@ -279,6 +279,15 @@
         }
     }
 
+    private static long tryParseLong(String value, long defValue) {
+        if (TextUtils.isEmpty(value)) return defValue;
+        try {
+            return Long.valueOf(value);
+        } catch (NumberFormatException e) {
+            return defValue;
+        }
+    }
+
     public static ZenModeConfig readXml(XmlPullParser parser, Migration migration)
             throws XmlPullParserException, IOException {
         int type = parser.getEventType();
@@ -367,7 +376,7 @@
         rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID);
         rt.component = safeComponentName(parser, RULE_ATT_COMPONENT);
         rt.condition = readConditionXml(parser);
-        return rt.condition != null || !conditionRequired ? rt : null;
+        return rt;
     }
 
     public static void writeRuleXml(ZenRule rule, XmlSerializer out) throws IOException {
@@ -568,10 +577,12 @@
                 Condition.FLAG_RELEVANT_NOW);
     }
 
-    // For built-in conditions
+    // ==== Built-in system conditions ====
+
     public static final String SYSTEM_AUTHORITY = "android";
 
-    // Built-in countdown conditions, e.g. condition://android/countdown/1399917958951
+    // ==== Built-in system condition: countdown ====
+
     public static final String COUNTDOWN_PATH = "countdown";
 
     public static Uri toCountdownConditionId(long time) {
@@ -598,9 +609,43 @@
         return tryParseCountdownConditionId(conditionId) != 0;
     }
 
-    // built-in schedule conditions
+    // ==== Built-in system condition: schedule ====
+
     public static final String SCHEDULE_PATH = "schedule";
 
+    public static Uri toScheduleConditionId(ScheduleInfo schedule) {
+        return new Uri.Builder().scheme(Condition.SCHEME)
+                .authority(SYSTEM_AUTHORITY)
+                .appendPath(SCHEDULE_PATH)
+                .appendQueryParameter("days", toDayList(schedule.days))
+                .appendQueryParameter("start", schedule.startHour + "." + schedule.startMinute)
+                .appendQueryParameter("end", schedule.endHour + "." + schedule.endMinute)
+                .build();
+    }
+
+    public static boolean isValidScheduleConditionId(Uri conditionId) {
+        return tryParseScheduleConditionId(conditionId) != null;
+    }
+
+    public static ScheduleInfo tryParseScheduleConditionId(Uri conditionId) {
+        final boolean isSchedule =  conditionId != null
+                && conditionId.getScheme().equals(Condition.SCHEME)
+                && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
+                && conditionId.getPathSegments().size() == 1
+                && conditionId.getPathSegments().get(0).equals(ZenModeConfig.SCHEDULE_PATH);
+        if (!isSchedule) return null;
+        final int[] start = tryParseHourAndMinute(conditionId.getQueryParameter("start"));
+        final int[] end = tryParseHourAndMinute(conditionId.getQueryParameter("end"));
+        if (start == null || end == null) return null;
+        final ScheduleInfo rt = new ScheduleInfo();
+        rt.days = tryParseDayList(conditionId.getQueryParameter("days"), "\\.");
+        rt.startHour = start[0];
+        rt.startMinute = start[1];
+        rt.endHour = end[0];
+        rt.endMinute = end[1];
+        return rt;
+    }
+
     public static class ScheduleInfo {
         public int[] days;
         public int startHour;
@@ -638,39 +683,76 @@
         }
     }
 
-    public static Uri toScheduleConditionId(ScheduleInfo schedule) {
+    // ==== Built-in system condition: event ====
+
+    public static final String EVENT_PATH = "event";
+
+    public static Uri toEventConditionId(EventInfo event) {
         return new Uri.Builder().scheme(Condition.SCHEME)
                 .authority(SYSTEM_AUTHORITY)
-                .appendPath(SCHEDULE_PATH)
-                .appendQueryParameter("days", toDayList(schedule.days))
-                .appendQueryParameter("start", schedule.startHour + "." + schedule.startMinute)
-                .appendQueryParameter("end", schedule.endHour + "." + schedule.endMinute)
+                .appendPath(EVENT_PATH)
+                .appendQueryParameter("calendar", Long.toString(event.calendar))
+                .appendQueryParameter("attendance", Integer.toString(event.attendance))
+                .appendQueryParameter("reply", Integer.toString(event.reply))
                 .build();
     }
 
-    public static boolean isValidScheduleConditionId(Uri conditionId) {
-        return tryParseScheduleConditionId(conditionId) != null;
+    public static boolean isValidEventConditionId(Uri conditionId) {
+        return tryParseEventConditionId(conditionId) != null;
     }
 
-    public static ScheduleInfo tryParseScheduleConditionId(Uri conditionId) {
-        final boolean isSchedule =  conditionId != null
+    public static EventInfo tryParseEventConditionId(Uri conditionId) {
+        final boolean isEvent = conditionId != null
                 && conditionId.getScheme().equals(Condition.SCHEME)
                 && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
                 && conditionId.getPathSegments().size() == 1
-                && conditionId.getPathSegments().get(0).equals(ZenModeConfig.SCHEDULE_PATH);
-        if (!isSchedule) return null;
-        final int[] start = tryParseHourAndMinute(conditionId.getQueryParameter("start"));
-        final int[] end = tryParseHourAndMinute(conditionId.getQueryParameter("end"));
-        if (start == null || end == null) return null;
-        final ScheduleInfo rt = new ScheduleInfo();
-        rt.days = tryParseDayList(conditionId.getQueryParameter("days"), "\\.");
-        rt.startHour = start[0];
-        rt.startMinute = start[1];
-        rt.endHour = end[0];
-        rt.endMinute = end[1];
+                && conditionId.getPathSegments().get(0).equals(EVENT_PATH);
+        if (!isEvent) return null;
+        final EventInfo rt = new EventInfo();
+        rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), 0L);
+        rt.attendance = tryParseInt(conditionId.getQueryParameter("attendance"), 0);
+        rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0);
         return rt;
     }
 
+    public static class EventInfo {
+        public static final int ATTENDANCE_REQUIRED_OR_OPTIONAL = 0;
+        public static final int ATTENDANCE_REQUIRED = 1;
+        public static final int ATTENDANCE_OPTIONAL = 2;
+
+        public static final int REPLY_ANY = 0;
+        public static final int REPLY_ANY_EXCEPT_NO = 1;
+        public static final int REPLY_YES = 2;
+
+        public long calendar;  // CalendarContract.Calendars._ID, or 0 for any
+        public int attendance;
+        public int reply;
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof EventInfo)) return false;
+            final EventInfo other = (EventInfo) o;
+            return calendar == other.calendar
+                    && attendance == other.attendance
+                    && reply == other.reply;
+        }
+
+        public EventInfo copy() {
+            final EventInfo rt = new EventInfo();
+            rt.calendar = calendar;
+            rt.attendance = attendance;
+            rt.reply = reply;
+            return rt;
+        }
+    }
+
+    // ==== End built-in system conditions ====
+
     private static int[] tryParseHourAndMinute(String value) {
         if (TextUtils.isEmpty(value)) return null;
         final int i = value.indexOf('.');
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index bbf120a..088adbb 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -18,6 +18,7 @@
 
 import static android.widget.SuggestionsAdapter.getColumnString;
 
+import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -120,6 +121,8 @@
     private final Intent mVoiceWebSearchIntent;
     private final Intent mVoiceAppSearchIntent;
 
+    private final CharSequence mDefaultQueryHint;
+
     private OnQueryTextListener mOnQueryChangeListener;
     private OnCloseListener mOnCloseListener;
     private OnFocusChangeListener mOnQueryTextFocusChangeListener;
@@ -329,10 +332,8 @@
             setMaxWidth(maxWidth);
         }
 
-        final CharSequence queryHint = a.getText(R.styleable.SearchView_queryHint);
-        if (!TextUtils.isEmpty(queryHint)) {
-            setQueryHint(queryHint);
-        }
+        mDefaultQueryHint = a.getText(R.styleable.SearchView_defaultQueryHint);
+        mQueryHint = a.getText(R.styleable.SearchView_queryHint);
 
         final int imeOptions = a.getInt(R.styleable.SearchView_imeOptions, -1);
         if (imeOptions != -1) {
@@ -570,36 +571,48 @@
     }
 
     /**
-     * Sets the hint text to display in the query text field. This overrides any hint specified
-     * in the SearchableInfo.
+     * Sets the hint text to display in the query text field. This overrides
+     * any hint specified in the {@link SearchableInfo}.
+     * <p>
+     * This value may be specified as an empty string to prevent any query hint
+     * from being displayed.
      *
-     * @param hint the hint text to display
-     *
+     * @param hint the hint text to display or {@code null} to clear
      * @attr ref android.R.styleable#SearchView_queryHint
      */
-    public void setQueryHint(CharSequence hint) {
+    public void setQueryHint(@Nullable CharSequence hint) {
         mQueryHint = hint;
         updateQueryHint();
     }
 
     /**
-     * Gets the hint text to display in the query text field.
-     * @return the query hint text, if specified, null otherwise.
+     * Returns the hint text that will be displayed in the query text field.
+     * <p>
+     * The displayed query hint is chosen in the following order:
+     * <ol>
+     * <li>Non-null value set with {@link #setQueryHint(CharSequence)}
+     * <li>Value specified in XML using
+     *     {@link android.R.styleable#SearchView_queryHint android:queryHint}
+     * <li>Valid string resource ID exposed by the {@link SearchableInfo} via
+     *     {@link SearchableInfo#getHintId()}
+     * <li>Default hint provided by the theme against which the view was
+     *     inflated
+     * </ol>
      *
+     * @return the displayed query hint text, or {@code null} if none set
      * @attr ref android.R.styleable#SearchView_queryHint
      */
+    @Nullable
     public CharSequence getQueryHint() {
+        final CharSequence hint;
         if (mQueryHint != null) {
-            return mQueryHint;
-        } else if (mSearchable != null) {
-            CharSequence hint = null;
-            int hintId = mSearchable.getHintId();
-            if (hintId != 0) {
-                hint = getContext().getString(hintId);
-            }
-            return hint;
+            hint = mQueryHint;
+        } else if (mSearchable != null && mSearchable.getHintId() != 0) {
+            hint = getContext().getText(mSearchable.getHintId());
+        } else {
+            hint = mDefaultQueryHint;
         }
-        return null;
+        return hint;
     }
 
     /**
@@ -1113,20 +1126,8 @@
     }
 
     private void updateQueryHint() {
-        if (mQueryHint != null) {
-            mSearchSrcTextView.setHint(getDecoratedHint(mQueryHint));
-        } else if (mSearchable != null) {
-            CharSequence hint = null;
-            int hintId = mSearchable.getHintId();
-            if (hintId != 0) {
-                hint = getContext().getString(hintId);
-            }
-            if (hint != null) {
-                mSearchSrcTextView.setHint(getDecoratedHint(hint));
-            }
-        } else {
-            mSearchSrcTextView.setHint(getDecoratedHint(""));
-        }
+        final CharSequence hint = getQueryHint();
+        mSearchSrcTextView.setHint(getDecoratedHint(hint == null ? "" : hint));
     }
 
     /**
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 092c148..3f96174 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -26,11 +26,12 @@
  */
 public class MetricsLogger implements MetricsConstants {
     // These constants are temporary, they should migrate to MetricsConstants.
-    // next value is 146;
+    // next value is 148;
 
     public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
     public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
     public static final int ACTION_BAN_APP_NOTES = 146;
+    public static final int NOTIFICATION_ZEN_MODE_EVENT_RULE = 147;
 
     public static void visible(Context context, int category) throws IllegalArgumentException {
         if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java
index 1a7fa0b..8ed5b5a 100644
--- a/core/java/com/android/internal/midi/MidiFramer.java
+++ b/core/java/com/android/internal/midi/MidiFramer.java
@@ -78,7 +78,7 @@
                         // Log.i(TAG, "SysEx End");
                         if (mInSysEx) {
                             mReceiver.sendWithTimestamp(data, sysExStartOffset,
-                                offset - sysExStartOffset, timestamp);
+                                offset - sysExStartOffset + 1, timestamp);
                             mInSysEx = false;
                             sysExStartOffset = -1;
                         }
@@ -90,6 +90,11 @@
                     }
                 } else { // real-time?
                     // Single byte message interleaved with other data.
+                    if (mInSysEx) {
+                        mReceiver.sendWithTimestamp(data, sysExStartOffset,
+                                offset - sysExStartOffset, timestamp);
+                        sysExStartOffset = offset + 1;
+                    }
                     mReceiver.sendWithTimestamp(data, offset, 1, timestamp);
                 }
             } else { // data byte
@@ -110,7 +115,7 @@
         }
 
         // send any accumulatedSysEx data
-        if (sysExStartOffset >= 0) {
+        if (sysExStartOffset >= 0 && sysExStartOffset < offset) {
             mReceiver.sendWithTimestamp(data, sysExStartOffset,
                     offset - sysExStartOffset, timestamp);
         }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 75b6446..1e7ee5a 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -40,6 +40,8 @@
     public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
     /** enable the JIT compiler */
     public static final int DEBUG_ENABLE_JIT         = 1 << 5;
+    /** Force generation of CFI code */
+    public static final int DEBUG_GENERATE_CFI       = 1 << 6;
 
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = 0;
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9106ccd..969d236 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -321,7 +321,7 @@
 
         /**
          * From --enable-debugger, --enable-checkjni, --enable-assert,
-         * --enable-safemode, --enable-jit, and --enable-jni-logging.
+         * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging.
          */
         int debugFlags;
 
@@ -433,6 +433,8 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
                 } else if (arg.equals("--enable-jit")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
+                } else if (arg.equals("--generate-cfi")) {
+                    debugFlags |= Zygote.DEBUG_GENERATE_CFI;
                 } else if (arg.equals("--enable-jni-logging")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
                 } else if (arg.equals("--enable-assert")) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index cd117eb1..bbdd860 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -176,6 +176,7 @@
     $(call include-path-for, libhardware)/hardware \
     $(call include-path-for, libhardware_legacy)/hardware_legacy \
     $(TOP)/frameworks/av/include \
+    $(TOP)/frameworks/base/media/jni \
     $(TOP)/system/media/camera/include \
     $(TOP)/system/netd/include \
     external/pdfium/core/include/fpdfapi \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 88f0697..7c2b28d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -875,6 +875,19 @@
     parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf,
                        "-Xzygote-max-boot-retry=");
 
+    /*
+     * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot
+     * image, if it is compiled on device, will include CFI info, as well as other compilations
+     * started by the runtime.
+     */
+    property_get("debug.gencfi", propBuf, "");
+    if (strcmp(propBuf, "true") == 0) {
+        addOption("-Xcompiler-option");
+        addOption("--include-cfi");
+        addOption("-Ximage-compiler-option");
+        addOption("--include-cfi");
+    }
+
     initArgs.version = JNI_VERSION_1_4;
     initArgs.options = mOptions.editArray();
     initArgs.nOptions = mOptions.size();
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index fc05a6d..3655adc 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -111,6 +111,7 @@
     jfieldID    mRouteFlags;
     jfieldID    mRegistrationId;
     jfieldID    mMixType;
+    jfieldID    mCallbackFlags;
 } gAudioMixFields;
 
 static jclass gAudioFormatClass;
@@ -149,6 +150,10 @@
     jmethodID    postEventFromNative;
 } gAudioPortEventHandlerMethods;
 
+static struct {
+    jmethodID postDynPolicyEventFromNative;
+} gDynPolicyEventHandlerMethods;
+
 static Mutex gLock;
 
 enum AudioError {
@@ -166,7 +171,7 @@
 #define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
 
 // ----------------------------------------------------------------------------
-// ref-counted object for callbacks
+// ref-counted object for audio port callbacks
 class JNIAudioPortCallback: public AudioSystem::AudioPortCallback
 {
 public:
@@ -361,6 +366,26 @@
     env->DeleteLocalRef(clazz);
 }
 
+static void
+android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    if (env == NULL) {
+        return;
+    }
+
+    jclass clazz = env->FindClass(kClassPathName);
+    const char* zechars = regId.string();
+    jstring zestring = env->NewStringUTF(zechars);
+
+    env->CallStaticVoidMethod(clazz, gDynPolicyEventHandlerMethods.postDynPolicyEventFromNative,
+            event, zestring, val);
+
+    env->ReleaseStringUTFChars(zestring, zechars);
+    env->DeleteLocalRef(clazz);
+
+}
+
 static jint
 android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name)
 {
@@ -1402,7 +1427,11 @@
     return (jint)AudioSystem::getAudioHwSyncForSession((audio_session_t)sessionId);
 }
 
-
+static void
+android_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
+{
+    AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
+}
 
 
 static jint convertAudioMixToNative(JNIEnv *env,
@@ -1419,6 +1448,8 @@
     env->ReleaseStringUTFChars(jRegistrationId, nRegistrationId);
     env->DeleteLocalRef(jRegistrationId);
 
+    nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
+
     jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
     nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
                                                      gAudioFormatFields.mSampleRate);
@@ -1567,7 +1598,8 @@
                                     (void *)android_media_AudioSystem_getAudioHwSyncForSession},
     {"registerPolicyMixes",    "(Ljava/util/ArrayList;Z)I",
                                             (void *)android_media_AudioSystem_registerPolicyMixes},
-
+    {"native_register_dynamic_policy_callback", "()V",
+                                    (void *)android_media_AudioSystem_registerDynPolicyCallback},
 };
 
 
@@ -1670,6 +1702,10 @@
     gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
                                                     eventHandlerClass, "mJniCallback", "J");
 
+    gDynPolicyEventHandlerMethods.postDynPolicyEventFromNative =
+            GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
+                    "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
+
     jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
     gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
     gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
@@ -1680,6 +1716,7 @@
     gAudioMixFields.mRegistrationId = GetFieldIDOrDie(env, audioMixClass, "mRegistrationId",
                                                       "Ljava/lang/String;");
     gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
+    gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
 
     jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
     gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 2f6a69c..26b82c5 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -35,6 +35,7 @@
 
 #include "android_media_AudioFormat.h"
 #include "android_media_AudioErrors.h"
+#include "android_media_PlaybackSettings.h"
 
 // ----------------------------------------------------------------------------
 
@@ -59,6 +60,7 @@
 };
 static audio_track_fields_t      javaAudioTrackFields;
 static audio_attributes_fields_t javaAudioAttrFields;
+static PlaybackSettings::fields_t gPlaybackSettingsFields;
 
 struct audiotrack_callback_cookie {
     jclass      audioTrack_class;
@@ -690,7 +692,7 @@
 
 // ----------------------------------------------------------------------------
 static void android_media_AudioTrack_set_playback_settings(JNIEnv *env,  jobject thiz,
-        jfloatArray floatArray, jintArray intArray) {
+        jobject settings) {
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
@@ -698,50 +700,39 @@
         return;
     }
 
-    // NOTE: Get<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid.
-    // TODO: consider the actual occupancy.
-    float farray[2];
-    int iarray[2];
-    if ((env->GetFloatArrayRegion(floatArray, 0, 2, farray), env->ExceptionCheck()) == JNI_FALSE
-            &&
-        (env->GetIntArrayRegion(intArray, 0, 2, iarray), env->ExceptionCheck()) == JNI_FALSE) {
-        // arrays retrieved OK
-        AudioPlaybackRate playbackRate;
-        playbackRate.mSpeed = farray[0];
-        playbackRate.mPitch = farray[1];
-        playbackRate.mFallbackMode = (AudioTimestretchFallbackMode)iarray[0];
-        playbackRate.mStretchMode = (AudioTimestretchStretchMode)iarray[1];
-        if (lpTrack->setPlaybackRate(playbackRate) != OK) {
-            jniThrowException(env, "java/lang/IllegalArgumentException",
-                    "arguments out of range");
-        }
+    PlaybackSettings pbs;
+    pbs.fillFromJobject(env, gPlaybackSettingsFields, settings);
+
+    ALOGV("setPlaybackSettings: %d:%f %d:%f %d:%u %d:%u",
+            pbs.speedSet, pbs.audioRate.mSpeed,
+            pbs.pitchSet, pbs.audioRate.mPitch,
+            pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
+            pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
+
+    if (lpTrack->setPlaybackRate(pbs.audioRate) != OK) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                "arguments out of range");
     }
 }
 
 
 // ----------------------------------------------------------------------------
-static void android_media_AudioTrack_get_playback_settings(JNIEnv *env,  jobject thiz,
-        jfloatArray floatArray, jintArray intArray) {
+static jobject android_media_AudioTrack_get_playback_settings(JNIEnv *env,  jobject thiz,
+        jobject settings) {
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
             "AudioTrack not initialized");
-        return;
+        return NULL;
     }
 
-    AudioPlaybackRate playbackRate = lpTrack->getPlaybackRate();
-
-    float farray[2] = {
-            playbackRate.mSpeed,
-            playbackRate.mPitch,
-    };
-    int iarray[2] = {
-            playbackRate.mFallbackMode,
-            playbackRate.mStretchMode,
-    };
-    // NOTE: Set<Primitive>ArrayRegion throws ArrayIndexOutOfBoundsException if not valid.
-    env->SetFloatArrayRegion(floatArray, 0, 2, farray);
-    env->SetIntArrayRegion(intArray, 0, 2, iarray);
+    PlaybackSettings pbs;
+    pbs.audioRate = lpTrack->getPlaybackRate();
+    pbs.speedSet = true;
+    pbs.pitchSet = true;
+    pbs.audioFallbackModeSet = true;
+    pbs.audioStretchModeSet = true;
+    return pbs.asJobject(env, gPlaybackSettingsFields);
 }
 
 
@@ -1012,9 +1003,11 @@
     {"native_get_playback_rate",
                              "()I",      (void *)android_media_AudioTrack_get_playback_rate},
     {"native_set_playback_settings",
-                             "([F[I)V",  (void *)android_media_AudioTrack_set_playback_settings},
+                             "(Landroid/media/PlaybackSettings;)V",
+                                         (void *)android_media_AudioTrack_set_playback_settings},
     {"native_get_playback_settings",
-                             "([F[I)V",  (void *)android_media_AudioTrack_get_playback_settings},
+                             "()Landroid/media/PlaybackSettings;",
+                                         (void *)android_media_AudioTrack_get_playback_settings},
     {"native_set_marker_pos","(I)I",     (void *)android_media_AudioTrack_set_marker_pos},
     {"native_get_marker_pos","()I",      (void *)android_media_AudioTrack_get_marker_pos},
     {"native_set_pos_update_period",
@@ -1088,6 +1081,8 @@
     javaAudioTrackFields.fieldStreamType = GetFieldIDOrDie(env,
             audioTrackClass, JAVA_STREAMTYPE_FIELD_NAME, "I");
 
+    env->DeleteLocalRef(audioTrackClass);
+
     // Get the AudioAttributes class and fields
     jclass audioAttrClass = FindClassOrDie(env, kAudioAttributesClassPathName);
     javaAudioAttrFields.fieldUsage = GetFieldIDOrDie(env, audioAttrClass, "mUsage", "I");
@@ -1097,6 +1092,11 @@
     javaAudioAttrFields.fieldFormattedTags = GetFieldIDOrDie(env,
             audioAttrClass, "mFormattedTags", "Ljava/lang/String;");
 
+    env->DeleteLocalRef(audioAttrClass);
+
+    // initialize PlaybackSettings field info
+    gPlaybackSettingsFields.init(env);
+
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/res/res/layout/floating_popup_container.xml b/core/res/res/layout/floating_popup_container.xml
index e1af94c..c2b4ccc 100644
--- a/core/res/res/layout/floating_popup_container.xml
+++ b/core/res/res/layout/floating_popup_container.xml
@@ -24,4 +24,4 @@
     android:elevation="2dp"
     android:focusable="true"
     android:focusableInTouchMode="true"
-    android:background="@color/floating_toolbar_background_color"/>
+    android:background="?attr/colorBackgroundFloating"/>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 70227fa..23ae7f0 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -29,5 +29,5 @@
     android:fontFamily="sans-serif"
     android:textSize="@dimen/floating_toolbar_text_size"
     android:textAllCaps="true"
-    android:textColor="@color/floating_toolbar_text_color"
+    android:textColor="?attr/colorForeground"
     android:background="?attr/selectableItemBackground" />
diff --git a/core/res/res/layout/floating_popup_overflow_list_item b/core/res/res/layout/floating_popup_overflow_list_item
index c0db1bd..59a6d7e 100644
--- a/core/res/res/layout/floating_popup_overflow_list_item
+++ b/core/res/res/layout/floating_popup_overflow_list_item
@@ -31,5 +31,5 @@
     android:ellipsize="end"
     android:fontFamily="sans-serif"
     android:textSize="@dimen/floating_toolbar_text_size"
-    android:textColor="@color/floating_toolbar_text_color"
+    android:textColor="?attr/colorForeground"
     android:textAllCaps="true" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a95cc79..e993ceb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7430,6 +7430,10 @@
         <attr name="maxWidth" />
         <!-- An optional query hint string to be displayed in the empty query field. -->
         <attr name="queryHint" format="string" />
+        <!-- Default query hint used when {@code queryHint} is undefined and
+             the search view's {@code SearchableInfo} does not provide a hint.
+             @hide -->
+        <attr name="defaultQueryHint" format="string" />
         <!-- The IME options to set on the query text field. -->
         <attr name="imeOptions" />
         <!-- The input type to set on the query text field. -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index f1d2242..b9825c5 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -174,8 +174,4 @@
     <color name="Pink_800">#ffad1457</color>
     <color name="Red_700">#ffc53929</color>
     <color name="Red_800">#ffb93221</color>
-
-    <!-- Floating toolbar colors -->
-    <color name="floating_toolbar_text_color">#DD000000</color>
-    <color name="floating_toolbar_background_color">#FAFAFA</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 56eab2c..6f60188 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2054,6 +2054,7 @@
     <string-array translatable="false" name="config_system_condition_providers">
         <item>countdown</item>
         <item>schedule</item>
+        <item>event</item>
     </string-array>
 
     <!-- Priority repeat caller threshold, in minutes -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3146f41..f36d448 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4013,9 +4013,11 @@
     <!-- Lock-to-app unlock password string -->
     <string name="lock_to_app_unlock_password">Ask for password before unpinning</string>
 
-    <!-- Notification shown when device owner silently installs a package -->
+    <!-- Notification shown when device owner silently installs a package [CHAR LIMIT=NONE] -->
     <string name="package_installed_device_owner">Installed by your administrator</string>
-    <!-- Notification shown when device owner silently deletes a package -->
+    <!-- Notification shown when device owner silently updates a package [CHAR LIMIT=NONE] -->
+    <string name="package_updated_device_owner">Updated by your administrator</string>
+    <!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] -->
     <string name="package_deleted_device_owner">Deleted by your administrator</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index f81ee8c..c2371ee 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -533,7 +533,7 @@
         <item name="queryBackground">@empty</item>
         <item name="submitBackground">@empty</item>
         <item name="searchHintIcon">@empty</item>
-        <item name="queryHint">@string/search_hint</item>
+        <item name="defaultQueryHint">@string/search_hint</item>
     </style>
 
     <style name="Widget.Material.SegmentedButton" parent="SegmentedButton">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 90437b9..625f003 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -698,6 +698,7 @@
   <java-symbol type="string" name="lock_to_app_unlock_pattern" />
   <java-symbol type="string" name="lock_to_app_unlock_password" />
   <java-symbol type="string" name="package_installed_device_owner" />
+  <java-symbol type="string" name="package_updated_device_owner" />
   <java-symbol type="string" name="package_deleted_device_owner" />
   <java-symbol type="string" name="lockscreen_access_pattern_cell_added" />
   <java-symbol type="string" name="lockscreen_access_pattern_cleared" />
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index a0b26f3..1ea459f 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -50,7 +50,7 @@
 # Do not include Motoya on space-constrained devices
 ifneq ($(SMALLER_FONT_FOOTPRINT),true)
 # Do not include Motoya if we are including full NotoSans
-ifneq ($(FONT_NOTOSANS_FULL),true)
+ifneq ($(FONT_NOTOSANS_JP_FULL),true)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := MTLmr3m.ttf
@@ -61,7 +61,7 @@
 include $(BUILD_PREBUILT)
 extra_font_files += MTLmr3m.ttf
 
-endif  # !FONT_NOTOSANS_FULL
+endif  # !FONT_NOTOSANS_JP_FULL
 endif  # !SMALLER_FONT_FOOTPRINT
 
 ################################
diff --git a/docs/html/guide/components/processes-and-threads.jd b/docs/html/guide/components/processes-and-threads.jd
index e7ef7ba..10a6410 100644
--- a/docs/html/guide/components/processes-and-threads.jd
+++ b/docs/html/guide/components/processes-and-threads.jd
@@ -274,7 +274,8 @@
 public void onClick(View v) {
     new Thread(new Runnable() {
         public void run() {
-            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
+            final Bitmap bitmap =
+                    loadImageFromNetwork("http://example.com/image.png");
             mImageView.post(new Runnable() {
                 public void run() {
                     mImageView.setImageBitmap(bitmap);
@@ -323,7 +324,7 @@
     protected Bitmap doInBackground(String... urls) {
         return loadImageFromNetwork(urls[0]);
     }
-    
+
     /** The system calls this to perform work in the UI thread and delivers
       * the result from doInBackground() */
     protected void onPostExecute(Bitmap result) {
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 06577720..31d2efb 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -4,27 +4,29 @@
 header.hide=1
 page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more.
 
-studio.version=1.1.0
+studio.version=1.2.0
 
-studio.linux_bundle_download=android-studio-ide-135.1740770-linux.zip
-studio.linux_bundle_bytes=259336386
-studio.linux_bundle_checksum=e8d166559c50a484f83ebfec6731cc0e3f259208
+studio.linux_bundle_download=android-studio-ide-141.1890965-linux.zip
+studio.linux_bundle_bytes=259139652 
+studio.linux_bundle_checksum=72149f65911ca18d8f0d360e6b7a1e2dc57e9935
 
-studio.mac_bundle_download=android-studio-ide-135.1740770-mac.dmg
-studio.mac_bundle_bytes=261303345
-studio.mac_bundle_checksum=f9745d0fec1eefd498f6160a2d6a1b5247d4cda3
+studio.mac_bundle_download=android-studio-ide-141.1890965-mac.dmg
+studio.mac_bundle_bytes=260877150
+studio.mac_bundle_checksum=06fe5a2d9ab6c99bf42fb2014e519a073fc7e90d
 
-studio.win_bundle_exe_download=android-studio-bundle-135.1740770-windows.exe
-studio.win_bundle_exe_bytes=856233768
-studio.win_bundle_exe_checksum=7484b9989d2914e1de30995fbaa97a271a514b3f
+studio.win_bundle_download=android-studio-ide-141.1890965-windows.zip
+studio.win_bundle_bytes=261548058
+studio.win_bundle_checksum=29416e54ad074881a1e668e61e3d0c2316108dbe
 
-studio.win_notools_exe_download=android-studio-ide-135.1740770-windows.exe
-studio.win_notools_exe_bytes=242135128
-studio.win_notools_exe_checksum=5ea77661cd2300cea09e8e34f4a2219a0813911f
 
-studio.win_bundle_download=android-studio-ide-135.1740770-windows.zip
-studio.win_bundle_bytes=261667054
-studio.win_bundle_checksum=e903f17cc6a57c7e3d460c4555386e3e65c6b4eb
+studio.win_bundle_exe_download=android-studio-bundle-141.1890965-windows.exe
+studio.win_bundle_exe_bytes=928285584
+studio.win_bundle_exe_checksum=47be67749409f0d710c05b9a8f22d9191c47a9d0
+
+studio.win_notools_exe_download=android-studio-ide-141.1890965-windows.exe
+studio.win_notools_exe_bytes=243621072
+studio.win_notools_exe_checksum=760d45212bea42f52adb1cbeab2390156d49c74d
+
 
 
 
@@ -425,8 +427,7 @@
 
 <p style="margin:0">
 For more details about features available in Android Studio,
-read the guide to <a href="{@docRoot}tools/studio/index.html"
-  >Android Studio Basics</a>.</p>
+read the overview at <a href="{@docRoot}tools/studio/index.html">Android Studio</a>.</p>
 </div>
 
 
diff --git a/docs/html/tools/revisions/gradle-plugin.jd b/docs/html/tools/revisions/gradle-plugin.jd
index fd294d2..90ec44a 100644
--- a/docs/html/tools/revisions/gradle-plugin.jd
+++ b/docs/html/tools/revisions/gradle-plugin.jd
@@ -36,9 +36,77 @@
 <p>For a summary of known issues in Android Plugin for Gradle, see <a
 href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
+
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Android Plugin for Gradle, Revision 1.2.0</a> <em>(April 2015)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Gradle 2.2.1 or higher.</li>
+        <li>Build Tools 21.1.1 or higher.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+      <li>Enhanced support for running unit tests with Gradle.  </li>
+        <ul>
+          <li>Added support to include Java-style resources in the classpath when running unit
+            tests directly from Gradle.
+          </li>
+          <li>Added unit test dependency support for Android ARchive (AAR) artifacts.
+          </li>
+          <li>Added support for the <code>unitTestVariants</code> property so unit test variants
+            can be manipulated using the <code>build.gradle</code> file.
+          </li>
+          <li>Added the <code>unitTest.all</code> code block under <code>testOptions</code> to
+            configure customized tasks for unit test. The following sample code shows how to add
+            unit test configuration settings using this new option:
+<pre>
+android {
+  testOptions {
+    unitTest.all {
+      jvmArgs '-XX:MaxPermSize=256m' // Or any other gradle option.
+    }
+  }
+}
+</pre>
+           </li>
+          <li>Fixed the handling of enums and public instance fields in the packaging of the
+           <code>mockable-android.jar</code> file.
+          </li>
+          <li>Fixed library project task dependencies so test classes recompile after changes.
+          </li>
+          </ul>
+        <li>Added the <code>testProguardFile</code> property to apply
+          <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> files when minifying a test APK.
+        </li>
+        <li>Added the <code>timeOut</code> property to the <code>adbOptions</code> code block
+          for setting the maximum recording time for
+          <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a> screen recording.
+        </li>
+        <li>Added support for 280 dpi resources.
+        </li>
+        <li>Improved performance during project evaluation.
+        </li>
+     </ul>
+    </dd>
+  </div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Android Plugin for Gradle, Revision 1.1.3</a> <em>(March 2015)</em>
   </p>
 
diff --git a/docs/html/tools/revisions/index.jd b/docs/html/tools/revisions/index.jd
index 0e7ceef..0b8db83 100644
--- a/docs/html/tools/revisions/index.jd
+++ b/docs/html/tools/revisions/index.jd
@@ -6,4 +6,8 @@
 an update at their own schedule, so some have their own set of release notes. You can
 find information about some of the packages in this section, including the core <a
 href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools</a> and the latest <a
-href="{@docRoot}tools/revisions/platforms.html">Platforms</a>.</p>
\ No newline at end of file
+href="{@docRoot}tools/revisions/platforms.html">SDK Platforms</a>. Release notes are also available
+for Android developer tools, such as
+<a href="{@docRoot}tools/revisions/studio.html">Android Studio</a> and the
+<a href="{@docRoot}tools/revisions/gradle-plugin.html">Android Plugin for Gradle</a>.
+</p>
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index 3982f2e..4f153e3 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -29,9 +29,9 @@
 <p>For an introduction to Android Studio, read the
 <a href="{@docRoot}tools/studio/index.html">Android Studio</a> guide.</p>
 
-<p>Periodic updates are pushed to Android Studio without requiring you to update. To
-manually check for updates, select <strong>Help > Check for updates</strong> (on Mac, select
-<strong>Android Studio > Check for updates</strong>).</p>
+<p>Periodic updates are pushed to Android Studio without requiring you to update your Android
+project. To manually check for updates, select <strong>Help > Check for updates</strong> (on Mac,
+select <strong>Android Studio > Check for updates</strong>).</p>
 
 
 <h2 id="Revisions">Revisions</h2>
@@ -43,6 +43,53 @@
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>Android Studio v1.2.0</a> <em>(April 2015)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+    <p>Various fixes and enhancements:</p>
+    <ul>
+      <li>Updated the Android runtime window to include the
+        <a href="{@docRoot}tools/studio/index.html#memory-monitor">Memory Monitor</a> tool
+        and added a tab for CPU performance monitoring.</li>
+      <li>Added a <em>Captures</em> tab in the left margin to display the captured memory and CPU
+        performance data files, such as CPU method tracking and memory heap snapshots.</li>
+      <li>Expanded <a href="{@docRoot}tools/debugging/annotations.html">annotation</a>
+          support with additional metadata annotations and inferred nullability. </li>
+      <li>Enhanced the Translations Editor with additional support for Best Current Practice
+          (BCP) 47, which uses 3-letter language and region codes.</li>
+      <li>Integrated IntelliJ 14 and 14.1 features for improved code analysis and performance:</li>
+         <ul>
+          <li>Enhanced debugging to show inline values for variables and referring objects,
+            as well as perform inline evaluation of lambda and operator expressions. </li>
+          <li>Added code style detection for tab and indent sizes. </li>
+          <li>Added scratch files for code experiments and prototyping without project files.</li>
+          <li>Added the simultaneous insertion of opening and closing tags in HTML and XML files.</li>
+          <li>Added a built-in Java class decompiler so you can look at what’s inside a library
+            for which the source code is not available. </li>
+         </ul>
+         <p>See
+         <a class="external-link" href="https://www.jetbrains.com/idea/whatsnew">What's New in IntelliJ</a>
+         for a complete description of the new features and enhancements.</p>
+       </li>
+      <li>Added additional <a href="{@docRoot}tools/studio/index.html#project-view">Project Views</a>
+        for <em>Scratches</em>, <em>Project Files</em>, <em>Problems</em>, <em>Production</em>,
+        and <em>Tests</em> to enhance project management and access. </li>
+      <li>Enhanced the <strong>File &gt; Settings</strong> menu and dialogs for improved settings
+          access and management. </li>
+      <li>Added support for high-density displays for Windows and Linux. </li>
+      <li>Added support for 280 dpi resources in the <code>res/drawable-280dpi/</code> folder.
+     </ul>
+    </ul>
+  </div>
+</div>
+
+
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>Android Studio v1.1.0</a> <em>(February 2015)</em>
   </p>
 
@@ -63,6 +110,7 @@
       for region and language combinations, launcher icons, resource names, and other common
       code problems.</li>
       <li>Added support for Best Current Practice (BCP) language tag 47.  </li>
+    </ul>
   </div>
 </div>
 
@@ -85,6 +133,7 @@
       updates, use <strong>File > Settings > Updates</strong> to change to the <strong>Stable</strong>
       update channel.
       </li>
+    </ul>
   </div>
 </div>
 
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index 1860feb..360b863 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -243,7 +243,7 @@
 
 
 
-<h3>Memory Monitor</h3>
+<h3 id="memory-monitor">Memory Monitor</h3>
 <p>Android Studio provides a memory monitor view so you can more easily monitor your
 app's memory usage to find deallocated objects, locate memory leaks and track the amount of
 memory the connected device is using. With your app running on a device or emulator, click the
diff --git a/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java
new file mode 100644
index 0000000..45329cf
--- /dev/null
+++ b/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import java.security.Provider;
+
+/**
+ * {@link Provider} of JCA crypto operations operating on Android KeyStore keys.
+ *
+ * <p>This provider was separated out of {@link AndroidKeyStoreProvider} to work around the issue
+ * that Bouncy Castle provider incorrectly declares that it accepts arbitrary keys (incl. Android
+ * KeyStore ones). This causes JCA to select the Bouncy Castle's implementation of JCA crypto
+ * operations for Android KeyStore keys unless Android KeyStore's own implementations are installed
+ * as higher-priority than Bouncy Castle ones. The purpose of this provider is to do just that: to
+ * offer crypto operations operating on Android KeyStore keys and to be installed at higher priority
+ * than the Bouncy Castle provider.
+ *
+ * <p>Once Bouncy Castle provider is fixed, this provider can be merged into the
+ * {@code AndroidKeyStoreProvider}.
+ *
+ * @hide
+ */
+class AndroidKeyStoreBCWorkaroundProvider extends Provider {
+
+    // IMPLEMENTATION NOTE: Class names are hard-coded in this provider to avoid loading these
+    // classes when this provider is instantiated and installed early on during each app's
+    // initialization process.
+
+    private static final String PACKAGE_NAME = "android.security";
+    private static final String KEYSTORE_SECRET_KEY_CLASS_NAME =
+            PACKAGE_NAME + ".KeyStoreSecretKey";
+
+    AndroidKeyStoreBCWorkaroundProvider() {
+        super("AndroidKeyStoreBCWorkaround",
+                1.0,
+                "Android KeyStore security provider to work around Bouncy Castle");
+
+        // javax.crypto.Mac
+        putMacImpl("HmacSHA1", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA1");
+        putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224");
+        putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256");
+        putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384");
+        putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512");
+
+        // javax.crypto.Cipher
+        putSymmetricCipherImpl("AES/ECB/NoPadding",
+                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$NoPadding");
+        putSymmetricCipherImpl("AES/ECB/PKCS7Padding",
+                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$PKCS7Padding");
+
+        putSymmetricCipherImpl("AES/CBC/NoPadding",
+                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$NoPadding");
+        putSymmetricCipherImpl("AES/CBC/PKCS7Padding",
+                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$PKCS7Padding");
+
+        putSymmetricCipherImpl("AES/CTR/NoPadding",
+                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding");
+    }
+
+    private void putMacImpl(String algorithm, String implClass) {
+        put("Mac." + algorithm, implClass);
+        put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
+    }
+
+    private void putSymmetricCipherImpl(String transformation, String implClass) {
+        put("Cipher." + transformation, implClass);
+        put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
+    }
+}
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
index 43f3b30..518067b 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -17,6 +17,7 @@
 package android.security;
 
 import java.security.Provider;
+import java.security.Security;
 
 import javax.crypto.Cipher;
 import javax.crypto.Mac;
@@ -32,10 +33,12 @@
     // IMPLEMENTATION NOTE: Class names are hard-coded in this provider to avoid loading these
     // classes when this provider is instantiated and installed early on during each app's
     // initialization process.
+    //
+    // Crypto operations operating on the AndroidKeyStore keys must not be offered by this provider.
+    // Instead, they need to be offered by AndroidKeyStoreBCWorkaroundProvider. See its Javadoc
+    // for details.
 
     private static final String PACKAGE_NAME = "android.security";
-    private static final String KEYSTORE_SECRET_KEY_CLASS_NAME =
-            PACKAGE_NAME + ".KeyStoreSecretKey";
 
     public AndroidKeyStoreProvider() {
         super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
@@ -62,43 +65,39 @@
         putSecretKeyFactoryImpl("HmacSHA256");
         putSecretKeyFactoryImpl("HmacSHA384");
         putSecretKeyFactoryImpl("HmacSHA512");
+    }
 
-        // javax.crypto.Mac
-        putMacImpl("HmacSHA1", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA1");
-        putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224");
-        putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256");
-        putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384");
-        putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512");
+    /**
+     * Installs a new instance of this provider (and the
+     * {@link AndroidKeyStoreBCWorkaroundProvider}).
+     */
+    public static void install() {
+        Provider[] providers = Security.getProviders();
+        int bcProviderPosition = -1;
+        for (int position = 0; position < providers.length; position++) {
+            Provider provider = providers[position];
+            if ("BC".equals(provider.getName())) {
+                bcProviderPosition = position;
+                break;
+            }
+        }
 
-        // javax.crypto.Cipher
-        putSymmetricCipherImpl("AES/ECB/NoPadding",
-                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$NoPadding");
-        putSymmetricCipherImpl("AES/ECB/PKCS7Padding",
-                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$PKCS7Padding");
-
-        putSymmetricCipherImpl("AES/CBC/NoPadding",
-                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$NoPadding");
-        putSymmetricCipherImpl("AES/CBC/PKCS7Padding",
-                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$PKCS7Padding");
-
-        putSymmetricCipherImpl("AES/CTR/NoPadding",
-                PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding");
+        Security.addProvider(new AndroidKeyStoreProvider());
+        Provider workaroundProvider = new AndroidKeyStoreBCWorkaroundProvider();
+        if (bcProviderPosition != -1) {
+            // Bouncy Castle provider found -- install the workaround provider above it.
+            Security.insertProviderAt(workaroundProvider, bcProviderPosition);
+        } else {
+            // Bouncy Castle provider not found -- install the workaround provider at lowest
+            // priority.
+            Security.addProvider(workaroundProvider);
+        }
     }
 
     private void putSecretKeyFactoryImpl(String algorithm) {
         put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi");
     }
 
-    private void putMacImpl(String algorithm, String implClass) {
-        put("Mac." + algorithm, implClass);
-        put("Mac." + algorithm + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
-    }
-
-    private void putSymmetricCipherImpl(String transformation, String implClass) {
-        put("Cipher." + transformation, implClass);
-        put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME);
-    }
-
     /**
      * Gets the {@link KeyStore} operation handle corresponding to the provided JCA crypto
      * primitive.
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index c9f06e9..5617836 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -15,13 +15,17 @@
     private GateKeeper() {}
 
     public static IGateKeeperService getService() {
-        return IGateKeeperService.Stub.asInterface(
+        IGateKeeperService service = IGateKeeperService.Stub.asInterface(
                 ServiceManager.getService("android.service.gatekeeper.IGateKeeperService"));
+        if (service == null) {
+            throw new IllegalStateException("Gatekeeper service not available");
+        }
+        return service;
     }
 
     public static long getSecureUserId() throws IllegalStateException {
         try {
-            return GateKeeper.getService().getSecureUserId(UserHandle.myUserId());
+            return getService().getSecureUserId(UserHandle.myUserId());
         } catch (RemoteException e) {
             throw new IllegalStateException(
                     "Failed to obtain secure user ID from gatekeeper", e);
diff --git a/keystore/java/android/security/KeyPermanentlyInvalidatedException.java b/keystore/java/android/security/KeyPermanentlyInvalidatedException.java
new file mode 100644
index 0000000..229eab0
--- /dev/null
+++ b/keystore/java/android/security/KeyPermanentlyInvalidatedException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import java.security.InvalidKeyException;
+
+/**
+ * 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.
+ */
+public class KeyPermanentlyInvalidatedException extends InvalidKeyException {
+
+    /**
+     * Constructs a new {@code KeyPermanentlyInvalidatedException} without detail message and cause.
+     */
+    public KeyPermanentlyInvalidatedException() {
+        super("Key permanently invalidated");
+    }
+
+    /**
+     * Constructs a new {@code KeyPermanentlyInvalidatedException} with the provided detail message
+     * and no cause.
+     */
+    public KeyPermanentlyInvalidatedException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new {@code KeyPermanentlyInvalidatedException} with the provided detail message
+     * and cause.
+     */
+    public KeyPermanentlyInvalidatedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 5d863c2..1563863 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -18,6 +18,8 @@
 
 import com.android.org.conscrypt.NativeConstants;
 
+import android.content.Context;
+import android.hardware.fingerprint.IFingerprintService;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -31,6 +33,7 @@
 import android.util.Log;
 
 import java.security.InvalidKeyException;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -490,7 +493,8 @@
     /**
      * Check if the operation referenced by {@code token} is currently authorized.
      *
-     * @param token An operation token returned by a call to {@link KeyStore.begin}.
+     * @param token An operation token returned by a call to
+     * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}.
      */
     public boolean isOperationAuthorized(IBinder token) {
         try {
@@ -539,6 +543,8 @@
                     return new KeyStoreException(errorCode, "Key not found");
                 case VALUE_CORRUPTED:
                     return new KeyStoreException(errorCode, "Key blob corrupted");
+                case OP_AUTH_NEEDED:
+                    return new KeyStoreException(errorCode, "Operation requires authorization");
                 default:
                     return new KeyStoreException(errorCode, String.valueOf(errorCode));
             }
@@ -561,27 +567,81 @@
      * Returns an {@link InvalidKeyException} corresponding to the provided
      * {@link KeyStoreException}.
      */
-    static InvalidKeyException getInvalidKeyException(KeyStoreException e) {
+    InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, KeyStoreException e) {
         switch (e.getErrorCode()) {
             case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                 return new KeyExpiredException();
             case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
                 return new KeyNotYetValidException();
             case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
-                return new UserNotAuthenticatedException();
-            // TODO: Handle TBD Keymaster error code "invalid key: new fingerprint enrolled"
-            // case KeymasterDefs.KM_ERROR_TBD
-            //     return new NewFingerprintEnrolledException();
+            case OP_AUTH_NEEDED:
+            {
+                // We now need to determine whether the key/operation can become usable if user
+                // authentication is performed, or whether it can never become usable again.
+                // User authentication requirements are contained in the key's characteristics. We
+                // need to check whether these requirements can be be satisfied by asking the user
+                // to authenticate.
+                KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
+                int getKeyCharacteristicsErrorCode =
+                        getKeyCharacteristics(keystoreKeyAlias, null, null, keyCharacteristics);
+                if (getKeyCharacteristicsErrorCode != NO_ERROR) {
+                    return new InvalidKeyException(
+                            "Failed to obtained key characteristics",
+                            getKeyStoreException(getKeyCharacteristicsErrorCode));
+                }
+                List<Long> keySids =
+                        keyCharacteristics.getLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
+                if (keySids.isEmpty()) {
+                    // Key is not bound to any SIDs -- no amount of authentication will help here.
+                    return new KeyPermanentlyInvalidatedException();
+                }
+                long rootSid = GateKeeper.getSecureUserId();
+                if ((rootSid != 0) && (keySids.contains(Long.valueOf(rootSid)))) {
+                    // One of the key's SIDs is the current root SID -- user can be authenticated
+                    // against that SID.
+                    return new UserNotAuthenticatedException();
+                }
+
+                long fingerprintOnlySid = getFingerprintOnlySid();
+                if ((fingerprintOnlySid != 0)
+                        && (keySids.contains(Long.valueOf(fingerprintOnlySid)))) {
+                    // One of the key's SIDs is the current fingerprint SID -- user can be
+                    // authenticated against that SID.
+                    return new UserNotAuthenticatedException();
+                }
+
+                // None of the key's SIDs can ever be authenticated
+                return new KeyPermanentlyInvalidatedException();
+            }
             default:
                 return new InvalidKeyException("Keystore operation failed", e);
         }
     }
 
+    private static long getFingerprintOnlySid() {
+        IFingerprintService service = IFingerprintService.Stub.asInterface(
+                ServiceManager.getService(Context.FINGERPRINT_SERVICE));
+        if (service == null) {
+            return 0;
+        }
+
+        try {
+            long deviceId = 0; // TODO: plumb hardware id to FPMS
+            if (!service.isHardwareDetected(deviceId)) {
+                return 0;
+            }
+
+            return service.getAuthenticatorId();
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Failed to communicate with fingerprint service", e);
+        }
+    }
+
     /**
      * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
      * code.
      */
-    static InvalidKeyException getInvalidKeyException(int errorCode) {
-        return getInvalidKeyException(getKeyStoreException(errorCode));
+    InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) {
+        return getInvalidKeyException(keystoreKeyAlias, getKeyStoreException(errorCode));
     }
 }
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 3b13e83..917f716 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -298,17 +298,20 @@
         mAdditionalEntropyForBegin = null;
         if (opResult == null) {
             throw new KeyStoreConnectException();
-        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
+        } else if ((opResult.resultCode != KeyStore.NO_ERROR)
+                && (opResult.resultCode != KeyStore.OP_AUTH_NEEDED)) {
             switch (opResult.resultCode) {
                 case KeymasterDefs.KM_ERROR_INVALID_NONCE:
                     throw new InvalidAlgorithmParameterException("Invalid IV");
             }
-            throw KeyStore.getInvalidKeyException(opResult.resultCode);
+            throw mKeyStore.getInvalidKeyException(mKey.getAlias(), opResult.resultCode);
         }
 
         if (opResult.token == null) {
             throw new IllegalStateException("Keystore returned null operation token");
         }
+        // The operation handle/token is now either valid for use immediately or needs to be
+        // authorized through user authentication (if the error code was OP_AUTH_NEEDED).
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
         loadAlgorithmSpecificParametersFromBeginResult(keymasterOutputArgs);
@@ -317,6 +320,16 @@
         mMainDataStreamer = new KeyStoreCryptoOperationChunkedStreamer(
                 new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
                         mKeyStore, opResult.token));
+
+        if (opResult.resultCode != KeyStore.NO_ERROR) {
+            // The operation requires user authentication. Check whether such authentication is
+            // possible (e.g., the key may have been permanently invalidated).
+            InvalidKeyException e =
+                    mKeyStore.getInvalidKeyException(mKey.getAlias(), opResult.resultCode);
+            if (!(e instanceof UserNotAuthenticatedException)) {
+                throw e;
+            }
+        }
     }
 
     @Override
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index 175369c..4590b9c 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -168,17 +168,31 @@
                 new KeymasterArguments());
         if (opResult == null) {
             throw new KeyStoreConnectException();
-        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
-            throw KeyStore.getInvalidKeyException(opResult.resultCode);
+        } else if ((opResult.resultCode != KeyStore.NO_ERROR)
+                && (opResult.resultCode != KeyStore.OP_AUTH_NEEDED)) {
+            throw mKeyStore.getInvalidKeyException(mKey.getAlias(), opResult.resultCode);
         }
+
         if (opResult.token == null) {
             throw new IllegalStateException("Keystore returned null operation token");
         }
+        // The operation handle/token is now either valid for use immediately or needs to be
+        // authorized through user authentication (if the error code was OP_AUTH_NEEDED).
         mOperationToken = opResult.token;
         mOperationHandle = opResult.operationHandle;
         mChunkedStreamer = new KeyStoreCryptoOperationChunkedStreamer(
                 new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
                         mKeyStore, mOperationToken));
+
+        if (opResult.resultCode != KeyStore.NO_ERROR) {
+            // The operation requires user authentication. Check whether such authentication is
+            // possible (e.g., the key may have been permanently invalidated).
+            InvalidKeyException e =
+                    mKeyStore.getInvalidKeyException(mKey.getAlias(), opResult.resultCode);
+            if (!(e instanceof UserNotAuthenticatedException)) {
+                throw e;
+            }
+        }
     }
 
     @Override
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 7bf5475..3ccb588 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -18,12 +18,8 @@
 
 import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
 import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterDefs;
-import android.service.gatekeeper.IGateKeeperService;
 
 import libcore.util.EmptyArray;
 
@@ -347,20 +343,6 @@
         return result;
     }
 
-    private static long getRootSid() {
-        IGateKeeperService gatekeeperService = IGateKeeperService.Stub.asInterface(
-                ServiceManager.getService("android.service.gatekeeper.IGateKeeperService"));
-        if (gatekeeperService == null) {
-            throw new IllegalStateException("Gatekeeper service not available");
-        }
-
-        try {
-            return gatekeeperService.getSecureUserId(UserHandle.myUserId());
-        } catch (RemoteException e) {
-            throw new IllegalStateException("Failed to obtain root SID");
-        }
-    }
-
     /**
      * Adds keymaster arguments to express the key's authorization policy supported by user
      * authentication.
@@ -402,7 +384,7 @@
         } else {
             // The key is authorized for use for the specified amount of time after the user has
             // authenticated. Whatever unlocks the secure lock screen should authorize this key.
-            long rootSid = getRootSid();
+            long rootSid = GateKeeper.getSecureUserId();
             if (rootSid == 0) {
                 throw new IllegalStateException("Secure lock screen must be enabled"
                         + " to create keys requiring user authentication");
diff --git a/keystore/java/android/security/NewFingerprintEnrolledException.java b/keystore/java/android/security/NewFingerprintEnrolledException.java
deleted file mode 100644
index 4fe210b..0000000
--- a/keystore/java/android/security/NewFingerprintEnrolledException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import java.security.InvalidKeyException;
-
-/**
- * Indicates that a cryptographic operation could not be performed because the key used by the
- * operation is permanently invalid because a new fingerprint was enrolled.
- */
-public class NewFingerprintEnrolledException extends InvalidKeyException {
-
-    /**
-     * Constructs a new {@code NewFingerprintEnrolledException} without detail message and cause.
-     */
-    public NewFingerprintEnrolledException() {
-        super("Invalid key: new fingerprint enrolled");
-    }
-
-    /**
-     * Constructs a new {@code NewFingerprintEnrolledException} with the provided detail message and
-     * no cause.
-     */
-    public NewFingerprintEnrolledException(String message) {
-        super(message);
-    }
-}
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
index 66f4dd8..2954fa7 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -20,7 +20,7 @@
 
 /**
  * Indicates that a cryptographic operation could not be performed because the user has not been
- * authenticated recently enough.
+ * authenticated recently enough. Authenticating the user will resolve this issue.
  */
 public class UserNotAuthenticatedException extends InvalidKeyException {
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 4863ed2..e9d6ebc 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1423,7 +1423,7 @@
     }
 
     virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName());
+        OP_LOG("Draw RenderNode %p %s", mRenderNode, mRenderNode->getName());
         if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) {
             mRenderNode->output(level + 1);
         }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 25e6594..3dae543 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.media.audiopolicy.AudioMix;
+import android.util.Log;
 
 import java.util.ArrayList;
 
@@ -32,6 +33,7 @@
  */
 public class AudioSystem
 {
+    private static final String TAG = "AudioSystem";
     /* These values must be kept in sync with system/audio.h */
     /*
      * If these are modified, please also update Settings.System.VOLUME_SETTINGS
@@ -224,6 +226,48 @@
         }
     }
 
+    /**
+     * Handles events for the audio policy manager about dynamic audio policies
+     * @see android.media.audiopolicy.AudioPolicy
+     */
+    public interface DynamicPolicyCallback
+    {
+        void onDynamicPolicyMixStateUpdate(String regId, int state);
+    }
+
+    //keep in sync with include/media/AudioPolicy.h
+    private final static int DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE = 0;
+
+    private static DynamicPolicyCallback sDynPolicyCallback;
+
+    public static void setDynamicPolicyCallback(DynamicPolicyCallback cb)
+    {
+        synchronized (AudioSystem.class) {
+            sDynPolicyCallback = cb;
+            native_register_dynamic_policy_callback();
+        }
+    }
+
+    private static void dynamicPolicyCallbackFromNative(int event, String regId, int val)
+    {
+        DynamicPolicyCallback cb = null;
+        synchronized (AudioSystem.class) {
+            if (sDynPolicyCallback != null) {
+                cb = sDynPolicyCallback;
+            }
+        }
+        if (cb != null) {
+            switch(event) {
+                case DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE:
+                    cb.onDynamicPolicyMixStateUpdate(regId, val);
+                    break;
+                default:
+                    Log.e(TAG, "dynamicPolicyCallbackFromNative: unknown event " + event);
+            }
+        }
+    }
+
+
     /*
      * Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...)
      * Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h
@@ -580,6 +624,9 @@
     public static native int listAudioPatches(ArrayList<AudioPatch> patches, int[] generation);
     public static native int setAudioPortConfig(AudioPortConfig config);
 
+    // declare this instance as having a dynamic policy callback handler
+    private static native final void native_register_dynamic_policy_callback();
+
     // must be kept in sync with value in include/system/audio.h
     public static final int AUDIO_HW_SYNC_INVALID = 0;
 
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 6f1fd24..cb05cc5 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -920,13 +920,7 @@
      * @throws IllegalStateException if track is not initialized.
      */
     public @NonNull PlaybackSettings getPlaybackSettings() {
-        float[] floatArray = new float[2];
-        int[] intArray = new int[2];
-        native_get_playback_settings(floatArray, intArray);
-        return new PlaybackSettings()
-                .setSpeed(floatArray[0])
-                .setPitch(floatArray[1])
-                .setAudioFallbackMode(intArray[0]);
+        return native_get_playback_settings();
     }
 
     /**
@@ -1340,21 +1334,7 @@
         if (settings == null) {
             throw new IllegalArgumentException("settings is null");
         }
-        float[] floatArray;
-        int[] intArray;
-        try {
-            floatArray = new float[] {
-                    settings.getSpeed(),
-                    settings.getPitch(),
-            };
-            intArray = new int[] {
-                    settings.getAudioFallbackMode(),
-                    PlaybackSettings.AUDIO_STRETCH_MODE_DEFAULT,
-            };
-        } catch (IllegalStateException e) {
-            throw new IllegalArgumentException(e);
-        }
-        native_set_playback_settings(floatArray, intArray);
+        native_set_playback_settings(settings);
     }
 
 
@@ -2353,14 +2333,8 @@
     private native final int native_set_playback_rate(int sampleRateInHz);
     private native final int native_get_playback_rate();
 
-    // floatArray must be a non-null array of length >= 2
-    // [0] is speed
-    // [1] is pitch
-    // intArray must be a non-null array of length >= 2
-    // [0] is audio fallback mode
-    // [1] is audio stretch mode
-    private native final void native_set_playback_settings(float[] floatArray, int[] intArray);
-    private native final void native_get_playback_settings(float[] floatArray, int[] intArray);
+    private native final void native_set_playback_settings(@NonNull PlaybackSettings settings);
+    private native final @NonNull PlaybackSettings native_get_playback_settings();
 
     private native final int native_set_marker_pos(int marker);
     private native final int native_get_marker_pos();
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 6aa4d8a..4ffac6d 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -36,20 +36,30 @@
     private int mRouteFlags;
     private String mRegistrationId;
     private int mMixType = MIX_TYPE_INVALID;
-    private int mMixState = MIX_STATE_DISABLED;
+    int mMixState = MIX_STATE_DISABLED;
+    int mCallbackFlags;
 
     /**
      * All parameters are guaranteed valid through the Builder.
      */
-    private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags) {
+    private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags) {
         mRule = rule;
         mFormat = format;
         mRouteFlags = routeFlags;
         mRegistrationId = null;
         mMixType = rule.getTargetMixType();
+        mCallbackFlags = callbackFlags;
     }
 
-    // ROUTE_FLAG_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h
+    // CALLBACK_FLAG_* values: keep in sync with AudioMix::kCbFlag* values defined
+    // in frameworks/av/include/media/AudioPolicy.h
+    /** @hide */
+    public final static int CALLBACK_FLAG_NOTIFY_ACTIVITY = 0x1;
+    // when adding new MIX_FLAG_* flags, add them to this mask of authorized masks:
+    private final static int CALLBACK_FLAGS_ALL = CALLBACK_FLAG_NOTIFY_ACTIVITY;
+
+    // ROUTE_FLAG_* values: keep in sync with MIX_ROUTE_FLAG_* values defined
+    // in frameworks/av/include/media/AudioPolicy.h
     /**
      * An audio mix behavior where the output of the mix is sent to the original destination of
      * the audio signal, i.e. an output device for an output mix, or a recording for an input mix.
@@ -161,6 +171,7 @@
         private AudioMixingRule mRule = null;
         private AudioFormat mFormat = null;
         private int mRouteFlags = 0;
+        private int mCallbackFlags = 0;
 
         /**
          * @hide
@@ -199,6 +210,22 @@
         }
 
         /**
+         * @hide
+         * Only used by AudioPolicyConfig, not a public API.
+         * @param callbackFlags which callbacks are called from native
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setCallbackFlags(int flags) throws IllegalArgumentException {
+            if ((flags != 0) && ((flags & CALLBACK_FLAGS_ALL) == 0)) {
+                throw new IllegalArgumentException("Illegal callback flags 0x"
+                        + Integer.toHexString(flags).toUpperCase());
+            }
+            mCallbackFlags = flags;
+            return this;
+        }
+
+        /**
          * Sets the {@link AudioFormat} for the mix.
          * @param format a non-null {@link AudioFormat} instance.
          * @return the same Builder instance.
@@ -256,7 +283,7 @@
                 }
                 mFormat = new AudioFormat.Builder().setSampleRate(rate).build();
             }
-            return new AudioMix(mRule, mFormat, mRouteFlags);
+            return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags);
         }
     }
 }
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index f128044..423b467 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -189,6 +189,12 @@
 
         @SystemApi
         public AudioPolicy build() {
+            if (mStatusListener != null) {
+                // the AudioPolicy status listener includes updates on each mix activity state
+                for (AudioMix mix : mMixes) {
+                    mix.mCallbackFlags |= AudioMix.CALLBACK_FLAG_NOTIFY_ACTIVITY;
+                }
+            }
             return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper,
                     mFocusListener, mStatusListener);
         }
@@ -432,6 +438,18 @@
                         + afi.getClientId() + "wasNotified=" + wasNotified);
             }
         }
+
+        public void notifyMixStateUpdate(String regId, int state) {
+            for (AudioMix mix : mConfig.getMixes()) {
+                if (mix.getRegistration().equals(regId)) {
+                    mix.mMixState = state;
+                    sendMsg(MSG_MIX_STATE_UPDATE, mix, 0/*ignored*/);
+                    if (DEBUG) {
+                        Log.v(TAG, "notifyMixStateUpdate: regId=" + regId + " state=" + state);
+                    }
+                }
+            }
+        }
     };
 
     //==================================================
@@ -440,6 +458,7 @@
     private final static int MSG_POLICY_STATUS_CHANGE = 0;
     private final static int MSG_FOCUS_GRANT = 1;
     private final static int MSG_FOCUS_LOSS = 2;
+    private final static int MSG_MIX_STATE_UPDATE = 3;
 
     private class EventHandler extends Handler {
         public EventHandler(AudioPolicy ap, Looper looper) {
@@ -464,6 +483,11 @@
                                 (AudioFocusInfo) msg.obj, msg.arg1 != 0);
                     }
                     break;
+                case MSG_MIX_STATE_UPDATE:
+                    if (mStatusListener != null) {
+                        mStatusListener.onMixStateUpdate((AudioMix) msg.obj);
+                    }
+                    break;
                 default:
                     Log.e(TAG, "Unknown event " + msg.what);
             }
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index 917e07b..252f5f4 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -59,6 +59,10 @@
         mMixes.add(mix);
     }
 
+    public ArrayList<AudioMix> getMixes() {
+        return mMixes;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mMixes);
@@ -75,6 +79,8 @@
         for (AudioMix mix : mMixes) {
             // write mix route flags
             dest.writeInt(mix.getRouteFlags());
+            // write callback flags
+            dest.writeInt(mix.mCallbackFlags);
             // write mix format
             dest.writeInt(mix.getFormat().getSampleRate());
             dest.writeInt(mix.getFormat().getEncoding());
@@ -96,6 +102,8 @@
             // read mix route flags
             int routeFlags = in.readInt();
             mixBuilder.setRouteFlags(routeFlags);
+            // read callback flags
+            mixBuilder.setCallbackFlags(in.readInt());
             // read mix format
             int sampleRate = in.readInt();
             int encoding = in.readInt();
diff --git a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
index c777c58..ad8af15 100644
--- a/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
+++ b/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl
@@ -25,4 +25,7 @@
     // callbacks for audio focus
     void notifyAudioFocusGrant(in AudioFocusInfo afi, int requestResult);
     void notifyAudioFocusLoss(in AudioFocusInfo afi, boolean wasNotified);
+
+    // callback for mix activity status update
+    void notifyMixStateUpdate(in String regId, int state);
 }
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 5f586a9..e34f9ed 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -592,8 +592,8 @@
         break;
     }
 
-    // TODO: propagate reason from MediaCodec.
-    int reason = gExceptionReason.reasonHardware;
+    int reason =
+        (err == DEAD_OBJECT) ? gExceptionReason.reasonReclaimed : gExceptionReason.reasonHardware;
     return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get(), reason);
 }
 
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 25c6154..84ae3b4 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -514,10 +514,11 @@
         if (strncmp(mime, "audio/", 6) == 0) {
 
             AMediaCodec *codec = AMediaCodec_createDecoderByType(mime);
-            if (AMediaCodec_configure(codec, format,
-                    NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK
-                || AMediaCodec_start(codec) != AMEDIA_OK
-                || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) {
+            if (codec == NULL
+                    || AMediaCodec_configure(codec, format,
+                            NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK
+                    || AMediaCodec_start(codec) != AMEDIA_OK
+                    || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) {
                 AMediaExtractor_delete(ex);
                 AMediaCodec_delete(codec);
                 AMediaFormat_delete(format);
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index b5e49ce..6876222 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -67,6 +67,10 @@
 
     <!-- Status message of Wi-Fi when it is connected by a Wi-Fi assistant application. [CHAR LIMIT=NONE] -->
     <string name="connected_via_wfa">Connected via Wi\u2011Fi assistant</string>
+    <!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] -->
+    <string name="connected_via_passpoint">Connected via %1$s</string>
+    <!-- Status message of Wi-Fi when network has matching passpoint credentials. [CHAR LIMIT=NONE] -->
+    <string name="available_via_passpoint">Available via %1$s</string>
 
     <!-- Bluetooth settings.  Message when a device is disconnected -->
     <string name="bluetooth_disconnected">Disconnected</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index e8ab220..2fde4f9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -26,6 +26,7 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.LruCache;
 
@@ -199,7 +200,10 @@
     }
 
     public boolean matches(WifiConfiguration config) {
-        return ssid.equals(removeDoubleQuotes(config.SSID)) && security == getSecurity(config);
+        if (config.isPasspoint() && mConfig != null && mConfig.isPasspoint())
+            return config.FQDN.equals(mConfig.providerFriendlyName);
+        else
+            return ssid.equals(removeDoubleQuotes(config.SSID)) && security == getSecurity(config);
     }
 
     public WifiConfiguration getConfig() {
@@ -265,19 +269,47 @@
         return ssid;
     }
 
+    public String getConfigName() {
+        if (mConfig != null && mConfig.isPasspoint()) {
+            return mConfig.providerFriendlyName;
+        } else {
+            return ssid;
+        }
+    }
+
     public DetailedState getDetailedState() {
         return mNetworkInfo != null ? mNetworkInfo.getDetailedState() : null;
     }
 
+    public String getSavedNetworkSummary() {
+        // Update to new summary
+        if (mConfig != null && mConfig.isPasspoint()) {
+            return "";
+        } else {
+            return getSettingsSummary();
+        }
+    }
+
     public String getSummary() {
+        return getSettingsSummary();
+    }
+
+    public String getSettingsSummary() {
         // Update to new summary
         StringBuilder summary = new StringBuilder();
 
-        if (isActive()) { // This is the active connection
+        if (isActive() && mConfig != null && mConfig.isPasspoint()) {
+            // This is the active connection on passpoint
+            summary.append(getSummary(mContext, getDetailedState(),
+                    false, mConfig.providerFriendlyName));
+        } else if (isActive()) {
+            // This is the active connection on non-passpoint network
             summary.append(getSummary(mContext, getDetailedState(),
                     networkId == WifiConfiguration.INVALID_NETWORK_ID));
-        } else if (mConfig != null
-                && mConfig.hasNoInternetAccess()) {
+        } else if (mConfig != null && mConfig.isPasspoint()) {
+            String format = mContext.getString(R.string.available_via_passpoint);
+            summary.append(String.format(format, mConfig.providerFriendlyName));
+        } else if (mConfig != null && mConfig.hasNoInternetAccess()) {
             summary.append(mContext.getString(R.string.wifi_no_internet));
         } else if (mConfig != null && ((mConfig.status == WifiConfiguration.Status.DISABLED &&
                 mConfig.disableReason != WifiConfiguration.DISABLED_UNKNOWN_REASON)
@@ -559,7 +591,11 @@
     }
 
     void loadConfig(WifiConfiguration config) {
-        ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
+        if (config.isPasspoint())
+            ssid = config.providerFriendlyName;
+        else
+            ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
+            
         security = getSecurity(config);
         networkId = config.networkId;
         mConfig = config;
@@ -643,11 +679,25 @@
         return reorder;
     }
 
+    void update(WifiConfiguration config) {
+        mConfig = config;
+        networkId = config.networkId;
+        if (mAccessPointListener != null) {
+            mAccessPointListener.onAccessPointChanged(this);
+        }
+    }
+    
     public static String getSummary(Context context, String ssid, DetailedState state,
-            boolean isEphemeral) {
-        if (state == DetailedState.CONNECTED && isEphemeral && ssid == null) {
-            // Special case for connected + ephemeral networks.
-            return context.getString(R.string.connected_via_wfa);
+            boolean isEphemeral, String passpointProvider) {
+        if (state == DetailedState.CONNECTED && ssid == null) {
+            if (TextUtils.isEmpty(passpointProvider) == false) {
+                // Special case for connected + passpoint networks.
+                String format = context.getString(R.string.connected_via_passpoint);
+                return String.format(format, passpointProvider);
+            } else if (isEphemeral) {
+                // Special case for connected + ephemeral networks.
+                return context.getString(R.string.connected_via_wfa);
+            }
         }
 
         String[] formats = context.getResources().getStringArray((ssid == null)
@@ -661,7 +711,12 @@
     }
 
     public static String getSummary(Context context, DetailedState state, boolean isEphemeral) {
-        return getSummary(context, null, state, isEphemeral);
+        return getSummary(context, null, state, isEphemeral, null);
+    }
+
+    public static String getSummary(Context context, DetailedState state, boolean isEphemeral,
+            String passpointProvider) {
+        return getSummary(context, null, state, isEphemeral, passpointProvider);
     }
 
     public static String convertToQuotedString(String string) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 2eb7abf..09e6912 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -61,6 +61,7 @@
     private final WifiListener mListener;
     private final boolean mIncludeSaved;
     private final boolean mIncludeScans;
+    private final boolean mIncludePasspoints;
 
     private boolean mSavedNetworksExist;
     private boolean mRegistered;
@@ -74,14 +75,18 @@
     Scanner mScanner;
 
     public WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved,
-            boolean includeScans) {
-        this(context, wifiListener, includeSaved, includeScans,
+                       boolean includeScans) {
+        this(context, wifiListener, includeSaved, includeScans, false);
+    }
+    public WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved,
+            boolean includeScans, boolean includePasspoints) {
+        this(context, wifiListener, includeSaved, includeScans, includePasspoints,
                 (WifiManager) context.getSystemService(Context.WIFI_SERVICE));
     }
 
     @VisibleForTesting
     WifiTracker(Context context, WifiListener wifiListener, boolean includeSaved,
-            boolean includeScans, WifiManager wifiManager) {
+            boolean includeScans, boolean includePasspoints, WifiManager wifiManager) {
         if (!includeSaved && !includeScans) {
             throw new IllegalArgumentException("Must include either saved or scans");
         }
@@ -89,6 +94,7 @@
         mWifiManager = wifiManager;
         mIncludeSaved = includeSaved;
         mIncludeScans = includeScans;
+        mIncludePasspoints = includePasspoints;
         mListener = wifiListener;
 
         // check if verbose logging has been turned on or off
@@ -220,21 +226,31 @@
         /** Lookup table to more quickly update AccessPoints by only considering objects with the
          * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
+        WifiConfiguration connectionConfig = null;
 
         final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
         if (configs != null) {
             mSavedNetworksExist = configs.size() != 0;
             for (WifiConfiguration config : configs) {
+                if (mLastInfo != null && mLastInfo.getNetworkId() == config.networkId) {
+                    connectionConfig = config;
+                }
                 if (config.selfAdded && config.numAssociation == 0) {
                     continue;
                 }
                 AccessPoint accessPoint = getCachedOrCreate(config);
                 if (mLastInfo != null && mLastNetworkInfo != null) {
-                    accessPoint.update(mLastInfo, mLastNetworkInfo);
+                    if (config.isPasspoint() == false) {
+                        accessPoint.update(mLastInfo, mLastNetworkInfo);
+                    }
                 }
                 if (mIncludeSaved) {
-                    mAccessPoints.add(accessPoint);
-                    apMap.put(accessPoint.getSsid(), accessPoint);
+                    if (!config.isPasspoint() || mIncludePasspoints)
+                        mAccessPoints.add(accessPoint);
+
+                    if (config.isPasspoint() == false) {
+                        apMap.put(accessPoint.getSsid(), accessPoint);
+                    }
                 } else {
                     // If we aren't using saved networks, drop them into the cache so that
                     // we have access to their saved info.
@@ -264,6 +280,22 @@
                     if (mLastInfo != null && mLastNetworkInfo != null) {
                         accessPoint.update(mLastInfo, mLastNetworkInfo);
                     }
+
+                    if (result.passpointNetwork) {
+                        WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result);
+                        if (config != null) {
+                            accessPoint.update(config);
+                        }
+                    }
+
+                    if (mLastInfo != null && mLastInfo.getBSSID() != null
+                            && mLastInfo.getBSSID().equals(result.BSSID)
+                            && connectionConfig != null && connectionConfig.isPasspoint()) {
+                        /* This network is connected via this passpoint config */
+                        /* SSID match is not going to work for it; so update explicitly */
+                        accessPoint.update(connectionConfig);
+                    }
+
                     mAccessPoints.add(accessPoint);
                     apMap.put(accessPoint.getSsid(), accessPoint);
                 }
@@ -354,8 +386,9 @@
     }
 
     public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
-            boolean includeScans) {
-        WifiTracker tracker = new WifiTracker(context, null, includeSaved, includeScans);
+            boolean includeScans, boolean includePasspoints) {
+        WifiTracker tracker = new WifiTracker(context,
+                null, includeSaved, includeScans, includePasspoints);
         tracker.forceUpdate();
         return tracker.getAccessPoints();
     }
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8b50774..f383a52 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -890,23 +890,32 @@
     <!-- Monitoring dialog device owner body text [CHAR LIMIT=400] -->
     <string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string>
 
-    <!-- Monitoring dialog profile owner body text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
-
-    <!-- Monitoring dialog device and profile owner body text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_device_and_profile_owned">Your device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
-
     <!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites.</string>
+    <string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and websites.</string>
 
     <!-- Monitoring dialog VPN with device owner text [CHAR LIMIT=400] -->
     <string name="monitoring_description_vpn_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to a VPN, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string>
 
     <!-- Monitoring dialog VPN with profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string>
+    <string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string>
 
-    <!-- Monitoring dialog VPN with device and profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn_device_and_profile_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your personal network activity</string>
+    <!-- Name for a generic legacy VPN connection [CHAR LIMIT=20] -->
+    <string name="legacy_vpn_name">VPN</string>
+
+    <!-- Monitoring dialog text for single app (no profile or device owner) [CHAR LIMIT=400] -->
+    <string name="monitoring_description_app">You\'re connected to <xliff:g id="application">%1$s</xliff:g>, which can monitor your network activity including emails, apps and websites.</string>
+
+    <!-- Monitoring dialog text for single app (inside personal profile) [CHAR LIMIT=400] -->
+    <string name="monitoring_description_app_personal">You\'re connected to <xliff:g id="application">%1$s</xliff:g>, which can monitor your personal network activity, including emails, apps and websites.</string>
+
+    <!-- Monitoring dialog text for single app (inside work profile) [CHAR LIMIT=400] -->
+    <string name="monitoring_description_app_work">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>. It is connected to <xliff:g id="application">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nFor more information, contact your administrator.</string>
+
+    <!-- Monitoring dialog text for multiple apps (in personal and work profiles) [CHAR LIMIT=400] -->
+    <string name="monitoring_description_app_personal_work">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>. It is connected to <xliff:g id="application_work">%2$s</xliff:g>, which can monitor your work network activity, including emails, apps and websites.\n\nYou\'re also connected to <xliff:g id="application_personal">%3$s</xliff:g>, which can monitor your personal network activity.</string>
+
+    <!-- Monitoring dialog text for single app (with device owner) [CHAR LIMIT=400] -->
+    <string name="monitoring_description_vpn_app_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to <xliff:g id="application">%2$s</xliff:g>, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string>
 
     <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
     <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index d8e3984..f59e864 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -110,21 +110,15 @@
     }
 
     private void handleRefreshState() {
-        if (mSecurityController.hasDeviceOwner()) {
+        boolean hasDeviceOwner = mSecurityController.hasDeviceOwner();
+        boolean hasVpn = mSecurityController.isVpnEnabled();
+
+        mIsVisible = (hasVpn || hasDeviceOwner);
+        mIsIconVisible = hasVpn;
+        if (hasDeviceOwner) {
             mFooterTextId = R.string.device_owned_footer;
-            mIsVisible = true;
-            mIsIconVisible = false;
-        } else if (mSecurityController.hasProfileOwner()) {
-            mFooterTextId = R.string.profile_owned_footer;
-            mIsVisible = true;
-            mIsIconVisible = false;
-        } else if (mSecurityController.isVpnEnabled()) {
-            mFooterTextId = R.string.vpn_footer;
-            mIsVisible = true;
-            mIsIconVisible = true;
         } else {
-            mIsVisible = false;
-            mIsIconVisible = false;
+            mFooterTextId = R.string.vpn_footer;
         }
         mMainHandler.post(mUpdateDisplayState);
     }
@@ -162,37 +156,17 @@
 
     private String getMessage(boolean hasDeviceOwner, boolean hasProfile, boolean hasVpn) {
         if (hasDeviceOwner) {
-            if (hasProfile) {
-                if (hasVpn) {
-                    return mContext.getString(
-                            R.string.monitoring_description_vpn_device_and_profile_owned,
-                            mSecurityController.getDeviceOwnerName(),
-                            mSecurityController.getProfileOwnerName());
-                } else {
-                    return mContext.getString(
-                            R.string.monitoring_description_device_and_profile_owned,
-                            mSecurityController.getDeviceOwnerName(),
-                            mSecurityController.getProfileOwnerName());
-                }
+            if (hasVpn) {
+                return mContext.getString(R.string.monitoring_description_vpn_device_owned,
+                        mSecurityController.getDeviceOwnerName());
             } else {
-                if (hasVpn) {
-                    return mContext.getString(R.string.monitoring_description_vpn_device_owned,
-                            mSecurityController.getDeviceOwnerName());
-                } else {
-                    return mContext.getString(R.string.monitoring_description_device_owned,
-                            mSecurityController.getDeviceOwnerName());
-                }
+                return mContext.getString(R.string.monitoring_description_device_owned,
+                        mSecurityController.getDeviceOwnerName());
             }
         } else if (hasProfile) {
-            if (hasVpn) {
-                return mContext.getString(
-                        R.string.monitoring_description_vpn_profile_owned,
-                        mSecurityController.getProfileOwnerName());
-            } else {
-                return mContext.getString(
-                        R.string.monitoring_description_profile_owned,
-                        mSecurityController.getProfileOwnerName());
-            }
+            return mContext.getString(
+                    R.string.monitoring_description_vpn_profile_owned,
+                    mSecurityController.getProfileOwnerName());
         } else {
             return mContext.getString(R.string.monitoring_description_vpn);
         }
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 7b13e4b..a8ecc42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2158,7 +2158,7 @@
     }
 
     @Override
-    public void onPinnedModeChanged(final boolean inPinnedMode) {
+    public void onHeadsUpPinnedModeChanged(final boolean inPinnedMode) {
         if (inPinnedMode) {
             mHeadsUpExistenceChangedRunnable.run();
             updateNotificationTranslucency();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index bf27e84..9a6a80e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1852,7 +1852,7 @@
     }
 
     @Override
-    public void onPinnedModeChanged(boolean inPinnedMode) {
+    public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
         if (inPinnedMode) {
             mStatusBarWindowManager.setHeadsUpShowing(true);
         } else {
@@ -1874,6 +1874,7 @@
 
     @Override
     public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+        dismissVolumeDialog();
     }
 
     @Override
@@ -2377,13 +2378,17 @@
         }
         // manually dismiss the volume panel when interacting with the nav bar
         if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
-            if (mVolumeComponent != null) {
-                mVolumeComponent.dismissNow();
-            }
+            dismissVolumeDialog();
         }
         checkBarModes();
     }
 
+    private void dismissVolumeDialog() {
+        if (mVolumeComponent != null) {
+            mVolumeComponent.dismissNow();
+        }
+    }
+
     private void resumeSuspendedAutohide() {
         if (mAutohideSuspended) {
             scheduleAutohide();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index ae98e76..e6edbeac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -347,7 +347,7 @@
     }
 
     @Override
-    public void onPinnedModeChanged(boolean inPinnedMode) {
+    public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 8f83daa..0db9221 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -208,7 +208,7 @@
         }
         mHasPinnedNotification = hasPinnedNotification;
         for (OnHeadsUpChangedListener listener : mListeners) {
-            listener.onPinnedModeChanged(hasPinnedNotification);
+            listener.onHeadsUpPinnedModeChanged(hasPinnedNotification);
         }
     }
 
@@ -539,7 +539,7 @@
          *
          * @param inPinnedMode whether there are any pinned heads-ups
          */
-        void onPinnedModeChanged(boolean inPinnedMode);
+        void onHeadsUpPinnedModeChanged(boolean inPinnedMode);
 
         /**
          * A notification was just pinned to the top.
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index deed895..e6c95b5 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -26,6 +26,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.MoveCallback;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.os.storage.DiskInfo;
@@ -36,6 +37,7 @@
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.internal.R;
 import com.android.systemui.SystemUI;
@@ -57,6 +59,16 @@
     private NotificationManager mNotificationManager;
     private StorageManager mStorageManager;
 
+    private static class MoveInfo {
+        public int moveId;
+        public Bundle extras;
+        public String packageName;
+        public String label;
+        public String volumeUuid;
+    }
+
+    private final SparseArray<MoveInfo> mMoves = new SparseArray<>();
+
     private final StorageEventListener mListener = new StorageEventListener() {
         @Override
         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
@@ -64,20 +76,20 @@
         }
 
         @Override
-        public void onVolumeMetadataChanged(String fsUuid) {
+        public void onVolumeRecordChanged(VolumeRecord rec) {
             // Avoid kicking notifications when getting early metadata before
             // mounted. If already mounted, we're being kicked because of a
             // nickname or init'ed change.
-            final VolumeInfo vol = mStorageManager.findVolumeByUuid(fsUuid);
+            final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid());
             if (vol != null && vol.isMountedReadable()) {
                 onVolumeStateChangedInternal(vol);
             }
+        }
 
-            final VolumeRecord rec = mStorageManager.findRecordByUuid(fsUuid);
-            if (rec == null) {
-                // Private volume was probably just forgotten
-                mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
-            }
+        @Override
+        public void onVolumeForgotten(String fsUuid) {
+            // Stop annoying the user
+            mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
         }
 
         @Override
@@ -97,11 +109,30 @@
 
     private final MoveCallback mMoveCallback = new MoveCallback() {
         @Override
-        public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+        public void onCreated(int moveId, Bundle extras) {
+            final MoveInfo move = new MoveInfo();
+            move.moveId = moveId;
+            move.extras = extras;
+            if (extras != null) {
+                move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
+                move.label = extras.getString(Intent.EXTRA_TITLE);
+                move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID);
+            }
+            mMoves.put(moveId, move);
+        }
+
+        @Override
+        public void onStatusChanged(int moveId, int status, long estMillis) {
+            final MoveInfo move = mMoves.get(moveId);
+            if (move == null) {
+                Log.w(TAG, "Ignoring unknown move " + moveId);
+                return;
+            }
+
             if (PackageManager.isMoveStatusFinished(status)) {
-                onMoveFinished(moveId, moveTitle, status);
+                onMoveFinished(move, status);
             } else {
-                onMoveProgress(moveId, moveTitle, status, estMillis);
+                onMoveProgress(move, status, estMillis);
             }
         }
     };
@@ -149,10 +180,10 @@
                         .setColor(mContext.getColor(R.color.system_notification_accent_color))
                         .setContentTitle(title)
                         .setContentText(text)
+                        .setContentIntent(buildForgetPendingIntent(rec))
                         .setStyle(new Notification.BigTextStyle().bigText(text))
                         .setVisibility(Notification.VISIBILITY_PUBLIC)
                         .setLocalOnly(true)
-                        .setContentIntent(buildForgetPendingIntent(rec))
                         .setCategory(Notification.CATEGORY_SYSTEM)
                         .setOngoing(true)
                         .build();
@@ -175,10 +206,10 @@
                     .setColor(mContext.getColor(R.color.system_notification_accent_color))
                     .setContentTitle(title)
                     .setContentText(text)
+                    .setContentIntent(buildInitPendingIntent(disk))
                     .setStyle(new Notification.BigTextStyle().bigText(text))
                     .setVisibility(Notification.VISIBILITY_PUBLIC)
                     .setLocalOnly(true)
-                    .setContentIntent(buildInitPendingIntent(disk))
                     .setCategory(Notification.CATEGORY_ERROR)
                     .build();
 
@@ -280,13 +311,13 @@
             final CharSequence text = mContext.getString(
                     R.string.ext_media_new_notification_message, disk.getDescription());
 
-            final PendingIntent initAction = buildInitPendingIntent(vol);
+            final PendingIntent initIntent = buildInitPendingIntent(vol);
             return buildNotificationBuilder(vol, title, text)
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
-                            initAction))
+                            initIntent))
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
                             buildUnmountPendingIntent(vol)))
-                    .setContentIntent(initAction)
+                    .setContentIntent(initIntent)
                     .setDeleteIntent(buildSnoozeIntent(vol))
                     .setCategory(Notification.CATEGORY_SYSTEM)
                     .build();
@@ -296,13 +327,13 @@
             final CharSequence text = mContext.getString(
                     R.string.ext_media_ready_notification_message, disk.getDescription());
 
-            final PendingIntent browseAction = buildBrowsePendingIntent(vol);
+            final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
             return buildNotificationBuilder(vol, title, text)
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
-                            browseAction))
+                            browseIntent))
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
                             buildUnmountPendingIntent(vol)))
-                    .setContentIntent(browseAction)
+                    .setContentIntent(browseIntent)
                     .setDeleteIntent(buildSnoozeIntent(vol))
                     .setCategory(Notification.CATEGORY_SYSTEM)
                     .setPriority(Notification.PRIORITY_LOW)
@@ -337,7 +368,7 @@
                 R.string.ext_media_unmountable_notification_message, disk.getDescription());
 
         return buildNotificationBuilder(vol, title, text)
-                .setContentIntent(buildDetailsPendingIntent(vol))
+                .setContentIntent(buildVolumeSettingsPendingIntent(vol))
                 .setCategory(Notification.CATEGORY_ERROR)
                 .build();
     }
@@ -376,10 +407,10 @@
                 .build();
     }
 
-    private void onMoveProgress(int moveId, String moveTitle, int status, long estMillis) {
+    private void onMoveProgress(MoveInfo move, int status, long estMillis) {
         final CharSequence title;
-        if (!TextUtils.isEmpty(moveTitle)) {
-            title = mContext.getString(R.string.ext_media_move_specific_title, moveTitle);
+        if (!TextUtils.isEmpty(move.label)) {
+            title = mContext.getString(R.string.ext_media_move_specific_title, move.label);
         } else {
             title = mContext.getString(R.string.ext_media_move_title);
         }
@@ -391,11 +422,19 @@
             text = DateUtils.formatDuration(estMillis);
         }
 
+        final PendingIntent intent;
+        if (move.packageName != null) {
+            intent = buildWizardMovePendingIntent(move);
+        } else {
+            intent = buildWizardMigratePendingIntent(move);
+        }
+
         final Notification notif = new Notification.Builder(mContext)
                 .setSmallIcon(R.drawable.stat_notify_sdcard)
                 .setColor(mContext.getColor(R.color.system_notification_accent_color))
                 .setContentTitle(title)
                 .setContentText(text)
+                .setContentIntent(intent)
                 .setStyle(new Notification.BigTextStyle().bigText(text))
                 .setVisibility(Notification.VISIBILITY_PUBLIC)
                 .setLocalOnly(true)
@@ -405,19 +444,19 @@
                 .setOngoing(true)
                 .build();
 
-        mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
+        mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
     }
 
-    private void onMoveFinished(int moveId, String moveTitle, int status) {
-        if (!TextUtils.isEmpty(moveTitle)) {
+    private void onMoveFinished(MoveInfo move, int status) {
+        if (move.packageName != null) {
             // We currently ignore finished app moves; just clear the last
             // published progress
-            mNotificationManager.cancelAsUser(moveTitle, MOVE_ID, UserHandle.ALL);
+            mNotificationManager.cancelAsUser(move.packageName, MOVE_ID, UserHandle.ALL);
             return;
         }
 
-        final VolumeInfo vol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
-        final String descrip = mStorageManager.getBestVolumeDescription(vol);
+        final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
+        final String descrip = mStorageManager.getBestVolumeDescription(privateVol);
 
         final CharSequence title;
         final CharSequence text;
@@ -429,19 +468,29 @@
             text = mContext.getString(R.string.ext_media_move_failure_message);
         }
 
+        // Jump back into the wizard flow if we moved to a real disk
+        final PendingIntent intent;
+        if (privateVol != null && privateVol.getDisk() != null) {
+            intent = buildWizardReadyPendingIntent(privateVol.getDisk());
+        } else {
+            intent = buildVolumeSettingsPendingIntent(privateVol);
+        }
+
         final Notification notif = new Notification.Builder(mContext)
                 .setSmallIcon(R.drawable.stat_notify_sdcard)
                 .setColor(mContext.getColor(R.color.system_notification_accent_color))
                 .setContentTitle(title)
                 .setContentText(text)
+                .setContentIntent(intent)
                 .setStyle(new Notification.BigTextStyle().bigText(text))
                 .setVisibility(Notification.VISIBILITY_PUBLIC)
                 .setLocalOnly(true)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setPriority(Notification.PRIORITY_LOW)
+                .setAutoCancel(true)
                 .build();
 
-        mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
+        mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
     }
 
     private int getSmallIcon(DiskInfo disk, int state) {
@@ -513,10 +562,20 @@
                 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
     }
 
-    private PendingIntent buildDetailsPendingIntent(VolumeInfo vol) {
+    private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.Settings$PublicVolumeSettingsActivity");
+        switch (vol.getType()) {
+            case VolumeInfo.TYPE_PRIVATE:
+                intent.setClassName("com.android.settings",
+                        "com.android.settings.Settings$PrivateVolumeSettingsActivity");
+                break;
+            case VolumeInfo.TYPE_PUBLIC:
+                intent.setClassName("com.android.settings",
+                        "com.android.settings.Settings$PublicVolumeSettingsActivity");
+                break;
+            default:
+                return null;
+        }
         intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
 
         final int requestKey = vol.getId().hashCode();
@@ -543,4 +602,38 @@
         return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
                 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
     }
+
+    private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
+        intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
+
+        final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
+        intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+
+        return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
+                PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+    }
+
+    private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.deviceinfo.StorageWizardMoveProgress");
+        intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
+
+        return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
+                PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+    }
+
+    private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.deviceinfo.StorageWizardReady");
+        intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
+
+        final int requestKey = disk.getId().hashCode();
+        return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+                PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+    }
 }
diff --git a/preloaded-classes b/preloaded-classes
index c94623a..d2ed762 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1152,6 +1152,7 @@
 android.provider.Settings$System
 android.provider.Telephony$Mms
 android.renderscript.RenderScript
+android.security.AndroidKeyStoreBCWorkaroundProvider
 android.security.AndroidKeyStoreProvider
 android.speech.tts.TextToSpeechService
 android.speech.tts.TextToSpeechService$SpeechItemV1
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index 6cfdfee..a387aab 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -241,7 +241,7 @@
     }
 
     static void validateUplo(@Uplo int Uplo) {
-        if (Uplo != LEFT && Uplo != RIGHT) {
+        if (Uplo != UPPER && Uplo != LOWER) {
             throw new RSRuntimeException("Invalid uplo passed to BLAS");
         }
     }
@@ -276,36 +276,36 @@
             expectedYDim = 1 + (N - 1) * incY;
         }
         if (X.getType().getX() != expectedXDim ||
-            Y.getType().getY() != expectedXDim) {
+            Y.getType().getX() != expectedYDim) {
             throw new RSRuntimeException("Incorrect vector dimensions for GEMV");
         }
     }
-    void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+    public void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
         validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+    public void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
         validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+    public void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
         validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+    public void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
         validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
 
-    void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+    public void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
         // GBMV has the same validation requirements as GEMV + KL and KU >= 0
         validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
         if (KL < 0 || KU < 0) {
@@ -315,7 +315,7 @@
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU);
     }
-    void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+    public void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
         // GBMV has the same validation requirements as GEMV + KL and KU >= 0
         validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
         if (KL < 0 || KU < 0) {
@@ -325,7 +325,7 @@
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU);
     }
-    void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+    public void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
         // GBMV has the same validation requirements as GEMV + KL and KU >= 0
         validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
         if (KL < 0 || KU < 0) {
@@ -335,7 +335,7 @@
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, KL, KU);
     }
-    void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+    public void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
         // GBMV has the same validation requirements as GEMV + KL and KU >= 0
         validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
         if (KL < 0 || KU < 0) {
@@ -346,8 +346,10 @@
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, KL, KU);
     }
 
-    static void validateTRMV(Element e, @Transpose int TransA, Allocation A, Allocation X, int incX) {
+    static void validateTRMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
         validateTranspose(TransA);
+        validateUplo(Uplo);
+        validateDiag(Diag);
         int N = A.getType().getY();
         if (A.getType().getX() != N) {
             throw new RSRuntimeException("A must be a square matrix for TRMV");
@@ -386,158 +388,174 @@
         }
 
         int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        //is it really doing anything?
         if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
             throw new RSRuntimeException("Invalid dimension for Ap");
         }
-
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
+            throw new RSRuntimeException("Incorrect vector dimensions for TPMV");
         }
 
         return N;
     }
 
-    void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F32(mRS), TransA, A, X, incX);
+    public void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F64(mRS), TransA, A, X, incX);
+    public void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F32_2(mRS), TransA, A, X, incX);
+    public void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F64_2(mRS), TransA, A, X, incX);
+    public void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV
-        validateTRMV(Element.F32(mRS), TransA, A, X, incX);
+
+    public void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV
-        validateTRMV(Element.F64(mRS), TransA, A, X, incX);
+    public void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV
-        validateTRMV(Element.F32_2(mRS), TransA, A, X, incX);
+    public void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV
-        validateTRMV(Element.F64_2(mRS), TransA, A, X, incX);
+    public void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+    public void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
         // TRSV is the same as TRMV
-        validateTRMV(Element.F32(mRS), TransA, A, X, incX);
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
 
     }
-    void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+    public void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
         // TRSV is the same as TRMV
-        validateTRMV(Element.F64(mRS), TransA, A, X, incX);
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
 
     }
-    void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+    public void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
         // TRSV is the same as TRMV
-        validateTRMV(Element.F32_2(mRS), TransA, A, X, incX);
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
 
     }
-    void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+    public void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
         // TRSV is the same as TRMV
-        validateTRMV(Element.F64_2(mRS), TransA, A, X, incX);
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
 
     }
-    void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV
-        validateTRMV(Element.F32(mRS), TransA, A, X, incX);
+    public void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         if (K < 0) {
             throw new RSRuntimeException("Number of diagonals must be positive");
         }
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV
-        validateTRMV(Element.F64(mRS), TransA, A, X, incX);
+    public void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         if (K < 0) {
             throw new RSRuntimeException("Number of diagonals must be positive");
         }
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV
-        validateTRMV(Element.F32_2(mRS), TransA, A, X, incX);
+    public void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         if (K < 0) {
             throw new RSRuntimeException("Number of diagonals must be positive");
         }
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV
-        validateTRMV(Element.F64_2(mRS), TransA, A, X, incX);
+    public void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
         int N = A.getType().getY();
         if (K < 0) {
             throw new RSRuntimeException("Number of diagonals must be positive");
         }
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         // TPSV is same as TPMV
         int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         // TPSV is same as TPMV
         int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0);
     }
-    void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         // TPSV is same as TPMV
         int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
     }
-    void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+    public void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
         // TPSV is same as TPMV
         int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0);
@@ -593,7 +611,9 @@
         if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
             throw new RSRuntimeException("Invalid dimension for Ap");
         }
-
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
             throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
@@ -622,8 +642,10 @@
         if (N < 1 || M < 1) {
             throw new RSRuntimeException("M and N must be 1 or greater for GER");
         }
-
-        int expectedXDim = 1 + (N - 1) * incX;
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
             throw new RSRuntimeException("Incorrect vector dimensions for GER");
         }
@@ -649,7 +671,9 @@
         if (N != A.getType().getY()) {
             throw new RSRuntimeException("A must be a symmetric matrix");
         }
-
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
             throw new RSRuntimeException("Incorrect vector dimensions for SYR");
@@ -674,10 +698,12 @@
         if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
             throw new RSRuntimeException("Invalid dimension for Ap");
         }
-
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+            throw new RSRuntimeException("Incorrect vector dimensions for SPR");
         }
 
         return N;
@@ -700,7 +726,9 @@
         if (N != A.getType().getY()) {
             throw new RSRuntimeException("A must be a symmetric matrix");
         }
-
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         int expectedYDim = 1 + (N - 1) * incY;
         if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
@@ -728,81 +756,91 @@
         if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
             throw new RSRuntimeException("Invalid dimension for Ap");
         }
-
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
         int expectedXDim = 1 + (N - 1) * incX;
         int expectedYDim = 1 + (N - 1) * incY;
         if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+            throw new RSRuntimeException("Incorrect vector dimensions for SPR2");
         }
 
         return N;
     }
 
-    void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+    public void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
         int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        // SBMV is the same as SYMV
+    public void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        // SBMV is the same as SYMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
         int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
+    public void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
         int N = validateSPMV(Element.F32(mRS), Uplo, Ap, X, incX, Y, incY);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         int M = A.getType().getY();
         int N = A.getType().getX();
+        validateGER(Element.F32(mRS), X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0);
     }
-    void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+    public void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
         int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0);
     }
-    void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+    public void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
         int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0);
     }
-    void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         int N = validateSYR2(Element.F32(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+    public void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
         int N = validateSPR2(Element.F32(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0);
     }
-    void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+    public void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
         int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        // SBMV is the same as SYMV
+    public void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        // SBMV is the same as SYMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
         int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
+    public void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
         int N = validateSPMV(Element.F64(mRS), Uplo, Ap, X, incX, Y, incY);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         int M = A.getType().getY();
         int N = A.getType().getX();
+        validateGER(Element.F64(mRS), X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0);
     }
-    void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+    public void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
         int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0);
     }
-    void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+    public void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
         int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0);
     }
-    void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         int N = validateSYR2(Element.F64(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+    public void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
         int N = validateSPR2(Element.F64(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0);
     }
@@ -824,8 +862,10 @@
 
         int M = A.getType().getY();
         int N = A.getType().getX();
-
-        int expectedXDim = 1 + (N - 1) * incX;
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
         if (X.getType().getX() != expectedXDim) {
             throw new RSRuntimeException("Incorrect vector dimensions for GERU");
         }
@@ -836,12 +876,12 @@
 
     }
 
-    void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+    public void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
         // HEMV is the same as SYR2 validation-wise
         int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+    public void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
         // HBMV is the same as SYR2 validation-wise
         int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
         if (K < 0) {
@@ -849,50 +889,50 @@
         }
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+    public void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
         // HPMV is the same as SPR2
         int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         // same as GERU
         validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+    public void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
         // same as SYR
-        int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
+        int N = validateSYR(Element.F32_2(mRS), Uplo, X, incX, A);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0);
     }
-    void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+    public void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
         // equivalent to SPR for validation
         int N = validateSPR(Element.F32_2(mRS), Uplo, X, incX, Ap);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0);
     }
-    void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         // same as SYR2
         int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+    public void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
         // same as SPR2
         int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, Ap.getID(mRS), incX, incY, 0, 0);
     }
-    void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+    public void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
         // HEMV is the same as SYR2 validation-wise
         int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+    public void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
         // HBMV is the same as SYR2 validation-wise
         int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
         if (K < 0) {
@@ -900,40 +940,40 @@
         }
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+    public void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
         // HPMV is the same as SPR2
         int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0);
     }
-    void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         // same as GERU
         validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
         int M = A.getType().getY();
         int N = A.getType().getX();
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+    public void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
         // same as SYR
-        int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
+        int N = validateSYR(Element.F64_2(mRS), Uplo, X, incX, A);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0);
     }
-    void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+    public void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
         // equivalent to SPR for validation
         int N = validateSPR(Element.F64_2(mRS), Uplo, X, incX, Ap);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0);
     }
-    void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+    public void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
         // same as SYR2
         int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0);
     }
-    void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+    public void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
         // same as SPR2
         int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, Ap.getID(mRS), incX, incY, 0, 0);
@@ -945,56 +985,74 @@
      */
 
     static void validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
-        int aX = -1, aY = -1, bX = -1, bY = -1, cX = -1, cY = -1;
+        int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
         if ((A != null && !A.getType().getElement().isCompatible(e)) ||
             (B != null && !B.getType().getElement().isCompatible(e)) ||
             (C != null && !C.getType().getElement().isCompatible(e))) {
             throw new RSRuntimeException("Called BLAS with wrong Element type");
         }
-        if (C != null) {
-            cX = C.getType().getY();
-            cY = C.getType().getX();
+        if (C == null) {
+            //since matrix C is used to store the result, it cannot be null.
+            throw new RSRuntimeException("Allocation C cannot be null");
         }
+        cM = C.getType().getY();
+        cN = C.getType().getX();
+
         if (Side == RIGHT) {
+            if ((A == null && B != null) || (A != null && B == null)) {
+                throw new RSRuntimeException("Provided Matrix A without Matrix B, or vice versa");
+            }
             if (B != null) {
-                bX = A.getType().getY();
-                bY = A.getType().getX();
+                bM = A.getType().getY();
+                bN = A.getType().getX();
             }
             if (A != null) {
-                aX = B.getType().getY();
-                aY = B.getType().getX();
+                aM = B.getType().getY();
+                aN = B.getType().getX();
             }
         } else {
             if (A != null) {
-                if (TransA == TRANSPOSE) {
-                    aY = A.getType().getY();
-                    aX = A.getType().getX();
+                if (TransA != NO_TRANSPOSE) {
+                    aN = A.getType().getY();
+                    aM = A.getType().getX();
                 } else {
-                    aX = A.getType().getY();
-                    aY = A.getType().getX();
+                    aM = A.getType().getY();
+                    aN = A.getType().getX();
                 }
             }
             if (B != null) {
-                if (TransB == TRANSPOSE) {
-                    bY = B.getType().getY();
-                    bX = B.getType().getX();
+                if (TransB != NO_TRANSPOSE) {
+                    bN = B.getType().getY();
+                    bM = B.getType().getX();
                 } else {
-                    bX = B.getType().getY();
-                    bY = B.getType().getX();
+                    bM = B.getType().getY();
+                    bN = B.getType().getX();
                 }
             }
         }
         if (A != null && B != null && C != null) {
-            if (aY != bX || aX != cX || bY != cY) {
+            if (aN != bM || aM != cM || bN != cN) {
                 throw new RSRuntimeException("Called BLAS with invalid dimensions");
             }
         } else if (A != null && C != null) {
-            // A and C only
-            if (aX != cY || aY != cX) {
-                throw new RSRuntimeException("Called BLAS with invalid dimensions");
+            // A and C only, for SYRK
+            if (cM != cN) {
+                throw new RSRuntimeException("Matrix C is not symmetric");
+            }
+            if (TransA != NO_TRANSPOSE) {
+                if (aN != cM) {
+                    throw new RSRuntimeException("Called BLAS with invalid dimensions");
+                }
+            } else {
+                if (aM != cM) {
+                    throw new RSRuntimeException("Called BLAS with invalid dimensions");
+                }
             }
         } else if (A != null && B != null) {
             // A and B only
+            if (aN != bM) {
+                throw new RSRuntimeException("Called BLAS with invalid dimensions");
+            }
         }
 
     }
@@ -1006,14 +1064,14 @@
         validateL3(Element.F32(mRS), TransA, TransB, 0, A, B, C);
 
         int M = -1, N = -1, K = -1;
-        if (TransA == TRANSPOSE) {
+        if (TransA != NO_TRANSPOSE) {
             M = A.getType().getX();
             K = A.getType().getY();
         } else {
             M = A.getType().getY();
             K = A.getType().getX();
         }
-        if (TransB == TRANSPOSE) {
+        if (TransB != NO_TRANSPOSE) {
             N = B.getType().getY();
         } else {
             N = B.getType().getX();
@@ -1027,14 +1085,14 @@
         validateTranspose(TransB);
         validateL3(Element.F64(mRS), TransA, TransB, 0, A, B, C);
         int M = -1, N = -1, K = -1;
-        if (TransA == TRANSPOSE) {
+        if (TransA != NO_TRANSPOSE) {
             M = A.getType().getX();
             K = A.getType().getY();
         } else {
             M = A.getType().getY();
             K = A.getType().getX();
         }
-        if (TransB == TRANSPOSE) {
+        if (TransB != NO_TRANSPOSE) {
             N = B.getType().getY();
         } else {
             N = B.getType().getX();
@@ -1048,14 +1106,14 @@
         validateTranspose(TransB);
         validateL3(Element.F32_2(mRS), TransA, TransB, 0, A, B, C);
         int M = -1, N = -1, K = -1;
-        if (TransA == TRANSPOSE) {
+        if (TransA != NO_TRANSPOSE) {
             M = A.getType().getX();
             K = A.getType().getY();
         } else {
             M = A.getType().getY();
             K = A.getType().getX();
         }
-        if (TransB == TRANSPOSE) {
+        if (TransB != NO_TRANSPOSE) {
             N = B.getType().getY();
         } else {
             N = B.getType().getX();
@@ -1070,14 +1128,14 @@
         validateTranspose(TransB);
         validateL3(Element.F64_2(mRS), TransA, TransB, 0, A, B, C);
         int M = -1, N = -1, K = -1;
-        if (TransA == TRANSPOSE) {
+        if (TransA != NO_TRANSPOSE) {
             M = A.getType().getX();
             K = A.getType().getY();
         } else {
             M = A.getType().getY();
             K = A.getType().getX();
         }
-        if (TransB == TRANSPOSE) {
+        if (TransB != NO_TRANSPOSE) {
             N = B.getType().getY();
         } else {
             N = B.getType().getX();
@@ -1090,6 +1148,10 @@
                       Allocation B, float beta, Allocation C) {
         validateSide(Side);
         validateUplo(Uplo);
+        //For SYMM, Matrix A should be symmetric
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
         validateL3(Element.F32(mRS), 0, 0, Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS),
                                         beta, C.getID(mRS), 0, 0, 0, 0);
@@ -1098,6 +1160,9 @@
                       Allocation B, double beta, Allocation C) {
         validateSide(Side);
         validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
         validateL3(Element.F64(mRS), 0, 0, Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS),
                                         beta, C.getID(mRS), 0, 0, 0, 0);
@@ -1106,6 +1171,9 @@
                       Allocation B, Float2 beta, Allocation C) {
         validateSide(Side);
         validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
         validateL3(Element.F32_2(mRS), 0, 0, Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS),
                                          beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
@@ -1114,6 +1182,9 @@
                       Allocation B, Double2 beta, Allocation C) {
         validateSide(Side);
         validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
         validateL3(Element.F64_2(mRS), 0, 0, Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS),
                                    beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
@@ -1124,7 +1195,7 @@
         validateUplo(Uplo);
         validateL3(Element.F32(mRS), Trans, 0, 0, A, null, C);
         int K = -1;
-        if (Trans == TRANSPOSE) {
+        if (Trans != NO_TRANSPOSE) {
             K = A.getType().getY();
         } else {
             K = A.getType().getX();
@@ -1138,37 +1209,37 @@
         validateUplo(Uplo);
         validateL3(Element.F64(mRS), Trans, 0, 0, A, null, C);
         int K = -1;
-        if (Trans == TRANSPOSE) {
+        if (Trans != NO_TRANSPOSE) {
             K = A.getType().getY();
         } else {
             K = A.getType().getX();
         }
         mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), 0, beta, C.getID(mRS), 0, 0, 0, 0);
     }
-    public void CSYRK(@Uplo int Uplo, @Transpose int Trans, float alphaX, float alphaY, Allocation A, float betaX, float betaY, Allocation C) {
+    public void CSYRK(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Float2 beta, Allocation C) {
         validateTranspose(Trans);
         validateUplo(Uplo);
         validateL3(Element.F32_2(mRS), Trans, 0, 0, A, null, C);
         int K = -1;
-        if (Trans == TRANSPOSE) {
+        if (Trans != NO_TRANSPOSE) {
             K = A.getType().getY();
         } else {
             K = A.getType().getX();
         }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alphaX, alphaY, A.getID(mRS), 0, betaX, betaY,
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), 0, beta.x, beta.y,
                                          C.getID(mRS), 0, 0, 0, 0);
     }
-    public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, double alphaX, double alphaY, Allocation A, double betaX, double betaY, Allocation C) {
+    public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Double2 beta, Allocation C) {
         validateTranspose(Trans);
         validateUplo(Uplo);
         validateL3(Element.F64_2(mRS), Trans, 0, 0, A, null, C);
         int K = -1;
-        if (Trans == TRANSPOSE) {
+        if (Trans != NO_TRANSPOSE) {
             K = A.getType().getY();
         } else {
             K = A.getType().getX();
         }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alphaX, alphaY, A.getID(mRS), 0, betaX, betaY,
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), 0, beta.x, beta.y,
                                    C.getID(mRS), 0, 0, 0, 0);
     }
 
@@ -1189,7 +1260,7 @@
             // check rows versus C
             Cdim = A.getType().getY();
         }
-        if (C.getType().getX() != Cdim && C.getType().getY() != Cdim) {
+        if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
             throw new RSRuntimeException("Invalid symmetric matrix in SYR2K");
         }
         // A dims == B dims
@@ -1245,26 +1316,26 @@
     static void validateTRMM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
         validateSide(Side);
         validateTranspose(TransA);
-        int aX = -1, aY = -1, bX = -1, bY = -1;
+        int aM = -1, aN = -1, bM = -1, bN = -1;
         if (!A.getType().getElement().isCompatible(e) ||
             !B.getType().getElement().isCompatible(e)) {
             throw new RSRuntimeException("Called BLAS with wrong Element type");
         }
-        if (TransA == TRANSPOSE) {
-            aY = A.getType().getY();
-            aX = A.getType().getX();
-        } else {
-            aY = A.getType().getX();
-            aX = A.getType().getY();
+
+        aM = A.getType().getY();
+        aN = A.getType().getX();
+        if (aM != aN) {
+            throw new RSRuntimeException("Called TRMM with a non-symmetric matrix A");
         }
-        bX = B.getType().getY();
-        bY = B.getType().getX();
+
+        bM = B.getType().getY();
+        bN = B.getType().getX();
         if (Side == LEFT) {
-            if (aX == 0 || aY != bX) {
+            if (aN != bM) {
                 throw new RSRuntimeException("Called TRMM with invalid matrices");
             }
         } else {
-            if (bY != aX || aY == 0) {
+            if (bN != aM) {
                 throw new RSRuntimeException("Called TRMM with invalid matrices");
             }
         }
@@ -1299,7 +1370,7 @@
     }
 
     static void validateTRSM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
-        int adim = -1, bX = -1, bY = -1;
+        int adim = -1, bM = -1, bN = -1;
         validateSide(Side);
         validateTranspose(TransA);
         if (!A.getType().getElement().isCompatible(e) ||
@@ -1313,16 +1384,16 @@
             // for now we assume adapters are sufficient, will reevaluate in the future
             throw new RSRuntimeException("Called TRSM with a non-symmetric matrix A");
         }
-        bX = B.getType().getY();
-        bY = B.getType().getX();
+        bM = B.getType().getY();
+        bN = B.getType().getX();
         if (Side == LEFT) {
             // A is M*M
-            if (adim != bY) {
+            if (adim != bM) {
                 throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
             }
         } else {
             // A is N*N
-            if (adim != bX) {
+            if (adim != bN) {
                 throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
             }
         }
@@ -1379,17 +1450,17 @@
             throw new RSRuntimeException("Called HEMM with mismatched B and C");
         }
     }
-    public void CHEMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A, Allocation B, float beta, Allocation C) {
+    public void CHEMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
         validateUplo(Uplo);
         validateHEMM(Element.F32_2(mRS), Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
-                                         alpha, 0, A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0);
+                                         alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
     }
-    public void ZHEMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A, Allocation B, double beta, Allocation C) {
+    public void ZHEMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
         validateUplo(Uplo);
-        validateHEMM(Element.F32_2(mRS), Side, A, B, C);
+        validateHEMM(Element.F64_2(mRS), Side, A, B, C);
         mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
-                                   alpha, 0, A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0);
+                                   alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0);
     }
 
     static void validateHERK(Element e, @Transpose int Trans, Allocation A, Allocation C) {
@@ -1403,11 +1474,11 @@
             throw new RSRuntimeException("Called HERK with non-square C");
         }
         if (Trans == NO_TRANSPOSE) {
-            if (cdim != A.getType().getX()) {
+            if (cdim != A.getType().getY()) {
                 throw new RSRuntimeException("Called HERK with invalid A");
             }
         } else {
-            if (cdim != A.getType().getY()) {
+            if (cdim != A.getType().getX()) {
                 throw new RSRuntimeException("Called HERK with invalid A");
             }
         }
@@ -1416,7 +1487,7 @@
         validateUplo(Uplo);
         validateHERK(Element.F32_2(mRS), Trans, A, C);
         int k = 0;
-        if (Trans == TRANSPOSE) {
+        if (Trans == CONJ_TRANSPOSE) {
             k = A.getType().getY();
         } else {
             k = A.getType().getX();
@@ -1428,7 +1499,7 @@
         validateUplo(Uplo);
         validateHERK(Element.F64_2(mRS), Trans, A, C);
         int k = 0;
-        if (Trans == TRANSPOSE) {
+        if (Trans == CONJ_TRANSPOSE) {
             k = A.getType().getY();
         } else {
             k = A.getType().getX();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 82a77d2..860939c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2060,7 +2060,9 @@
             UserState userState = getUserStateLocked(mUserId);
             if (!mIsAutomation) {
                 if (mService == null && mContext.bindServiceAsUser(
-                        mIntent, this, Context.BIND_AUTO_CREATE, new UserHandle(mUserId))) {
+                        mIntent, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
+                        new UserHandle(mUserId))) {
                     userState.mBindingServices.add(mComponentName);
                 }
             } else {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index f42aef1..17c7e0c 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1492,7 +1492,8 @@
         // RemoteViewsService.
         final long token = Binder.clearCallingIdentity();
         try {
-            mContext.bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
+            mContext.bindServiceAsUser(intent, conn,
+                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                     widget.provider.info.getProfile());
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -2907,7 +2908,8 @@
             UserHandle userHandle) {
         final long token = Binder.clearCallingIdentity();
         try {
-            mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
+            mContext.bindServiceAsUser(intent, connection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                     userHandle);
         } finally {
             Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 0f9090d..4fda370 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1993,7 +1993,8 @@
             if (mHaveConnection && !mVisibleBound) {
                 bindCurrentInputMethodService(
                         mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE
-                                | Context.BIND_TREAT_LIKE_ACTIVITY);
+                                | Context.BIND_TREAT_LIKE_ACTIVITY
+                                | Context.BIND_FOREGROUND_SERVICE);
                 mVisibleBound = true;
             }
             res = true;
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 74adeb7..0925fa5 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -229,6 +229,7 @@
         public static final int VOLUME_FS_UUID_CHANGED = 653;
         public static final int VOLUME_FS_LABEL_CHANGED = 654;
         public static final int VOLUME_PATH_CHANGED = 655;
+        public static final int VOLUME_INTERNAL_PATH_CHANGED = 656;
         public static final int VOLUME_DESTROYED = 659;
 
         public static final int MOVE_STATUS = 660;
@@ -661,6 +662,9 @@
 
             try {
                 mConnector.execute("volume", "reset");
+                for (int userId : mStartedUsers) {
+                    mConnector.execute("volume", "start_user", userId);
+                }
             } catch (NativeDaemonConnectorException e) {
                 Slog.w(TAG, "Failed to reset vold", e);
             }
@@ -902,6 +906,14 @@
                 }
                 break;
             }
+            case VoldResponseCode.VOLUME_INTERNAL_PATH_CHANGED: {
+                if (cooked.length != 3) break;
+                final VolumeInfo vol = mVolumes.get(cooked[1]);
+                if (vol != null) {
+                    vol.internalPath = cooked[2];
+                }
+                break;
+            }
             case VoldResponseCode.VOLUME_DESTROYED: {
                 if (cooked.length != 2) break;
                 mVolumes.remove(cooked[1]);
@@ -1076,7 +1088,7 @@
 
         // TODO: estimate remaining time
         try {
-            mMoveCallback.onStatusChanged(-1, null, status, -1);
+            mMoveCallback.onStatusChanged(-1, status, -1);
         } catch (RemoteException ignored) {
         }
 
@@ -1433,10 +1445,11 @@
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
+        Preconditions.checkNotNull(fsUuid);
         synchronized (mLock) {
             final VolumeRecord rec = mRecords.get(fsUuid);
             rec.nickname = nickname;
-            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+            mCallbacks.notifyVolumeRecordChanged(rec);
             writeSettingsLocked();
         }
     }
@@ -1446,10 +1459,11 @@
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
+        Preconditions.checkNotNull(fsUuid);
         synchronized (mLock) {
             final VolumeRecord rec = mRecords.get(fsUuid);
             rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
-            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+            mCallbacks.notifyVolumeRecordChanged(rec);
             writeSettingsLocked();
         }
     }
@@ -1459,13 +1473,39 @@
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
+        Preconditions.checkNotNull(fsUuid);
         synchronized (mLock) {
             mRecords.remove(fsUuid);
-            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+
+            // TODO: tell vold to forget keys
+
+            // If this had been primary storage, revert back to internal and
+            // reset vold so we bind into new volume into place.
+            if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
+                mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
+                resetIfReadyAndConnected();
+            }
+
+            mCallbacks.notifyVolumeForgotten(fsUuid);
             writeSettingsLocked();
         }
     }
 
+    private void forgetAll() {
+        synchronized (mLock) {
+            for (int i = 0; i < mRecords.size(); i++) {
+                final String fsUuid = mRecords.keyAt(i);
+                mCallbacks.notifyVolumeForgotten(fsUuid);
+            }
+
+            mRecords.clear();
+            writeSettingsLocked();
+
+            mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
+            resetIfReadyAndConnected();
+        }
+    }
+
     @Override
     public String getPrimaryStorageUuid() {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
@@ -2818,8 +2858,9 @@
     private static class Callbacks extends Handler {
         private static final int MSG_STORAGE_STATE_CHANGED = 1;
         private static final int MSG_VOLUME_STATE_CHANGED = 2;
-        private static final int MSG_VOLUME_METADATA_CHANGED = 3;
-        private static final int MSG_DISK_SCANNED = 4;
+        private static final int MSG_VOLUME_RECORD_CHANGED = 3;
+        private static final int MSG_VOLUME_FORGOTTEN = 4;
+        private static final int MSG_DISK_SCANNED = 5;
 
         private final RemoteCallbackList<IMountServiceListener>
                 mCallbacks = new RemoteCallbackList<>();
@@ -2863,8 +2904,12 @@
                     callback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
                     break;
                 }
-                case MSG_VOLUME_METADATA_CHANGED: {
-                    callback.onVolumeMetadataChanged((String) args.arg1);
+                case MSG_VOLUME_RECORD_CHANGED: {
+                    callback.onVolumeRecordChanged((VolumeRecord) args.arg1);
+                    break;
+                }
+                case MSG_VOLUME_FORGOTTEN: {
+                    callback.onVolumeForgotten((String) args.arg1);
                     break;
                 }
                 case MSG_DISK_SCANNED: {
@@ -2890,10 +2935,16 @@
             obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget();
         }
 
-        private void notifyVolumeMetadataChanged(String fsUuid) {
+        private void notifyVolumeRecordChanged(VolumeRecord rec) {
+            final SomeArgs args = SomeArgs.obtain();
+            args.arg1 = rec.clone();
+            obtainMessage(MSG_VOLUME_RECORD_CHANGED, args).sendToTarget();
+        }
+
+        private void notifyVolumeForgotten(String fsUuid) {
             final SomeArgs args = SomeArgs.obtain();
             args.arg1 = fsUuid;
-            obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
+            obtainMessage(MSG_VOLUME_FORGOTTEN, args).sendToTarget();
         }
 
         private void notifyDiskScanned(DiskInfo disk, int volumeCount) {
@@ -2909,11 +2960,8 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
         for (String arg : args) {
-            if ("--clear".equals(arg)) {
-                synchronized (mLock) {
-                    mRecords.clear();
-                    writeSettingsLocked();
-                }
+            if ("--forget-all".equals(arg)) {
+                forgetAll();
             }
         }
 
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 9a6f696..5bce6eb 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -555,7 +555,8 @@
         if (DBG) {
             Slog.w(TAG, "bind service: " + info.getId());
         }
-        if (!bindCurrentSpellCheckerService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+        if (!bindCurrentSpellCheckerService(serviceIntent, connection,
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) {
             Slog.e(TAG, "Failed to get a spell checker service.");
             return;
         }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ac2f5b0..62f168d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2771,26 +2771,10 @@
                                             mAccountName, mAccountType
                                     });
                         }
-                        result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH,
+                        result.putLong(AccountManager.KEY_LAST_AUTHENTICATED_TIME,
                                 lastAuthenticatedTime);
                     }
                 }
-                if (mAuthDetailsRequired) {
-                    long lastAuthenticatedTime = -1;
-                    if (isAccountPresentForCaller(mAccountName, mAccountType)) {
-                        lastAuthenticatedTime = DatabaseUtils.longForQuery(
-                                mAccounts.openHelper.getReadableDatabase(),
-                                "select " + ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS + " from "
-                                        +
-                                        TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
-                                        + ACCOUNTS_TYPE + "=?",
-                                new String[] {
-                                        mAccountName, mAccountType
-                                });
-                    }
-                    result.putLong(AccountManager.KEY_LAST_AUTHENTICATE_TIME_MILLIS_EPOCH,
-                            lastAuthenticatedTime);
-                }
             }
             if (result != null
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 25a98c0..069878e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3113,8 +3113,16 @@
         checkTime(startTime, "startProcess: done updating cpu stats");
 
         try {
-            int uid = app.uid;
+            try {
+                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
+                    // This is caught below as if we had failed to fork zygote
+                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
+                }
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
 
+            int uid = app.uid;
             int[] gids = null;
             int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
             if (!app.isolated) {
@@ -3124,7 +3132,7 @@
                     permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
                             app.userId);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "Unable to retrieve gids", e);
+                    throw e.rethrowAsRuntimeException();
                 }
 
                 /*
@@ -3177,6 +3185,10 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
                 }
             }
+            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
+            if ("true".equals(genCFIDebugProperty)) {
+                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+            }
             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
             }
@@ -10878,8 +10890,8 @@
             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
                 ProcessRecord proc = mLruProcesses.get(i);
                 if (proc.notCachedSinceIdle) {
-                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP
-                            && proc.setProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
+                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
                         if (doKilling && proc.initialIdlePss != 0
                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
@@ -17038,7 +17050,7 @@
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "instrumentation";
-            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
         } else if ((queue = isReceivingBroadcast(app)) != null) {
             // An app that is currently receiving a broadcast also
             // counts as being in the foreground for OOM killer purposes.
@@ -17376,8 +17388,19 @@
                                     // processes).  These should not bring the current process
                                     // into the top state, since they are not on top.  Instead
                                     // give them the best state after that.
-                                    clientProcState =
-                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
+                                        clientProcState =
+                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+                                    } else if (mWakefulness
+                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
+                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
+                                                    != 0) {
+                                        clientProcState =
+                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+                                    } else {
+                                        clientProcState =
+                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                                    }
                                 }
                             }
                         } else {
@@ -17487,7 +17510,7 @@
                         // into the top state, since they are not on top.  Instead
                         // give them the best state after that.
                         clientProcState =
-                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
                     }
                 }
                 if (procState > clientProcState) {
@@ -17527,7 +17550,7 @@
                 case ActivityManager.PROCESS_STATE_SERVICE:
                     // These all are longer-term states, so pull them up to the top
                     // of the background states, but not all the way to the top state.
-                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                    procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
                     break;
                 default:
                     // Otherwise, top is a better choice, so take it.
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index 423e540..cd37041 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -87,7 +87,16 @@
             sb.append("IMP ");
         }
         if ((flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
-            sb.append("ACT ");
+            sb.append("WACT ");
+        }
+        if ((flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) {
+            sb.append("FGSA ");
+        }
+        if ((flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
+            sb.append("FGS ");
+        }
+        if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+            sb.append("LACT ");
         }
         if ((flags&Context.BIND_VISIBLE) != 0) {
             sb.append("VIS ");
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eb28ed0..06fba34 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -65,6 +65,7 @@
 import android.media.VolumePolicy;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
+import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicy;
 import android.media.audiopolicy.AudioPolicyConfig;
 import android.media.audiopolicy.IAudioPolicyCallback;
@@ -206,6 +207,7 @@
     private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 22;
     private static final int MSG_PERSIST_MICROPHONE_MUTE = 23;
     private static final int MSG_UNMUTE_STREAM = 24;
+    private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 25;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -4337,6 +4339,9 @@
                 case MSG_UNMUTE_STREAM:
                     onUnmuteStream(msg.arg1, msg.arg2);
                     break;
+                case MSG_DYN_POLICY_MIX_STATE_UPDATE:
+                    onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
+                    break;
             }
         }
     }
@@ -5758,6 +5763,8 @@
     //==========================================================================================
     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
             boolean hasFocusListener) {
+        AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
+
         if (DEBUG_AP) Log.d(TAG, "registerAudioPolicy for " + pcb.asBinder()
                 + " with config:" + policyConfig);
         String regId = null;
@@ -5853,6 +5860,39 @@
     }
 
     //======================
+    // Audio policy callback from AudioSystem
+    //======================
+    private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
+            new AudioSystem.DynamicPolicyCallback() {
+        public void onDynamicPolicyMixStateUpdate(String regId, int state) {
+            if (!TextUtils.isEmpty(regId)) {
+                sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
+                        state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
+            }
+        }
+    };
+
+    private void onDynPolicyMixStateUpdate(String regId, int state) {
+        if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
+        synchronized (mAudioPolicies) {
+            for (AudioPolicyProxy policy : mAudioPolicies.values()) {
+                for (AudioMix mix : policy.getMixes()) {
+                    if (mix.getRegistration().equals(regId)) {
+                        try {
+                            policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
+                                    + policy.mPolicyCallback.asBinder(), e);
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+
+    }
+
+    //======================
     // Audio policy proxy
     //======================
     /**
@@ -5861,8 +5901,7 @@
      */
     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
         private static final String TAG = "AudioPolicyProxy";
-        AudioPolicyConfig mConfig;
-        IAudioPolicyCallback mPolicyToken;
+        IAudioPolicyCallback mPolicyCallback;
         boolean mHasFocusListener;
         /**
          * Audio focus ducking behavior for an audio policy.
@@ -5877,19 +5916,19 @@
                 boolean hasFocusListener) {
             super(config);
             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
-            mPolicyToken = token;
+            mPolicyCallback = token;
             mHasFocusListener = hasFocusListener;
             if (mHasFocusListener) {
-                mMediaFocusControl.addFocusFollower(mPolicyToken);
+                mMediaFocusControl.addFocusFollower(mPolicyCallback);
             }
             connectMixes();
         }
 
         public void binderDied() {
             synchronized (mAudioPolicies) {
-                Log.i(TAG, "audio policy " + mPolicyToken + " died");
+                Log.i(TAG, "audio policy " + mPolicyCallback + " died");
                 release();
-                mAudioPolicies.remove(mPolicyToken.asBinder());
+                mAudioPolicies.remove(mPolicyCallback.asBinder());
             }
         }
 
@@ -5902,7 +5941,7 @@
                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
             }
             if (mHasFocusListener) {
-                mMediaFocusControl.removeFocusFollower(mPolicyToken);
+                mMediaFocusControl.removeFocusFollower(mPolicyCallback);
             }
             AudioSystem.registerPolicyMixes(mMixes, false);
         }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 3d478f9..a07591c9 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -529,8 +529,9 @@
                 throw new IllegalArgumentException("At least one address must be specified");
             }
             Connection connection = new Connection();
-            if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
-                        new UserHandle(mUserHandle))) {
+            if (!mContext.bindServiceAsUser(intent, connection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                    new UserHandle(mUserHandle))) {
                 throw new IllegalStateException("Cannot bind " + config.user);
             }
 
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 768ccf2..cff4814 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -136,7 +136,8 @@
             intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
             try {
                 if (!mContext.bindServiceAsUser(intent, mCurrentDream,
-                        Context.BIND_AUTO_CREATE, new UserHandle(userId))) {
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                        new UserHandle(userId))) {
                     Slog.e(TAG, "Unable to bind dream service: " + intent);
                     stopDream(true /*immediate*/);
                     return;
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index d3240ec..6bd646d 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -952,13 +952,18 @@
                     return GPS_POSITION_MODE_STANDALONE;
                 }
             }
+            // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
+            // such mode when it is available
+            if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
+                return GPS_POSITION_MODE_MS_BASED;
+            }
+            // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
+            // do fallback only for single-shot requests, because it is too expensive to do for
+            // periodic requests as well
             if (singleShot
                     && hasCapability(GPS_CAPABILITY_MSA)
                     && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
                 return GPS_POSITION_MODE_MS_ASSISTED;
-            } else if (hasCapability(GPS_CAPABILITY_MSB)
-                    && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
-                return GPS_POSITION_MODE_MS_BASED;
             }
         }
         return GPS_POSITION_MODE_STANDALONE;
diff --git a/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java b/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java
index a5fe9f2..ba98a0a 100644
--- a/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java
+++ b/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java
@@ -190,7 +190,8 @@
             Intent service = new Intent(RemoteDisplayState.SERVICE_INTERFACE);
             service.setComponent(mComponentName);
             try {
-                mBound = mContext.bindServiceAsUser(service, this, Context.BIND_AUTO_CREATE,
+                mBound = mContext.bindServiceAsUser(service, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                         new UserHandle(mUserId));
                 if (!mBound && DEBUG) {
                     Slog.d(TAG, this + ": Bind failed");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 57df1c3..0ae6735 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2023,7 +2023,7 @@
         // to have data access.  Otherwise, we restrict data access to only
         // the top apps.
         mCurForegroundState = (!mRestrictBackground && (mRestrictPower || mDeviceIdleMode))
-                ? ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+                ? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
                 : ActivityManager.PROCESS_STATE_TOP;
 
         // update rules for all installed applications
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 50e03a2..0035d01 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -561,9 +561,10 @@
             final int callingUid = Binder.getCallingUid();
             final DevicePolicyManagerInternal dpmi = LocalServices.getService(
                     DevicePolicyManagerInternal.class);
-            if (dpmi.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)
-                    || dpmi.isActiveAdminWithPolicy(callingUid,
-                            DeviceAdminInfo.USES_POLICY_DEVICE_OWNER)) {
+
+            // Device owners are also profile owners so it is enough to check for that.
+            if (dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
+                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)) {
                 return;
             }
         }
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
index 6a04688c..b5b97d6 100644
--- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -64,7 +64,7 @@
     }
 
     @Override
-    public boolean isValidConditionid(Uri id) {
+    public boolean isValidConditionId(Uri id) {
         return ZenModeConfig.isValidCountdownConditionId(id);
     }
 
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
new file mode 100644
index 0000000..425e222
--- /dev/null
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.service.notification.Condition;
+import android.service.notification.IConditionProvider;
+import android.service.notification.ZenModeConfig;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.notification.NotificationManagerService.DumpFilter;
+
+import java.io.PrintWriter;
+
+/**
+ * Built-in zen condition provider for calendar event-based conditions.
+ */
+public class EventConditionProvider extends SystemConditionProviderService {
+    private static final String TAG = "ConditionProviders";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    public static final ComponentName COMPONENT =
+            new ComponentName("android", EventConditionProvider.class.getName());
+    private static final String NOT_SHOWN = "...";
+
+    private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>();
+
+    private boolean mConnected;
+    private boolean mRegistered;
+
+    public EventConditionProvider() {
+        if (DEBUG) Slog.d(TAG, "new EventConditionProvider()");
+    }
+
+    @Override
+    public ComponentName getComponent() {
+        return COMPONENT;
+    }
+
+    @Override
+    public boolean isValidConditionId(Uri id) {
+        return ZenModeConfig.isValidEventConditionId(id);
+    }
+
+    @Override
+    public void dump(PrintWriter pw, DumpFilter filter) {
+        pw.println("    EventConditionProvider:");
+        pw.print("      mConnected="); pw.println(mConnected);
+        pw.print("      mRegistered="); pw.println(mRegistered);
+        pw.println("      mSubscriptions=");
+        for (Uri conditionId : mSubscriptions) {
+            pw.print("        ");
+            pw.println(conditionId);
+        }
+    }
+
+    @Override
+    public void onConnected() {
+        if (DEBUG) Slog.d(TAG, "onConnected");
+        mConnected = true;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (DEBUG) Slog.d(TAG, "onDestroy");
+        mConnected = false;
+    }
+
+    @Override
+    public void onRequestConditions(int relevance) {
+        if (DEBUG) Slog.d(TAG, "onRequestConditions relevance=" + relevance);
+        // does not advertise conditions
+    }
+
+    @Override
+    public void onSubscribe(Uri conditionId) {
+        if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
+        if (!ZenModeConfig.isValidEventConditionId(conditionId)) {
+            notifyCondition(conditionId, Condition.STATE_FALSE, "badCondition");
+            return;
+        }
+        mSubscriptions.add(conditionId);
+        evaluateSubscriptions();
+    }
+
+    @Override
+    public void onUnsubscribe(Uri conditionId) {
+        if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId);
+        if (mSubscriptions.remove(conditionId)) {
+            evaluateSubscriptions();
+        }
+    }
+
+    @Override
+    public void attachBase(Context base) {
+        attachBaseContext(base);
+    }
+
+    @Override
+    public IConditionProvider asInterface() {
+        return (IConditionProvider) onBind(null);
+    }
+
+    private void evaluateSubscriptions() {
+        for (Uri conditionId : mSubscriptions) {
+            notifyCondition(conditionId, Condition.STATE_FALSE, "notImplemented");
+        }
+    }
+
+    private void notifyCondition(Uri conditionId, int state, String reason) {
+        if (DEBUG) Slog.d(TAG, "notifyCondition " + Condition.stateToString(state)
+                + " reason=" + reason);
+        notifyCondition(createCondition(conditionId, state));
+    }
+
+    private Condition createCondition(Uri id, int state) {
+        final String summary = NOT_SHOWN;
+        final String line1 = NOT_SHOWN;
+        final String line2 = NOT_SHOWN;
+        return new Condition(id, summary, line1, line2, 0, state, Condition.FLAG_RELEVANT_ALWAYS);
+    }
+
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 9ccb2ea..b92c734 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -495,7 +495,7 @@
                                 Slog.v(TAG, getCaption() + " connection lost: " + name);
                             }
                         },
-                        Context.BIND_AUTO_CREATE,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                         new UserHandle(userid)))
                 {
                     mServicesBinding.remove(servicesBindingTag);
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 383d56c..0912e97 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -69,7 +69,7 @@
     }
 
     @Override
-    public boolean isValidConditionid(Uri id) {
+    public boolean isValidConditionId(Uri id) {
         return ZenModeConfig.isValidScheduleConditionId(id);
     }
 
diff --git a/services/core/java/com/android/server/notification/SystemConditionProviderService.java b/services/core/java/com/android/server/notification/SystemConditionProviderService.java
index a217623..3282a69a 100644
--- a/services/core/java/com/android/server/notification/SystemConditionProviderService.java
+++ b/services/core/java/com/android/server/notification/SystemConditionProviderService.java
@@ -32,5 +32,5 @@
     abstract public void attachBase(Context context);
     abstract public IConditionProvider asInterface();
     abstract public ComponentName getComponent();
-    abstract public boolean isValidConditionid(Uri id);
+    abstract public boolean isValidConditionId(Uri id);
 }
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 766d6c5..fa314de 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -38,20 +38,19 @@
     private final ConditionProviders mConditionProviders;
     private final ArrayMap<Uri, ComponentName> mSubscriptions = new ArrayMap<>();
 
-    private CountdownConditionProvider mCountdown;
-    private ScheduleConditionProvider mSchedule;
     private boolean mFirstEvaluation = true;
 
     public ZenModeConditions(ZenModeHelper helper, ConditionProviders conditionProviders) {
         mHelper = helper;
         mConditionProviders = conditionProviders;
         if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.COUNTDOWN_PATH)) {
-            mCountdown = new CountdownConditionProvider();
-            mConditionProviders.addSystemProvider(mCountdown);
+            mConditionProviders.addSystemProvider(new CountdownConditionProvider());
         }
         if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.SCHEDULE_PATH)) {
-            mSchedule = new ScheduleConditionProvider();
-            mConditionProviders.addSystemProvider(mSchedule);
+            mConditionProviders.addSystemProvider(new ScheduleConditionProvider());
+        }
+        if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.EVENT_PATH)) {
+            mConditionProviders.addSystemProvider(new EventConditionProvider());
         }
         mConditionProviders.setCallback(this);
     }
@@ -128,7 +127,7 @@
         final Uri id = rule.conditionId;
         boolean isSystemCondition = false;
         for (SystemConditionProviderService sp : mConditionProviders.getSystemProviders()) {
-            if (sp.isValidConditionid(id)) {
+            if (sp.isValidConditionId(id)) {
                 mConditionProviders.ensureRecordExists(sp.getComponent(), id, sp.asInterface());
                 rule.component = sp.getComponent();
                 isSystemCondition = true;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a406175..09096ff 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -969,8 +969,11 @@
         public void onPackageInstalled(String basePackageName, int returnCode, String msg,
                 Bundle extras) {
             if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) {
+                boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
                 Notification notification = buildSuccessNotification(mContext,
-                        mContext.getResources().getString(R.string.package_installed_device_owner),
+                        mContext.getResources()
+                                .getString(update ? R.string.package_updated_device_owner :
+                                        R.string.package_installed_device_owner),
                         basePackageName,
                         mUserId);
                 if (notification != null) {
@@ -980,6 +983,7 @@
                 }
             }
             final Intent fillIn = new Intent();
+            fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
             fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
             fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
                     PackageManager.installStatusToPublicStatus(returnCode));
@@ -1030,6 +1034,7 @@
                         R.color.system_notification_accent_color))
                 .setContentTitle(packageLabel)
                 .setContentText(contentText)
+                .setStyle(new Notification.BigTextStyle().bigText(contentText))
                 .setLargeIcon(packageIcon)
                 .build();
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8a19056..11ab042 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -155,6 +155,7 @@
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
 import android.security.KeyStore;
 import android.security.SystemKeyStore;
 import android.system.ErrnoException;
@@ -298,7 +299,6 @@
     static final int SCAN_BOOTING = 1<<8;
     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
-    static final int SCAN_REPLACING = 1<<11;
     static final int SCAN_REQUIRE_KNOWN = 1<<12;
 
     static final int REMOVE_CHATTY = 1<<16;
@@ -1558,6 +1558,11 @@
                 }
             }
         }
+
+        @Override
+        public void onVolumeForgotten(String fsUuid) {
+            // TODO: remove all packages hosted on this uuid
+        }
     };
 
     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) {
@@ -1597,6 +1602,12 @@
                         res.origPackage);
                 break;
             }
+            case PackageManager.INSTALL_SUCCEEDED: {
+                extras = new Bundle();
+                extras.putBoolean(Intent.EXTRA_REPLACING,
+                        res.removedInfo != null && res.removedInfo.removedPackage != null);
+                break;
+            }
         }
         return extras;
     }
@@ -2374,6 +2385,18 @@
     }
 
     @Override
+    public boolean isPackageFrozen(String packageName) {
+        synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (ps != null) {
+                return ps.frozen;
+            }
+        }
+        Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen");
+        return true;
+    }
+
+    @Override
     public boolean isPackageAvailable(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return false;
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
@@ -6476,14 +6499,6 @@
             }
         }
 
-        // Request the ActivityManager to kill the process(only for existing packages)
-        // so that we do not end up in a confused state while the user is still using the older
-        // version of the application while the new one gets installed.
-        if ((scanFlags & SCAN_REPLACING) != 0) {
-            killApplication(pkg.applicationInfo.packageName,
-                        pkg.applicationInfo.uid, "update pkg");
-        }
-
         // Also need to kill any apps that are dependent on the library.
         if (clientLibPkgs != null) {
             for (int i=0; i<clientLibPkgs.size(); i++) {
@@ -10791,16 +10806,17 @@
     private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
             UserHandle user, String installerPackageName, String volumeUuid,
             PackageInstalledInfo res) {
-        PackageParser.Package oldPackage;
-        String pkgName = pkg.packageName;
-        int[] allUsers;
-        boolean[] perUserInstalled;
+        final PackageParser.Package oldPackage;
+        final String pkgName = pkg.packageName;
+        final int[] allUsers;
+        final boolean[] perUserInstalled;
+        final boolean weFroze;
 
         // First find the old package info and check signatures
         synchronized(mPackages) {
             oldPackage = mPackages.get(pkgName);
             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
-            PackageSetting ps = mSettings.mPackages.get(pkgName);
+            final PackageSetting ps = mSettings.mPackages.get(pkgName);
             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
                 // default to original signature matching
                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
@@ -10824,15 +10840,35 @@
             for (int i = 0; i < allUsers.length; i++) {
                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
             }
+
+            // Mark the app as frozen to prevent launching during the upgrade
+            // process, and then kill all running instances
+            if (!ps.frozen) {
+                ps.frozen = true;
+                weFroze = true;
+            } else {
+                weFroze = false;
+            }
         }
 
-        boolean sysPkg = (isSystemApp(oldPackage));
-        if (sysPkg) {
-            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
-                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
-        } else {
-            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
-                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
+        // Now that we're guarded by frozen state, kill app during upgrade
+        killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg");
+
+        try {
+            boolean sysPkg = (isSystemApp(oldPackage));
+            if (sysPkg) {
+                replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
+                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
+            } else {
+                replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
+                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
+            }
+        } finally {
+            // Regardless of success or failure of upgrade steps above, always
+            // unfreeze the package if we froze it
+            if (weFroze) {
+                unfreezePackage(pkgName);
+            }
         }
     }
 
@@ -10962,8 +10998,6 @@
             }
         }
 
-        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
-
         res.removedInfo.uid = oldPkg.applicationInfo.uid;
         res.removedInfo.removedPackage = packageName;
         // Remove existing system package
@@ -11308,7 +11342,7 @@
         startIntentFilterVerifications(args.user.getIdentifier(), pkg);
 
         if (replace) {
-            replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
+            replacePackageLI(pkg, parseFlags, scanFlags, args.user,
                     installerPackageName, volumeUuid, res);
         } else {
             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
@@ -14194,6 +14228,15 @@
         sendResourcesChangedBroadcast(false, false, unloaded, null);
     }
 
+    private void unfreezePackage(String packageName) {
+        synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (ps != null) {
+                ps.frozen = false;
+            }
+        }
+    }
+
     @Override
     public int movePackage(final String packageName, final String volumeUuid) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
@@ -14203,7 +14246,7 @@
             movePackageInternal(packageName, volumeUuid, moveId);
         } catch (PackageManagerException e) {
             Slog.d(TAG, "Failed to move " + packageName, e);
-            mMoveCallbacks.notifyStatusChanged(moveId, null,
+            mMoveCallbacks.notifyStatusChanged(moveId,
                     PackageManager.MOVE_FAILED_INTERNAL_ERROR);
         }
         return moveId;
@@ -14221,7 +14264,7 @@
         final String packageAbiOverride;
         final int appId;
         final String seinfo;
-        final String moveTitle;
+        final String label;
 
         // reader
         synchronized (mPackages) {
@@ -14234,14 +14277,19 @@
             if (pkg.applicationInfo.isSystemApp()) {
                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
                         "Cannot move system application");
-            } else if (pkg.mOperationPending) {
-                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
-                        "Attempt to move package which has pending operations");
             }
 
-            // TODO: yell if already in desired location
+            if (Objects.equals(ps.volumeUuid, volumeUuid)) {
+                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+                        "Package already moved to " + volumeUuid);
+            }
 
-            pkg.mOperationPending = true;
+            if (ps.frozen) {
+                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
+                        "Failed to move already frozen package");
+            }
+
+            ps.frozen = true;
 
             currentAsec = pkg.applicationInfo.isForwardLocked()
                     || pkg.applicationInfo.isExternalAsec();
@@ -14251,9 +14299,17 @@
             packageAbiOverride = ps.cpuAbiOverrideString;
             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
             seinfo = pkg.applicationInfo.seinfo;
-            moveTitle = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
+            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
         }
 
+        // Now that we're guarded by frozen state, kill app during upgrade
+        killApplication(packageName, appId, "move pkg");
+
+        final Bundle extras = new Bundle();
+        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
+        extras.putString(Intent.EXTRA_TITLE, label);
+        mMoveCallbacks.notifyCreated(moveId, extras);
+
         int installFlags;
         final boolean moveData;
 
@@ -14268,6 +14324,7 @@
             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
                     || !volume.isMountedWritable()) {
+                unfreezePackage(packageName);
                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                         "Move location not mounted private volume");
             }
@@ -14279,27 +14336,21 @@
         }
 
         Slog.d(TAG, "Moving " + packageName + " from " + currentVolumeUuid + " to " + volumeUuid);
-        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 10);
+        mMoveCallbacks.notifyStatusChanged(moveId, 10);
 
         if (moveData) {
             synchronized (mInstallLock) {
                 // TODO: split this into separate copy and delete operations
                 if (mInstaller.moveUserDataDirs(currentVolumeUuid, volumeUuid, packageName, appId,
                         seinfo) != 0) {
-                    synchronized (mPackages) {
-                        final PackageParser.Package pkg = mPackages.get(packageName);
-                        if (pkg != null) {
-                            pkg.mOperationPending = false;
-                        }
-                    }
-
+                    unfreezePackage(packageName);
                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
-                            "Failed to move private data");
+                            "Failed to move private data to " + volumeUuid);
                 }
             }
         }
 
-        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 50);
+        mMoveCallbacks.notifyStatusChanged(moveId, 50);
 
         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
             @Override
@@ -14313,28 +14364,22 @@
                 Slog.d(TAG, "Install result for move: "
                         + PackageManager.installStatusToString(returnCode, msg));
 
-                // We usually have a new package now after the install, but if
-                // we failed we need to clear the pending flag on the original
-                // package object.
-                synchronized (mPackages) {
-                    final PackageParser.Package pkg = mPackages.get(packageName);
-                    if (pkg != null) {
-                        pkg.mOperationPending = false;
-                    }
-                }
+                // Regardless of success or failure of the move operation,
+                // always unfreeze the package
+                unfreezePackage(packageName);
 
                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
                 switch (status) {
                     case PackageInstaller.STATUS_SUCCESS:
-                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
+                        mMoveCallbacks.notifyStatusChanged(moveId,
                                 PackageManager.MOVE_SUCCEEDED);
                         break;
                     case PackageInstaller.STATUS_FAILURE_STORAGE:
-                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
+                        mMoveCallbacks.notifyStatusChanged(moveId,
                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                         break;
                     default:
-                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
+                        mMoveCallbacks.notifyStatusChanged(moveId,
                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                         break;
                 }
@@ -14357,12 +14402,19 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
 
         final int realMoveId = mNextMoveId.getAndIncrement();
-        final String realTitle = null;
+        final Bundle extras = new Bundle();
+        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
+        mMoveCallbacks.notifyCreated(realMoveId, extras);
 
         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
             @Override
-            public void onStatusChanged(int moveId, String title, int status, long estMillis) {
-                mMoveCallbacks.notifyStatusChanged(realMoveId, realTitle, status, estMillis);
+            public void onCreated(int moveId, Bundle extras) {
+                // Ignored
+            }
+
+            @Override
+            public void onStatusChanged(int moveId, int status, long estMillis) {
+                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
             }
         };
 
@@ -14717,6 +14769,7 @@
     }
 
     private static class MoveCallbacks extends Handler {
+        private static final int MSG_CREATED = 1;
         private static final int MSG_STATUS_CHANGED = 2;
 
         private final RemoteCallbackList<IPackageMoveObserver>
@@ -14754,26 +14807,37 @@
         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
                 throws RemoteException {
             switch (what) {
+                case MSG_CREATED: {
+                    callback.onCreated(args.argi1, (Bundle) args.arg2);
+                    break;
+                }
                 case MSG_STATUS_CHANGED: {
-                    callback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
-                            (long) args.arg4);
+                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
                     break;
                 }
             }
         }
 
-        private void notifyStatusChanged(int moveId, String moveTitle, int status) {
-            notifyStatusChanged(moveId, moveTitle, status, -1);
+        private void notifyCreated(int moveId, Bundle extras) {
+            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
+
+            final SomeArgs args = SomeArgs.obtain();
+            args.argi1 = moveId;
+            args.arg2 = extras;
+            obtainMessage(MSG_CREATED, args).sendToTarget();
         }
 
-        private void notifyStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+        private void notifyStatusChanged(int moveId, int status) {
+            notifyStatusChanged(moveId, status, -1);
+        }
+
+        private void notifyStatusChanged(int moveId, int status, long estMillis) {
             Slog.v(TAG, "Move " + moveId + " status " + status);
 
             final SomeArgs args = SomeArgs.obtain();
             args.argi1 = moveId;
-            args.arg2 = moveTitle;
-            args.argi3 = status;
-            args.arg4 = estMillis;
+            args.argi2 = status;
+            args.arg3 = estMillis;
             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
 
             synchronized (mLastStatus) {
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 5429517..f62c00c 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -108,6 +108,13 @@
 
     int installStatus = PKG_INSTALL_COMPLETE;
 
+    /**
+     * Non-persisted value indicating this package has been temporarily frozen,
+     * usually during a critical section of the package update pipeline. The
+     * platform will refuse to launch packages in a frozen state.
+     */
+    boolean frozen = false;
+
     PackageSettingBase origPackage;
 
     /** Package name of the app that installed this package */
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 252c16a..f9c248d 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3759,6 +3759,10 @@
             pw.print(Integer.toHexString(System.identityHashCode(ps)));
             pw.println("):");
 
+        if (ps.frozen) {
+            pw.print(prefix); pw.println("  FROZEN!");
+        }
+
         if (ps.realName != null) {
             pw.print(prefix); pw.print("  compat name=");
             pw.println(ps.name);
@@ -3790,9 +3794,6 @@
             pw.print(prefix); pw.print("  priavateFlags="); printFlags(pw,
                     ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
             pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
-            if (ps.pkg.mOperationPending) {
-                pw.print(prefix); pw.println("  mOperationPending=true");
-            }
             pw.print(prefix); pw.print("  supportsScreens=[");
             boolean first = true;
             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 22fee22..9abdf21 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -96,7 +96,8 @@
         TelecomServiceConnection serviceConnection = new TelecomServiceConnection();
         Intent intent = new Intent(SERVICE_ACTION);
         intent.setComponent(SERVICE_COMPONENT);
-        int flags = Context.BIND_IMPORTANT | Context.BIND_AUTO_CREATE;
+        int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
+                | Context.BIND_AUTO_CREATE;
 
         // Bind to Telecom and register the service
         if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) {
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index fb7d186..e5c5b2bc 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -276,7 +276,8 @@
         // Schedules a restart for when connecting times out. If the connection succeeds,
         // the restart is canceled in mCallback's onConnected.
         scheduleRestart();
-        mBound = context.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, user);
+        mBound = context.bindServiceAsUser(intent, mConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, user);
         if (mBound) {
             mContext.registerReceiver(mBroadcastReceiver, alarmFilter, PERMISSION, null);
         } else {
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 5972247..56816f9 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -529,7 +529,9 @@
 
             Intent i = new Intent(TvInputService.SERVICE_INTERFACE).setComponent(component);
             serviceState.bound = mContext.bindServiceAsUser(
-                    i, serviceState.connection, Context.BIND_AUTO_CREATE, new UserHandle(userId));
+                    i, serviceState.connection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
+                    new UserHandle(userId));
         } else if (serviceState.service != null && !maintainConnection) {
             // This means that the service is already connected but its state indicates that we have
             // nothing to do with it. Then, disconnect the service.
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 54be380..755c414 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1038,7 +1038,8 @@
                             mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
                     0, null, new UserHandle(serviceUserId)));
             if (!mContext.bindServiceAsUser(intent, newConn,
-                    Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI,
+                    Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI
+                            | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                     new UserHandle(serviceUserId))) {
                 String msg = "Unable to bind service: "
                         + componentName;
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index a8c739c..0ab1657 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -507,7 +507,8 @@
         }
         mBinding = true;
         mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE, new UserHandle(mUserId));
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                new UserHandle(mUserId));
     }
 
     private void ensureUnbound() {
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index 7ab3840..85c876a 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -365,7 +365,7 @@
         }
 
         mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE, mUserHandle);
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, mUserHandle);
 
         final long startMillis = SystemClock.uptimeMillis();
         while (true) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 61ec162..f439915 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -229,7 +229,7 @@
         Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
         intent.setComponent(mComponent);
         mBound = mContext.bindServiceAsUser(intent, mConnection,
-                Context.BIND_AUTO_CREATE, new UserHandle(mUser));
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUser));
         if (!mBound) {
             Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
         }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 9634ab8..42eb6c3 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -180,7 +180,8 @@
         if (mBound) {
             if (!mFullyBound) {
                 mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
-                        Context.BIND_AUTO_CREATE|Context.BIND_TREAT_LIKE_ACTIVITY,
+                        Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY
+                                | Context.BIND_FOREGROUND_SERVICE,
                         new UserHandle(mUser));
             }
             mShown = true;