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

Commit 9f845cff authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Increase activity timeouts when using a wrapper process."

parents 801525ce 3f9dd287
Loading
Loading
Loading
Loading
+31 −25
Original line number Diff line number Diff line
@@ -270,13 +270,12 @@ public class Process {
     * @param targetSdkVersion The target SDK version for the app.
     * @param zygoteArgs Additional arguments to supply to the zygote process.
     * 
     * @return int If > 0 the pid of the new process; if 0 the process is
     *         being emulated by a thread
     * @return An object that describes the result of the attempt to start the process.
     * @throws RuntimeException on fatal start failure
     * 
     * {@hide}
     */
    public static final int start(final String processClass,
    public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int targetSdkVersion,
@@ -376,14 +375,11 @@ public class Process {
     * and returns the child's pid. Please note: the present implementation
     * replaces newlines in the argument list with spaces.
     * @param args argument list
     * @return PID of new child process
     * @return An object that describes the result of the attempt to start the process.
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
    private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
            throws ZygoteStartFailedEx {

        int pid;

        openZygoteSocketIfNeeded();

        try {
@@ -394,7 +390,8 @@ public class Process {
             * b) a number of newline-separated argument strings equal to count
             *
             * After the zygote process reads these it will write the pid of
             * the child or -1 on failure.
             * the child or -1 on failure, followed by boolean to
             * indicate whether a wrapper process was used.
             */

            sZygoteWriter.write(Integer.toString(args.size()));
@@ -414,11 +411,13 @@ public class Process {
            sZygoteWriter.flush();

            // Should there be a timeout on this?
            pid = sZygoteInputStream.readInt();

            if (pid < 0) {
            ProcessStartResult result = new ProcessStartResult();
            result.pid = sZygoteInputStream.readInt();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            result.usingWrapper = sZygoteInputStream.readBoolean();
            return result;
        } catch (IOException ex) {
            try {
                if (sZygoteSocket != null) {
@@ -433,8 +432,6 @@ public class Process {

            throw new ZygoteStartFailedEx(ex);
        }

        return pid;
    }

    /**
@@ -449,18 +446,16 @@ public class Process {
     * @param debugFlags Additional flags.
     * @param targetSdkVersion The target SDK version for the app.
     * @param extraArgs Additional arguments to supply to the zygote process.
     * @return PID
     * @return An object that describes the result of the attempt to start the process.
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private static int startViaZygote(final String processClass,
    private static ProcessStartResult startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags, int targetSdkVersion,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
        int pid;

        synchronized(Process.class) {
            ArrayList<String> argsForZygote = new ArrayList<String>();

@@ -517,14 +512,8 @@ public class Process {
                }
            }

            pid = zygoteSendArgsAndGetPid(argsForZygote);
            return zygoteSendArgsAndGetResult(argsForZygote);
        }

        if (pid <= 0) {
            throw new ZygoteStartFailedEx("zygote start failed:" + pid);
        }

        return pid;
    }
    
    /**
@@ -808,4 +797,21 @@ public class Process {
     * @hide
     */
    public static final native long getPss(int pid);

    /**
     * Specifies the outcome of having started a process.
     * @hide
     */
    public static final class ProcessStartResult {
        /**
         * The PID of the newly started process.
         * Always >= 0.  (If the start failed, an exception will have been thrown instead.)
         */
        public int pid;

        /**
         * True if the process was started with a wrapper attached.
         */
        public boolean usingWrapper;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -900,6 +900,7 @@ class ZygoteConnection {
            }
        }

        boolean usingWrapper = false;
        if (pipeFd != null && pid > 0) {
            DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
            int innerPid = -1;
@@ -924,6 +925,7 @@ class ZygoteConnection {
                if (parentPid > 0) {
                    Log.i(TAG, "Wrapped process has pid " + innerPid);
                    pid = innerPid;
                    usingWrapper = true;
                } else {
                    Log.w(TAG, "Wrapped process reported a pid that is not a child of "
                            + "the process that we forked: childPid=" + pid
@@ -934,6 +936,7 @@ class ZygoteConnection {

        try {
            mSocketOutStream.writeInt(pid);
            mSocketOutStream.writeBoolean(usingWrapper);
        } catch (IOException ex) {
            Log.e(TAG, "Error reading from command socket", ex);
            return true;
+23 −19
Original line number Diff line number Diff line
@@ -208,6 +208,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    // before we decide it's never going to come up for real.
    static final int PROC_START_TIMEOUT = 10*1000;
    // How long we wait for a launched process to attach to the activity manager
    // before we decide it's never going to come up for real, when the process was
    // started with a wrapper for instrumentation (such as Valgrind) because it
    // could take much longer than usual.
    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    // How long to wait after going idle before forcing apps to GC.
    static final int GC_TIMEOUT = 5*1000;
@@ -1950,9 +1956,13 @@ public final class ActivityManagerService extends ActivityManagerNative
            if ("1".equals(SystemProperties.get("debug.assert"))) {
                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
            }
            int pid = Process.start("android.app.ActivityThread",
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                    app.processName, uid, uid, gids, debugFlags,
                    app.info.targetSdkVersion, null);
            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
            synchronized (bs) {
                if (bs.isOnBattery()) {
@@ -1960,12 +1970,12 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
            }
            
            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
                    app.processName, hostingType,
                    hostingNameStr != null ? hostingNameStr : "");
            
            if (app.persistent) {
                Watchdog.getInstance().processStarted(app.processName, pid);
                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
            }
            
            StringBuilder buf = mStringBuilder;
@@ -1979,7 +1989,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                buf.append(hostingNameStr);
            }
            buf.append(": pid=");
            buf.append(pid);
            buf.append(startResult.pid);
            buf.append(" uid=");
            buf.append(uid);
            buf.append(" gids={");
@@ -1992,21 +2002,15 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            buf.append("}");
            Slog.i(TAG, buf.toString());
            if (pid > 0) {
                app.pid = pid;
            app.pid = startResult.pid;
            app.usingWrapper = startResult.usingWrapper;
            app.removed = false;
            synchronized (mPidsSelfLocked) {
                    this.mPidsSelfLocked.put(pid, app);
                this.mPidsSelfLocked.put(startResult.pid, app);
                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
                }
            } else {
                app.pid = 0;
                RuntimeException e = new RuntimeException(
                        "Failure starting process " + app.processName
                        + ": returned pid=" + pid);
                Slog.e(TAG, e.getMessage(), e);
                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
            }
        } catch (RuntimeException e) {
            // XXX do better error recovery.
+5 −5
Original line number Diff line number Diff line
@@ -658,12 +658,12 @@ final class ActivityRecord extends IApplicationToken.Stub {
    public long getKeyDispatchingTimeout() {
        synchronized(service) {
            ActivityRecord r = getWaitingHistoryRecordLocked();
            if (r == null || r.app == null
                    || r.app.instrumentationClass == null) {
                return ActivityManagerService.KEY_DISPATCHING_TIMEOUT;
            if (r != null && r.app != null
                    && (r.app.instrumentationClass != null || r.app.usingWrapper)) {
                return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
            }

            return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
            return ActivityManagerService.KEY_DISPATCHING_TIMEOUT;
        }
    }

+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ class ProcessRecord {
    IInstrumentationWatcher instrumentationWatcher; // who is waiting
    Bundle instrumentationArguments;// as given to us
    ComponentName instrumentationResultClass;// copy of instrumentationClass
    boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
    BroadcastRecord curReceiver;// receiver currently running in the app
    long lastWakeTime;          // How long proc held wake lock at last check
    long lastCpuTime;           // How long proc has run CPU at last check