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

Commit 110e897e authored by Calin Juravle's avatar Calin Juravle Committed by android-build-merger
Browse files

[PM] Clean up logic for secondary dex oat files

am: e69fba3f

Change-Id: I223b27221acf25e628003dde0f63cffe66779753
parents 468be64c e69fba3f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -509,6 +509,13 @@ interface IPackageManager {

    void forceDexOpt(String packageName);

    /**
     * Reconcile the information we have about the secondary dex files belonging to
     * {@code packagName} and the actual dex files. For all dex files that were
     * deleted, update the internal records and delete the generated oat files.
     */
    void reconcileSecondaryDexFiles(String packageName);

    /**
     * Update status of external media on the package manager to scan and
     * install packages installed on the external media. Like say the
+14 −0
Original line number Diff line number Diff line
@@ -433,6 +433,20 @@ public class Installer extends SystemService {
        }
    }

    public boolean reconcileSecondaryDexFile(String apkPath, String packageName, int uid,
            String[] isas, @Nullable String volumeUuid, int flags) throws InstallerException {
        for (int i = 0; i < isas.length; i++) {
            assertValidInstructionSet(isas[i]);
        }
        if (!checkBeforeRemote()) return false;
        try {
            return mInstalld.reconcileSecondaryDexFile(apkPath, packageName, uid, isas,
                    volumeUuid, flags);
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }

    private static void assertValidInstructionSet(String instructionSet)
            throws InstallerException {
        for (String abi : Build.SUPPORTED_ABIS) {
+11 −1
Original line number Diff line number Diff line
@@ -2133,7 +2133,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        mInstaller = installer;
        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        mDexManager = new DexManager(this, mPackageDexOptimizer);
        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
@@ -7549,6 +7549,16 @@ public class PackageManagerService extends IPackageManager.Stub {
        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
    }
    /**
     * Reconcile the information we have about the secondary dex files belonging to
     * {@code packagName} and the actual dex files. For all dex files that were
     * deleted, update the internal records and delete the generated oat files.
     */
    @Override
    public void reconcileSecondaryDexFiles(String packageName) {
        mDexManager.reconcileSecondaryDexFiles(packageName);
    }
    Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
        if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
+10 −0
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runInstallWrite();
                case "compile":
                    return runCompile();
                case "reconcile-secondary-dex-files":
                    return runreconcileSecondaryDexFiles();
                case "dump-profiles":
                    return runDumpProfiles();
                case "list":
@@ -423,6 +425,12 @@ class PackageManagerShellCommand extends ShellCommand {
        }
    }

    private int runreconcileSecondaryDexFiles() throws RemoteException {
        String packageName = getNextArg();
        mInterface.reconcileSecondaryDexFiles(packageName);
        return 0;
    }

    private int runDumpProfiles() throws RemoteException {
        String packageName = getNextArg();
        mInterface.dumpProfiles(packageName);
@@ -1475,6 +1483,8 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("      -3: filter to only show third party packages");
        pw.println("      -i: see the installer for the packages");
        pw.println("      -u: also include uninstalled packages");
        pw.println("  reconcile-secondary-dex-files TARGET-PACKAGE");
        pw.println("    Reconciles the package secondary dex files with the generated oat files.");
        pw.println("  list permission-groups");
        pw.println("    Prints all known permission groups.");
        pw.println("  list permissions [-g] [-f] [-d] [-u] [GROUP]");
+80 −2
Original line number Diff line number Diff line
@@ -21,8 +21,13 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.os.RemoteException;
import android.os.storage.StorageManager;

import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.PackageDexOptimizer;
import com.android.server.pm.PackageManagerServiceUtils;
import com.android.server.pm.PackageManagerServiceCompilerMapping;
@@ -62,6 +67,9 @@ public class DexManager {

    private final IPackageManager mPackageManager;
    private final PackageDexOptimizer mPackageDexOptimizer;
    private final Object mInstallLock;
    @GuardedBy("mInstallLock")
    private final Installer mInstaller;

    // Possible outcomes of a dex search.
    private static int DEX_SEARCH_NOT_FOUND = 0;  // dex file not found
@@ -69,11 +77,14 @@ public class DexManager {
    private static int DEX_SEARCH_FOUND_SPLIT = 2;  // dex file is a split apk
    private static int DEX_SEARCH_FOUND_SECONDARY = 3;  // dex file is a secondary dex

    public DexManager(IPackageManager pms, PackageDexOptimizer pdo) {
    public DexManager(IPackageManager pms, PackageDexOptimizer pdo,
            Installer installer, Object installLock) {
      mPackageCodeLocationsCache = new HashMap<>();
      mPackageDexUsage = new PackageDexUsage();
      mPackageManager = pms;
      mPackageDexOptimizer = pdo;
      mInstaller = installer;
      mInstallLock = installLock;
    }

    /**
@@ -255,7 +266,7 @@ public class DexManager {
            if (pkg == null) {
                Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName
                        + " for user " + dexUseInfo.getOwnerUserId());
                // Skip over it, another user might still have the package.
                mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
                continue;
            }
            int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath,
@@ -265,6 +276,73 @@ public class DexManager {
        return success;
    }

    /**
     * Reconcile the information we have about the secondary dex files belonging to
     * {@code packagName} and the actual dex files. For all dex files that were
     * deleted, update the internal records and delete any generated oat files.
     */
    public void reconcileSecondaryDexFiles(String packageName) {
        PackageUseInfo useInfo = getPackageUseInfo(packageName);
        if (useInfo == null || useInfo.getDexUseInfoMap().isEmpty()) {
            if (DEBUG) {
                Slog.d(TAG, "No secondary dex use for package:" + packageName);
            }
            // Nothing to reconcile.
            return;
        }
        Set<String> dexFilesToRemove = new HashSet<>();
        for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
            String dexPath = entry.getKey();
            DexUseInfo dexUseInfo = entry.getValue();
            PackageInfo pkg = null;
            try {
                // Note that we look for the package in the PackageManager just to be able
                // to get back the real app uid and its storage kind. These are only used
                // to perform extra validation in installd.
                // TODO(calin): maybe a bit overkill.
                pkg = mPackageManager.getPackageInfo(packageName, /*flags*/0,
                    dexUseInfo.getOwnerUserId());
            } catch (RemoteException ignore) {
                // Can't happen, DexManager is local.
            }
            if (pkg == null) {
                // It may be that the package was uninstalled while we process the secondary
                // dex files.
                Slog.d(TAG, "Could not find package when compiling secondary dex " + packageName
                        + " for user " + dexUseInfo.getOwnerUserId());
                // Update the usage and continue, another user might still have the package.
                mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
                continue;
            }
            ApplicationInfo info = pkg.applicationInfo;
            int flags = 0;
            if (info.dataDir.equals(info.deviceProtectedDataDir)) {
                flags |= StorageManager.FLAG_STORAGE_DE;
            } else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
                flags |= StorageManager.FLAG_STORAGE_CE;
            } else {
                Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
                mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
                continue;
            }

            boolean dexStillExists = true;
            synchronized(mInstallLock) {
                try {
                    String[] isas = dexUseInfo.getLoaderIsas().toArray(new String[0]);
                    dexStillExists = mInstaller.reconcileSecondaryDexFile(dexPath, packageName,
                            pkg.applicationInfo.uid, isas, pkg.applicationInfo.volumeUuid, flags);
                } catch (InstallerException e) {
                    Slog.e(TAG, "Got InstallerException when reconciling dex " + dexPath +
                            " : " + e.getMessage());
                }
            }
            if (!dexStillExists) {
                mPackageDexUsage.removeDexFile(packageName, dexPath, dexUseInfo.getOwnerUserId());
            }
        }
    }

    /**
     * Retrieves the package which owns the given dexPath.
     */
Loading