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

Commit dd4bb316 authored by Tobias Sargeant's avatar Tobias Sargeant Committed by Stephen Li
Browse files

Refactor ZygoteInit to support a WebView-specific zygote.

This is a non-functional change that separates out functionality
that should be shared between the system zygote and the WebView
zygote from that which is system zygote specific.

* Move MethodAndArgsCaller to Zygote.
* Split out server socket functions into ZygoteServer.
* Add a new (stub, for now) WebViewZygoteInit class.

Bug: 22084679
Bug: 21643067
(cherry picked from commit ba816e0c)
(cherry picked from commit b9679dc1)

Change-Id: Iefdb0784dd08ac09a23aafe18663c13dce421775
parent 82df72dc
Loading
Loading
Loading
Loading
+5 −5
Original line number Original line Diff line number Diff line
@@ -230,7 +230,7 @@ public class RuntimeInit {
     * @param classLoader the classLoader to load {@className} with
     * @param classLoader the classLoader to load {@className} with
     */
     */
    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;
        Class<?> cl;


        try {
        try {
@@ -264,7 +264,7 @@ public class RuntimeInit {
         * clears up all the stack frames that were required in setting
         * clears up all the stack frames that were required in setting
         * up the process.
         * up the process.
         */
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }
    }


    public static final void main(String[] argv) {
    public static final void main(String[] argv) {
@@ -301,7 +301,7 @@ public class RuntimeInit {
     * @param argv arg strings
     * @param argv arg strings
     */
     */
    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
            throws Zygote.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");


        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
@@ -324,14 +324,14 @@ public class RuntimeInit {
     * @param argv arg strings
     * @param argv arg strings
     */
     */
    public static void wrapperInit(int targetSdkVersion, String[] argv)
    public static void wrapperInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
            throws Zygote.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper");
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper");


        applicationInit(targetSdkVersion, argv, null);
        applicationInit(targetSdkVersion, argv, null);
    }
    }


    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
            throws Zygote.MethodAndArgsCaller {
        // If the application calls System.exit(), terminate the process
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // shutdown an Android application gracefully.  Among other things, the
+32 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 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.internal.os;

/**
 * Startup class for the WebView zygote process.
 *
 * See {@link ZygoteInit} for generic zygote startup documentation.
 *
 * @hide
 */
class WebViewZygoteInit {
    public static final String TAG = "WebViewZygoteInit";

    public static void main(String argv[]) {
        throw new RuntimeException("Not implemented yet");
    }
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -74,14 +74,14 @@ public class WrapperInit {
                }
                }
            }
            }


            // Mimic Zygote preloading.
            // Mimic system Zygote preloading.
            ZygoteInit.preload();
            ZygoteInit.preload();


            // Launch the application.
            // Launch the application.
            String[] runtimeArgs = new String[args.length - 2];
            String[] runtimeArgs = new String[args.length - 2];
            System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
            System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
            RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
            RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
        } catch (ZygoteInit.MethodAndArgsCaller caller) {
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
            caller.run();
        }
        }
    }
    }
+38 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,9 @@ import dalvik.system.ZygoteHooks;
import android.system.ErrnoException;
import android.system.ErrnoException;
import android.system.Os;
import android.system.Os;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/** @hide */
/** @hide */
public final class Zygote {
public final class Zygote {
    /*
    /*
@@ -191,4 +194,39 @@ public final class Zygote {
            command.append(" '").append(arg.replace("'", "'\\''")).append("'");
            command.append(" '").append(arg.replace("'", "'\\''")).append("'");
        }
        }
    }
    }

    /**
     * Helper exception class which holds a method and arguments and
     * can call them. This is used as part of a trampoline to get rid of
     * the initial process setup stack frames.
     */
    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }
}
}
+8 −9
Original line number Original line Diff line number Diff line
@@ -117,7 +117,7 @@ class ZygoteConnection {


    /**
    /**
     * Reads one start command from the command socket. If successful,
     * Reads one start command from the command socket. If successful,
     * a child is forked and a {@link ZygoteInit.MethodAndArgsCaller}
     * a child is forked and a {@link Zygote.MethodAndArgsCaller}
     * exception is thrown in that child while in the parent process,
     * exception is thrown in that child while in the parent process,
     * the method returns normally. On failure, the child is not
     * the method returns normally. On failure, the child is not
     * spawned and messages are printed to the log and stderr. Returns
     * spawned and messages are printed to the log and stderr. Returns
@@ -126,10 +126,10 @@ class ZygoteConnection {
     *
     *
     * @return false if command socket should continue to be read from, or
     * @return false if command socket should continue to be read from, or
     * true if an end-of-file has been encountered.
     * true if an end-of-file has been encountered.
     * @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main()
     * @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
     * method in child process
     * method in child process
     */
     */
    boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {


        String args[];
        String args[];
        Arguments parsedArgs = null;
        Arguments parsedArgs = null;
@@ -214,7 +214,7 @@ class ZygoteConnection {
                fdsToClose[0] = fd.getInt$();
                fdsToClose[0] = fd.getInt$();
            }
            }


            fd = ZygoteInit.getServerSocketFileDescriptor();
            fd = zygoteServer.getServerSocketFileDescriptor();


            if (fd != null) {
            if (fd != null) {
                fdsToClose[1] = fd.getInt$();
                fdsToClose[1] = fd.getInt$();
@@ -238,12 +238,13 @@ class ZygoteConnection {
        try {
        try {
            if (pid == 0) {
            if (pid == 0) {
                // in child
                // in child
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                serverPipeFd = null;
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);


                // should never get here, the child is expected to either
                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                // throw Zygote.MethodAndArgsCaller or exec().
                return true;
                return true;
            } else {
            } else {
                // in parent...pid of < 0 means failure
                // in parent...pid of < 0 means failure
@@ -712,12 +713,12 @@ class ZygoteConnection {
     * @param newStderr null-ok; stream to use for stderr until stdio
     * @param newStderr null-ok; stream to use for stderr until stdio
     * is reopened.
     * is reopened.
     *
     *
     * @throws ZygoteInit.MethodAndArgsCaller on success to
     * @throws Zygote.MethodAndArgsCaller on success to
     * trampoline to code that invokes static main.
     * trampoline to code that invokes static main.
     */
     */
    private void handleChildProc(Arguments parsedArgs,
    private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            throws ZygoteInit.MethodAndArgsCaller {
            throws Zygote.MethodAndArgsCaller {
        /**
        /**
         * By the time we get here, the native code has closed the two actual Zygote
         * By the time we get here, the native code has closed the two actual Zygote
         * socket connections, and substituted /dev/null in their place.  The LocalSocket
         * socket connections, and substituted /dev/null in their place.  The LocalSocket
@@ -725,8 +726,6 @@ class ZygoteConnection {
         */
         */


        closeSocket();
        closeSocket();
        ZygoteInit.closeServerSocket();

        if (descriptors != null) {
        if (descriptors != null) {
            try {
            try {
                Os.dup2(descriptors[0], STDIN_FILENO);
                Os.dup2(descriptors[0], STDIN_FILENO);
Loading