diff options
3 files changed, 64 insertions, 18 deletions
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 1ccf31133e00..05f43e4abbf5 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.POLLIN; 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; @@ -59,18 +62,6 @@ class ZygoteConnection { 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 @@ -858,10 +849,6 @@ class ZygoteConnection { 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[] { @@ -870,7 +857,7 @@ class ZygoteConnection { byte data[] = new byte[BYTES_REQUIRED]; - int remainingSleepTime = SLEEP_IN_MS; + int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS; int dataIndex = 0; long startTime = System.nanoTime(); @@ -882,7 +869,8 @@ class ZygoteConnection { 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 000000000000..506e39f30617 --- /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 b18fa322bd2b..93e29c1a59f8 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -19,6 +19,7 @@ package com.android.server; 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 @@ public class Watchdog extends Thread { // 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; @@ -261,6 +267,10 @@ public class Watchdog extends Thread { // 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) { |