Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97b0ca1e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use new app preload path for WebView zygote."

parents c18eb1c3 e032061d
Loading
Loading
Loading
Loading
+29 −27
Original line number Original line Diff line number Diff line
@@ -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",
@@ -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);
@@ -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();
+40 −7
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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.
@@ -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");
        }
        }
    }
    }