Loading core/java/android/os/ChildZygoteProcess.java 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 android.os; import android.net.LocalSocketAddress; /** * Represents a connection to a child-zygote process. A child-zygote is spawend from another * zygote process using {@link startChildZygote()}. * * {@hide} */ public class ChildZygoteProcess extends ZygoteProcess { /** * The PID of the child zygote process. */ private final int mPid; ChildZygoteProcess(LocalSocketAddress socketAddress, int pid) { super(socketAddress, null); mPid = pid; } /** * Returns the PID of the child-zygote process. */ public int getPid() { return mPid; } } core/java/android/os/ZygoteProcess.java +54 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; /*package*/ class ZygoteStartFailedEx extends Exception { ZygoteStartFailedEx(String s) { Loading Loading @@ -217,7 +218,8 @@ public class ZygoteProcess { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); Loading Loading @@ -333,6 +335,8 @@ public class ZygoteProcess { * @param abi the ABI the process should use. * @param instructionSet null-ok the instruction set to use. * @param appDataDir null-ok the data directory of the app. * @param startChildZygote Start a sub-zygote. This creates a new zygote process * that has its state cloned from this zygote process. * @param extraArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason Loading @@ -348,6 +352,7 @@ public class ZygoteProcess { String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<String>(); Loading Loading @@ -404,6 +409,10 @@ public class ZygoteProcess { argsForZygote.add(invokeWith); } if (startChildZygote) { argsForZygote.add("--start-child-zygote"); } argsForZygote.add(processClass); if (extraArgs != null) { Loading @@ -417,6 +426,18 @@ public class ZygoteProcess { } } /** * Closes the connections to the zygote, if they exist. */ public void close() { if (primaryZygoteState != null) { primaryZygoteState.close(); } if (secondaryZygoteState != null) { secondaryZygoteState.close(); } } /** * Tries to establish a connection to the zygote that handles a given {@code abi}. Might block * and retry if the zygote is unresponsive. This method is a no-op if a connection is Loading Loading @@ -549,4 +570,36 @@ public class ZygoteProcess { } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + address.getName()); } /** * Starts a new zygote process as a child of this zygote. This is used to create * secondary zygotes that inherit data from the zygote that this object * communicates with. This returns a new ZygoteProcess representing a connection * to the newly created zygote. Throws an exception if the zygote cannot be started. */ public ChildZygoteProcess startChildZygote(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, String seInfo, String abi, String instructionSet) { // Create an unguessable address in the global abstract namespace. final LocalSocketAddress serverAddress = new LocalSocketAddress( processClass + "/" + UUID.randomUUID().toString()); final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName()}; Process.ProcessStartResult result; try { result = startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo, abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } return new ChildZygoteProcess(serverAddress, result.pid); } } core/java/com/android/internal/os/RuntimeInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public class RuntimeInit { * @param argv Argument vector for main() * @param classLoader the classLoader to load {@className} with */ private static Runnable findStaticMain(String className, String[] argv, protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; Loading core/java/com/android/internal/os/WebViewZygoteInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ class WebViewZygoteInit { final Runnable caller; try { sServer.registerServerSocket("webview_zygote"); sServer.registerServerSocketFromEnv("webview_zygote"); // The select loop returns early in the child process after a fork and // loops forever in the zygote. caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS)); Loading core/java/com/android/internal/os/Zygote.java +14 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,13 @@ public final class Zygote { private static final ZygoteHooks VM_HOOKS = new ZygoteHooks(); /** * An extraArg passed when a zygote process is forking a child-zygote, specifying a name * in the abstract socket namespace. This socket name is what the new child zygote * should listen for connections on. */ public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket="; private Zygote() {} /** Called for some security initialization before any fork. */ Loading Loading @@ -102,6 +109,8 @@ public final class Zygote { * @param fdsToIgnore null-ok an array of ints, either null or holding * one or more POSIX file descriptor numbers that are to be ignored * in the file descriptor table check. * @param startChildZygote if true, the new child process will itself be a * new zygote process. * @param instructionSet null-ok the instruction set to use. * @param appDataDir null-ok the data directory of the app. * Loading @@ -110,13 +119,13 @@ public final class Zygote { */ public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, String instructionSet, String appDataDir) { int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) { VM_HOOKS.preFork(); // Resets nice priority for zygote process. resetNicePriority(); int pid = nativeForkAndSpecialize( uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, instructionSet, appDataDir); fdsToIgnore, startChildZygote, instructionSet, appDataDir); // Enable tracing as soon as possible for the child process. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); Loading @@ -130,7 +139,7 @@ public final class Zygote { native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, String instructionSet, String appDataDir); int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir); /** * Called to do any initialization before starting an application. Loading Loading @@ -190,8 +199,8 @@ public final class Zygote { native protected static void nativeUnmountStorageOnInit(); private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer, String instructionSet) { VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, instructionSet); boolean isZygote, String instructionSet) { VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet); } /** Loading Loading
core/java/android/os/ChildZygoteProcess.java 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 android.os; import android.net.LocalSocketAddress; /** * Represents a connection to a child-zygote process. A child-zygote is spawend from another * zygote process using {@link startChildZygote()}. * * {@hide} */ public class ChildZygoteProcess extends ZygoteProcess { /** * The PID of the child zygote process. */ private final int mPid; ChildZygoteProcess(LocalSocketAddress socketAddress, int pid) { super(socketAddress, null); mPid = pid; } /** * Returns the PID of the child-zygote process. */ public int getPid() { return mPid; } }
core/java/android/os/ZygoteProcess.java +54 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; /*package*/ class ZygoteStartFailedEx extends Exception { ZygoteStartFailedEx(String s) { Loading Loading @@ -217,7 +218,8 @@ public class ZygoteProcess { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); Loading Loading @@ -333,6 +335,8 @@ public class ZygoteProcess { * @param abi the ABI the process should use. * @param instructionSet null-ok the instruction set to use. * @param appDataDir null-ok the data directory of the app. * @param startChildZygote Start a sub-zygote. This creates a new zygote process * that has its state cloned from this zygote process. * @param extraArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason Loading @@ -348,6 +352,7 @@ public class ZygoteProcess { String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<String>(); Loading Loading @@ -404,6 +409,10 @@ public class ZygoteProcess { argsForZygote.add(invokeWith); } if (startChildZygote) { argsForZygote.add("--start-child-zygote"); } argsForZygote.add(processClass); if (extraArgs != null) { Loading @@ -417,6 +426,18 @@ public class ZygoteProcess { } } /** * Closes the connections to the zygote, if they exist. */ public void close() { if (primaryZygoteState != null) { primaryZygoteState.close(); } if (secondaryZygoteState != null) { secondaryZygoteState.close(); } } /** * Tries to establish a connection to the zygote that handles a given {@code abi}. Might block * and retry if the zygote is unresponsive. This method is a no-op if a connection is Loading Loading @@ -549,4 +570,36 @@ public class ZygoteProcess { } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + address.getName()); } /** * Starts a new zygote process as a child of this zygote. This is used to create * secondary zygotes that inherit data from the zygote that this object * communicates with. This returns a new ZygoteProcess representing a connection * to the newly created zygote. Throws an exception if the zygote cannot be started. */ public ChildZygoteProcess startChildZygote(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, String seInfo, String abi, String instructionSet) { // Create an unguessable address in the global abstract namespace. final LocalSocketAddress serverAddress = new LocalSocketAddress( processClass + "/" + UUID.randomUUID().toString()); final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName()}; Process.ProcessStartResult result; try { result = startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo, abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } return new ChildZygoteProcess(serverAddress, result.pid); } }
core/java/com/android/internal/os/RuntimeInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public class RuntimeInit { * @param argv Argument vector for main() * @param classLoader the classLoader to load {@className} with */ private static Runnable findStaticMain(String className, String[] argv, protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; Loading
core/java/com/android/internal/os/WebViewZygoteInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ class WebViewZygoteInit { final Runnable caller; try { sServer.registerServerSocket("webview_zygote"); sServer.registerServerSocketFromEnv("webview_zygote"); // The select loop returns early in the child process after a fork and // loops forever in the zygote. caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS)); Loading
core/java/com/android/internal/os/Zygote.java +14 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,13 @@ public final class Zygote { private static final ZygoteHooks VM_HOOKS = new ZygoteHooks(); /** * An extraArg passed when a zygote process is forking a child-zygote, specifying a name * in the abstract socket namespace. This socket name is what the new child zygote * should listen for connections on. */ public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket="; private Zygote() {} /** Called for some security initialization before any fork. */ Loading Loading @@ -102,6 +109,8 @@ public final class Zygote { * @param fdsToIgnore null-ok an array of ints, either null or holding * one or more POSIX file descriptor numbers that are to be ignored * in the file descriptor table check. * @param startChildZygote if true, the new child process will itself be a * new zygote process. * @param instructionSet null-ok the instruction set to use. * @param appDataDir null-ok the data directory of the app. * Loading @@ -110,13 +119,13 @@ public final class Zygote { */ public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, String instructionSet, String appDataDir) { int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) { VM_HOOKS.preFork(); // Resets nice priority for zygote process. resetNicePriority(); int pid = nativeForkAndSpecialize( uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, instructionSet, appDataDir); fdsToIgnore, startChildZygote, instructionSet, appDataDir); // Enable tracing as soon as possible for the child process. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); Loading @@ -130,7 +139,7 @@ public final class Zygote { native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, String instructionSet, String appDataDir); int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir); /** * Called to do any initialization before starting an application. Loading Loading @@ -190,8 +199,8 @@ public final class Zygote { native protected static void nativeUnmountStorageOnInit(); private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer, String instructionSet) { VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, instructionSet); boolean isZygote, String instructionSet) { VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet); } /** Loading