Loading core/java/com/android/internal/os/RuntimeInit.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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 Loading core/java/com/android/internal/os/WebViewZygoteInit.java 0 → 100644 +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"); } } core/java/com/android/internal/os/WrapperInit.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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(); } } } } Loading core/java/com/android/internal/os/Zygote.java +38 −0 Original line number Original line Diff line number Diff line Loading @@ -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 { /* /* Loading Loading @@ -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); } } } } } core/java/com/android/internal/os/ZygoteConnection.java +8 −9 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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$(); Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading
core/java/com/android/internal/os/RuntimeInit.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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 Loading
core/java/com/android/internal/os/WebViewZygoteInit.java 0 → 100644 +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"); } }
core/java/com/android/internal/os/WrapperInit.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -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(); } } } } Loading
core/java/com/android/internal/os/Zygote.java +38 −0 Original line number Original line Diff line number Diff line Loading @@ -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 { /* /* Loading Loading @@ -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); } } } } }
core/java/com/android/internal/os/ZygoteConnection.java +8 −9 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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$(); Loading @@ -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 Loading Loading @@ -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 Loading @@ -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