Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63037798 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Decrease the app zygote preload timeout.

We have received reports of apps in the field not completing their code
preload in reasonable amounts of time, which blocks other processes from
starting. Start timing out on zygote socket if preloading takes longer
than 15 seconds. Let's start conservative and bring this down over time.

Additionally, introduce a way to change the timeout through shell
commands; our tests for preloading code in the AppZygote can take a very
long time to complete, but are also difficult to split up.

Test: atest
android.seccomp.cts.SeccompHostJUnit4DeviceTest#testAppZygoteSyscalls
Bug: 263711574
Bug: 290874550
Bug: 362143834
Flag: EXEMPT bugfix

Change-Id: Ic80eca35734953a952fcb5814cac26c093204986
parent 93a6b69a
Loading
Loading
Loading
Loading
+38 −14
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ public class ZygoteProcess {

    private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 60000;

    // How long we wait for an AppZygote to complete pre-loading; this is a pretty conservative
    // value that we can probably decrease over time, but we want to be careful here.
    public static volatile int sAppZygotePreloadTimeoutMs = 15000;
    /**
     * Use a relatively short delay, because for app zygote, this is in the critical path of
     * service launch.
@@ -1099,6 +1102,17 @@ public class ZygoteProcess {
        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }

    /**
     * Updates the timeout used when preloading code in the app-zygote
     *
     * @param timeoutMs timeout in milliseconds
     */
    public static void setAppZygotePreloadTimeout(int timeoutMs) {
        Slog.i(LOG_TAG, "Changing app-zygote preload timeout to " + timeoutMs + " ms.");

        sAppZygotePreloadTimeoutMs = timeoutMs;
    }

    /**
     * Instructs the zygote to pre-load the application code for the given Application.
     * Only the app zygote supports this function.
@@ -1107,7 +1121,13 @@ public class ZygoteProcess {
    public boolean preloadApp(ApplicationInfo appInfo, String abi)
            throws ZygoteStartFailedEx, IOException {
        synchronized (mLock) {
            int ret;
            ZygoteState state = openZygoteSocketIfNeeded(abi);
            int previousSocketTimeout = state.mZygoteSessionSocket.getSoTimeout();

            try {
                state.mZygoteSessionSocket.setSoTimeout(sAppZygotePreloadTimeoutMs);

                state.mZygoteOutputWriter.write("2");
                state.mZygoteOutputWriter.newLine();

@@ -1125,7 +1145,11 @@ public class ZygoteProcess {

                state.mZygoteOutputWriter.flush();

            return (state.mZygoteInputStream.readInt() == 0);
                ret = state.mZygoteInputStream.readInt();
            } finally {
                state.mZygoteSessionSocket.setSoTimeout(previousSocketTimeout);
            }
            return ret == 0;
        }
    }

+14 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.ZygoteProcess;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -439,6 +440,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runSetForegroundServiceDelegate(pw);
                case "capabilities":
                    return runCapabilities(pw);
                case "set-app-zygote-preload-timeout":
                    return runSetAppZygotePreloadTimeout(pw);
                default:
                    return handleDefaultCommands(cmd);
            }
@@ -448,6 +451,15 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return -1;
    }

    int runSetAppZygotePreloadTimeout(PrintWriter pw) throws RemoteException {
        final String timeout = getNextArgRequired();
        final int timeoutMs = Integer.parseInt(timeout);

        ZygoteProcess.setAppZygotePreloadTimeout(timeoutMs);

        return 0;
    }

    int runCapabilities(PrintWriter pw) throws RemoteException {
        final PrintWriter err = getErrPrintWriter();
        boolean outputAsProtobuf = false;
@@ -4603,6 +4615,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("  capabilities [--protobuf]");
            pw.println("         Output am supported features (text format). Options are:");
            pw.println("         --protobuf: format output using protobuffer");
            pw.println("  set-app-zygote-preload-timeout <TIMEOUT_IN_MS>");
            pw.println("         Set the timeout for preloading code in the app-zygote");
            Intent.printIntentArgsHelp(pw, "");
        }
    }