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

Commit 674633ee authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Follow installd changes, throw exceptions."

parents b0fed2b7 fdeeeea6
Loading
Loading
Loading
Loading
+53 −32
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.os;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;

import com.android.internal.util.Preconditions;
@@ -29,6 +30,7 @@ import libcore.io.Streams;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

/**
 * Represents a connection to {@code installd}. Allows multiple connect and
@@ -61,6 +63,11 @@ public class InstallerConnection {
    }

    public synchronized String transact(String cmd) {
        if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
                    + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable());
        }

        if (!connect()) {
            Slog.e(TAG, "connection failed");
            return "-1";
@@ -96,44 +103,50 @@ public class InstallerConnection {
        }
    }

    public int execute(String cmd) {
        if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
                    + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable());
    public void execute(String cmd, Object... args) throws InstallerException {
        final String resRaw = executeForResult(cmd, args);
        int res = -1;
        try {
            res = Integer.parseInt(resRaw);
        } catch (NumberFormatException ignored) {
        }
        if (res != 0) {
            throw new InstallerException(
                    "Failed to execute " + cmd + " " + Arrays.toString(args) + ": " + res);
        }
    }

        String res = transact(cmd);
        try {
            return Integer.parseInt(res);
        } catch (NumberFormatException ex) {
            return -1;
    public String executeForResult(String cmd, Object... args)
            throws InstallerException {
        final StringBuilder builder = new StringBuilder(cmd);
        for (Object arg : args) {
            String escaped;
            if (arg == null) {
                escaped = "";
            } else {
                escaped = String.valueOf(arg);
            }
            if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) {
                throw new InstallerException(
                        "Invalid argument while executing " + cmd + " " + Arrays.toString(args));
            }
            if (TextUtils.isEmpty(escaped)) {
                escaped = "!";
            }
            builder.append(' ').append(escaped);
        }
        return transact(builder.toString());
    }

    public int dexopt(String apkPath, int uid, String instructionSet,
            int dexoptNeeded, int dexFlags) {
        return dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded,
                null /*outputPath*/, dexFlags);
    public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
            int dexFlags) throws InstallerException {
        dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /* outputPath */, dexFlags);
    }

    public int dexopt(String apkPath, int uid, String pkgName, String instructionSet,
            int dexoptNeeded, String outputPath, int dexFlags) {
        StringBuilder builder = new StringBuilder("dexopt");
        builder.append(' ');
        builder.append(apkPath);
        builder.append(' ');
        builder.append(uid);
        builder.append(' ');
        builder.append(pkgName);
        builder.append(' ');
        builder.append(instructionSet);
        builder.append(' ');
        builder.append(dexoptNeeded);
        builder.append(' ');
        builder.append(outputPath != null ? outputPath : "!");
        builder.append(' ');
        builder.append(dexFlags);
        return execute(builder.toString());
    public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
            int dexoptNeeded, String outputPath, int dexFlags) throws InstallerException {
        execute("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath,
                dexFlags);
    }

    private boolean connect() {
@@ -227,11 +240,19 @@ public class InstallerConnection {

    public void waitForConnection() {
        for (;;) {
            if (execute("ping") >= 0) {
            try {
                execute("ping");
                return;
            } catch (InstallerException ignored) {
            }
            Slog.w(TAG, "installd not ready");
            SystemClock.sleep(1000);
        }
    }

    public static class InstallerException extends Exception {
        public InstallerException(String detailMessage) {
            super(detailMessage);
        }
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import android.util.EventLog;
import android.util.Log;
import android.webkit.WebViewFactory;

import com.android.internal.os.InstallerConnection.InstallerException;

import dalvik.system.DexFile;
import dalvik.system.PathClassLoader;
import dalvik.system.VMRuntime;
@@ -502,8 +504,8 @@ public class ZygoteInit {
                            dexoptNeeded, 0 /*dexFlags*/);
                }
            }
        } catch (IOException ioe) {
            throw new RuntimeException("Error starting system_server", ioe);
        } catch (IOException | InstallerException e) {
            throw new RuntimeException("Error starting system_server", e);
        } finally {
            installer.disconnect();
        }
+5 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
import com.android.internal.os.InstallerConnection.InstallerException;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
@@ -6590,8 +6591,10 @@ public final class ActivityManagerService extends ActivityManagerNative
            Process.establishZygoteConnectionForAbi(abi);
            final String instructionSet = VMRuntime.getInstructionSet(abi);
            if (!completedIsas.contains(instructionSet)) {
                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
                try {
                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
                } catch (InstallerException e) {
                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
                }
                completedIsas.add(instructionSet);
            }
+88 −369

File changed.

Preview size limit exceeded, changes collapsed.

+15 −7
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;

import com.android.internal.os.InstallerConnection.InstallerException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -166,12 +168,13 @@ final class PackageDexOptimizer {
                            | (vmSafeMode ? DEXOPT_SAFEMODE : 0)
                            | (debuggable ? DEXOPT_DEBUGGABLE : 0)
                            | DEXOPT_BOOTCOMPLETE;
                    final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
                            pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags);

                    // Dex2oat might fail due to compiler / verifier errors.
                    if (ret == 0) {
                    try {
                        mPackageManagerService.mInstaller.dexopt(path, sharedGid,
                                pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir,
                                dexFlags);
                        performedDexOpt = true;
                    } catch (InstallerException e) {
                        Slog.w(TAG, "Failed to dexopt", e);
                    }
                }
            }
@@ -210,8 +213,13 @@ final class PackageDexOptimizer {
        File codePath = new File(pkg.codePath);
        if (codePath.isDirectory()) {
            File oatDir = getOatDir(codePath);
            try {
                mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
                        dexInstructionSet);
            } catch (InstallerException e) {
                Slog.w(TAG, "Failed to create oat dir", e);
                return null;
            }
            return oatDir.getAbsolutePath();
        }
        return null;
Loading