Loading core/java/android/os/Process.java +2 −13 Original line number Diff line number Diff line Loading @@ -29,16 +29,6 @@ import dalvik.system.VMRuntime; public class Process { private static final String LOG_TAG = "Process"; /** * @hide for internal use only. */ public static final String ZYGOTE_SOCKET = "zygote"; /** * @hide for internal use only. */ public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary"; /** * An invalid UID value. */ Loading Loading @@ -454,8 +444,7 @@ public class Process { * State associated with the zygote process. * @hide */ public static final ZygoteProcess zygoteProcess = new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET); public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess(); /** * Start a new process. Loading Loading @@ -507,7 +496,7 @@ public class Process { String appDataDir, String invokeWith, String[] zygoteArgs) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); } Loading core/java/android/os/ZygoteProcess.java +145 −100 Original line number Diff line number Diff line Loading @@ -58,87 +58,119 @@ import java.util.UUID; * {@hide} */ public class ZygoteProcess { /** * @hide for internal use only. */ public static final String ZYGOTE_SOCKET_NAME = "zygote"; /** * @hide for internal use only. */ public static final String ZYGOTE_SECONDARY_SOCKET_NAME = "zygote_secondary"; /** * @hide for internal use only */ private static final String LOG_TAG = "ZygoteProcess"; /** * The name of the socket used to communicate with the primary zygote. */ private final LocalSocketAddress mSocket; private final LocalSocketAddress mZygoteSocketAddress; /** * The name of the secondary (alternate ABI) zygote socket. */ private final LocalSocketAddress mSecondarySocket; private final LocalSocketAddress mZygoteSecondarySocketAddress; public ZygoteProcess(String primarySocket, String secondarySocket) { this(new LocalSocketAddress(primarySocket, LocalSocketAddress.Namespace.RESERVED), new LocalSocketAddress(secondarySocket, LocalSocketAddress.Namespace.RESERVED)); public ZygoteProcess() { mZygoteSocketAddress = new LocalSocketAddress(ZYGOTE_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); mZygoteSecondarySocketAddress = new LocalSocketAddress(ZYGOTE_SECONDARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); } public ZygoteProcess(LocalSocketAddress primarySocket, LocalSocketAddress secondarySocket) { mSocket = primarySocket; mSecondarySocket = secondarySocket; public ZygoteProcess(LocalSocketAddress primarySocketAddress, LocalSocketAddress secondarySocketAddress) { mZygoteSocketAddress = primarySocketAddress; mZygoteSecondarySocketAddress = secondarySocketAddress; } public LocalSocketAddress getPrimarySocketAddress() { return mSocket; return mZygoteSocketAddress; } /** * State for communicating with the zygote process. */ public static class ZygoteState { final LocalSocket socket; final DataInputStream inputStream; final BufferedWriter writer; final List<String> abiList; final LocalSocketAddress mZygoteSocketAddress; private final LocalSocket mZygoteSessionSocket; final DataInputStream mZygoteInputStream; final BufferedWriter mZygoteOutputWriter; boolean mClosed; private final List<String> mABIList; private ZygoteState(LocalSocket socket, DataInputStream inputStream, BufferedWriter writer, List<String> abiList) { this.socket = socket; this.inputStream = inputStream; this.writer = writer; this.abiList = abiList; private boolean mClosed; private ZygoteState(LocalSocketAddress zygoteSocketAddress, LocalSocket zygoteSessionSocket, DataInputStream zygoteInputStream, BufferedWriter zygoteOutputWriter, List<String> abiList) { this.mZygoteSocketAddress = zygoteSocketAddress; this.mZygoteSessionSocket = zygoteSessionSocket; this.mZygoteInputStream = zygoteInputStream; this.mZygoteOutputWriter = zygoteOutputWriter; this.mABIList = abiList; } public static ZygoteState connect(LocalSocketAddress address) throws IOException { /** * Create a new ZygoteState object by connecting to the given Zygote socket. * * @param zygoteSocketAddress Zygote socket to connect to * @return A new ZygoteState object containing a session socket for the given Zygote socket * address * @throws IOException */ public static ZygoteState connect(LocalSocketAddress zygoteSocketAddress) throws IOException { DataInputStream zygoteInputStream = null; BufferedWriter zygoteWriter = null; final LocalSocket zygoteSocket = new LocalSocket(); BufferedWriter zygoteOutputWriter = null; final LocalSocket zygoteSessionSocket = new LocalSocket(); try { zygoteSocket.connect(address); zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream()); zygoteWriter = new BufferedWriter(new OutputStreamWriter( zygoteSocket.getOutputStream()), 256); zygoteSessionSocket.connect(zygoteSocketAddress); zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream()); zygoteOutputWriter = new BufferedWriter( new OutputStreamWriter(zygoteSessionSocket.getOutputStream()), 256); } catch (IOException ex) { try { zygoteSocket.close(); } catch (IOException ignore) { } zygoteSessionSocket.close(); } catch (IOException ignore) { } throw ex; } String abiListString = getAbiList(zygoteWriter, zygoteInputStream); Log.i("Zygote", "Process: zygote socket " + address.getNamespace() + "/" + address.getName() + " opened, supported ABIS: " + abiListString); return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter, Arrays.asList(abiListString.split(","))); return new ZygoteState(zygoteSocketAddress, zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter, getAbiList(zygoteOutputWriter, zygoteInputStream)); } boolean matches(String abi) { return abiList.contains(abi); return mABIList.contains(abi); } public void close() { try { socket.close(); mZygoteSessionSocket.close(); } catch (IOException ex) { Log.e(LOG_TAG,"I/O exception on routine close", ex); } Loading Loading @@ -231,8 +263,8 @@ public class ZygoteProcess { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/false, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); Loading @@ -250,7 +282,7 @@ public class ZygoteProcess { * @throws ZygoteStartFailedEx if the query failed. */ @GuardedBy("mLock") private static String getAbiList(BufferedWriter writer, DataInputStream inputStream) private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream) throws IOException { // Each query starts with the argument count (1 in this case) writer.write("1"); Loading @@ -266,7 +298,9 @@ public class ZygoteProcess { byte[] bytes = new byte[numBytes]; inputStream.readFully(bytes); return new String(bytes, StandardCharsets.US_ASCII); String rawList = new String(bytes, StandardCharsets.US_ASCII); return Arrays.asList(rawList.split(",")); } /** Loading Loading @@ -300,8 +334,8 @@ public class ZygoteProcess { * the child or -1 on failure, followed by boolean to * indicate whether a wrapper process was used. */ final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; final BufferedWriter writer = zygoteState.mZygoteOutputWriter; final DataInputStream inputStream = zygoteState.mZygoteInputStream; writer.write(Integer.toString(args.size())); writer.newLine(); Loading Loading @@ -475,18 +509,18 @@ public class ZygoteProcess { ZygoteState state = openZygoteSocketIfNeeded(abi); // Each query starts with the argument count (1 in this case) state.writer.write("1"); state.mZygoteOutputWriter.write("1"); // ... followed by a new-line. state.writer.newLine(); state.mZygoteOutputWriter.newLine(); // ... followed by our only argument. state.writer.write("--get-pid"); state.writer.newLine(); state.writer.flush(); state.mZygoteOutputWriter.write("--get-pid"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); // The response is a length prefixed stream of ASCII bytes. int numBytes = state.inputStream.readInt(); int numBytes = state.mZygoteInputStream.readInt(); byte[] bytes = new byte[numBytes]; state.inputStream.readFully(bytes); state.mZygoteInputStream.readFully(bytes); return Integer.parseInt(new String(bytes, StandardCharsets.US_ASCII)); } Loading Loading @@ -540,16 +574,16 @@ public class ZygoteProcess { return true; } try { state.writer.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.writer.newLine(); state.writer.write("--set-api-blacklist-exemptions"); state.writer.newLine(); state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--set-api-blacklist-exemptions"); state.mZygoteOutputWriter.newLine(); for (int i = 0; i < mApiBlacklistExemptions.size(); ++i) { state.writer.write(mApiBlacklistExemptions.get(i)); state.writer.newLine(); state.mZygoteOutputWriter.write(mApiBlacklistExemptions.get(i)); state.mZygoteOutputWriter.newLine(); } state.writer.flush(); int status = state.inputStream.readInt(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); if (status != 0) { Slog.e(LOG_TAG, "Failed to set API blacklist exemptions; status " + status); } Loading @@ -569,13 +603,13 @@ public class ZygoteProcess { return; } try { state.writer.write(Integer.toString(1)); state.writer.newLine(); state.writer.write("--hidden-api-log-sampling-rate=" state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate=" + Integer.toString(mHiddenApiAccessLogSampleRate)); state.writer.newLine(); state.writer.flush(); int status = state.inputStream.readInt(); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); if (status != 0) { Slog.e(LOG_TAG, "Failed to set hidden API log sampling rate; status " + status); } Loading @@ -585,22 +619,29 @@ public class ZygoteProcess { } /** * Tries to open socket to Zygote process if not already open. If * already open, does nothing. May block and retry. Requires that mLock be held. * Tries to open a session socket to a Zygote process with a compatible ABI if one is not * already open. If a compatible session socket is already open that session socket is returned. * This function may block and may have to try connecting to multiple Zygotes to find the * appropriate one. Requires that mLock be held. */ @GuardedBy("mLock") private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(mSocket); primaryZygoteState = ZygoteState.connect(mZygoteSocketAddress); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } Loading @@ -608,10 +649,12 @@ public class ZygoteProcess { // The primary zygote didn't match. Try the secondary. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { secondaryZygoteState = ZygoteState.connect(mSecondarySocket); secondaryZygoteState = ZygoteState.connect(mZygoteSecondarySocketAddress); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } maybeSetApiBlacklistExemptions(secondaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState); } Loading @@ -632,27 +675,27 @@ public class ZygoteProcess { IOException { synchronized(mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.writer.write("5"); state.writer.newLine(); state.mZygoteOutputWriter.write("5"); state.mZygoteOutputWriter.newLine(); state.writer.write("--preload-package"); state.writer.newLine(); state.mZygoteOutputWriter.write("--preload-package"); state.mZygoteOutputWriter.newLine(); state.writer.write(packagePath); state.writer.newLine(); state.mZygoteOutputWriter.write(packagePath); state.mZygoteOutputWriter.newLine(); state.writer.write(libsPath); state.writer.newLine(); state.mZygoteOutputWriter.write(libsPath); state.mZygoteOutputWriter.newLine(); state.writer.write(libFileName); state.writer.newLine(); state.mZygoteOutputWriter.write(libFileName); state.mZygoteOutputWriter.newLine(); state.writer.write(cacheKey); state.writer.newLine(); state.mZygoteOutputWriter.write(cacheKey); state.mZygoteOutputWriter.newLine(); state.writer.flush(); state.mZygoteOutputWriter.flush(); return (state.inputStream.readInt() == 0); return (state.mZygoteInputStream.readInt() == 0); } } Loading @@ -666,13 +709,13 @@ public class ZygoteProcess { synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); // Each query starts with the argument count (1 in this case) state.writer.write("1"); state.writer.newLine(); state.writer.write("--preload-default"); state.writer.newLine(); state.writer.flush(); state.mZygoteOutputWriter.write("1"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--preload-default"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); return (state.inputStream.readInt() == 0); return (state.mZygoteInputStream.readInt() == 0); } } Loading @@ -680,20 +723,21 @@ public class ZygoteProcess { * Try connecting to the Zygote over and over again until we hit a time-out. * @param socketName The name of the socket to connect to. */ public static void waitForConnectionToZygote(String socketName) { final LocalSocketAddress address = new LocalSocketAddress(socketName, LocalSocketAddress.Namespace.RESERVED); waitForConnectionToZygote(address); public static void waitForConnectionToZygote(String zygoteSocketName) { final LocalSocketAddress zygoteSocketAddress = new LocalSocketAddress(zygoteSocketName, LocalSocketAddress.Namespace.RESERVED); waitForConnectionToZygote(zygoteSocketAddress); } /** * Try connecting to the Zygote over and over again until we hit a time-out. * @param address The name of the socket to connect to. */ public static void waitForConnectionToZygote(LocalSocketAddress address) { public static void waitForConnectionToZygote(LocalSocketAddress zygoteSocketAddress) { for (int n = 20; n >= 0; n--) { try { final ZygoteState zs = ZygoteState.connect(address); final ZygoteState zs = ZygoteState.connect(zygoteSocketAddress); zs.close(); return; } catch (IOException ioe) { Loading @@ -706,7 +750,8 @@ public class ZygoteProcess { } catch (InterruptedException ie) { } } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + address.getName()); Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + zygoteSocketAddress.getName()); } /** Loading core/java/android/webkit/WebViewZygote.java +1 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ public class WebViewZygote { } try { sZygote = Process.zygoteProcess.startChildZygote( sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "webview_zygote", Process.WEBVIEW_ZYGOTE_UID, Loading core/java/com/android/internal/os/WebViewZygoteInit.java +0 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.internal.os; import android.app.ApplicationLoaders; import android.net.LocalSocket; import android.net.LocalServerSocket; import android.os.Build; import android.system.ErrnoException; import android.system.Os; Loading core/java/com/android/internal/os/ZygoteInit.java +2 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.system.OsConstants.S_IRWXO; import android.content.res.Resources; import android.content.res.TypedArray; import android.opengl.EGL14; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -853,8 +852,8 @@ public class ZygoteInit { } private static void waitForSecondaryZygote(String socketName) { String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ? Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET; String otherZygoteName = ZygoteProcess.ZYGOTE_SOCKET_NAME.equals(socketName) ? ZygoteProcess.ZYGOTE_SECONDARY_SOCKET_NAME : ZygoteProcess.ZYGOTE_SOCKET_NAME; ZygoteProcess.waitForConnectionToZygote(otherZygoteName); } Loading Loading
core/java/android/os/Process.java +2 −13 Original line number Diff line number Diff line Loading @@ -29,16 +29,6 @@ import dalvik.system.VMRuntime; public class Process { private static final String LOG_TAG = "Process"; /** * @hide for internal use only. */ public static final String ZYGOTE_SOCKET = "zygote"; /** * @hide for internal use only. */ public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary"; /** * An invalid UID value. */ Loading Loading @@ -454,8 +444,7 @@ public class Process { * State associated with the zygote process. * @hide */ public static final ZygoteProcess zygoteProcess = new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET); public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess(); /** * Start a new process. Loading Loading @@ -507,7 +496,7 @@ public class Process { String appDataDir, String invokeWith, String[] zygoteArgs) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); } Loading
core/java/android/os/ZygoteProcess.java +145 −100 Original line number Diff line number Diff line Loading @@ -58,87 +58,119 @@ import java.util.UUID; * {@hide} */ public class ZygoteProcess { /** * @hide for internal use only. */ public static final String ZYGOTE_SOCKET_NAME = "zygote"; /** * @hide for internal use only. */ public static final String ZYGOTE_SECONDARY_SOCKET_NAME = "zygote_secondary"; /** * @hide for internal use only */ private static final String LOG_TAG = "ZygoteProcess"; /** * The name of the socket used to communicate with the primary zygote. */ private final LocalSocketAddress mSocket; private final LocalSocketAddress mZygoteSocketAddress; /** * The name of the secondary (alternate ABI) zygote socket. */ private final LocalSocketAddress mSecondarySocket; private final LocalSocketAddress mZygoteSecondarySocketAddress; public ZygoteProcess(String primarySocket, String secondarySocket) { this(new LocalSocketAddress(primarySocket, LocalSocketAddress.Namespace.RESERVED), new LocalSocketAddress(secondarySocket, LocalSocketAddress.Namespace.RESERVED)); public ZygoteProcess() { mZygoteSocketAddress = new LocalSocketAddress(ZYGOTE_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); mZygoteSecondarySocketAddress = new LocalSocketAddress(ZYGOTE_SECONDARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); } public ZygoteProcess(LocalSocketAddress primarySocket, LocalSocketAddress secondarySocket) { mSocket = primarySocket; mSecondarySocket = secondarySocket; public ZygoteProcess(LocalSocketAddress primarySocketAddress, LocalSocketAddress secondarySocketAddress) { mZygoteSocketAddress = primarySocketAddress; mZygoteSecondarySocketAddress = secondarySocketAddress; } public LocalSocketAddress getPrimarySocketAddress() { return mSocket; return mZygoteSocketAddress; } /** * State for communicating with the zygote process. */ public static class ZygoteState { final LocalSocket socket; final DataInputStream inputStream; final BufferedWriter writer; final List<String> abiList; final LocalSocketAddress mZygoteSocketAddress; private final LocalSocket mZygoteSessionSocket; final DataInputStream mZygoteInputStream; final BufferedWriter mZygoteOutputWriter; boolean mClosed; private final List<String> mABIList; private ZygoteState(LocalSocket socket, DataInputStream inputStream, BufferedWriter writer, List<String> abiList) { this.socket = socket; this.inputStream = inputStream; this.writer = writer; this.abiList = abiList; private boolean mClosed; private ZygoteState(LocalSocketAddress zygoteSocketAddress, LocalSocket zygoteSessionSocket, DataInputStream zygoteInputStream, BufferedWriter zygoteOutputWriter, List<String> abiList) { this.mZygoteSocketAddress = zygoteSocketAddress; this.mZygoteSessionSocket = zygoteSessionSocket; this.mZygoteInputStream = zygoteInputStream; this.mZygoteOutputWriter = zygoteOutputWriter; this.mABIList = abiList; } public static ZygoteState connect(LocalSocketAddress address) throws IOException { /** * Create a new ZygoteState object by connecting to the given Zygote socket. * * @param zygoteSocketAddress Zygote socket to connect to * @return A new ZygoteState object containing a session socket for the given Zygote socket * address * @throws IOException */ public static ZygoteState connect(LocalSocketAddress zygoteSocketAddress) throws IOException { DataInputStream zygoteInputStream = null; BufferedWriter zygoteWriter = null; final LocalSocket zygoteSocket = new LocalSocket(); BufferedWriter zygoteOutputWriter = null; final LocalSocket zygoteSessionSocket = new LocalSocket(); try { zygoteSocket.connect(address); zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream()); zygoteWriter = new BufferedWriter(new OutputStreamWriter( zygoteSocket.getOutputStream()), 256); zygoteSessionSocket.connect(zygoteSocketAddress); zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream()); zygoteOutputWriter = new BufferedWriter( new OutputStreamWriter(zygoteSessionSocket.getOutputStream()), 256); } catch (IOException ex) { try { zygoteSocket.close(); } catch (IOException ignore) { } zygoteSessionSocket.close(); } catch (IOException ignore) { } throw ex; } String abiListString = getAbiList(zygoteWriter, zygoteInputStream); Log.i("Zygote", "Process: zygote socket " + address.getNamespace() + "/" + address.getName() + " opened, supported ABIS: " + abiListString); return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter, Arrays.asList(abiListString.split(","))); return new ZygoteState(zygoteSocketAddress, zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter, getAbiList(zygoteOutputWriter, zygoteInputStream)); } boolean matches(String abi) { return abiList.contains(abi); return mABIList.contains(abi); } public void close() { try { socket.close(); mZygoteSessionSocket.close(); } catch (IOException ex) { Log.e(LOG_TAG,"I/O exception on routine close", ex); } Loading Loading @@ -231,8 +263,8 @@ public class ZygoteProcess { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/false, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); Loading @@ -250,7 +282,7 @@ public class ZygoteProcess { * @throws ZygoteStartFailedEx if the query failed. */ @GuardedBy("mLock") private static String getAbiList(BufferedWriter writer, DataInputStream inputStream) private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream) throws IOException { // Each query starts with the argument count (1 in this case) writer.write("1"); Loading @@ -266,7 +298,9 @@ public class ZygoteProcess { byte[] bytes = new byte[numBytes]; inputStream.readFully(bytes); return new String(bytes, StandardCharsets.US_ASCII); String rawList = new String(bytes, StandardCharsets.US_ASCII); return Arrays.asList(rawList.split(",")); } /** Loading Loading @@ -300,8 +334,8 @@ public class ZygoteProcess { * the child or -1 on failure, followed by boolean to * indicate whether a wrapper process was used. */ final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; final BufferedWriter writer = zygoteState.mZygoteOutputWriter; final DataInputStream inputStream = zygoteState.mZygoteInputStream; writer.write(Integer.toString(args.size())); writer.newLine(); Loading Loading @@ -475,18 +509,18 @@ public class ZygoteProcess { ZygoteState state = openZygoteSocketIfNeeded(abi); // Each query starts with the argument count (1 in this case) state.writer.write("1"); state.mZygoteOutputWriter.write("1"); // ... followed by a new-line. state.writer.newLine(); state.mZygoteOutputWriter.newLine(); // ... followed by our only argument. state.writer.write("--get-pid"); state.writer.newLine(); state.writer.flush(); state.mZygoteOutputWriter.write("--get-pid"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); // The response is a length prefixed stream of ASCII bytes. int numBytes = state.inputStream.readInt(); int numBytes = state.mZygoteInputStream.readInt(); byte[] bytes = new byte[numBytes]; state.inputStream.readFully(bytes); state.mZygoteInputStream.readFully(bytes); return Integer.parseInt(new String(bytes, StandardCharsets.US_ASCII)); } Loading Loading @@ -540,16 +574,16 @@ public class ZygoteProcess { return true; } try { state.writer.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.writer.newLine(); state.writer.write("--set-api-blacklist-exemptions"); state.writer.newLine(); state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--set-api-blacklist-exemptions"); state.mZygoteOutputWriter.newLine(); for (int i = 0; i < mApiBlacklistExemptions.size(); ++i) { state.writer.write(mApiBlacklistExemptions.get(i)); state.writer.newLine(); state.mZygoteOutputWriter.write(mApiBlacklistExemptions.get(i)); state.mZygoteOutputWriter.newLine(); } state.writer.flush(); int status = state.inputStream.readInt(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); if (status != 0) { Slog.e(LOG_TAG, "Failed to set API blacklist exemptions; status " + status); } Loading @@ -569,13 +603,13 @@ public class ZygoteProcess { return; } try { state.writer.write(Integer.toString(1)); state.writer.newLine(); state.writer.write("--hidden-api-log-sampling-rate=" state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate=" + Integer.toString(mHiddenApiAccessLogSampleRate)); state.writer.newLine(); state.writer.flush(); int status = state.inputStream.readInt(); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); if (status != 0) { Slog.e(LOG_TAG, "Failed to set hidden API log sampling rate; status " + status); } Loading @@ -585,22 +619,29 @@ public class ZygoteProcess { } /** * Tries to open socket to Zygote process if not already open. If * already open, does nothing. May block and retry. Requires that mLock be held. * Tries to open a session socket to a Zygote process with a compatible ABI if one is not * already open. If a compatible session socket is already open that session socket is returned. * This function may block and may have to try connecting to multiple Zygotes to find the * appropriate one. Requires that mLock be held. */ @GuardedBy("mLock") private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(mSocket); primaryZygoteState = ZygoteState.connect(mZygoteSocketAddress); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } Loading @@ -608,10 +649,12 @@ public class ZygoteProcess { // The primary zygote didn't match. Try the secondary. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { secondaryZygoteState = ZygoteState.connect(mSecondarySocket); secondaryZygoteState = ZygoteState.connect(mZygoteSecondarySocketAddress); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } maybeSetApiBlacklistExemptions(secondaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState); } Loading @@ -632,27 +675,27 @@ public class ZygoteProcess { IOException { synchronized(mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.writer.write("5"); state.writer.newLine(); state.mZygoteOutputWriter.write("5"); state.mZygoteOutputWriter.newLine(); state.writer.write("--preload-package"); state.writer.newLine(); state.mZygoteOutputWriter.write("--preload-package"); state.mZygoteOutputWriter.newLine(); state.writer.write(packagePath); state.writer.newLine(); state.mZygoteOutputWriter.write(packagePath); state.mZygoteOutputWriter.newLine(); state.writer.write(libsPath); state.writer.newLine(); state.mZygoteOutputWriter.write(libsPath); state.mZygoteOutputWriter.newLine(); state.writer.write(libFileName); state.writer.newLine(); state.mZygoteOutputWriter.write(libFileName); state.mZygoteOutputWriter.newLine(); state.writer.write(cacheKey); state.writer.newLine(); state.mZygoteOutputWriter.write(cacheKey); state.mZygoteOutputWriter.newLine(); state.writer.flush(); state.mZygoteOutputWriter.flush(); return (state.inputStream.readInt() == 0); return (state.mZygoteInputStream.readInt() == 0); } } Loading @@ -666,13 +709,13 @@ public class ZygoteProcess { synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); // Each query starts with the argument count (1 in this case) state.writer.write("1"); state.writer.newLine(); state.writer.write("--preload-default"); state.writer.newLine(); state.writer.flush(); state.mZygoteOutputWriter.write("1"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--preload-default"); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); return (state.inputStream.readInt() == 0); return (state.mZygoteInputStream.readInt() == 0); } } Loading @@ -680,20 +723,21 @@ public class ZygoteProcess { * Try connecting to the Zygote over and over again until we hit a time-out. * @param socketName The name of the socket to connect to. */ public static void waitForConnectionToZygote(String socketName) { final LocalSocketAddress address = new LocalSocketAddress(socketName, LocalSocketAddress.Namespace.RESERVED); waitForConnectionToZygote(address); public static void waitForConnectionToZygote(String zygoteSocketName) { final LocalSocketAddress zygoteSocketAddress = new LocalSocketAddress(zygoteSocketName, LocalSocketAddress.Namespace.RESERVED); waitForConnectionToZygote(zygoteSocketAddress); } /** * Try connecting to the Zygote over and over again until we hit a time-out. * @param address The name of the socket to connect to. */ public static void waitForConnectionToZygote(LocalSocketAddress address) { public static void waitForConnectionToZygote(LocalSocketAddress zygoteSocketAddress) { for (int n = 20; n >= 0; n--) { try { final ZygoteState zs = ZygoteState.connect(address); final ZygoteState zs = ZygoteState.connect(zygoteSocketAddress); zs.close(); return; } catch (IOException ioe) { Loading @@ -706,7 +750,8 @@ public class ZygoteProcess { } catch (InterruptedException ie) { } } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + address.getName()); Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + zygoteSocketAddress.getName()); } /** Loading
core/java/android/webkit/WebViewZygote.java +1 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ public class WebViewZygote { } try { sZygote = Process.zygoteProcess.startChildZygote( sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "webview_zygote", Process.WEBVIEW_ZYGOTE_UID, Loading
core/java/com/android/internal/os/WebViewZygoteInit.java +0 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.internal.os; import android.app.ApplicationLoaders; import android.net.LocalSocket; import android.net.LocalServerSocket; import android.os.Build; import android.system.ErrnoException; import android.system.Os; Loading
core/java/com/android/internal/os/ZygoteInit.java +2 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.system.OsConstants.S_IRWXO; import android.content.res.Resources; import android.content.res.TypedArray; import android.opengl.EGL14; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -853,8 +852,8 @@ public class ZygoteInit { } private static void waitForSecondaryZygote(String socketName) { String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ? Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET; String otherZygoteName = ZygoteProcess.ZYGOTE_SOCKET_NAME.equals(socketName) ? ZygoteProcess.ZYGOTE_SECONDARY_SOCKET_NAME : ZygoteProcess.ZYGOTE_SOCKET_NAME; ZygoteProcess.waitForConnectionToZygote(otherZygoteName); } Loading