Merge "Code cleanup in ZygoteProcess.java."
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 40238d2..915baab 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -66,22 +66,14 @@
*/
public class ZygoteProcess {
- /**
- * @hide for internal use only.
- */
- public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
+ private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
/**
- * @hide for internal use only.
- *
* Use a relatively short delay, because for app zygote, this is in the critical path of
* service launch.
*/
- public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
+ private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
- /**
- * @hide for internal use only
- */
private static final String LOG_TAG = "ZygoteProcess";
/**
@@ -141,7 +133,7 @@
/**
* State for communicating with the zygote process.
*/
- public static class ZygoteState {
+ private static class ZygoteState implements AutoCloseable {
final LocalSocketAddress mZygoteSocketAddress;
final LocalSocketAddress mUsapSocketAddress;
@@ -178,12 +170,12 @@
* address
* @throws IOException
*/
- public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
- @Nullable LocalSocketAddress usapSocketAddress)
+ static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
+ @Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
- DataInputStream zygoteInputStream = null;
- BufferedWriter zygoteOutputWriter = null;
+ DataInputStream zygoteInputStream;
+ BufferedWriter zygoteOutputWriter;
final LocalSocket zygoteSessionSocket = new LocalSocket();
if (zygoteSocketAddress == null) {
@@ -357,8 +349,6 @@
/**
* Queries the zygote for the list of ABIS it supports.
- *
- * @throws ZygoteStartFailedEx if the query failed.
*/
@GuardedBy("mLock")
private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream)
@@ -411,52 +401,24 @@
* the child or -1 on failure, followed by boolean to
* indicate whether a wrapper process was used.
*/
- String msgStr = Integer.toString(args.size()) + "\n"
- + String.join("\n", args) + "\n";
+ String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
- // Should there be a timeout on this?
- Process.ProcessStartResult result = new Process.ProcessStartResult();
-
- // TODO (chriswailes): Move branch body into separate function.
if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) {
- LocalSocket usapSessionSocket = null;
-
try {
- usapSessionSocket = zygoteState.getUsapSessionSocket();
-
- final BufferedWriter usapWriter =
- new BufferedWriter(
- new OutputStreamWriter(usapSessionSocket.getOutputStream()),
- Zygote.SOCKET_BUFFER_SIZE);
- final DataInputStream usapReader =
- new DataInputStream(usapSessionSocket.getInputStream());
-
- usapWriter.write(msgStr);
- usapWriter.flush();
-
- result.pid = usapReader.readInt();
- // USAPs can't be used to spawn processes that need wrappers.
- result.usingWrapper = false;
-
- if (result.pid < 0) {
- throw new ZygoteStartFailedEx("USAP specialization failed");
- }
-
- return result;
+ return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
// If there was an IOException using the USAP pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
- + ex.getMessage());
- } finally {
- try {
- usapSessionSocket.close();
- } catch (IOException ex) {
- Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage());
- }
+ + ex.getMessage());
}
}
+ return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
+ }
+
+ private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
+ ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
@@ -467,20 +429,48 @@
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
+ Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
+
+ if (result.pid < 0) {
+ throw new ZygoteStartFailedEx("fork() failed");
+ }
+
+ return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
+ }
- if (result.pid < 0) {
- throw new ZygoteStartFailedEx("fork() failed");
+ private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
+ ZygoteState zygoteState, String msgStr)
+ throws ZygoteStartFailedEx, IOException {
+ try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
+ final BufferedWriter usapWriter =
+ new BufferedWriter(
+ new OutputStreamWriter(usapSessionSocket.getOutputStream()),
+ Zygote.SOCKET_BUFFER_SIZE);
+ final DataInputStream usapReader =
+ new DataInputStream(usapSessionSocket.getInputStream());
+
+ usapWriter.write(msgStr);
+ usapWriter.flush();
+
+ Process.ProcessStartResult result = new Process.ProcessStartResult();
+ result.pid = usapReader.readInt();
+ // USAPs can't be used to spawn processes that need wrappers.
+ result.usingWrapper = false;
+
+ if (result.pid >= 0) {
+ return result;
+ } else {
+ throw new ZygoteStartFailedEx("USAP specialization failed");
+ }
}
-
- return result;
}
/**
@@ -557,7 +547,7 @@
boolean useUnspecializedAppProcessPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
- ArrayList<String> argsForZygote = new ArrayList<String>();
+ ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
@@ -627,17 +617,7 @@
}
if (packagesForUid != null && packagesForUid.length > 0) {
- final StringBuilder sb = new StringBuilder();
- sb.append("--packages-for-uid=");
-
- // TODO (chriswailes): Replace with String.join
- for (int i = 0; i < packagesForUid.length; ++i) {
- if (i != 0) {
- sb.append(',');
- }
- sb.append(packagesForUid[i]);
- }
- argsForZygote.add(sb.toString());
+ argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid));
}
if (sandboxId != null) {
@@ -647,9 +627,7 @@
argsForZygote.add(processClass);
if (extraArgs != null) {
- for (String arg : extraArgs) {
- argsForZygote.add(arg);
- }
+ Collections.addAll(argsForZygote, extraArgs);
}
synchronized(mLock) {
@@ -805,10 +783,10 @@
if (state == null || state.isClosed()) {
Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection");
return false;
- }
- if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
+ } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
return true;
}
+
try {
state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1));
state.mZygoteOutputWriter.newLine();
@@ -832,17 +810,15 @@
}
private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) {
- if (state == null || state.isClosed()) {
+ if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) {
return;
}
- if (mHiddenApiAccessLogSampleRate == -1) {
- return;
- }
+
try {
state.mZygoteOutputWriter.write(Integer.toString(1));
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate="
- + Integer.toString(mHiddenApiAccessLogSampleRate));
+ + mHiddenApiAccessLogSampleRate);
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.flush();
int status = state.mZygoteInputStream.readInt();
@@ -855,17 +831,15 @@
}
private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) {
- if (state == null || state.isClosed()) {
+ if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) {
return;
}
- if (mHiddenApiAccessStatslogSampleRate == -1) {
- return;
- }
+
try {
state.mZygoteOutputWriter.write(Integer.toString(1));
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate="
- + Integer.toString(mHiddenApiAccessStatslogSampleRate));
+ + mHiddenApiAccessStatslogSampleRate);
state.mZygoteOutputWriter.newLine();
state.mZygoteOutputWriter.flush();
int status = state.mZygoteInputStream.readInt();
@@ -942,8 +916,8 @@
* Only the app zygote supports this function.
* TODO preloadPackageForAbi() can probably be removed and the callers an use this instead.
*/
- public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx,
- IOException {
+ public boolean preloadApp(ApplicationInfo appInfo, String abi)
+ throws ZygoteStartFailedEx, IOException {
synchronized (mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
state.mZygoteOutputWriter.write("2");
@@ -971,10 +945,10 @@
* Instructs the zygote to pre-load the classes and native libraries at the given paths
* for the specified abi. Not all zygotes support this function.
*/
- public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
- String cacheKey, String abi) throws ZygoteStartFailedEx,
- IOException {
- synchronized(mLock) {
+ public boolean preloadPackageForAbi(
+ String packagePath, String libsPath, String libFileName, String cacheKey, String abi)
+ throws ZygoteStartFailedEx, IOException {
+ synchronized (mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
state.mZygoteOutputWriter.write("5");
state.mZygoteOutputWriter.newLine();
@@ -1049,8 +1023,7 @@
try {
Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS);
- } catch (InterruptedException ie) {
- }
+ } catch (InterruptedException ignored) { }
}
Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket "
+ zygoteSocketAddress.getName());