Loading core/java/android/webkit/WebViewZygote.java +29 −27 Original line number Original line Diff line number Diff line Loading @@ -150,6 +150,7 @@ public class WebViewZygote { } } try { try { String abi = sPackage.applicationInfo.primaryCpuAbi; sZygote = Process.ZYGOTE_PROCESS.startChildZygote( sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "com.android.internal.os.WebViewZygoteInit", "webview_zygote", "webview_zygote", Loading @@ -158,18 +159,21 @@ public class WebViewZygote { null, // gids null, // gids 0, // runtimeFlags 0, // runtimeFlags "webview_zygote", // seInfo "webview_zygote", // seInfo sPackage.applicationInfo.primaryCpuAbi, // abi abi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), TextUtils.join(",", Build.SUPPORTED_ABIS), null, // instructionSet null, // instructionSet Process.FIRST_ISOLATED_UID, Process.FIRST_ISOLATED_UID, Process.LAST_ISOLATED_UID); Process.LAST_ISOLATED_UID); ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress()); // All the work below is usually done by LoadedApk, but the zygote can't talk to if (sPackageOriginalAppInfo.sourceDir.equals(sPackage.applicationInfo.sourceDir)) { // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so // No stub WebView is involved here, so we can preload the package the "clean" way // doesn't have an ActivityThread and can't use Binder. // using the ApplicationInfo. // Instead, figure out the paths here, in the system server where we have access to sZygote.preloadApp(sPackage.applicationInfo, abi); // the package manager. Reuse the logic from LoadedApk to determine the correct } else { // paths and pass them to the zygote as strings. // Legacy path to support the stub WebView. // Reuse the logic from LoadedApk to determine the correct paths and pass them to // the zygote as strings. final List<String> zipPaths = new ArrayList<>(10); final List<String> zipPaths = new ArrayList<>(10); final List<String> libPaths = new ArrayList<>(10); final List<String> libPaths = new ArrayList<>(10); LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths); LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths); Loading @@ -179,18 +183,16 @@ public class WebViewZygote { String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo); String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo); // In the case where the ApplicationInfo has been modified by the stub WebView, // Use the original ApplicationInfo to determine what the original classpath would // we need to use the original ApplicationInfo to determine what the original classpath // have been to use as a cache key. // would have been to use as a cache key. LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null); LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null); final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) : final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) : TextUtils.join(File.pathSeparator, zipPaths); TextUtils.join(File.pathSeparator, zipPaths); ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress()); Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey, sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey, Build.SUPPORTED_ABIS[0]); Build.SUPPORTED_ABIS[0]); } } catch (Exception e) { } catch (Exception e) { Log.e(LOGTAG, "Error connecting to webview zygote", e); Log.e(LOGTAG, "Error connecting to webview zygote", e); stopZygoteLocked(); stopZygoteLocked(); Loading core/java/com/android/internal/os/WebViewZygoteInit.java +40 −7 Original line number Original line Diff line number Diff line Loading @@ -17,8 +17,9 @@ package com.android.internal.os; package com.android.internal.os; import android.app.ApplicationLoaders; import android.app.ApplicationLoaders; import android.app.LoadedApk; import android.content.pm.ApplicationInfo; import android.net.LocalSocket; import android.net.LocalSocket; import android.os.Build; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.webkit.WebViewFactory; import android.webkit.WebViewFactory; Loading Loading @@ -65,6 +66,34 @@ class WebViewZygoteInit { return true; return true; } } @Override protected boolean canPreloadApp() { return true; } @Override protected void handlePreloadApp(ApplicationInfo appInfo) { Log.i(TAG, "Beginning application preload for " + appInfo.packageName); LoadedApk loadedApk = new LoadedApk(null, appInfo, null, null, false, true, false); ClassLoader loader = loadedApk.getClassLoader(); doPreload(loader, WebViewFactory.getWebViewLibrary(appInfo)); // Add the APK to the Zygote's list of allowed files for children. Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir); if (appInfo.splitSourceDirs != null) { for (String path : appInfo.splitSourceDirs) { Zygote.nativeAllowFileAcrossFork(path); } } if (appInfo.sharedLibraryFiles != null) { for (String path : appInfo.sharedLibraryFiles) { Zygote.nativeAllowFileAcrossFork(path); } } Log.i(TAG, "Application preload done"); } @Override @Override protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName, protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName, String cacheKey) { String cacheKey) { Loading @@ -76,16 +105,22 @@ class WebViewZygoteInit { ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( packagePath, libsPath, cacheKey); packagePath, libsPath, cacheKey); // Load the native library using WebViewLibraryLoader to share the RELRO data with other // processes. WebViewLibraryLoader.loadNativeLibrary(loader, libFileName); // Add the APK to the Zygote's list of allowed files for children. // Add the APK to the Zygote's list of allowed files for children. String[] packageList = TextUtils.split(packagePath, File.pathSeparator); String[] packageList = TextUtils.split(packagePath, File.pathSeparator); for (String packageEntry : packageList) { for (String packageEntry : packageList) { Zygote.nativeAllowFileAcrossFork(packageEntry); Zygote.nativeAllowFileAcrossFork(packageEntry); } } doPreload(loader, libFileName); Log.i(TAG, "Package preload done"); } private void doPreload(ClassLoader loader, String libFileName) { // Load the native library using WebViewLibraryLoader to share the RELRO data with other // processes. WebViewLibraryLoader.loadNativeLibrary(loader, libFileName); // Once we have the classloader, look up the WebViewFactoryProvider implementation and // Once we have the classloader, look up the WebViewFactoryProvider implementation and // call preloadInZygote() on it to give it the opportunity to preload the native library // call preloadInZygote() on it to give it the opportunity to preload the native library // and perform any other initialisation work that should be shared among the children. // and perform any other initialisation work that should be shared among the children. Loading Loading @@ -114,8 +149,6 @@ class WebViewZygoteInit { } catch (IOException ioe) { } catch (IOException ioe) { throw new IllegalStateException("Error writing to command socket", ioe); throw new IllegalStateException("Error writing to command socket", ioe); } } Log.i(TAG, "Package preload done"); } } } } Loading Loading
core/java/android/webkit/WebViewZygote.java +29 −27 Original line number Original line Diff line number Diff line Loading @@ -150,6 +150,7 @@ public class WebViewZygote { } } try { try { String abi = sPackage.applicationInfo.primaryCpuAbi; sZygote = Process.ZYGOTE_PROCESS.startChildZygote( sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "com.android.internal.os.WebViewZygoteInit", "webview_zygote", "webview_zygote", Loading @@ -158,18 +159,21 @@ public class WebViewZygote { null, // gids null, // gids 0, // runtimeFlags 0, // runtimeFlags "webview_zygote", // seInfo "webview_zygote", // seInfo sPackage.applicationInfo.primaryCpuAbi, // abi abi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), TextUtils.join(",", Build.SUPPORTED_ABIS), null, // instructionSet null, // instructionSet Process.FIRST_ISOLATED_UID, Process.FIRST_ISOLATED_UID, Process.LAST_ISOLATED_UID); Process.LAST_ISOLATED_UID); ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress()); // All the work below is usually done by LoadedApk, but the zygote can't talk to if (sPackageOriginalAppInfo.sourceDir.equals(sPackage.applicationInfo.sourceDir)) { // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so // No stub WebView is involved here, so we can preload the package the "clean" way // doesn't have an ActivityThread and can't use Binder. // using the ApplicationInfo. // Instead, figure out the paths here, in the system server where we have access to sZygote.preloadApp(sPackage.applicationInfo, abi); // the package manager. Reuse the logic from LoadedApk to determine the correct } else { // paths and pass them to the zygote as strings. // Legacy path to support the stub WebView. // Reuse the logic from LoadedApk to determine the correct paths and pass them to // the zygote as strings. final List<String> zipPaths = new ArrayList<>(10); final List<String> zipPaths = new ArrayList<>(10); final List<String> libPaths = new ArrayList<>(10); final List<String> libPaths = new ArrayList<>(10); LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths); LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths); Loading @@ -179,18 +183,16 @@ public class WebViewZygote { String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo); String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo); // In the case where the ApplicationInfo has been modified by the stub WebView, // Use the original ApplicationInfo to determine what the original classpath would // we need to use the original ApplicationInfo to determine what the original classpath // have been to use as a cache key. // would have been to use as a cache key. LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null); LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null); final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) : final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) : TextUtils.join(File.pathSeparator, zipPaths); TextUtils.join(File.pathSeparator, zipPaths); ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress()); Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey, sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey, Build.SUPPORTED_ABIS[0]); Build.SUPPORTED_ABIS[0]); } } catch (Exception e) { } catch (Exception e) { Log.e(LOGTAG, "Error connecting to webview zygote", e); Log.e(LOGTAG, "Error connecting to webview zygote", e); stopZygoteLocked(); stopZygoteLocked(); Loading
core/java/com/android/internal/os/WebViewZygoteInit.java +40 −7 Original line number Original line Diff line number Diff line Loading @@ -17,8 +17,9 @@ package com.android.internal.os; package com.android.internal.os; import android.app.ApplicationLoaders; import android.app.ApplicationLoaders; import android.app.LoadedApk; import android.content.pm.ApplicationInfo; import android.net.LocalSocket; import android.net.LocalSocket; import android.os.Build; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.webkit.WebViewFactory; import android.webkit.WebViewFactory; Loading Loading @@ -65,6 +66,34 @@ class WebViewZygoteInit { return true; return true; } } @Override protected boolean canPreloadApp() { return true; } @Override protected void handlePreloadApp(ApplicationInfo appInfo) { Log.i(TAG, "Beginning application preload for " + appInfo.packageName); LoadedApk loadedApk = new LoadedApk(null, appInfo, null, null, false, true, false); ClassLoader loader = loadedApk.getClassLoader(); doPreload(loader, WebViewFactory.getWebViewLibrary(appInfo)); // Add the APK to the Zygote's list of allowed files for children. Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir); if (appInfo.splitSourceDirs != null) { for (String path : appInfo.splitSourceDirs) { Zygote.nativeAllowFileAcrossFork(path); } } if (appInfo.sharedLibraryFiles != null) { for (String path : appInfo.sharedLibraryFiles) { Zygote.nativeAllowFileAcrossFork(path); } } Log.i(TAG, "Application preload done"); } @Override @Override protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName, protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName, String cacheKey) { String cacheKey) { Loading @@ -76,16 +105,22 @@ class WebViewZygoteInit { ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( packagePath, libsPath, cacheKey); packagePath, libsPath, cacheKey); // Load the native library using WebViewLibraryLoader to share the RELRO data with other // processes. WebViewLibraryLoader.loadNativeLibrary(loader, libFileName); // Add the APK to the Zygote's list of allowed files for children. // Add the APK to the Zygote's list of allowed files for children. String[] packageList = TextUtils.split(packagePath, File.pathSeparator); String[] packageList = TextUtils.split(packagePath, File.pathSeparator); for (String packageEntry : packageList) { for (String packageEntry : packageList) { Zygote.nativeAllowFileAcrossFork(packageEntry); Zygote.nativeAllowFileAcrossFork(packageEntry); } } doPreload(loader, libFileName); Log.i(TAG, "Package preload done"); } private void doPreload(ClassLoader loader, String libFileName) { // Load the native library using WebViewLibraryLoader to share the RELRO data with other // processes. WebViewLibraryLoader.loadNativeLibrary(loader, libFileName); // Once we have the classloader, look up the WebViewFactoryProvider implementation and // Once we have the classloader, look up the WebViewFactoryProvider implementation and // call preloadInZygote() on it to give it the opportunity to preload the native library // call preloadInZygote() on it to give it the opportunity to preload the native library // and perform any other initialisation work that should be shared among the children. // and perform any other initialisation work that should be shared among the children. Loading Loading @@ -114,8 +149,6 @@ class WebViewZygoteInit { } catch (IOException ioe) { } catch (IOException ioe) { throw new IllegalStateException("Error writing to command socket", ioe); throw new IllegalStateException("Error writing to command socket", ioe); } } Log.i(TAG, "Package preload done"); } } } } Loading