Merge "Acquire the wake lock to ensure RoR isn't delayed"
diff --git a/Android.bp b/Android.bp
index 003f0ad..8548920 100644
--- a/Android.bp
+++ b/Android.bp
@@ -103,8 +103,8 @@
         ":android.hardware.security.secureclock-V1-java-source",
         ":android.security.apc-java-source",
         ":android.security.authorization-java-source",
+        ":android.security.legacykeystore-java-source",
         ":android.security.maintenance-java-source",
-        ":android.security.vpnprofilestore-java-source",
         ":android.system.keystore2-V1-java-source",
         ":credstore_aidl",
         ":dumpstate_aidl",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 1f15dfd..7c1eb9f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -681,6 +681,7 @@
     char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
     char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
     std::string fingerprintBuf;
+    char javaZygoteForkLoopBuf[sizeof("-XX:ForceJavaZygoteForkLoop=") + PROPERTY_VALUE_MAX];
     char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX];
     char opaqueJniIds[sizeof("-Xopaque-jni-ids:") - 1 + PROPERTY_VALUE_MAX];
     char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX];
@@ -899,6 +900,13 @@
     parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");
 
     /*
+     * Enable/disable zygote native fork loop.
+     */
+    parseRuntimeOption("dalvik.vm.force-java-zygote-fork-loop",
+                       javaZygoteForkLoopBuf,
+                       "-XX:ForceJavaZygoteForkLoop=");
+
+    /*
      * Enable debugging only for apps forked from zygote.
      */
     if (zygote) {
diff --git a/keystore/java/android/security/GenerateRkpKey.java b/keystore/java/android/security/GenerateRkpKey.java
index a1a7aa8..053bec74 100644
--- a/keystore/java/android/security/GenerateRkpKey.java
+++ b/keystore/java/android/security/GenerateRkpKey.java
@@ -22,6 +22,10 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * GenerateKey is a helper class to handle interactions between Keystore and the RemoteProvisioner
@@ -41,14 +45,25 @@
  * @hide
  */
 public class GenerateRkpKey {
+    private static final String TAG = "GenerateRkpKey";
+
+    private static final int NOTIFY_EMPTY = 0;
+    private static final int NOTIFY_KEY_GENERATED = 1;
+    private static final int TIMEOUT_MS = 1000;
 
     private IGenerateRkpKeyService mBinder;
     private Context mContext;
+    private CountDownLatch mCountDownLatch;
 
     private ServiceConnection mConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
             mBinder = IGenerateRkpKeyService.Stub.asInterface(service);
+            mCountDownLatch.countDown();
+        }
+
+        @Override public void onBindingDied(ComponentName className) {
+            mCountDownLatch.countDown();
         }
 
         @Override
@@ -64,36 +79,52 @@
         mContext = context;
     }
 
-    /**
-     * Fulfills the use case of (2) described in the class documentation. Blocks until the
-     * RemoteProvisioner application can get new attestation keys signed by the server.
-     */
-    public void notifyEmpty(int securityLevel) throws RemoteException {
+    private void bindAndSendCommand(int command, int securityLevel) throws RemoteException {
         Intent intent = new Intent(IGenerateRkpKeyService.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        if (comp == null) {
+            // On a system that does not use RKP, the RemoteProvisioner app won't be installed.
+            return;
+        }
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
-            throw new RemoteException("Failed to bind to GenerateKeyService");
+        mCountDownLatch = new CountDownLatch(1);
+        if (!mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+            throw new RemoteException("Failed to bind to GenerateRkpKeyService");
+        }
+        try {
+            mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Interrupted: ", e);
         }
         if (mBinder != null) {
-            mBinder.generateKey(securityLevel);
+            switch (command) {
+                case NOTIFY_EMPTY:
+                    mBinder.generateKey(securityLevel);
+                    break;
+                case NOTIFY_KEY_GENERATED:
+                    mBinder.notifyKeyGenerated(securityLevel);
+                    break;
+                default:
+                    Log.e(TAG, "Invalid case for command");
+            }
+        } else {
+            Log.e(TAG, "Binder object is null; failed to bind to GenerateRkpKeyService.");
         }
         mContext.unbindService(mConnection);
     }
 
     /**
-     * FUlfills the use case of (1) described in the class documentation. Non blocking call.
+     * Fulfills the use case of (2) described in the class documentation. Blocks until the
+     * RemoteProvisioner application can get new attestation keys signed by the server.
+     */
+    public void notifyEmpty(int securityLevel) throws RemoteException {
+        bindAndSendCommand(NOTIFY_EMPTY, securityLevel);
+    }
+
+    /**
+     * Fulfills the use case of (1) described in the class documentation. Non blocking call.
      */
     public void notifyKeyGenerated(int securityLevel) throws RemoteException {
-        Intent intent = new Intent(IGenerateRkpKeyService.class.getName());
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
-            throw new RemoteException("Failed to bind to GenerateKeyService");
-        }
-        if (mBinder != null) {
-            mBinder.notifyKeyGenerated(securityLevel);
-        }
-        mContext.unbindService(mConnection);
+        bindAndSendCommand(NOTIFY_KEY_GENERATED, securityLevel);
     }
 }
diff --git a/keystore/java/android/security/LegacyVpnProfileStore.java b/keystore/java/android/security/LegacyVpnProfileStore.java
index 1d2738e..c85b6b1 100644
--- a/keystore/java/android/security/LegacyVpnProfileStore.java
+++ b/keystore/java/android/security/LegacyVpnProfileStore.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
-import android.security.vpnprofilestore.IVpnProfileStore;
+import android.security.legacykeystore.ILegacyKeystore;
 import android.util.Log;
 
 /**
@@ -32,14 +32,14 @@
 public class LegacyVpnProfileStore {
     private static final String TAG = "LegacyVpnProfileStore";
 
-    public static final int SYSTEM_ERROR = IVpnProfileStore.ERROR_SYSTEM_ERROR;
-    public static final int PROFILE_NOT_FOUND = IVpnProfileStore.ERROR_PROFILE_NOT_FOUND;
+    public static final int SYSTEM_ERROR = ILegacyKeystore.ERROR_SYSTEM_ERROR;
+    public static final int PROFILE_NOT_FOUND = ILegacyKeystore.ERROR_ENTRY_NOT_FOUND;
 
-    private static final String VPN_PROFILE_STORE_SERVICE_NAME = "android.security.vpnprofilestore";
+    private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
 
-    private static IVpnProfileStore getService() {
-        return IVpnProfileStore.Stub.asInterface(
-                    ServiceManager.checkService(VPN_PROFILE_STORE_SERVICE_NAME));
+    private static ILegacyKeystore getService() {
+        return ILegacyKeystore.Stub.asInterface(
+                    ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
     }
 
     /**
@@ -52,7 +52,7 @@
      */
     public static boolean put(@NonNull String alias, @NonNull byte[] profile) {
         try {
-            getService().put(alias, profile);
+            getService().put(alias, ILegacyKeystore.UID_SELF, profile);
             return true;
         } catch (Exception e) {
             Log.e(TAG, "Failed to put vpn profile.", e);
@@ -71,7 +71,7 @@
      */
     public static byte[] get(@NonNull String alias) {
         try {
-            return getService().get(alias);
+            return getService().get(alias, ILegacyKeystore.UID_SELF);
         } catch (ServiceSpecificException e) {
             if (e.errorCode != PROFILE_NOT_FOUND) {
                 Log.e(TAG, "Failed to get vpn profile.", e);
@@ -90,7 +90,7 @@
      */
     public static boolean remove(@NonNull String alias) {
         try {
-            getService().remove(alias);
+            getService().remove(alias, ILegacyKeystore.UID_SELF);
             return true;
         } catch (ServiceSpecificException e) {
             if (e.errorCode != PROFILE_NOT_FOUND) {
@@ -110,7 +110,7 @@
      */
     public static @NonNull String[] list(@NonNull String prefix) {
         try {
-            final String[] aliases = getService().list(prefix);
+            final String[] aliases = getService().list(prefix, ILegacyKeystore.UID_SELF);
             for (int i = 0; i < aliases.length; ++i) {
                 aliases[i] = aliases[i].substring(prefix.length());
             }
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index dc7f3dd..c048f3b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -580,7 +580,7 @@
             } catch (RemoteException e) {
                 // This is not really an error state, and necessarily does not apply to non RKP
                 // systems or hybrid systems where RKP is not currently turned on.
-                Log.d(TAG, "Couldn't connect to the RemoteProvisioner backend.");
+                Log.d(TAG, "Couldn't connect to the RemoteProvisioner backend.", e);
             }
             success = true;
             return new KeyPair(publicKey, publicKey.getPrivateKey());
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java
index 3d78828..141d4dc 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java
@@ -44,6 +44,8 @@
                     return requestLskf();
                 case "clear-lskf":
                     return clearLskf();
+                case "is-lskf-captured":
+                    return isLskfCaptured();
                 case "reboot-and-apply":
                     return rebootAndApply();
                 default:
@@ -74,6 +76,14 @@
         return 0;
     }
 
+    private int isLskfCaptured() throws RemoteException {
+        String packageName = getNextArgRequired();
+        boolean captured = mService.isLskfCaptured(packageName);
+        PrintWriter pw = getOutPrintWriter();
+        pw.printf("%s LSKF capture status: %s\n", packageName, captured ? "true" : "false");
+        return 0;
+    }
+
     private int rebootAndApply() throws RemoteException {
         String packageName = getNextArgRequired();
         String rebootReason = getNextArgRequired();
@@ -90,8 +100,9 @@
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
         pw.println("Recovery system commands:");
-        pw.println("  request-lskf <token>");
+        pw.println("  request-lskf <package_name>");
         pw.println("  clear-lskf");
-        pw.println("  reboot-and-apply <token> <reason>");
+        pw.println("  is-lskf-captured <package_name>");
+        pw.println("  reboot-and-apply <package_name> <reason>");
     }
 }
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 9fcf034..d80f0bd 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -30,11 +30,19 @@
         "libcutils",
         "liblog",
     ],
+    target: {
+        linux_glibc: {
+            static_libs: [
+                // libbinder is only available for linux
+                "libbinder",
+            ],
+        },
+    },
 
     // This tool is prebuilt if we're doing an app-only build.
     product_variables: {
         unbundled_build: {
-          enabled: false,
+            enabled: false,
         },
     },
 }