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

Commit 45ecfa67 authored by Calin Juravle's avatar Calin Juravle Committed by android-build-merger
Browse files

Merge "Keep track of protected data dirs in DexManager" into oc-dev am: 539128f6

am: 50d47492

Change-Id: Ie68b20aa4e30ba24c2ec7a3e2c7e0b315d59d931
parents 9118af6d 50d47492
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.os.Environment;
import android.os.FileUtils;
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -259,9 +260,11 @@ public class PackageDexOptimizer {
        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
        int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX;
        // Check the app storage and add the appropriate flags.
        if (info.dataDir.equals(info.deviceProtectedDataDir)) {
        if (info.deviceProtectedDataDir != null &&
                FileUtils.contains(info.deviceProtectedDataDir, path)) {
            dexoptFlags |= DEXOPT_STORAGE_DE;
        } else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
        } else if (info.credentialProtectedDataDir != null &&
                FileUtils.contains(info.credentialProtectedDataDir, path)) {
            dexoptFlags |= DEXOPT_STORAGE_CE;
        } else {
            Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
+36 −16
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ package com.android.server.pm.dex;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.os.FileUtils;
import android.os.RemoteException;
import android.os.storage.StorageManager;
import android.os.UserHandle;
@@ -93,7 +93,7 @@ public class DexManager {
     * Note that this method is invoked when apps load dex files and it should
     * return as fast as possible.
     *
     * @param loadingPackage the package performing the load
     * @param loadingAppInfo the package performing the load
     * @param dexPaths the list of dex files being loaded
     * @param loaderIsa the ISA of the app loading the dex files
     * @param loaderUserId the user id which runs the code loading the dex files
@@ -191,8 +191,7 @@ public class DexManager {
            throw new IllegalArgumentException(
                "notifyPackageInstalled called with USER_ALL");
        }
        cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
                pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
        cachePackageInfo(pi, userId);
    }

    /**
@@ -231,15 +230,34 @@ public class DexManager {
        }
    }

    public void cachePackageCodeLocation(String packageName, String baseCodePath,
            String[] splitCodePaths, String dataDir, int userId) {
    /**
     * Caches the code location from the given package info.
     */
    private void cachePackageInfo(PackageInfo pi, int userId) {
        ApplicationInfo ai = pi.applicationInfo;
        String[] dataDirs = new String[] {ai.dataDir, ai.deviceProtectedDataDir,
                ai.credentialProtectedDataDir};
        cachePackageCodeLocation(pi.packageName, ai.sourceDir, ai.splitSourceDirs,
                dataDirs, userId);
    }

    private void cachePackageCodeLocation(String packageName, String baseCodePath,
            String[] splitCodePaths, String[] dataDirs, int userId) {
        PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
                new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
        pcl.updateCodeLocation(baseCodePath, splitCodePaths);
        if (dataDirs != null) {
            for (String dataDir : dataDirs) {
                // The set of data dirs includes deviceProtectedDataDir and
                // credentialProtectedDataDir which might be null for shared
                // libraries. Currently we don't track these but be lenient
                // and check in case we ever decide to store their usage data.
                if (dataDir != null) {
                    pcl.mergeAppDataDirs(dataDir, userId);
                }
            }
        }
    }

    private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) {
        Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
@@ -250,8 +268,7 @@ public class DexManager {
            int userId = entry.getKey();
            for (PackageInfo pi : packageInfoList) {
                // Cache the code locations.
                cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
                        pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
                cachePackageInfo(pi, userId);

                // Cache a map from package name to the set of user ids who installed the package.
                // We will use it to sync the data and remove obsolete entries from
@@ -329,6 +346,7 @@ public class DexManager {
                mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
                continue;
            }

            int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath,
                    dexUseInfo.getLoaderIsas(), compilerFilter, dexUseInfo.isUsedByOtherApps());
            success = success && (result != PackageDexOptimizer.DEX_OPT_FAILED);
@@ -350,7 +368,7 @@ public class DexManager {
            // Nothing to reconcile.
            return;
        }
        Set<String> dexFilesToRemove = new HashSet<>();

        boolean updated = false;
        for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
            String dexPath = entry.getKey();
@@ -378,14 +396,16 @@ public class DexManager {
            }
            ApplicationInfo info = pkg.applicationInfo;
            int flags = 0;
            if (info.dataDir.equals(info.deviceProtectedDataDir)) {
            if (info.deviceProtectedDataDir != null &&
                    FileUtils.contains(info.deviceProtectedDataDir, dexPath)) {
                flags |= StorageManager.FLAG_STORAGE_DE;
            } else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
            } else if (info.credentialProtectedDataDir!= null &&
                    FileUtils.contains(info.credentialProtectedDataDir, dexPath)) {
                flags |= StorageManager.FLAG_STORAGE_CE;
            } else {
                Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
                updated = mPackageDexUsage.removeUserPackage(
                        packageName, dexUseInfo.getOwnerUserId()) || updated;
                Slog.e(TAG, "Could not infer CE/DE storage for path " + dexPath);
                updated = mPackageDexUsage.removeDexFile(
                        packageName, dexPath, dexUseInfo.getOwnerUserId()) || updated;
                continue;
            }

+22 −0
Original line number Diff line number Diff line
@@ -360,6 +360,19 @@ public class DexManagerTests {
        assertNull(mDexManager.getPackageUseInfo(frameworkDex));
    }

    @Test
    public void testNotifySecondaryFromProtected() {
        // Foo loads its own secondary files.
        List<String> fooSecondaries = mFooUser0.getSecondaryDexPathsFromProtectedDirs();
        notifyDexLoad(mFooUser0, fooSecondaries, mUser0);

        PackageUseInfo pui = getPackageUseInfo(mFooUser0);
        assertNotNull(pui);
        assertFalse(pui.isUsedByOtherApps());
        assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
        assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
    }

    private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
            List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
        for (String dex : secondaries) {
@@ -394,6 +407,8 @@ public class DexManagerTests {
        ai.setBaseCodePath(codeDir + "/base.dex");
        ai.setSplitCodePaths(new String[] {codeDir + "/split-1.dex", codeDir + "/split-2.dex"});
        ai.dataDir = "/data/user/" + userId + "/" + packageName;
        ai.deviceProtectedDataDir = "/data/user_de/" + userId + "/" + packageName;
        ai.credentialProtectedDataDir = "/data/user_ce/" + userId + "/" + packageName;
        ai.packageName = packageName;
        return ai;
    }
@@ -426,6 +441,13 @@ public class DexManagerTests {
            return paths;
        }

        List<String> getSecondaryDexPathsFromProtectedDirs() {
            List<String> paths = new ArrayList<>();
            paths.add(mPackageInfo.applicationInfo.dataDir + "/secondary6.dex");
            paths.add(mPackageInfo.applicationInfo.dataDir + "/secondary7.dex");
            return paths;
        }

        List<String> getBaseAndSplitDexPaths() {
            List<String> paths = new ArrayList<>();
            paths.add(mPackageInfo.applicationInfo.sourceDir);