Loading cmds/app_process/app_main.cpp +19 −1 Original line number Diff line number Diff line Loading @@ -10,8 +10,9 @@ #include <binder/IPCThreadState.h> #include <binder/ProcessState.h> #include <utils/Log.h> #include <cutils/process_name.h> #include <cutils/memory.h> #include <cutils/process_name.h> #include <cutils/properties.h> #include <cutils/trace.h> #include <android_runtime/AndroidRuntime.h> Loading Loading @@ -135,6 +136,12 @@ static size_t computeArgBlockSize(int argc, char* const argv[]) { return (end - start); } #if defined(__LP64__) static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64"; #else static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32"; #endif int main(int argc, char* const argv[]) { AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); Loading Loading @@ -205,6 +212,17 @@ int main(int argc, char* const argv[]) args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to deterimine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { Loading core/java/com/android/internal/os/ZygoteConnection.java +31 −43 Original line number Diff line number Diff line Loading @@ -22,9 +22,7 @@ import android.os.Process; import android.os.SELinux; import android.os.SystemProperties; import android.util.Log; import dalvik.system.PathClassLoader; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; Loading @@ -34,8 +32,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import libcore.io.ErrnoException; import libcore.io.IoUtils; import libcore.io.Libcore; Loading Loading @@ -73,15 +71,18 @@ class ZygoteConnection { private final BufferedReader mSocketReader; private final Credentials peer; private final String peerSecurityContext; private final String abiList; /** * Constructs instance from connected socket. * * @param socket non-null; connected socket * @param abiList non-null; a list of ABIs this zygote supports. * @throws IOException */ ZygoteConnection(LocalSocket socket) throws IOException { ZygoteConnection(LocalSocket socket, String abiList) throws IOException { mSocket = socket; this.abiList = abiList; mSocketOutStream = new DataOutputStream(socket.getOutputStream()); Loading Loading @@ -110,43 +111,6 @@ class ZygoteConnection { return mSocket.getFileDescriptor(); } /** * Reads start commands from an open command socket. * Start commands are presently a pair of newline-delimited lines * indicating a) class to invoke main() on b) nice name to set argv[0] to. * Continues to read commands and forkAndSpecialize children until * the socket is closed. This method is used in ZYGOTE_FORK_MODE * * @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main() * method in child process */ void run() throws ZygoteInit.MethodAndArgsCaller { int loopCount = ZygoteInit.GC_LOOP_COUNT; while (true) { /* * Call gc() before we block in readArgumentList(). * It's work that has to be done anyway, and it's better * to avoid making every child do it. It will also * madvise() any free memory as a side-effect. * * Don't call it every time, because walking the entire * heap is a lot of overhead to free a few hundred bytes. */ if (loopCount <= 0) { ZygoteInit.gc(); loopCount = ZygoteInit.GC_LOOP_COUNT; } else { loopCount--; } if (runOnce()) { break; } } } /** * Reads one start command from the command socket. If successful, * a child is forked and a {@link ZygoteInit.MethodAndArgsCaller} Loading Loading @@ -196,6 +160,11 @@ class ZygoteConnection { try { parsedArgs = new Arguments(args); if (parsedArgs.abiListQuery) { return handleAbiListQuery(); } if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " + "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) + Loading Loading @@ -287,6 +256,18 @@ class ZygoteConnection { } } private boolean handleAbiListQuery() { try { final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII); mSocketOutStream.writeInt(abiListBytes.length); mSocketOutStream.write(abiListBytes); return false; } catch (IOException ioe) { Log.e(TAG, "Error writing to command socket", ioe); return true; } } /** * Closes socket associated with this connection. */ Loading Loading @@ -387,6 +368,11 @@ class ZygoteConnection { */ String remainingArgs[]; /** * Whether the current arguments constitute an ABI list query. */ boolean abiListQuery; /** * Constructs instance and parses args * @param args zygote command-line args Loading Loading @@ -540,6 +526,8 @@ class ZygoteConnection { mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; } else if (arg.equals("--mount-external-multiuser-all")) { mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; } else if (arg.equals("--query-abi-list")) { abiListQuery = true; } else { break; } Loading Loading @@ -975,7 +963,7 @@ class ZygoteConnection { mSocketOutStream.writeInt(pid); mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error reading from command socket", ex); Log.e(TAG, "Error writing to command socket", ex); return true; } Loading core/java/com/android/internal/os/ZygoteInit.java +34 −22 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class ZygoteInit { private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload"; private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote"; private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_"; private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020; private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030; Loading @@ -72,8 +72,9 @@ public class ZygoteInit { /** when preloading, GC after allocating this many bytes */ private static final int PRELOAD_GC_THRESHOLD = 50000; public static final String USAGE_STRING = " <\"start-system-server\"|\"\" for startSystemServer>"; private static final String ABI_LIST_ARG = "--abi-list="; private static final String SOCKET_NAME_ARG = "--socket-name="; private static LocalServerSocket sServerSocket; Loading Loading @@ -150,15 +151,15 @@ public class ZygoteInit { * * @throws RuntimeException when open fails */ private static void registerZygoteSocket() { private static void registerZygoteSocket(String socketName) { if (sServerSocket == null) { int fileDesc; final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { String env = System.getenv(ANDROID_SOCKET_ENV); String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException( ANDROID_SOCKET_ENV + " unset or invalid", ex); throw new RuntimeException(fullSocketName + " unset or invalid", ex); } try { Loading @@ -175,9 +176,9 @@ public class ZygoteInit { * Waits for and accepts a single command connection. Throws * RuntimeException on failure. */ private static ZygoteConnection acceptCommandPeer() { private static ZygoteConnection acceptCommandPeer(String abiList) { try { return new ZygoteConnection(sServerSocket.accept()); return new ZygoteConnection(sServerSocket.accept(), abiList); } catch (IOException ex) { throw new RuntimeException( "IOException during accept()", ex); Loading Loading @@ -576,7 +577,26 @@ public class ZygoteInit { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); registerZygoteSocket(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } registerZygoteSocket(socketName); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(); Loading @@ -593,20 +613,12 @@ public class ZygoteInit { // Zygote. Trace.setTracingEnabled(false); // If requested, start system server directly from Zygote if (argv.length != 2) { throw new RuntimeException(argv[0] + USAGE_STRING); } if (argv[1].equals("start-system-server")) { if (startSystemServer) { startSystemServer(); } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(); runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { Loading @@ -626,7 +638,7 @@ public class ZygoteInit { * @throws MethodAndArgsCaller in a child process when a main() should * be executed. */ private static void runSelectLoop() throws MethodAndArgsCaller { private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); FileDescriptor[] fdArray = new FileDescriptor[4]; Loading Loading @@ -665,7 +677,7 @@ public class ZygoteInit { if (index < 0) { throw new RuntimeException("Error in select()"); } else if (index == 0) { ZygoteConnection newPeer = acceptCommandPeer(); ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { Loading Loading
cmds/app_process/app_main.cpp +19 −1 Original line number Diff line number Diff line Loading @@ -10,8 +10,9 @@ #include <binder/IPCThreadState.h> #include <binder/ProcessState.h> #include <utils/Log.h> #include <cutils/process_name.h> #include <cutils/memory.h> #include <cutils/process_name.h> #include <cutils/properties.h> #include <cutils/trace.h> #include <android_runtime/AndroidRuntime.h> Loading Loading @@ -135,6 +136,12 @@ static size_t computeArgBlockSize(int argc, char* const argv[]) { return (end - start); } #if defined(__LP64__) static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64"; #else static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32"; #endif int main(int argc, char* const argv[]) { AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); Loading Loading @@ -205,6 +212,17 @@ int main(int argc, char* const argv[]) args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to deterimine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { Loading
core/java/com/android/internal/os/ZygoteConnection.java +31 −43 Original line number Diff line number Diff line Loading @@ -22,9 +22,7 @@ import android.os.Process; import android.os.SELinux; import android.os.SystemProperties; import android.util.Log; import dalvik.system.PathClassLoader; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; Loading @@ -34,8 +32,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import libcore.io.ErrnoException; import libcore.io.IoUtils; import libcore.io.Libcore; Loading Loading @@ -73,15 +71,18 @@ class ZygoteConnection { private final BufferedReader mSocketReader; private final Credentials peer; private final String peerSecurityContext; private final String abiList; /** * Constructs instance from connected socket. * * @param socket non-null; connected socket * @param abiList non-null; a list of ABIs this zygote supports. * @throws IOException */ ZygoteConnection(LocalSocket socket) throws IOException { ZygoteConnection(LocalSocket socket, String abiList) throws IOException { mSocket = socket; this.abiList = abiList; mSocketOutStream = new DataOutputStream(socket.getOutputStream()); Loading Loading @@ -110,43 +111,6 @@ class ZygoteConnection { return mSocket.getFileDescriptor(); } /** * Reads start commands from an open command socket. * Start commands are presently a pair of newline-delimited lines * indicating a) class to invoke main() on b) nice name to set argv[0] to. * Continues to read commands and forkAndSpecialize children until * the socket is closed. This method is used in ZYGOTE_FORK_MODE * * @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main() * method in child process */ void run() throws ZygoteInit.MethodAndArgsCaller { int loopCount = ZygoteInit.GC_LOOP_COUNT; while (true) { /* * Call gc() before we block in readArgumentList(). * It's work that has to be done anyway, and it's better * to avoid making every child do it. It will also * madvise() any free memory as a side-effect. * * Don't call it every time, because walking the entire * heap is a lot of overhead to free a few hundred bytes. */ if (loopCount <= 0) { ZygoteInit.gc(); loopCount = ZygoteInit.GC_LOOP_COUNT; } else { loopCount--; } if (runOnce()) { break; } } } /** * Reads one start command from the command socket. If successful, * a child is forked and a {@link ZygoteInit.MethodAndArgsCaller} Loading Loading @@ -196,6 +160,11 @@ class ZygoteConnection { try { parsedArgs = new Arguments(args); if (parsedArgs.abiListQuery) { return handleAbiListQuery(); } if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " + "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) + Loading Loading @@ -287,6 +256,18 @@ class ZygoteConnection { } } private boolean handleAbiListQuery() { try { final byte[] abiListBytes = abiList.getBytes(StandardCharsets.US_ASCII); mSocketOutStream.writeInt(abiListBytes.length); mSocketOutStream.write(abiListBytes); return false; } catch (IOException ioe) { Log.e(TAG, "Error writing to command socket", ioe); return true; } } /** * Closes socket associated with this connection. */ Loading Loading @@ -387,6 +368,11 @@ class ZygoteConnection { */ String remainingArgs[]; /** * Whether the current arguments constitute an ABI list query. */ boolean abiListQuery; /** * Constructs instance and parses args * @param args zygote command-line args Loading Loading @@ -540,6 +526,8 @@ class ZygoteConnection { mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; } else if (arg.equals("--mount-external-multiuser-all")) { mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; } else if (arg.equals("--query-abi-list")) { abiListQuery = true; } else { break; } Loading Loading @@ -975,7 +963,7 @@ class ZygoteConnection { mSocketOutStream.writeInt(pid); mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error reading from command socket", ex); Log.e(TAG, "Error writing to command socket", ex); return true; } Loading
core/java/com/android/internal/os/ZygoteInit.java +34 −22 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class ZygoteInit { private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload"; private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote"; private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_"; private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020; private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030; Loading @@ -72,8 +72,9 @@ public class ZygoteInit { /** when preloading, GC after allocating this many bytes */ private static final int PRELOAD_GC_THRESHOLD = 50000; public static final String USAGE_STRING = " <\"start-system-server\"|\"\" for startSystemServer>"; private static final String ABI_LIST_ARG = "--abi-list="; private static final String SOCKET_NAME_ARG = "--socket-name="; private static LocalServerSocket sServerSocket; Loading Loading @@ -150,15 +151,15 @@ public class ZygoteInit { * * @throws RuntimeException when open fails */ private static void registerZygoteSocket() { private static void registerZygoteSocket(String socketName) { if (sServerSocket == null) { int fileDesc; final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { String env = System.getenv(ANDROID_SOCKET_ENV); String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException( ANDROID_SOCKET_ENV + " unset or invalid", ex); throw new RuntimeException(fullSocketName + " unset or invalid", ex); } try { Loading @@ -175,9 +176,9 @@ public class ZygoteInit { * Waits for and accepts a single command connection. Throws * RuntimeException on failure. */ private static ZygoteConnection acceptCommandPeer() { private static ZygoteConnection acceptCommandPeer(String abiList) { try { return new ZygoteConnection(sServerSocket.accept()); return new ZygoteConnection(sServerSocket.accept(), abiList); } catch (IOException ex) { throw new RuntimeException( "IOException during accept()", ex); Loading Loading @@ -576,7 +577,26 @@ public class ZygoteInit { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); registerZygoteSocket(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } registerZygoteSocket(socketName); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(); Loading @@ -593,20 +613,12 @@ public class ZygoteInit { // Zygote. Trace.setTracingEnabled(false); // If requested, start system server directly from Zygote if (argv.length != 2) { throw new RuntimeException(argv[0] + USAGE_STRING); } if (argv[1].equals("start-system-server")) { if (startSystemServer) { startSystemServer(); } else if (!argv[1].equals("")) { throw new RuntimeException(argv[0] + USAGE_STRING); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(); runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { Loading @@ -626,7 +638,7 @@ public class ZygoteInit { * @throws MethodAndArgsCaller in a child process when a main() should * be executed. */ private static void runSelectLoop() throws MethodAndArgsCaller { private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); FileDescriptor[] fdArray = new FileDescriptor[4]; Loading Loading @@ -665,7 +677,7 @@ public class ZygoteInit { if (index < 0) { throw new RuntimeException("Error in select()"); } else if (index == 0) { ZygoteConnection newPeer = acceptCommandPeer(); ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { Loading