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

Commit eef66fd0 authored by Calin Juravle's avatar Calin Juravle Committed by Gerrit Code Review
Browse files

Merge "PackageManager: Clean up code related to foreign dex use"

parents d0f092af 4c06f55f
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -606,19 +606,17 @@ public final class LoadedApk {
        }

        final File profileFile = getPrimaryProfileFile(mPackageName);
        final File foreignDexProfilesFile =
                Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());

        VMRuntime.registerAppInfo(profileFile.getPath(), mApplicationInfo.dataDir,
                codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesFile.getPath());
        VMRuntime.registerAppInfo(profileFile.getPath(),
                codePaths.toArray(new String[codePaths.size()]));

        // Setup the reporter to notify package manager of any relevant dex loads.
        // At this point the primary apk is loaded and will not be reported.
        // Anything loaded from now on will be tracked as a potential secondary
        // or foreign dex file. The goal is to enable:
        //    1) monitoring and compilation of secondary dex file
        //    2) track foreign dex file usage (used to determined the
        //       compilation filter of apks).
        //    2) track whether or not a dex file is used by other apps (used to
        //       determined the compilation filter of apks).
        if (BaseDexClassLoader.getReporter() != DexLoadReporter.INSTANCE) {
            // Set the dex load reporter if not already set.
            // Note that during the app's life cycle different LoadedApks may be
+0 −5
Original line number Diff line number Diff line
@@ -295,11 +295,6 @@ public class Environment {
        return buildPath(getDataProfilesDeDirectory(userId), packageName);
    }

    /** {@hide} */
    public static File getDataProfilesDeForeignDexDirectory(int userId) {
        return buildPath(getDataProfilesDeDirectory(userId), "foreign-dex");
    }

    /** {@hide} */
    public static File getDataAppDirectory(String volumeUuid) {
        return new File(getDataDirectory(volumeUuid), "app");
+0 −133
Original line number Diff line number Diff line
@@ -7747,60 +7747,9 @@ public class PackageManagerService extends IPackageManager.Stub {
            return;
        }
        destroyAppProfilesLeafLIF(pkg);
        destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
        for (int i = 0; i < childCount; i++) {
            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
            destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
                    true /* removeBaseMarker */);
        }
    }
    private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
            boolean removeBaseMarker) {
        if (pkg.isForwardLocked()) {
            return;
        }
        for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
            try {
                path = PackageManagerServiceUtils.realpath(new File(path));
            } catch (IOException e) {
                // TODO: Should we return early here ?
                Slog.w(TAG, "Failed to get canonical path", e);
                continue;
            }
            final String useMarker = path.replace('/', '@');
            for (int realUserId : resolveUserIds(userId)) {
                File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
                if (removeBaseMarker) {
                    File foreignUseMark = new File(profileDir, useMarker);
                    if (foreignUseMark.exists()) {
                        if (!foreignUseMark.delete()) {
                            Slog.w(TAG, "Unable to delete foreign user mark for package: "
                                    + pkg.packageName);
                        }
                    }
                }
                File[] markers = profileDir.listFiles();
                if (markers != null) {
                    final String searchString = "@" + pkg.packageName + "@";
                    // We also delete all markers that contain the package name we're
                    // uninstalling. These are associated with secondary dex-files belonging
                    // to the package. Reconstructing the path of these dex files is messy
                    // in general.
                    for (File marker : markers) {
                        if (marker.getName().indexOf(searchString) > 0) {
                            if (!marker.delete()) {
                                Slog.w(TAG, "Unable to delete foreign user mark for package: "
                                    + pkg.packageName);
                            }
                        }
                    }
                }
            }
        }
    }
@@ -7818,10 +7767,6 @@ public class PackageManagerService extends IPackageManager.Stub {
            return;
        }
        clearAppProfilesLeafLIF(pkg);
        // We don't remove the base foreign use marker when clearing profiles because
        // we will rename it when the app is updated. Unlike the actual profile contents,
        // the foreign use marker is good across installs.
        destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
        for (int i = 0; i < childCount; i++) {
            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
@@ -8701,14 +8646,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        synchronized (mPackages) {
            // We don't expect installation to fail beyond this point
            if (pkgSetting.pkg != null) {
                // Note that |user| might be null during the initial boot scan. If a codePath
                // for an app has changed during a boot scan, it's due to an app update that's
                // part of the system partition and marker changes must be applied to all users.
                maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
                    (user != null) ? user : UserHandle.ALL);
            }
            // Add the new setting to mSettings
            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
            // Add the new setting to mPackages
@@ -9073,74 +9010,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        return pkg;
    }
    private void maybeRenameForeignDexMarkers(PackageParser.Package existing,
            PackageParser.Package update, UserHandle user) {
        if (existing.applicationInfo == null || update.applicationInfo == null) {
            // This isn't due to an app installation.
            return;
        }
        final File oldCodePath = new File(existing.applicationInfo.getCodePath());
        final File newCodePath = new File(update.applicationInfo.getCodePath());
        // The codePath hasn't changed, so there's nothing for us to do.
        if (Objects.equals(oldCodePath, newCodePath)) {
            return;
        }
        File canonicalNewCodePath;
        try {
            canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
        } catch (IOException e) {
            Slog.w(TAG, "Failed to get canonical path.", e);
            return;
        }
        // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
        // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
        // that the last component of the path (i.e, the name) doesn't need canonicalization
        // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
        // but may change in the future. Hopefully this function won't exist at that point.
        final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
                oldCodePath.getName());
        // Calculate the prefixes of the markers. These are just the paths with "/" replaced
        // with "@".
        String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
        if (!oldMarkerPrefix.endsWith("@")) {
            oldMarkerPrefix += "@";
        }
        String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
        if (!newMarkerPrefix.endsWith("@")) {
            newMarkerPrefix += "@";
        }
        List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
        List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
        for (String updatedPath : updatedPaths) {
            String updatedPathName = new File(updatedPath).getName();
            markerSuffixes.add(updatedPathName.replace('/', '@'));
        }
        for (int userId : resolveUserIds(user.getIdentifier())) {
            File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
            for (String markerSuffix : markerSuffixes) {
                File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
                File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
                if (oldForeignUseMark.exists()) {
                    try {
                        Os.rename(oldForeignUseMark.getAbsolutePath(),
                                newForeignUseMark.getAbsolutePath());
                    } catch (ErrnoException e) {
                        Slog.w(TAG, "Failed to rename foreign use marker", e);
                        oldForeignUseMark.delete();
                    }
                }
            }
        }
    }
    /**
     * Derive the ABI of a non-system package located at {@code scanFile}. This information
     * is derived purely on the basis of the contents of {@code scanFile} and
@@ -16623,8 +16492,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
            synchronized (mInstallLock) {
                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
                destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
                        true /* removeBaseMarker */);
            }
        }
    }