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

Commit 2c6d5cd7 authored by Calin Juravle's avatar Calin Juravle Committed by android-build-merger
Browse files

Merge "Fix potential race in DexManager" into oc-dev am: c54fa39d

am: 43284ad8

Change-Id: I72dc2159438834c568a43ea8101109f34ea15c9a
parents 914d42db 43284ad8
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public class DexManager {
    // Maps package name to code locations.
    // It caches the code locations for the installed packages. This allows for
    // faster lookups (no locks) when finding what package owns the dex file.
    @GuardedBy("mPackageCodeLocationsCache")
    private final Map<String, PackageCodeLocations> mPackageCodeLocationsCache;

    // PackageDexUsage handles the actual I/O operations. It is responsible to
@@ -206,7 +207,7 @@ public class DexManager {
        // In case there was an update, write the package use info to disk async.
        // Note that we do the writing here and not in PackageDexUsage in order to be
        // consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
        // multiple updates in PackaeDexUsage before writing it).
        // multiple updates in PackageDexUsage before writing it).
        if (mPackageDexUsage.clearUsedByOtherApps(packageName)) {
            mPackageDexUsage.maybeWriteAsync();
        }
@@ -226,7 +227,7 @@ public class DexManager {
        // In case there was an update, write the package use info to disk async.
        // Note that we do the writing here and not in PackageDexUsage in order to be
        // consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
        // multiple updates in PackaeDexUsage before writing it).
        // multiple updates in PackageDexUsage before writing it).
        if (updated) {
            mPackageDexUsage.maybeWriteAsync();
        }
@@ -245,8 +246,12 @@ public class DexManager {

    private void cachePackageCodeLocation(String packageName, String baseCodePath,
            String[] splitCodePaths, String[] dataDirs, int userId) {
        synchronized (mPackageCodeLocationsCache) {
            PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
                    new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
            // TODO(calin): We are forced to extend the scope of this synchronization because
            // the values of the cache (PackageCodeLocations) are updated in place.
            // Make PackageCodeLocations immutable to simplify the synchronization reasoning.
            pcl.updateCodeLocation(baseCodePath, splitCodePaths);
            if (dataDirs != null) {
                for (String dataDir : dataDirs) {
@@ -260,6 +265,7 @@ public class DexManager {
                }
            }
        }
    }

    private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) {
        Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
@@ -527,12 +533,14 @@ public class DexManager {
        // The loadingPackage does not own the dex file.
        // Perform a reverse look-up in the cache to detect if any package has ownership.
        // Note that we can have false negatives if the cache falls out of date.
        synchronized (mPackageCodeLocationsCache) {
            for (PackageCodeLocations pcl : mPackageCodeLocationsCache.values()) {
                outcome = pcl.searchDex(dexPath, userId);
                if (outcome != DEX_SEARCH_NOT_FOUND) {
                    return new DexSearchResult(pcl.mPackageName, outcome);
                }
            }
        }

        if (DEBUG) {
            // TODO(calin): Consider checking for /data/data symlink.