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

Commit 7b08b35b authored by Richard Uhler's avatar Richard Uhler
Browse files

Reuse dexopt method for both dex2oat and patchoat.

Change-Id: Ib9a6373f98474f1242367b5285086251a9d580e5
parent 6aed9ec1
Loading
Loading
Loading
Loading
+8 −22
Original line number Original line Diff line number Diff line
@@ -90,12 +90,15 @@ public class InstallerConnection {
        }
        }
    }
    }


    public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
    public int dexopt(String apkPath, int uid, boolean isPublic,
        return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null);
            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,
    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");
        StringBuilder builder = new StringBuilder("dexopt");
        builder.append(' ');
        builder.append(' ');
        builder.append(apkPath);
        builder.append(apkPath);
@@ -106,6 +109,8 @@ public class InstallerConnection {
        builder.append(pkgName);
        builder.append(pkgName);
        builder.append(' ');
        builder.append(' ');
        builder.append(instructionSet);
        builder.append(instructionSet);
        builder.append(' ');
        builder.append(dexoptNeeded);
        builder.append(vmSafeMode ? " 1" : " 0");
        builder.append(vmSafeMode ? " 1" : " 0");
        builder.append(debuggable ? " 1" : " 0");
        builder.append(debuggable ? " 1" : " 0");
        builder.append(' ');
        builder.append(' ');
@@ -113,25 +118,6 @@ public class InstallerConnection {
        return execute(builder.toString());
        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() {
    private boolean connect() {
        if (mSocket != null) {
        if (mSocket != null) {
            return true;
            return true;
+5 −6
Original line number Original line Diff line number Diff line
@@ -465,12 +465,11 @@ public class ZygoteInit {


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


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


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

    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);
    }
    }


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

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


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


            for (String path : paths) {
            for (String path : paths) {
                try {
                try {
                    // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
                    final int dexoptNeeded;
                    // package or the one we find does not match the image checksum (i.e. it was
                    if (forceDex) {
                    // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
                        dexoptNeeded = DexFile.DEX2OAT_NEEDED;
                    // odex file and it matches the checksum of the image but not its base address,
                    } else {
                    // meaning we need to move it.
                        dexoptNeeded = DexFile.getDexOptNeeded(path,
                    final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
                                pkg.packageName, dexCodeInstructionSet, defer);
                                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) {
                    if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                            int ret = mPackageManagerService.mInstaller.dexopt(
                        // We're deciding to defer a needed dexopt. Don't bother dexopting for other
                                    path, sharedGid, !pkg.isForwardLocked(), pkg.packageName,
                        // paths and instruction sets. We'll deal with them all together when we process
                                    dexCodeInstructionSet, vmSafeMode, debuggable,
                        // our list of deferred dexopts.
                                    oatDir.getAbsolutePath());
                        addPackageForDeferredDexopt(pkg);
                            if (ret < 0) {
                        return DEX_OPT_DEFERRED;
                                return DEX_OPT_FAILED;
                    }
                    }

                    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 {
                        } else {
                            final int ret = mPackageManagerService.mInstaller
                            throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
                                    .dexopt(path, sharedGid,
                                            !pkg.isForwardLocked(), pkg.packageName,
                                            dexCodeInstructionSet,
                                            vmSafeMode, debuggable, null);
                            if (ret < 0) {
                                return DEX_OPT_FAILED;
                        }
                        }
                        }
                        Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="

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

                                dexoptNeeded, vmSafeMode, debuggable, oatDir);
                        if (ret < 0) {
                        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;
                            return DEX_OPT_FAILED;
                        }
                        }

                        performedDexOpt = true;
                        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) {
                } catch (FileNotFoundException e) {
                    Slog.w(TAG, "Apk not found for dexopt: " + path);
                    Slog.w(TAG, "Apk not found for dexopt: " + path);
                    return DEX_OPT_FAILED;
                    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
            // 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 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's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
            // it.
            // it.
@@ -209,10 +193,11 @@ final class PackageDexOptimizer {
     *      <li>Package location is not a directory, i.e. monolithic install.</li>
     *      <li>Package location is not a directory, i.e. monolithic install.</li>
     * </ul>
     * </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
    @Nullable
    private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
    private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
            throws IOException {
            throws IOException {
        if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
        if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
            return null;
            return null;
@@ -222,7 +207,7 @@ final class PackageDexOptimizer {
            File oatDir = getOatDir(codePath);
            File oatDir = getOatDir(codePath);
            mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
            mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
                    dexInstructionSet);
                    dexInstructionSet);
            return oatDir;
            return oatDir.getAbsolutePath();
        }
        }
        return null;
        return null;
    }
    }
+6 −18
Original line number Original line Diff line number Diff line
@@ -1457,18 +1457,10 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                        }
                        try {
                        try {
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
                                                                                 dexCodeInstructionSet,
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                                                                 false);
                            if (dexoptRequired != DexFile.UP_TO_DATE) {
                                alreadyDexOpted.add(lib);
                                alreadyDexOpted.add(lib);
                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
                                // 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);
                                }
                            }
                            }
                        } catch (FileNotFoundException e) {
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, "Library not found: " + lib);
                            Slog.w(TAG, "Library not found: " + lib);
@@ -1514,13 +1506,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                            continue;
                            continue;
                        }
                        }
                        try {
                        try {
                            byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
                                                                                 dexCodeInstructionSet,
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                                                                 false);
                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
                            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);
                            }
                            }
                        } catch (FileNotFoundException e) {
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, "Jar not found: " + path);
                            Slog.w(TAG, "Jar not found: " + path);