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

Commit d3b6b5c5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Remove PackageInfo from ApexPackageInfo"""

parents 14e6daea 8e316e4b
Loading
Loading
Loading
Loading
+115 −90
Original line number Diff line number Diff line
@@ -22,10 +22,9 @@ 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;
@@ -33,8 +32,9 @@ 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.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;

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

    @GuardedBy("mLock")
    private List<PackageInfo> mAllPackagesCache;
    private List<Pair<ApexInfo, AndroidPackage>> 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;
    @Nullable
    private final PackageManagerService mPackageManager;

    ApexPackageInfo() {
        mPackageManager = null;
    }

    ApexPackageInfo(@NonNull PackageManagerService pms) {
        mPackageManager = pms;
    }

    /**
@@ -105,20 +106,23 @@ class ApexPackageInfo {
     *         is not found.
     */
    @Nullable
    PackageInfo getPackageInfo(String packageName, @ApexManager.PackageInfoFlags int flags) {
    Pair<ApexInfo, AndroidPackage> 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 PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (!packageInfo.packageName.equals(packageName)) {
                final Pair<ApexInfo, AndroidPackage> pair = mAllPackagesCache.get(i);
                var apexInfo = pair.first;
                var pkg = pair.second;
                if (!pkg.getPackageName().equals(packageName)) {
                    continue;
                }
                if ((matchActive && isActive(packageInfo))
                        || (matchFactory && isFactory(packageInfo))) {
                    return packageInfo;
                if ((matchActive && apexInfo.isActive)
                        || (matchFactory && apexInfo.isFactory)) {
                    return pair;
                }
            }
            return null;
@@ -128,18 +132,18 @@ class ApexPackageInfo {
    /**
     * Retrieves information about all active APEX packages.
     *
     * @return a List of PackageInfo object, each one containing information about a different
     *         active package.
     * @return list containing information about different active packages.
     */
    List<PackageInfo> getActivePackages() {
    @NonNull
    List<Pair<ApexInfo, AndroidPackage>> getActivePackages() {
        synchronized (mLock) {
            Preconditions.checkState(mAllPackagesCache != null,
                    "APEX packages have not been scanned");
            final List<PackageInfo> activePackages = new ArrayList<>();
            final List<Pair<ApexInfo, AndroidPackage>> activePackages = new ArrayList<>();
            for (int i = 0; i < mAllPackagesCache.size(); i++) {
                final PackageInfo packageInfo = mAllPackagesCache.get(i);
                if (isActive(packageInfo)) {
                    activePackages.add(packageInfo);
                final var pair = mAllPackagesCache.get(i);
                if (pair.first.isActive) {
                    activePackages.add(pair);
                }
            }
            return activePackages;
@@ -147,20 +151,20 @@ class ApexPackageInfo {
    }

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

    void notifyPackageInstalled(ApexInfo apexInfo, AndroidPackage pkg) {
        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;
        final String packageName = pkg.getPackageName();
        synchronized (mLock) {
            for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
                PackageInfo oldApexPkg = mAllPackagesCache.get(i);
                if (oldApexPkg.isActiveApex && oldApexPkg.packageName.equals(packageName)) {
                    if (isFactory(oldApexPkg)) {
                        oldApexPkg.isActiveApex = false;
                        mAllPackagesCache.add(newApexPkg);
                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));
                    } else {
                        mAllPackagesCache.set(i, newApexPkg);
                        mAllPackagesCache.set(i, Pair.create(apexInfo, pkg));
                    }
                    break;
                }
@@ -244,16 +245,6 @@ 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.
     *
@@ -288,33 +279,25 @@ class ApexPackageInfo {
        HashSet<String> factoryPackagesSet = new HashSet<>();
        for (ApexManager.ScanResult result : scanResults) {
            ApexInfo ai = result.apexInfo;

            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)) {
            String packageName = result.pkg.getPackageName();
            if (!packageName.equals(result.packageName)) {
                throw new IllegalStateException("Unmatched package name: "
                        + result.packageName + " != " + packageInfo.packageName
                        + result.packageName + " != " + packageName
                        + ", path=" + ai.modulePath);
            }
            mAllPackagesCache.add(packageInfo);
            mAllPackagesCache.add(Pair.create(ai, result.pkg));
            if (ai.isActive) {
                if (!activePackagesSet.add(packageInfo.packageName)) {
                if (!activePackagesSet.add(packageName)) {
                    throw new IllegalStateException(
                            "Two active packages have the same name: "
                                    + packageInfo.packageName);
                            "Two active packages have the same name: " + packageName);
                }
            }
            if (ai.isFactory) {
                // Don't throw when the duplicating APEX is VNDK APEX
                if (!factoryPackagesSet.add(packageInfo.packageName)
                if (!factoryPackagesSet.add(packageName)
                        && !ai.moduleName.startsWith(VNDK_APEX_MODULE_NAME_PREFIX)) {
                    throw new IllegalStateException(
                            "Two factory packages have the same name: "
                                    + packageInfo.packageName);
                            "Two factory packages have the same name: " + packageName);
                }
            }
        }
@@ -348,6 +331,13 @@ class ApexPackageInfo {
            if (throwable == null) {
                // Calling hideAsFinal to assign derived fields for the app info flags.
                parseResult.parsedPackage.hideAsFinal();

                // TODO: When ENABLE_FEATURE_SCAN_APEX is finalized, remove this and the entire
                //  calling path code
                ScanPackageUtils.applyPolicy(parseResult.parsedPackage,
                        PackageManagerService.SCAN_AS_SYSTEM,
                        mPackageManager == null ? null : mPackageManager.getPlatformPackage(),
                        false);
                results.add(new ApexManager.ScanResult(
                        ai, parseResult.parsedPackage, parseResult.parsedPackage.getPackageName()));
            } else if (throwable instanceof PackageManagerException) {
@@ -362,6 +352,37 @@ 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.
@@ -369,24 +390,28 @@ 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<PackageInfo> packagesCache,
    static void dumpPackages(List<Pair<ApexInfo, AndroidPackage>> packagesCache,
            @Nullable String packageName, IndentingPrintWriter ipw) {
        ipw.println();
        ipw.increaseIndent();
        for (int i = 0, size = packagesCache.size(); i < size; i++) {
            final PackageInfo pi = packagesCache.get(i);
            if (packageName != null && !packageName.equals(pi.packageName)) {
            final var pair = packagesCache.get(i);
            var apexInfo = pair.first;
            var pkg = pair.second;
            if (packageName != null && !packageName.equals(pkg.getPackageName())) {
                continue;
            }
            ipw.println(pi.packageName);
            ipw.println(pkg.getPackageName());
            ipw.increaseIndent();
            ipw.println("Version: " + pi.versionCode);
            ipw.println("Path: " + pi.applicationInfo.sourceDir);
            ipw.println("IsActive: " + isActive(pi));
            ipw.println("IsFactory: " + isFactory(pi));
            ipw.println("Version: " + pkg.getLongVersionCode());
            ipw.println("Path: " + pkg.getBaseApkPath());
            ipw.println("IsActive: " + apexInfo.isActive);
            ipw.println("IsFactory: " + apexInfo.isFactory);
            ipw.println("ApplicationInfo: ");
            ipw.increaseIndent();
            pi.applicationInfo.dump(new PrintWriterPrinter(ipw), "");
            // TODO: Dump the package manually
            AndroidPackageUtils.generateAppInfoWithoutState(pkg)
                    .dump(new PrintWriterPrinter(ipw), "");
            ipw.decreaseIndent();
            ipw.decreaseIndent();
        }
+42 −28
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ 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;
@@ -1018,11 +1019,12 @@ public class ComputerEngine implements Computer {
                if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
                    apexFlags = ApexManager.MATCH_FACTORY_PACKAGE;
                }
                final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
                if (pi == null) {
                final var pair = mApexPackageInfo.getPackageInfo(packageName, apexFlags);
                if (pair == null) {
                    return null;
                }
                return pi.applicationInfo;
                return PackageInfoUtils.generateApplicationInfo(pair.second, flags,
                        PackageUserStateInternal.DEFAULT, userId, null);
            }
        }
        if ("android".equals(packageName) || "system".equals(packageName)) {
@@ -1718,8 +1720,12 @@ public class ComputerEngine implements Computer {
            // Instant app filtering for APEX modules is ignored
            if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
                if (matchApex) {
                    return mApexPackageInfo.getPackageInfo(packageName,
                    final var pair = 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);
@@ -1775,8 +1781,12 @@ public class ComputerEngine implements Computer {
        }
        if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            if (matchApex) {
                return mApexPackageInfo.getPackageInfo(packageName,
                final var pair = mApexPackageInfo.getPackageInfo(packageName,
                        ApexManager.MATCH_ACTIVE_PACKAGE);
                if (pair == null) {
                    return null;
                }
                return PackageInfoUtils.generate(pair.second, pair.first, flags, null, userId);
            }
        }
        return null;
@@ -1883,10 +1893,17 @@ public class ComputerEngine implements Computer {
        }
        if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            if (listApex) {
                List<Pair<ApexInfo, AndroidPackage>> pairs;
                if (listFactory) {
                    list.addAll(mApexPackageInfo.getFactoryPackages());
                    pairs = mApexPackageInfo.getFactoryPackages();
                } else {
                    list.addAll(mApexPackageInfo.getActivePackages());
                    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));
                }
            }
        }
@@ -3404,29 +3421,23 @@ public class ComputerEngine implements Computer {
        } // switch
    }

    private void generateApexPackageInfo(List<PackageInfo> activePackages,
            List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) {
    private void generateApexPackageInfo(@NonNull List<PackageStateInternal> activePackages,
            @NonNull List<PackageStateInternal> inactivePackages,
            @NonNull List<PackageStateInternal> factoryActivePackages,
            @NonNull List<PackageStateInternal> factoryInactivePackages) {
        for (AndroidPackage p : mPackages.values()) {
            final String packageName = p.getPackageName();
            PackageStateInternal ps = mSettings.getPackage(packageName);
            if (!p.isApex() || ps == null) {
                continue;
            }
            PackageInfo pi = generatePackageInfo(ps, 0, 0);
            if (pi == null) {
                continue;
            }
            pi.isActiveApex = true;
            activePackages.add(pi);
            activePackages.add(ps);
            if (!ps.isUpdatedSystemApp()) {
                factoryPackages.add(pi);
                factoryActivePackages.add(ps);
            } else {
                PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName);
                pi = generatePackageInfo(psDisabled, 0, 0);
                if (pi != null) {
                    factoryPackages.add(pi);
                    inactivePackages.add(pi);
                }
                factoryInactivePackages.add(psDisabled);
                inactivePackages.add(psDisabled);
            }
        }
    }
@@ -3434,16 +3445,19 @@ 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<PackageInfo> activePackages = new ArrayList<>();
            List<PackageInfo> inactivePackages = new ArrayList<>();
            List<PackageInfo> factoryPackages = new ArrayList<>();
            generateApexPackageInfo(activePackages, inactivePackages, factoryPackages);
            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);
            ipw.println("Active APEX packages:");
            ApexPackageInfo.dumpPackages(activePackages, packageName, ipw);
            ApexPackageInfo.dumpPackageStates(activePackages, true, packageName, ipw);
            ipw.println("Inactive APEX packages:");
            ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw);
            ApexPackageInfo.dumpPackageStates(inactivePackages, false, packageName, ipw);
            ipw.println("Factory APEX packages:");
            ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw);
            ApexPackageInfo.dumpPackageStates(factoryActivePackages, true, packageName, ipw);
            ApexPackageInfo.dumpPackageStates(factoryInactivePackages, false, 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();
        mApexPackageInfo = new ApexPackageInfo(this);
        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();
        mApexPackageInfo = new ApexPackageInfo(this);
        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, AndroidPackage platformPkg,
            boolean isUpdatedSystemApp) {
            final @PackageManagerService.ScanFlags int scanFlags,
            @Nullable 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
+5 −3
Original line number Diff line number Diff line
@@ -93,12 +93,14 @@ 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, int flags,
            @Nullable PackageStateInternal pkgSetting) {
    public static PackageInfo generate(AndroidPackage pkg, ApexInfo apexInfo, long flags,
            @Nullable PackageStateInternal pkgSetting, @UserIdInt int userId) {
        return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(),
                PackageUserStateInternal.DEFAULT, UserHandle.getCallingUserId(), apexInfo, pkgSetting);
                PackageUserStateInternal.DEFAULT, userId, apexInfo, pkgSetting);
    }

    /**
Loading