Loading services/core/java/com/android/server/pm/ApexPackageInfo.java +115 −90 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; } /** Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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; } Loading @@ -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. * Loading Loading @@ -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); } } } Loading Loading @@ -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) { Loading @@ -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. Loading @@ -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(); } Loading services/core/java/com/android/server/pm/ComputerEngine.java +42 −28 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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)); } } } Loading Loading @@ -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); } } } Loading @@ -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); } Loading services/core/java/com/android/server/pm/PackageManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading services/core/java/com/android/server/pm/ScanPackageUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +5 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/pm/ApexPackageInfo.java +115 −90 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; } /** Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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; } Loading @@ -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. * Loading Loading @@ -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); } } } Loading Loading @@ -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) { Loading @@ -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. Loading @@ -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(); } Loading
services/core/java/com/android/server/pm/ComputerEngine.java +42 −28 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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)); } } } Loading Loading @@ -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); } } } Loading @@ -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); } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading
services/core/java/com/android/server/pm/ScanPackageUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +5 −3 Original line number Diff line number Diff line Loading @@ -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