Merge "Zygote: Increase wrap-pid timeout to thirty seconds" into oc-mr1-dev
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 1e82054..9fa3239 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -22,6 +22,9 @@
import static android.system.OsConstants.STDERR_FILENO;
import static android.system.OsConstants.STDIN_FILENO;
import static android.system.OsConstants.STDOUT_FILENO;
+import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS;
+import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
+import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
import android.net.Credentials;
import android.net.LocalSocket;
@@ -56,18 +59,6 @@
private static final int[][] intArray2d = new int[0][0];
/**
- * {@link android.net.LocalSocket#setSoTimeout} value for connections.
- * Effectively, the amount of time a requestor has between the start of
- * the request and the completed request. The select-loop mode Zygote
- * doesn't have the logic to return to the select loop in the middle of
- * a request, so we need to time out here to avoid being denial-of-serviced.
- */
- private static final int CONNECTION_TIMEOUT_MILLIS = 1000;
-
- /** max number of arguments that a connection can specify */
- private static final int MAX_ZYGOTE_ARGC = 1024;
-
- /**
* The command socket.
*
* mSocket is retained in the child process in "peer wait" mode, so
@@ -835,10 +826,6 @@
try {
// Do a busy loop here. We can't guarantee that a failure (and thus an exception
// bail) happens in a timely manner.
- //
- // We'll wait up to five seconds. This should give enough time for the fork to go
- // through, but not to trigger the watchdog in the system server.
- final int SLEEP_IN_MS = 5000;
final int BYTES_REQUIRED = 4; // Bytes in an int.
StructPollfd fds[] = new StructPollfd[] {
@@ -847,7 +834,7 @@
byte data[] = new byte[BYTES_REQUIRED];
- int remainingSleepTime = SLEEP_IN_MS;
+ int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS;
int dataIndex = 0;
long startTime = System.nanoTime();
@@ -859,7 +846,8 @@
int res = android.system.Os.poll(fds, remainingSleepTime);
long endTime = System.nanoTime();
- remainingSleepTime = SLEEP_IN_MS - (int)((endTime - startTime) / 1000000l);
+ int elapsedTimeMs = (int)((endTime - startTime) / 1000000l);
+ remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS - elapsedTimeMs;
if (res > 0) {
if ((fds[0].revents & POLLIN) != 0) {
diff --git a/core/java/com/android/internal/os/ZygoteConnectionConstants.java b/core/java/com/android/internal/os/ZygoteConnectionConstants.java
new file mode 100644
index 0000000..506e39f
--- /dev/null
+++ b/core/java/com/android/internal/os/ZygoteConnectionConstants.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 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;
+
+/**
+ * Sharable zygote constants.
+ *
+ * @hide
+ */
+public class ZygoteConnectionConstants {
+ /**
+ * {@link android.net.LocalSocket#setSoTimeout} value for connections.
+ * Effectively, the amount of time a requestor has between the start of
+ * the request and the completed request. The select-loop mode Zygote
+ * doesn't have the logic to return to the select loop in the middle of
+ * a request, so we need to time out here to avoid being denial-of-serviced.
+ */
+ public static final int CONNECTION_TIMEOUT_MILLIS = 1000;
+
+ /** max number of arguments that a connection can specify */
+ public static final int MAX_ZYGOTE_ARGC = 1024;
+
+ /**
+ * Wait time for a wrapped app to report back its pid.
+ *
+ * We'll wait up to thirty seconds. This should give enough time for the fork
+ * to go through, but not to trigger the watchdog in the system server (by default
+ * sixty seconds).
+ *
+ * WARNING: This may trigger the watchdog in debug mode. However, to support
+ * wrapping on lower-end devices we do not have much choice.
+ */
+ public static final int WRAPPED_PID_TIMEOUT_MILLIS = 30000;
+}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index aceedf1..6a81d32 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -19,6 +19,7 @@
import android.app.IActivityController;
import android.os.Binder;
import android.os.RemoteException;
+import com.android.internal.os.ZygoteConnectionConstants;
import com.android.server.am.ActivityManagerService;
import android.content.BroadcastReceiver;
@@ -57,6 +58,11 @@
// Set this to true to have the watchdog record kernel thread stacks when it fires
static final boolean RECORD_KERNEL_THREADS = true;
+ // Note 1: Do not lower this value below thirty seconds without tightening the invoke-with
+ // timeout in com.android.internal.os.ZygoteConnection, or wrapped applications
+ // can trigger the watchdog.
+ // Note 2: The debug value is already below the wait time in ZygoteConnection. Wrapped
+ // applications may not work with a debug build. CTS will fail.
static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000;
static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2;
@@ -262,6 +268,10 @@
// Initialize monitor for Binder threads.
addMonitor(new BinderThreadMonitor());
+
+ // See the notes on DEFAULT_TIMEOUT.
+ assert DB ||
+ DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
}
public void init(Context context, ActivityManagerService activity) {