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

Commit 8c72e7f2 authored by Winson Chiu's avatar Winson Chiu Committed by Android (Google) Code Review
Browse files

Merge "Revert "Remove PackageInfo from ApexPackageInfo""

parents 5da7fe83 ba628fe0
Loading
Loading
Loading
Loading
+91 −98
Original line number Diff line number Diff line
@@ -22,9 +22,10 @@ import static com.android.server.pm.ApexManager.MATCH_FACTORY_PACKAGE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.apex.ApexInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.ArrayMap;
import android.util.Pair;
import android.util.PrintWriterPrinter;

import com.android.internal.annotations.GuardedBy;
@@ -32,9 +33,8 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;

import java.io.File;
@@ -59,7 +59,17 @@ class ApexPackageInfo {
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private List<Pair<ApexInfo, AndroidPackage>> mAllPackagesCache;
    private List<PackageInfo> mAllPackagesCache;

    /**
     * Whether an APEX package is active or not.
     *
     * @param packageInfo the package to check
     * @return {@code true} if this package is active, {@code false} otherwise.
     */
    private static boolean isActive(PackageInfo packageInfo) {
        return packageInfo.isActiveApex;
    }

    /**
     * Called by package manager service to scan apex package files when device boots up.
@@ -95,23 +105,20 @@ class ApexPackageInfo {
     *         is not found.
     */
    @Nullable
    Pair<ApexInfo, AndroidPackage> getPackageInfo(String packageName,
            @ApexManager.PackageInfoFlags int flags) {
    PackageInfo getPackageInfo(String packageName, @ApexManager.PackageInfoFlags int flags) {
        synchronized (mLock) {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            boolean matchActive = (flags & MATCH_ACTIVE_PACKAGE) != 0;
            boolean matchFactory = (flags & MATCH_FACTORY_PACKAGE) != 0;
            for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
                final Pair<ApexInfo, AndroidPackage> pair = mAllPackagesCache.get(i);
                var apexInfo = pair.first;
                var pkg = pair.second;
                if (!pkg.getPackageName().equals(packageName)) {
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (!packageInfo.packageName.equals(packageName)) {
                    continue;
                }
                if ((matchActive && apexInfo.isActive)
                        || (matchFactory && apexInfo.isFactory)) {
                    return pair;
                if ((matchActive && isActive(packageInfo))
                        || (matchFactory && isFactory(packageInfo))) {
                    return packageInfo;
                }
            }
            return null;
@@ -121,18 +128,18 @@ class ApexPackageInfo {
    /**
     * Retrieves information about all active APEX packages.
     *
     * @return list containing information about different active packages.
     * @return a List of PackageInfo object, each one containing information about a different
     *         active package.
     */
    @NonNull
    List<Pair<ApexInfo, AndroidPackage>> getActivePackages() {
    List<PackageInfo> getActivePackages() {
        synchronized (mLock) {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            final List<Pair<ApexInfo, AndroidPackage>> activePackages = new ArrayList<>();
            final List<PackageInfo> activePackages = new ArrayList<>();
            for (int i = 0; i < mAllPackagesCache.size(); i++) {
                final var pair = mAllPackagesCache.get(i);
                if (pair.first.isActive) {
                    activePackages.add(pair);
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (isActive(packageInfo)) {
                    activePackages.add(packageInfo);
                }
            }
            return activePackages;
@@ -140,20 +147,20 @@ class ApexPackageInfo {
    }

    /**
     * Retrieves information about all pre-installed APEX packages.
     * Retrieves information about all active pre-installed APEX packages.
     *
     * @return list containing information about different pre-installed packages.
     * @return a List of PackageInfo object, each one containing information about a different
     *         active pre-installed package.
     */
    @NonNull
    List<Pair<ApexInfo, AndroidPackage>> getFactoryPackages() {
    List<PackageInfo> getFactoryPackages() {
        synchronized (mLock) {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            final List<Pair<ApexInfo, AndroidPackage>> factoryPackages = new ArrayList<>();
            final List<PackageInfo> factoryPackages = new ArrayList<>();
            for (int i = 0; i < mAllPackagesCache.size(); i++) {
                final var pair = mAllPackagesCache.get(i);
                if (pair.first.isFactory) {
                    factoryPackages.add(pair);
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (isFactory(packageInfo)) {
                    factoryPackages.add(packageInfo);
                }
            }
            return factoryPackages;
@@ -163,18 +170,18 @@ class ApexPackageInfo {
    /**
     * Retrieves information about all inactive APEX packages.
     *
     * @return list containing information about different inactive packages.
     * @return a List of PackageInfo object, each one containing information about a different
     *         inactive package.
     */
    @NonNull
    List<Pair<ApexInfo, AndroidPackage>> getInactivePackages() {
    List<PackageInfo> getInactivePackages() {
        synchronized (mLock) {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            final List<Pair<ApexInfo, AndroidPackage>> inactivePackages = new ArrayList<>();
            final List<PackageInfo> inactivePackages = new ArrayList<>();
            for (int i = 0; i < mAllPackagesCache.size(); i++) {
                final var pair = mAllPackagesCache.get(i);
                if (!pair.first.isActive) {
                    inactivePackages.add(pair);
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (!isActive(packageInfo)) {
                    inactivePackages.add(packageInfo);
                }
            }
            return inactivePackages;
@@ -192,8 +199,8 @@ class ApexPackageInfo {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
                final var pair = mAllPackagesCache.get(i);
                if (pair.second.getPackageName().equals(packageName)) {
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (packageInfo.packageName.equals(packageName)) {
                    return true;
                }
            }
@@ -215,18 +222,21 @@ class ApexPackageInfo {
    }

    void notifyPackageInstalled(ApexInfo apexInfo, AndroidPackage pkg) {
        final String packageName = pkg.getPackageName();
        final int flags = PackageManager.GET_META_DATA
                | PackageManager.GET_SIGNING_CERTIFICATES
                | PackageManager.GET_SIGNATURES;
        final PackageInfo newApexPkg = PackageInfoWithoutStateUtils.generate(
                pkg, apexInfo, flags);
        final String packageName = newApexPkg.packageName;
        synchronized (mLock) {
            for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
                var pair = mAllPackagesCache.get(i);
                var oldApexInfo = pair.first;
                var oldApexPkg = pair.second;
                if (oldApexInfo.isActive && oldApexPkg.getPackageName().equals(packageName)) {
                    if (oldApexInfo.isFactory) {
                        oldApexInfo.isActive = false;
                        mAllPackagesCache.add(Pair.create(apexInfo, pkg));
                PackageInfo oldApexPkg = mAllPackagesCache.get(i);
                if (oldApexPkg.isActiveApex && oldApexPkg.packageName.equals(packageName)) {
                    if (isFactory(oldApexPkg)) {
                        oldApexPkg.isActiveApex = false;
                        mAllPackagesCache.add(newApexPkg);
                    } else {
                        mAllPackagesCache.set(i, Pair.create(apexInfo, pkg));
                        mAllPackagesCache.set(i, newApexPkg);
                    }
                    break;
                }
@@ -234,6 +244,16 @@ class ApexPackageInfo {
        }
    }

    /**
     * Whether the APEX package is pre-installed or not.
     *
     * @param packageInfo the package to check
     * @return {@code true} if this package is pre-installed, {@code false} otherwise.
     */
    private static boolean isFactory(@NonNull PackageInfo packageInfo) {
        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0;
    }

    /**
     * Dumps various state information to the provided {@link PrintWriter} object.
     *
@@ -268,25 +288,33 @@ class ApexPackageInfo {
        HashSet<String> factoryPackagesSet = new HashSet<>();
        for (ApexManager.ScanResult result : scanResults) {
            ApexInfo ai = result.apexInfo;
            String packageName = result.pkg.getPackageName();
            if (!packageName.equals(result.packageName)) {

            final PackageInfo packageInfo = PackageInfoWithoutStateUtils.generate(
                    result.pkg, ai, flags);
            if (packageInfo == null) {
                throw new IllegalStateException("Unable to generate package info: "
                        + ai.modulePath);
            }
            if (!packageInfo.packageName.equals(result.packageName)) {
                throw new IllegalStateException("Unmatched package name: "
                        + result.packageName + " != " + packageName
                        + result.packageName + " != " + packageInfo.packageName
                        + ", path=" + ai.modulePath);
            }
            mAllPackagesCache.add(Pair.create(ai, result.pkg));
            mAllPackagesCache.add(packageInfo);
            if (ai.isActive) {
                if (!activePackagesSet.add(packageName)) {
                if (!activePackagesSet.add(packageInfo.packageName)) {
                    throw new IllegalStateException(
                            "Two active packages have the same name: " + packageName);
                            "Two active packages have the same name: "
                                    + packageInfo.packageName);
                }
            }
            if (ai.isFactory) {
                // Don't throw when the duplicating APEX is VNDK APEX
                if (!factoryPackagesSet.add(packageName)
                if (!factoryPackagesSet.add(packageInfo.packageName)
                        && !ai.moduleName.startsWith(VNDK_APEX_MODULE_NAME_PREFIX)) {
                    throw new IllegalStateException(
                            "Two factory packages have the same name: " + packageName);
                            "Two factory packages have the same name: "
                                    + packageInfo.packageName);
                }
            }
        }
@@ -334,37 +362,6 @@ class ApexPackageInfo {
        return results;
    }

    /**
     * @see #dumpPackages(List, String, IndentingPrintWriter)
     */
    static void dumpPackageStates(List<PackageStateInternal> packageStates, boolean isActive,
            @Nullable String packageName, IndentingPrintWriter ipw) {
        ipw.println();
        ipw.increaseIndent();
        for (int i = 0, size = packageStates.size(); i < size; i++) {
            final var packageState = packageStates.get(i);
            var pkg = packageState.getPkg();
            if (packageName != null && !packageName.equals(pkg.getPackageName())) {
                continue;
            }
            ipw.println(pkg.getPackageName());
            ipw.increaseIndent();
            ipw.println("Version: " + pkg.getLongVersionCode());
            ipw.println("Path: " + pkg.getBaseApkPath());
            ipw.println("IsActive: " + isActive);
            ipw.println("IsFactory: " + !packageState.isUpdatedSystemApp());
            ipw.println("ApplicationInfo: ");
            ipw.increaseIndent();
            // TODO: Dump the package manually
            AndroidPackageUtils.generateAppInfoWithoutState(pkg)
                    .dump(new PrintWriterPrinter(ipw), "");
            ipw.decreaseIndent();
            ipw.decreaseIndent();
        }
        ipw.decreaseIndent();
        ipw.println();
    }

    /**
     * Dump information about the packages contained in a particular cache
     * @param packagesCache the cache to print information about.
@@ -372,28 +369,24 @@ class ApexPackageInfo {
     *                    only information about that specific package will be dumped.
     * @param ipw the {@link IndentingPrintWriter} object to send information to.
     */
    static void dumpPackages(List<Pair<ApexInfo, AndroidPackage>> packagesCache,
    static void dumpPackages(List<PackageInfo> packagesCache,
            @Nullable String packageName, IndentingPrintWriter ipw) {
        ipw.println();
        ipw.increaseIndent();
        for (int i = 0, size = packagesCache.size(); i < size; i++) {
            final var pair = packagesCache.get(i);
            var apexInfo = pair.first;
            var pkg = pair.second;
            if (packageName != null && !packageName.equals(pkg.getPackageName())) {
            final PackageInfo pi = packagesCache.get(i);
            if (packageName != null && !packageName.equals(pi.packageName)) {
                continue;
            }
            ipw.println(pkg.getPackageName());
            ipw.println(pi.packageName);
            ipw.increaseIndent();
            ipw.println("Version: " + pkg.getLongVersionCode());
            ipw.println("Path: " + pkg.getBaseApkPath());
            ipw.println("IsActive: " + apexInfo.isActive);
            ipw.println("IsFactory: " + apexInfo.isFactory);
            ipw.println("Version: " + pi.versionCode);
            ipw.println("Path: " + pi.applicationInfo.sourceDir);
            ipw.println("IsActive: " + isActive(pi));
            ipw.println("IsFactory: " + isFactory(pi));
            ipw.println("ApplicationInfo: ");
            ipw.increaseIndent();
            // TODO: Dump the package manually
            AndroidPackageUtils.generateAppInfoWithoutState(pkg)
                    .dump(new PrintWriterPrinter(ipw), "");
            pi.applicationInfo.dump(new PrintWriterPrinter(ipw), "");
            ipw.decreaseIndent();
            ipw.decreaseIndent();
        }
+28 −42
Original line number Diff line number Diff line
@@ -65,7 +65,6 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.apex.ApexInfo;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -1019,12 +1018,11 @@ public class ComputerEngine implements Computer {
                if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
                    apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
                }
                final var pair = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
                if (pair == null) {
                final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
                if (pi == null) {
                    return null;
                }
                return PackageInfoUtils.generateApplicationInfo(pair.second, flags,
                        PackageUserStateInternal.DEFAULT, userId, null);
                return pi.applicationInfo;
            }
        }
        if ("android".equals(packageName) || "system".equals(packageName)) {
@@ -1720,12 +1718,8 @@ public class ComputerEngine implements Computer {
            // Instant app filtering for APEX modules is ignored
            if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
                if (matchApex) {
                    final var pair = mApexPackageInfo.getPackageInfo(packageName,
                    return mApexPackageInfo.getPackageInfo(packageName,
                            ApexManager.MATCH_FACTORY_PACKAGE);
                    if (pair == null) {
                        return null;
                    }
                    return PackageInfoUtils.generate(pair.second, pair.first, flags, null, userId);
                }
            }
            final PackageStateInternal ps = mSettings.getDisabledSystemPkg(packageName);
@@ -1781,12 +1775,8 @@ public class ComputerEngine implements Computer {
        }
        if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            if (matchApex) {
                final var pair = mApexPackageInfo.getPackageInfo(packageName,
                return mApexPackageInfo.getPackageInfo(packageName,
                        ApexManager.MATCH_ACTIVE_PACKAGE);
                if (pair == null) {
                    return null;
                }
                return PackageInfoUtils.generate(pair.second, pair.first, flags, null, userId);
            }
        }
        return null;
@@ -1893,17 +1883,10 @@ public class ComputerEngine implements Computer {
        }
        if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            if (listApex) {
                List<Pair<ApexInfo, AndroidPackage>> pairs;
                if (listFactory) {
                    pairs = mApexPackageInfo.getFactoryPackages();
                    list.addAll(mApexPackageInfo.getFactoryPackages());
                } else {
                    pairs = mApexPackageInfo.getActivePackages();
                }

                for (int index = 0; index < pairs.size(); index++) {
                    var pair = pairs.get(index);
                    list.add(PackageInfoUtils.generate(pair.second, pair.first, flags, null,
                            userId));
                    list.addAll(mApexPackageInfo.getActivePackages());
                }
            }
        }
@@ -3421,23 +3404,29 @@ public class ComputerEngine implements Computer {
        } // switch
    }

    private void generateApexPackageInfo(@NonNull List<PackageStateInternal> activePackages,
            @NonNull List<PackageStateInternal> inactivePackages,
            @NonNull List<PackageStateInternal> factoryActivePackages,
            @NonNull List<PackageStateInternal> factoryInactivePackages) {
    private void generateApexPackageInfo(List<PackageInfo> activePackages,
            List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) {
        for (AndroidPackage p : mPackages.values()) {
            final String packageName = p.getPackageName();
            PackageStateInternal ps = mSettings.getPackage(packageName);
            if (!p.isApex() || ps == null) {
                continue;
            }
            activePackages.add(ps);
            PackageInfo pi = generatePackageInfo(ps, 0, 0);
            if (pi == null) {
                continue;
            }
            pi.isActiveApex = true;
            activePackages.add(pi);
            if (!ps.isUpdatedSystemApp()) {
                factoryActivePackages.add(ps);
                factoryPackages.add(pi);
            } else {
                PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName);
                factoryInactivePackages.add(psDisabled);
                inactivePackages.add(psDisabled);
                pi = generatePackageInfo(psDisabled, 0, 0);
                if (pi != null) {
                    factoryPackages.add(pi);
                    inactivePackages.add(pi);
                }
            }
        }
    }
@@ -3445,19 +3434,16 @@ public class ComputerEngine implements Computer {
    private void dumpApex(PrintWriter pw, String packageName) {
        if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
            List<PackageStateInternal> activePackages = new ArrayList<>();
            List<PackageStateInternal> inactivePackages = new ArrayList<>();
            List<PackageStateInternal> factoryActivePackages = new ArrayList<>();
            List<PackageStateInternal> factoryInactivePackages = new ArrayList<>();
            generateApexPackageInfo(activePackages, inactivePackages, factoryActivePackages,
                    factoryInactivePackages);
            List<PackageInfo> activePackages = new ArrayList<>();
            List<PackageInfo> inactivePackages = new ArrayList<>();
            List<PackageInfo> factoryPackages = new ArrayList<>();
            generateApexPackageInfo(activePackages, inactivePackages, factoryPackages);
            ipw.println("Active APEX packages:");
            ApexPackageInfo.dumpPackageStates(activePackages, true, packageName, ipw);
            ApexPackageInfo.dumpPackages(activePackages, packageName, ipw);
            ipw.println("Inactive APEX packages:");
            ApexPackageInfo.dumpPackageStates(inactivePackages, false, packageName, ipw);
            ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw);
            ipw.println("Factory APEX packages:");
            ApexPackageInfo.dumpPackageStates(factoryActivePackages, true, packageName, ipw);
            ApexPackageInfo.dumpPackageStates(factoryInactivePackages, false, packageName, ipw);
            ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw);
        } else {
            mApexPackageInfo.dump(pw, packageName);
        }
+2 −2
Original line number Diff line number Diff line
@@ -1611,7 +1611,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mSharedLibraries = injector.getSharedLibrariesImpl();

        mApexManager = testParams.apexManager;
        mApexPackageInfo = new ApexPackageInfo(this);
        mApexPackageInfo = new ApexPackageInfo();
        mArtManagerService = testParams.artManagerService;
        mAvailableFeatures = testParams.availableFeatures;
        mBackgroundDexOptService = testParams.backgroundDexOptService;
@@ -1811,7 +1811,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mProtectedPackages = new ProtectedPackages(mContext);

        mApexManager = injector.getApexManager();
        mApexPackageInfo = new ApexPackageInfo(this);
        mApexPackageInfo = new ApexPackageInfo();
        mAppsFilter = mInjector.getAppsFilter();

        mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
+2 −2
Original line number Diff line number Diff line
@@ -823,8 +823,8 @@ final class ScanPackageUtils {
     * ideally be static, but, it requires locks to read system state.
     */
    public static void applyPolicy(ParsedPackage parsedPackage,
            final @PackageManagerService.ScanFlags int scanFlags,
            @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp) {
            final @PackageManagerService.ScanFlags int scanFlags, AndroidPackage platformPkg,
            boolean isUpdatedSystemApp) {
        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
            parsedPackage.setSystem(true);
            // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
+3 −5
Original line number Diff line number Diff line
@@ -93,14 +93,12 @@ public class PackageInfoUtils {

    /**
     * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
     * @deprecated Once ENABLE_FEATURE_SCAN_APEX is removed, this should also be removed.
     */
    @Deprecated
    @Nullable
    public static PackageInfo generate(AndroidPackage pkg, ApexInfo apexInfo, long flags,
            @Nullable PackageStateInternal pkgSetting, @UserIdInt int userId) {
    public static PackageInfo generate(AndroidPackage pkg, ApexInfo apexInfo, int flags,
            @Nullable PackageStateInternal pkgSetting) {
        return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(),
                PackageUserStateInternal.DEFAULT, userId, apexInfo, pkgSetting);
                PackageUserStateInternal.DEFAULT, UserHandle.getCallingUserId(), apexInfo, pkgSetting);
    }

    /**
Loading