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

Commit 66d7275d authored by Narayan Kamath's avatar Narayan Kamath Committed by android-build-merger
Browse files

Merge changes Id931d441,I83faf974

am: 89c94f67

Change-Id: Ifc090e141092bcee11704e45d6f97f642040d002
parents f0a3c209 89c94f67
Loading
Loading
Loading
Loading
+41 −14
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import android.util.Slog;
import com.android.internal.logging.AndroidConfig;
import com.android.internal.logging.AndroidConfig;
import com.android.server.NetworkManagementSocketTagger;
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.VMRuntime;
import dalvik.system.VMRuntime;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Modifier;
import java.util.TimeZone;
import java.util.TimeZone;
@@ -228,8 +229,8 @@ public class RuntimeInit {
     * @param argv Argument vector for main()
     * @param argv Argument vector for main()
     * @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 Runnable findStaticMain(String className, String[] argv,
            throws Zygote.MethodAndArgsCaller {
            ClassLoader classLoader) {
        Class<?> cl;
        Class<?> cl;


        try {
        try {
@@ -263,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 Zygote.MethodAndArgsCaller(m, argv);
        return new MethodAndArgsCaller(m, argv);
    }
    }


    public static final void main(String[] argv) {
    public static final void main(String[] argv) {
@@ -286,8 +287,8 @@ public class RuntimeInit {
        if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
        if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!");
    }
    }


    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            throws Zygote.MethodAndArgsCaller {
            ClassLoader classLoader) {
        // 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
@@ -300,20 +301,13 @@ public class RuntimeInit {
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);


        final Arguments args;
        final Arguments args = new Arguments(argv);
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }


        // The end of of the RuntimeInit event (see #zygoteInit).
        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);


        // Remaining arguments are passed to the start class's static main
        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    }


    /**
    /**
@@ -422,4 +416,37 @@ public class RuntimeInit {
            System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
            System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
        }
        }
    }
    }

    /**
     * Helper 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.
     */
    static class MethodAndArgsCaller 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);
            }
        }
    }
}
}
+14 −10
Original line number Original line Diff line number Diff line
@@ -69,8 +69,7 @@ class WebViewZygoteInit {
        }
        }


        @Override
        @Override
        protected boolean handlePreloadPackage(String packagePath, String libsPath,
        protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
                                               String cacheKey) {
            Log.i(TAG, "Beginning package preload");
            Log.i(TAG, "Beginning package preload");
            // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
            // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
            // our children will reuse the same classloader instead of creating their own.
            // our children will reuse the same classloader instead of creating their own.
@@ -106,12 +105,10 @@ class WebViewZygoteInit {
                DataOutputStream socketOut = getSocketOutputStream();
                DataOutputStream socketOut = getSocketOutputStream();
                socketOut.writeInt(preloadSucceeded ? 1 : 0);
                socketOut.writeInt(preloadSucceeded ? 1 : 0);
            } catch (IOException ioe) {
            } catch (IOException ioe) {
                Log.e(TAG, "Error writing to command socket", ioe);
                throw new IllegalStateException("Error writing to command socket", ioe);
                return true;
            }
            }


            Log.i(TAG, "Package preload done");
            Log.i(TAG, "Package preload done");
            return false;
        }
        }
    }
    }


@@ -125,16 +122,23 @@ class WebViewZygoteInit {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }
        }


        final Runnable caller;
        try {
        try {
            sServer.registerServerSocket("webview_zygote");
            sServer.registerServerSocket("webview_zygote");
            sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
            // The select loop returns early in the child process after a fork and
            sServer.closeServerSocket();
            // loops forever in the zygote.
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
            caller.run();
        } catch (RuntimeException e) {
        } catch (RuntimeException e) {
            Log.e(TAG, "Fatal exception:", e);
            Log.e(TAG, "Fatal exception:", e);
            throw e;
        } finally {
            sServer.closeServerSocket();
        }
        }


        System.exit(0);
        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }
    }
}
}
+27 −31
Original line number Original line Diff line number Diff line
@@ -25,7 +25,6 @@ import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
import android.system.StructCapUserHeader;
import android.util.BootTimingsTraceLog;
import android.util.BootTimingsTraceLog;
import android.util.Slog;
import android.util.Slog;
import com.android.internal.os.Zygote.MethodAndArgsCaller;
import dalvik.system.VMRuntime;
import dalvik.system.VMRuntime;
import java.io.DataOutputStream;
import java.io.DataOutputStream;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
@@ -61,7 +60,6 @@ public class WrapperInit {
     * @param args The command-line arguments.
     * @param args The command-line arguments.
     */
     */
    public static void main(String[] args) {
    public static void main(String[] args) {
        try {
        // Parse our mandatory arguments.
        // Parse our mandatory arguments.
        int fdNum = Integer.parseInt(args[0], 10);
        int fdNum = Integer.parseInt(args[0], 10);
        int targetSdkVersion = Integer.parseInt(args[1], 10);
        int targetSdkVersion = Integer.parseInt(args[1], 10);
@@ -88,10 +86,9 @@ public class WrapperInit {
        // 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);
            WrapperInit.wrapperInit(targetSdkVersion, runtimeArgs);
        Runnable r = wrapperInit(targetSdkVersion, runtimeArgs);
        } catch (Zygote.MethodAndArgsCaller caller) {

            caller.run();
        r.run();
        }
    }
    }


    /**
    /**
@@ -142,8 +139,7 @@ public class WrapperInit {
     * @param targetSdkVersion target SDK version
     * @param targetSdkVersion target SDK version
     * @param argv arg strings
     * @param argv arg strings
     */
     */
    private static void wrapperInit(int targetSdkVersion, String[] argv)
    private static Runnable wrapperInit(int targetSdkVersion, String[] argv) {
            throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
        }
        }
@@ -165,7 +161,7 @@ public class WrapperInit {


        // Perform the same initialization that would happen after the Zygote forks.
        // Perform the same initialization that would happen after the Zygote forks.
        Zygote.nativePreApplicationInit();
        Zygote.nativePreApplicationInit();
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    }


    /**
    /**
+0 −35
Original line number Original line Diff line number Diff line
@@ -221,39 +221,4 @@ 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);
            }
        }
    }
}
}
+100 −145
Original line number Original line Diff line number Diff line
@@ -30,7 +30,6 @@ import android.net.Credentials;
import android.net.LocalSocket;
import android.net.LocalSocket;
import android.os.FactoryTest;
import android.os.FactoryTest;
import android.os.Process;
import android.os.Process;
import android.os.SELinux;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.Trace;
import android.system.ErrnoException;
import android.system.ErrnoException;
@@ -42,14 +41,13 @@ import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import libcore.io.IoUtils;
import libcore.io.IoUtils;


/**
/**
@@ -73,6 +71,7 @@ class ZygoteConnection {
    private final BufferedReader mSocketReader;
    private final BufferedReader mSocketReader;
    private final Credentials peer;
    private final Credentials peer;
    private final String abiList;
    private final String abiList;
    private boolean isEof;


    /**
    /**
     * Constructs instance from connected socket.
     * Constructs instance from connected socket.
@@ -99,6 +98,8 @@ class ZygoteConnection {
            Log.e(TAG, "Cannot read peer credentials", ex);
            Log.e(TAG, "Cannot read peer credentials", ex);
            throw ex;
            throw ex;
        }
        }

        isEof = false;
    }
    }


    /**
    /**
@@ -111,21 +112,14 @@ 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
     * a child is forked and a {@link Zygote.MethodAndArgsCaller}
     * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child
     * exception is thrown in that child while in the parent process,
     * process. {@code null} is always returned in the parent process (the zygote).
     * the method returns normally. On failure, the child is not
     * spawned and messages are printed to the log and stderr. Returns
     * a boolean status value indicating whether an end-of-file on the command
     * socket has been encountered.
     *
     *
     * @return false if command socket should continue to be read from, or
     * If the client closes the socket, an {@code EOF} condition is set, which callers can test
     * true if an end-of-file has been encountered.
     * for by calling {@code ZygoteConnection.isClosedByPeer}.
     * @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
     * method in child process
     */
     */
    boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
    Runnable processOneCommand(ZygoteServer zygoteServer) {

        String args[];
        String args[];
        Arguments parsedArgs = null;
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;
        FileDescriptor[] descriptors;
@@ -134,43 +128,36 @@ class ZygoteConnection {
            args = readArgumentList();
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
        } catch (IOException ex) {
            Log.w(TAG, "IOException on command socket " + ex.getMessage());
            throw new IllegalStateException("IOException on command socket", ex);
            closeSocket();
            return true;
        }
        }


        // readArgumentList returns null only when it has reached EOF with no available
        // data to read. This will only happen when the remote socket has disconnected.
        if (args == null) {
        if (args == null) {
            // EOF reached.
            isEof = true;
            closeSocket();
            return null;
            return true;
        }

        /** the stderr of the most recent request, if avail */
        PrintStream newStderr = null;

        if (descriptors != null && descriptors.length >= 3) {
            newStderr = new PrintStream(
                    new FileOutputStream(descriptors[2]));
        }
        }


        int pid = -1;
        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;
        FileDescriptor serverPipeFd = null;


        try {
        parsedArgs = new Arguments(args);
        parsedArgs = new Arguments(args);


        if (parsedArgs.abiListQuery) {
        if (parsedArgs.abiListQuery) {
                return handleAbiListQuery();
            handleAbiListQuery();
            return null;
        }
        }


        if (parsedArgs.preloadDefault) {
        if (parsedArgs.preloadDefault) {
                return handlePreload();
            handlePreload();
            return null;
        }
        }


        if (parsedArgs.preloadPackage != null) {
        if (parsedArgs.preloadPackage != null) {
                return handlePreloadPackage(parsedArgs.preloadPackage,
            handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
                        parsedArgs.preloadPackageLibs, parsedArgs.preloadPackageCacheKey);
                    parsedArgs.preloadPackageCacheKey);
            return null;
        }
        }


        if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
        if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
@@ -194,11 +181,15 @@ class ZygoteConnection {
        int[] fdsToIgnore = null;
        int[] fdsToIgnore = null;


        if (parsedArgs.invokeWith != null) {
        if (parsedArgs.invokeWith != null) {
            try {
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
                childPipeFd = pipeFds[1];
                childPipeFd = pipeFds[1];
                serverPipeFd = pipeFds[0];
                serverPipeFd = pipeFds[0];
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                Os.fcntlInt(childPipeFd, F_SETFD, 0);
                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
            } catch (ErrnoException errnoEx) {
                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
            }
        }
        }


        /**
        /**
@@ -233,31 +224,24 @@ class ZygoteConnection {
                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
                parsedArgs.appDataDir);
        } catch (ErrnoException ex) {
            logAndPrintError(newStderr, "Exception creating pipe", ex);
        } catch (IllegalArgumentException ex) {
            logAndPrintError(newStderr, "Invalid zygote arguments", ex);
        } catch (ZygoteSecurityException ex) {
            logAndPrintError(newStderr,
                    "Zygote security policy prevents request: ", ex);
        }


        try {
        try {
            if (pid == 0) {
            if (pid == 0) {
                // in child
                // in child
                zygoteServer.setForkChild();

                zygoteServer.closeServerSocket();
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                serverPipeFd = null;
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);


                // should never get here, the child is expected to either
                return handleChildProc(parsedArgs, descriptors, childPipeFd);
                // throw Zygote.MethodAndArgsCaller or exec().
                return true;
            } else {
            } else {
                // in parent...pid of < 0 means failure
                // In the parent. A pid < 0 indicates a failure and will be handled in
                // handleParentProc.
                IoUtils.closeQuietly(childPipeFd);
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                childPipeFd = null;
                return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
                handleParentProc(pid, descriptors, serverPipeFd);
                return null;
            }
            }
        } finally {
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(childPipeFd);
@@ -265,15 +249,13 @@ class ZygoteConnection {
        }
        }
    }
    }


    private boolean handleAbiListQuery() {
    private void handleAbiListQuery() {
        try {
        try {
            final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII);
            final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII);
            mSocketOutStream.writeInt(abiListBytes.length);
            mSocketOutStream.writeInt(abiListBytes.length);
            mSocketOutStream.write(abiListBytes);
            mSocketOutStream.write(abiListBytes);
            return false;
        } catch (IOException ioe) {
        } catch (IOException ioe) {
            Log.e(TAG, "Error writing to command socket", ioe);
            throw new IllegalStateException("Error writing to command socket", ioe);
            return true;
        }
        }
    }
    }


@@ -283,7 +265,7 @@ class ZygoteConnection {
     * if no preload was initiated. The latter implies that the zygote is not configured to load
     * if no preload was initiated. The latter implies that the zygote is not configured to load
     * resources lazy or that the zygote has already handled a previous request to handlePreload.
     * resources lazy or that the zygote has already handled a previous request to handlePreload.
     */
     */
    private boolean handlePreload() {
    private void handlePreload() {
        try {
        try {
            if (isPreloadComplete()) {
            if (isPreloadComplete()) {
                mSocketOutStream.writeInt(1);
                mSocketOutStream.writeInt(1);
@@ -291,11 +273,8 @@ class ZygoteConnection {
                preload();
                preload();
                mSocketOutStream.writeInt(0);
                mSocketOutStream.writeInt(0);
            }
            }

            return false;
        } catch (IOException ioe) {
        } catch (IOException ioe) {
            Log.e(TAG, "Error writing to command socket", ioe);
            throw new IllegalStateException("Error writing to command socket", ioe);
            return true;
        }
        }
    }
    }


@@ -311,7 +290,7 @@ class ZygoteConnection {
        return mSocketOutStream;
        return mSocketOutStream;
    }
    }


    protected boolean handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
    protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
        throw new RuntimeException("Zyogte does not support package preloading");
        throw new RuntimeException("Zyogte does not support package preloading");
    }
    }


@@ -327,6 +306,10 @@ class ZygoteConnection {
        }
        }
    }
    }


    boolean isClosedByPeer() {
        return isEof;
    }

    /**
    /**
     * Handles argument parsing for args related to the zygote spawner.
     * Handles argument parsing for args related to the zygote spawner.
     *
     *
@@ -757,15 +740,9 @@ class ZygoteConnection {
     * @param parsedArgs non-null; zygote args
     * @param parsedArgs non-null; zygote args
     * @param descriptors null-ok; new file descriptors for stdio if available.
     * @param descriptors null-ok; new file descriptors for stdio if available.
     * @param pipeFd null-ok; pipe for communication back to Zygote.
     * @param pipeFd null-ok; pipe for communication back to Zygote.
     * @param newStderr null-ok; stream to use for stderr until stdio
     * is reopened.
     *
     * @throws Zygote.MethodAndArgsCaller on success to
     * trampoline to code that invokes static main.
     */
     */
    private void handleChildProc(Arguments parsedArgs,
    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            FileDescriptor pipeFd) {
            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
@@ -782,7 +759,6 @@ class ZygoteConnection {
                for (FileDescriptor fd: descriptors) {
                for (FileDescriptor fd: descriptors) {
                    IoUtils.closeQuietly(fd);
                    IoUtils.closeQuietly(fd);
                }
                }
                newStderr = System.err;
            } catch (ErrnoException ex) {
            } catch (ErrnoException ex) {
                Log.e(TAG, "Error reopening stdio", ex);
                Log.e(TAG, "Error reopening stdio", ex);
            }
            }
@@ -799,9 +775,12 @@ class ZygoteConnection {
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(),
                    VMRuntime.getCurrentInstructionSet(),
                    pipeFd, parsedArgs.remainingArgs);
                    pipeFd, parsedArgs.remainingArgs);

            // Should not get here.
            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
        } else {
        } else {
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                    parsedArgs.remainingArgs, null /* classLoader */);
                    null /* classLoader */);
        }
        }
    }
    }


@@ -813,13 +792,8 @@ class ZygoteConnection {
     * @param descriptors null-ok; file descriptors for child's new stdio if
     * @param descriptors null-ok; file descriptors for child's new stdio if
     * specified.
     * specified.
     * @param pipeFd null-ok; pipe for communication with child.
     * @param pipeFd null-ok; pipe for communication with child.
     * @param parsedArgs non-null; zygote args
     * @return true for "exit command loop" and false for "continue command
     * loop"
     */
     */
    private boolean handleParentProc(int pid,
    private void handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd) {
            FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {

        if (pid > 0) {
        if (pid > 0) {
            setChildPgid(pid);
            setChildPgid(pid);
        }
        }
@@ -911,11 +885,8 @@ class ZygoteConnection {
            mSocketOutStream.writeInt(pid);
            mSocketOutStream.writeInt(pid);
            mSocketOutStream.writeBoolean(usingWrapper);
            mSocketOutStream.writeBoolean(usingWrapper);
        } catch (IOException ex) {
        } catch (IOException ex) {
            Log.e(TAG, "Error writing to command socket", ex);
            throw new IllegalStateException("Error writing to command socket", ex);
            return true;
        }
        }

        return false;
    }
    }


    private void setChildPgid(int pid) {
    private void setChildPgid(int pid) {
@@ -931,20 +902,4 @@ class ZygoteConnection {
                + "normal if peer is not in our session");
                + "normal if peer is not in our session");
        }
        }
    }
    }

    /**
     * Logs an error message and prints it to the specified stream, if
     * provided
     *
     * @param newStderr null-ok; a standard error stream
     * @param message non-null; error message
     * @param ex null-ok an exception
     */
    private static void logAndPrintError (PrintStream newStderr,
            String message, Throwable ex) {
        Log.e(TAG, message, ex);
        if (newStderr != null) {
            newStderr.println(message + (ex == null ? "" : ex));
        }
    }
}
}
Loading