Merge "ZygoteInit: warm up JCA providers during preload" into nyc-dev
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5554182..a3e41e4 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -56,6 +56,8 @@
 import java.io.InputStreamReader;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.security.Security;
+import java.security.Provider;
 import java.util.ArrayList;
 
 /**
@@ -198,6 +200,7 @@
         // Ask the WebViewFactory to do any initialization that must run in the zygote process,
         // for memory sharing purposes.
         WebViewFactory.prepareWebViewInZygote();
+        warmUpJcaProviders();
         Log.d(TAG, "end preload");
     }
 
@@ -220,6 +223,24 @@
     }
 
     /**
+     * Warm up the providers that are already registered.
+     *
+     * By doing it here we avoid that each app does it when requesting a service from the
+     * provider for the first time.
+     */
+    private static void warmUpJcaProviders() {
+        long startTime = SystemClock.uptimeMillis();
+        Trace.traceBegin(
+                Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
+        for (Provider p : Security.getProviders()) {
+            p.warmUpServiceProvision();
+        }
+        Log.i(TAG, "Warmed up JCA providers in "
+                + (SystemClock.uptimeMillis()-startTime) + "ms.");
+        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
+    }
+
+    /**
      * Performs Zygote process initialization. Loads and initializes
      * commonly used classes.
      *