Zygote: Increase wrap-pid timeout to thirty seconds

Some lowend devices under heavy instrumentation may not be able to
send the pid in the current five seconds. Drop the safety and
ignore watchdog debug builds, and move the timeout to thirty seconds.

Make the ZygoteConnection constants sharable in their own @hide class.
Add an assert into the watchdog that the wait time is less than the
watchdog time on non-debug builds.

Bug: 63904739
Bug: 63638768
Test: m
Test: manual test
Test: cts-tradefed run commandAndExit cts-dev -m CtsWrapWrapDebugTestCases
Change-Id: I80abdda54cd94e935de5a52b9f3c9192d0e31060
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 941ded3..f085d80 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;
@@ -59,18 +62,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
@@ -813,10 +804,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[] {
@@ -825,7 +812,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();
 
@@ -837,7 +824,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 be021ea..49a7889 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;
@@ -53,6 +54,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;
 
@@ -248,6 +254,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) {