Loading services/core/java/com/android/server/pm/ApexPackageInfo.java +91 −98 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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; } Loading @@ -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. * Loading Loading @@ -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); } } } Loading Loading @@ -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. Loading @@ -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(); } Loading services/core/java/com/android/server/pm/ComputerEngine.java +28 −42 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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()); } } } Loading Loading @@ -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); } } } } Loading @@ -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); } 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(this); mApexPackageInfo = new ApexPackageInfo(); 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(this); mApexPackageInfo = new ApexPackageInfo(); 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, @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 Loading services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +3 −5 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/pm/ApexPackageInfo.java +91 −98 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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; } Loading @@ -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. * Loading Loading @@ -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); } } } Loading Loading @@ -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. Loading @@ -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(); } Loading
services/core/java/com/android/server/pm/ComputerEngine.java +28 −42 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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()); } } } Loading Loading @@ -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); } } } } Loading @@ -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); } 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(this); mApexPackageInfo = new ApexPackageInfo(); 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(this); mApexPackageInfo = new ApexPackageInfo(); 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, @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 Loading
services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +3 −5 Original line number Diff line number Diff line Loading @@ -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