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

Commit f324d245 authored by Richard Uhler's avatar Richard Uhler Committed by Gerrit Code Review
Browse files

Merge "Reuse dexopt method for both dex2oat and patchoat."

parents 1be312df 7b08b35b
Loading
Loading
Loading
Loading
+8 −22
Original line number Diff line number Diff line
@@ -90,12 +90,15 @@ public class InstallerConnection {
        }
    }

    public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
        return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null);
    public int dexopt(String apkPath, int uid, boolean isPublic,
            String instructionSet, int dexoptNeeded) {
        return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded,
                false, false, null);
    }

    public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet, boolean vmSafeMode, boolean debuggable, String outputPath) {
            String instructionSet, int dexoptNeeded, boolean vmSafeMode,
            boolean debuggable, String outputPath) {
        StringBuilder builder = new StringBuilder("dexopt");
        builder.append(' ');
        builder.append(apkPath);
@@ -106,6 +109,8 @@ public class InstallerConnection {
        builder.append(pkgName);
        builder.append(' ');
        builder.append(instructionSet);
        builder.append(' ');
        builder.append(dexoptNeeded);
        builder.append(vmSafeMode ? " 1" : " 0");
        builder.append(debuggable ? " 1" : " 0");
        builder.append(' ');
@@ -113,25 +118,6 @@ public class InstallerConnection {
        return execute(builder.toString());
    }

    public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
        return patchoat(apkPath, uid, isPublic, "*", instructionSet);
    }

    public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet) {
        StringBuilder builder = new StringBuilder("patchoat");
        builder.append(' ');
        builder.append(apkPath);
        builder.append(' ');
        builder.append(uid);
        builder.append(isPublic ? " 1" : " 0");
        builder.append(' ');
        builder.append(pkgName);
        builder.append(' ');
        builder.append(instructionSet);
        return execute(builder.toString());
    }

    private boolean connect() {
        if (mSocket != null) {
            return true;
+5 −6
Original line number Diff line number Diff line
@@ -465,12 +465,11 @@ public class ZygoteInit {

        try {
            for (String classPathElement : classPathElements) {
                final byte dexopt = DexFile.isDexOptNeededInternal(classPathElement, "*", instructionSet,
                        false /* defer */);
                if (dexopt == DexFile.DEXOPT_NEEDED) {
                    installer.dexopt(classPathElement, Process.SYSTEM_UID, false, instructionSet);
                } else if (dexopt == DexFile.PATCHOAT_NEEDED) {
                    installer.patchoat(classPathElement, Process.SYSTEM_UID, false, instructionSet);
                final int dexoptNeeded = DexFile.getDexOptNeeded(
                        classPathElement, "*", instructionSet, false /* defer */);
                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                    installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
                            instructionSet, dexoptNeeded);
                }
            }
        } catch (IOException ioe) {
+7 −25
Original line number Diff line number Diff line
@@ -55,43 +55,25 @@ public final class Installer extends SystemService {
        return mInstaller.execute(builder.toString());
    }

    public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet) {
    public int dexopt(String apkPath, int uid, boolean isPublic,
            String instructionSet, int dexoptNeeded) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        return mInstaller.patchoat(apkPath, uid, isPublic, pkgName, instructionSet);
    }

    public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        return mInstaller.patchoat(apkPath, uid, isPublic, instructionSet);
    }

    public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet);
        return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded);
    }

    public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet, boolean vmSafeMode, boolean debuggable,
            @Nullable String outputPath) {
            String instructionSet, int dexoptNeeded, boolean vmSafeMode,
            boolean debuggable, @Nullable String outputPath) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode,
        return mInstaller.dexopt(apkPath, uid, isPublic, pkgName,
                instructionSet, dexoptNeeded, vmSafeMode,
                debuggable, outputPath);
    }

+38 −53
Original line number Diff line number Diff line
@@ -113,64 +113,48 @@ final class PackageDexOptimizer {

            for (String path : paths) {
                try {
                    // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
                    // package or the one we find does not match the image checksum (i.e. it was
                    // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
                    // odex file and it matches the checksum of the image but not its base address,
                    // meaning we need to move it.
                    final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
                    final int dexoptNeeded;
                    if (forceDex) {
                        dexoptNeeded = DexFile.DEX2OAT_NEEDED;
                    } else {
                        dexoptNeeded = DexFile.getDexOptNeeded(path,
                                pkg.packageName, dexCodeInstructionSet, defer);
                    if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
                        File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
                        Log.i(TAG, "Running dexopt on: " + path + " pkg="
                                + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                                + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
                                + " oatDir = " + oatDir);
                        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
                    }

                        if (oatDir != null) {
                            int ret = mPackageManagerService.mInstaller.dexopt(
                                    path, sharedGid, !pkg.isForwardLocked(), pkg.packageName,
                                    dexCodeInstructionSet, vmSafeMode, debuggable,
                                    oatDir.getAbsolutePath());
                            if (ret < 0) {
                                return DEX_OPT_FAILED;
                    if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                        // We're deciding to defer a needed dexopt. Don't bother dexopting for other
                        // paths and instruction sets. We'll deal with them all together when we process
                        // our list of deferred dexopts.
                        addPackageForDeferredDexopt(pkg);
                        return DEX_OPT_DEFERRED;
                    }

                    if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                        final String dexoptType;
                        String oatDir = null;
                        if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
                            dexoptType = "dex2oat";
                            oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
                        } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
                            dexoptType = "patchoat";
                        } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
                            dexoptType = "self patchoat";
                        } else {
                            final int ret = mPackageManagerService.mInstaller
                                    .dexopt(path, sharedGid,
                                            !pkg.isForwardLocked(), pkg.packageName,
                                            dexCodeInstructionSet,
                                            vmSafeMode, debuggable, null);
                            if (ret < 0) {
                                return DEX_OPT_FAILED;
                            throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
                        }
                        }

                        performedDexOpt = true;
                    } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
                        Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
                        Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
                                + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                                + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
                                + " oatDir = " + oatDir);
                        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
                        final int ret = mPackageManagerService.mInstaller.patchoat(path, sharedGid,
                                !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet);

                        final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
                                !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
                                dexoptNeeded, vmSafeMode, debuggable, oatDir);
                        if (ret < 0) {
                            // Don't bother running patchoat again if we failed, it will probably
                            // just result in an error again. Also, don't bother dexopting for other
                            // paths & ISAs.
                            return DEX_OPT_FAILED;
                        }

                        performedDexOpt = true;
                    }

                    // We're deciding to defer a needed dexopt. Don't bother dexopting for other
                    // paths and instruction sets. We'll deal with them all together when we process
                    // our list of deferred dexopts.
                    if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
                        addPackageForDeferredDexopt(pkg);
                        return DEX_OPT_DEFERRED;
                    }
                } catch (FileNotFoundException e) {
                    Slog.w(TAG, "Apk not found for dexopt: " + path);
                    return DEX_OPT_FAILED;
@@ -187,7 +171,7 @@ final class PackageDexOptimizer {
            }

            // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
            // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
            // either have either succeeded dexopt, or have had getDexOptNeeded tell us
            // it isn't required. We therefore mark that this package doesn't need dexopt unless
            // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
            // it.
@@ -209,10 +193,11 @@ final class PackageDexOptimizer {
     *      <li>Package location is not a directory, i.e. monolithic install.</li>
     * </ul>
     *
     * @return oat directory or null, if oat directory cannot be created.
     * @return Absolute path to the oat directory or null, if oat directory
     * cannot be created.
     */
    @Nullable
    private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
    private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
            throws IOException {
        if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
            return null;
@@ -222,7 +207,7 @@ final class PackageDexOptimizer {
            File oatDir = getOatDir(codePath);
            mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
                    dexInstructionSet);
            return oatDir;
            return oatDir.getAbsolutePath();
        }
        return null;
    }
+6 −18
Original line number Diff line number Diff line
@@ -1457,18 +1457,10 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                        try {
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
                                                                                 dexCodeInstructionSet,
                                                                                 false);
                            if (dexoptRequired != DexFile.UP_TO_DATE) {
                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                alreadyDexOpted.add(lib);
                                // The list of "shared libraries" we have at this point is
                                if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
                                    mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                } else {
                                    mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                                }
                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
                            }
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, "Library not found: " + lib);
@@ -1514,13 +1506,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                            continue;
                        }
                        try {
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
                                                                                 dexCodeInstructionSet,
                                                                                 false);
                            if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                            } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
                                mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
                            }
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, "Jar not found: " + path);