Loading services/core/java/com/android/server/pm/PackageManagerService.java +64 −153 Original line number Diff line number Diff line Loading @@ -545,7 +545,6 @@ public class PackageManagerService extends IPackageManager.Stub static final int SCAN_AS_SYSTEM_EXT = 1 << 21; static final int SCAN_AS_ODM = 1 << 22; static final int SCAN_AS_APK_IN_APEX = 1 << 23; static final int SCAN_EXPECTED_BETTER = 1 << 24; @IntDef(flag = true, prefix = { "SCAN_" }, value = { SCAN_NO_DEX, Loading Loading @@ -805,12 +804,11 @@ public class PackageManagerService extends IPackageManager.Stub final SparseIntArray mIsolatedOwners = new SparseIntArray(); /** * Tracks packages that we expect to find updated versions of on disk. * Keys are package name, values are package location and package version code. * * @see #expectBetter(String, File, long) * Tracks new system packages [received in an OTA] that we expect to * find updated user-installed versions. Keys are package name, values * are package location. */ private final ArrayMap<String, List<Pair<File, Long>>> mExpectingBetter = new ArrayMap<>(); final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); /** * Tracks existing packages prior to receiving an OTA. Keys are package name. Loading Loading @@ -3351,7 +3349,7 @@ public class PackageManagerService extends IPackageManager.Stub + ", versionCode=" + ps.versionCode + "; scanned versionCode=" + scannedPkg.getLongVersionCode()); removePackageLI(scannedPkg, true); expectBetter(ps.name, ps.getPath(), ps.versionCode); mExpectingBetter.put(ps.name, ps.getPath()); } continue; Loading Loading @@ -3381,8 +3379,7 @@ public class PackageManagerService extends IPackageManager.Stub // We're expecting that the system app should remain disabled, but add // it to expecting better to recover in case the data version cannot // be scanned. expectBetter(disabledPs.name, disabledPs.getPath(), disabledPs.versionCode); mExpectingBetter.put(disabledPs.name, disabledPs.getPath()); } } } Loading Loading @@ -3483,16 +3480,11 @@ public class PackageManagerService extends IPackageManager.Stub for (int i = 0; i < mExpectingBetter.size(); i++) { final String packageName = mExpectingBetter.keyAt(i); if (!mPackages.containsKey(packageName)) { final File scanFile = mExpectingBetter.valueAt(i); logCriticalInfo(Log.WARN, "Expected better " + packageName + " but never showed up; reverting to system"); final List<Pair<File, Long>> scanFiles = mExpectingBetter.valueAt(i); // Sort ascending and iterate backwards to take highest version code Collections.sort(scanFiles, (first, second) -> Long.compare(first.second, second.second)); for (int index = scanFiles.size() - 1; index >= 0; index--) { File scanFile = scanFiles.get(index).first; @ParseFlags int reparseFlags = 0; @ScanFlags int rescanFlags = 0; for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) { Loading @@ -3515,19 +3507,14 @@ public class PackageManagerService extends IPackageManager.Stub } mSettings.enableSystemPackageLPw(packageName); rescanFlags |= SCAN_EXPECTED_BETTER; try { scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null); // Take first success and break out of for loop break; } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse original system package: " + e.getMessage()); } } } } // Uncompress and install any stubbed system applications. // This must be done last to ensure all stubs are replaced or disabled. Loading Loading @@ -3913,33 +3900,6 @@ public class PackageManagerService extends IPackageManager.Stub } } /** * Mark a package as skipped during initial scan, expecting a more up to date version to be * available on the scan of a higher priority partition. This can be either a system partition * or the data partition. * * If for some reason that newer version cannot be scanned successfully, the data structure * created here will be used to backtrack in the scanning process to try and take the highest * version code of the package left on disk that scans successfully. * * This can occur if an OTA adds a new system package which the user has already installed an * update on data for. Or if the device image includes multiple versions of the same package, * for cases where the maintainer of a higher priority partition wants to update an app on * a lower priority partition before shipping a device to users. * * @param pkgName the package name identifier to queue under * @param codePath the path to re-scan if needed * @param knownVersionCode the version of the package so that the set of files can be sorted */ private void expectBetter(String pkgName, File codePath, long knownVersionCode) { List<Pair<File, Long>> pairs = mExpectingBetter.get(pkgName); if (pairs == null) { pairs = new ArrayList<>(0); mExpectingBetter.put(pkgName, pairs); } pairs.add(Pair.create(codePath, knownVersionCode)); } /** * Extract, install and enable a stub package. * <p>If the compressed file can not be extracted / installed for any reason, the stub Loading Loading @@ -11311,23 +11271,7 @@ public class PackageManagerService extends IPackageManager.Stub isUpdatedSystemApp = disabledPkgSetting != null; } applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp); try { assertPackageIsValid(parsedPackage, pkgSetting, parseFlags, scanFlags); } catch (PackageManagerException e) { if (e.error == INSTALL_FAILED_VERSION_DOWNGRADE && ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) && ((scanFlags & SCAN_BOOTING) != 0)) { if (pkgSetting != null && pkgSetting.getPkg() == null) { // If a package for the pkgSetting hasn't already been found, this is // skipping a downgrade on a lower priority partition, and so a later scan // is expected to fill the package. expectBetter(pkgSetting.name, new File(parsedPackage.getPath()), parsedPackage.getLongVersionCode()); } } throw e; } assertPackageIsValid(parsedPackage, parseFlags, scanFlags); SharedUserSetting sharedUserSetting = null; if (parsedPackage.getSharedUserId() != null) { Loading Loading @@ -12179,9 +12123,9 @@ public class PackageManagerService extends IPackageManager.Stub * * @throws PackageManagerException If the package fails any of the validation checks */ private void assertPackageIsValid(AndroidPackage pkg, @Nullable PackageSetting existingPkgSetting, final @ParseFlags int parseFlags, final @ScanFlags int scanFlags) throws PackageManagerException { private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags, final @ScanFlags int scanFlags) throws PackageManagerException { if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { assertCodePolicy(pkg); } Loading @@ -12196,11 +12140,11 @@ public class PackageManagerService extends IPackageManager.Stub // after OTA. final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; String pkgName = pkg.getPackageName(); if ((isUserInstall || isFirstBootOrUpgrade) && mApexManager.isApexPackage(pkgName)) { && mApexManager.isApexPackage(pkg.getPackageName())) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, pkgName + " is an APEX package and can't be installed as an APK."); pkg.getPackageName() + " is an APEX package and can't be installed as an APK."); } // Make sure we're not adding any bogus keyset info Loading @@ -12209,7 +12153,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { // The special "android" package can only be defined once if (pkgName.equals("android")) { if (pkg.getPackageName().equals("android")) { if (mAndroidApplication != null) { Slog.w(TAG, "*************************************************"); Slog.w(TAG, "Core android package being redefined. Skipping."); Loading @@ -12220,47 +12164,13 @@ public class PackageManagerService extends IPackageManager.Stub } } final long newLongVersionCode = pkg.getLongVersionCode(); if ((scanFlags & SCAN_NEW_INSTALL) == 0) { boolean runDuplicateCheck = false; // It's possible to re-scan a package if an updated system app was expected, but // no update on /data could be found. To avoid infinitely looping, a flag is passed // in when re-scanning and this first branch is skipped if the flag is set. if ((scanFlags & SCAN_EXPECTED_BETTER) == 0 && existingPkgSetting != null) { long existingLongVersionCode = existingPkgSetting.versionCode; if (newLongVersionCode <= existingLongVersionCode) { // Must check that real name is equivalent, as it's possible to downgrade // version code if the package is actually a different package taking over // a package name through <original-package/>. It is assumed that this // migration is one time, one way, and that there is no failsafe if this // doesn't hold true. if (Objects.equals(existingPkgSetting.realName, pkg.getRealPackage())) { if (newLongVersionCode != existingLongVersionCode) { throw new PackageManagerException( INSTALL_FAILED_VERSION_DOWNGRADE, "Ignoring lower version " + newLongVersionCode + " for package " + pkgName + " with expected version " + existingLongVersionCode); } } } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && (scanFlags & SCAN_BOOTING) != 0) { // During system boot scan, if there's already a package known, but this // package is higher version, use it instead, ignoring the duplicate check. // This will store the higher version in the setting object, and the above // branch/exception will cause future scans to skip the lower versions. runDuplicateCheck = false; } } if (runDuplicateCheck && mPackages.containsKey(pkgName)) { // A package name must be unique; don't allow duplicates if ((scanFlags & SCAN_NEW_INSTALL) == 0 && mPackages.containsKey(pkg.getPackageName())) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, "Application package " + pkgName "Application package " + pkg.getPackageName() + " already installed. Skipping duplicate."); } } if (pkg.isStaticSharedLibrary()) { // Static libs have a synthetic package name containing the version Loading Loading @@ -12379,8 +12289,8 @@ public class PackageManagerService extends IPackageManager.Stub } } } if (newLongVersionCode < minVersionCode || newLongVersionCode > maxVersionCode) { if (pkg.getLongVersionCode() < minVersionCode || pkg.getLongVersionCode() > maxVersionCode) { throw new PackageManagerException("Static shared" + " lib version codes must be ordered as lib versions"); } Loading @@ -12395,10 +12305,11 @@ public class PackageManagerService extends IPackageManager.Stub // to the user-installed location. If we don't allow this change, any newer, // user-installed version of the application will be ignored. if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { if (mExpectingBetter.containsKey(pkgName)) { Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkgName); if (mExpectingBetter.containsKey(pkg.getPackageName())) { Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.getPackageName()); } else { PackageSetting known = mSettings.getPackageLPr(pkgName); PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName()); if (known != null) { if (DEBUG_PACKAGE_SCANNING) { Log.d(TAG, "Examining " + pkg.getPath() Loading @@ -12406,14 +12317,14 @@ public class PackageManagerService extends IPackageManager.Stub } if (!pkg.getPath().equals(known.getPathString())) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, "Application package " + pkgName "Application package " + pkg.getPackageName() + " found at " + pkg.getPath() + " but expected at " + known.getPathString() + "; ignoring."); } } else { throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION, "Application package " + pkgName "Application package " + pkg.getPackageName() + " not found; ignoring."); } } Loading @@ -12436,7 +12347,7 @@ public class PackageManagerService extends IPackageManager.Stub INSTALL_FAILED_PROCESS_NOT_DEFINED, "Can't install because application tag's process attribute " + pkg.getProcessName() + " (in package " + pkgName + " (in package " + pkg.getPackageName() + ") is not included in the <processes> list"); } assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity"); Loading @@ -12460,7 +12371,7 @@ public class PackageManagerService extends IPackageManager.Stub pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Apps that share a user with a " + "privileged app must themselves be marked as privileged. " + pkgName + " shares privileged user " + pkg.getPackageName() + " shares privileged user " + pkg.getSharedUserId() + "."); } } Loading @@ -12477,21 +12388,21 @@ public class PackageManagerService extends IPackageManager.Stub // upgraded. Objects.requireNonNull(mOverlayConfig, "Parsing non-system dir before overlay configs are initialized"); if (!mOverlayConfig.isMutable(pkgName)) { if (!mOverlayConfig.isMutable(pkg.getPackageName())) { throw new PackageManagerException("Overlay " + pkgName + pkg.getPackageName() + " is static and cannot be upgraded."); } } else { if ((scanFlags & SCAN_AS_VENDOR) != 0) { if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) { Slog.w(TAG, "System overlay " + pkgName Slog.w(TAG, "System overlay " + pkg.getPackageName() + " targets an SDK below the required SDK level of vendor" + " overlays (" + getVendorPartitionVersion() + ")." + " This will become an install error in a future release"); } } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) { Slog.w(TAG, "System overlay " + pkgName Slog.w(TAG, "System overlay " + pkg.getPackageName() + " targets an SDK below the required SDK level of system" + " overlays (" + Build.VERSION.SDK_INT + ")." + " This will become an install error in a future release"); Loading @@ -12507,7 +12418,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!comparePackageSignatures(platformPkgSetting, pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Overlay " + pkgName + pkg.getPackageName() + " must target Q or later, " + "or be signed with the platform certificate"); } Loading @@ -12529,7 +12440,7 @@ public class PackageManagerService extends IPackageManager.Stub // check reference signature if (mOverlayConfigSignaturePackage == null) { throw new PackageManagerException("Overlay " + pkgName + " and target " + pkg.getPackageName() + " and target " + pkg.getOverlayTarget() + " signed with" + " different certificates, and the overlay lacks" + " <overlay android:targetName>"); Loading @@ -12539,7 +12450,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!comparePackageSignatures(refPkgSetting, pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Overlay " + pkgName + " signed with a different " + pkg.getPackageName() + " signed with a different " + "certificate than both the reference package and " + "target " + pkg.getOverlayTarget() + ", and the " + "overlay lacks <overlay android:targetName>"); Loading @@ -12559,7 +12470,7 @@ public class PackageManagerService extends IPackageManager.Stub if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) { throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, "No signature found in package of version " + minSignatureSchemeVersion + " or newer for package " + pkgName); + " or newer for package " + pkg.getPackageName()); } } } services/core/java/com/android/server/pm/parsing/PackageCacher.java +1 −10 Original line number Diff line number Diff line Loading @@ -57,16 +57,7 @@ public class PackageCacher { * Returns the cache key for a specified {@code packageFile} and {@code flags}. */ private String getCacheKey(File packageFile, int flags) { StringBuilder sb = new StringBuilder(); // To support packages with the same file name across partitions, use the partition name // as a prefix. The cache should only be used for cases where the file paths have been // established using the unique partition names, without canonicalization, so any links // which would point to the same partition name should be handled separately. String cachePrefix = packageFile.toPath().getName(0).toString(); sb.append(cachePrefix); sb.append('-'); sb.append(packageFile.getName()); StringBuilder sb = new StringBuilder(packageFile.getName()); sb.append('-'); sb.append(flags); Loading services/core/java/com/android/server/pm/parsing/PackageParser2.java +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ public class PackageParser2 implements AutoCloseable { } /** * TODO(b/155493909): Document new package parsing * TODO(b/135203078): Document new package parsing */ @AnyThread public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches) Loading services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -17,8 +17,11 @@ import org.junit.runner.RunWith class FactoryPackageTest : BaseHostJUnit4Test() { companion object { private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app" private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk" private const val VERSION_TWO = "PackageManagerTestAppVersion2.apk" private const val DEVICE_SIDE = "PackageManagerServiceDeviceSideTests.apk" private const val DEVICE_SIDE_PKG_NAME = "com.android.server.pm.test.deviceside" @get:ClassRule val deviceRebootRule = SystemPreparer.TestRuleDelegate(true) Loading @@ -37,8 +40,7 @@ class FactoryPackageTest : BaseHostJUnit4Test() { @Before @After fun removeApk() { HostUtils.deleteAllTestPackages(device, preparer) device.uninstallPackage(DEVICE_SIDE_PKG_NAME) device.uninstallPackage(TEST_PKG_NAME) device.deleteFile(filePath.parent.toString()) device.reboot() } Loading services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt +9 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/pm/PackageManagerService.java +64 −153 Original line number Diff line number Diff line Loading @@ -545,7 +545,6 @@ public class PackageManagerService extends IPackageManager.Stub static final int SCAN_AS_SYSTEM_EXT = 1 << 21; static final int SCAN_AS_ODM = 1 << 22; static final int SCAN_AS_APK_IN_APEX = 1 << 23; static final int SCAN_EXPECTED_BETTER = 1 << 24; @IntDef(flag = true, prefix = { "SCAN_" }, value = { SCAN_NO_DEX, Loading Loading @@ -805,12 +804,11 @@ public class PackageManagerService extends IPackageManager.Stub final SparseIntArray mIsolatedOwners = new SparseIntArray(); /** * Tracks packages that we expect to find updated versions of on disk. * Keys are package name, values are package location and package version code. * * @see #expectBetter(String, File, long) * Tracks new system packages [received in an OTA] that we expect to * find updated user-installed versions. Keys are package name, values * are package location. */ private final ArrayMap<String, List<Pair<File, Long>>> mExpectingBetter = new ArrayMap<>(); final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); /** * Tracks existing packages prior to receiving an OTA. Keys are package name. Loading Loading @@ -3351,7 +3349,7 @@ public class PackageManagerService extends IPackageManager.Stub + ", versionCode=" + ps.versionCode + "; scanned versionCode=" + scannedPkg.getLongVersionCode()); removePackageLI(scannedPkg, true); expectBetter(ps.name, ps.getPath(), ps.versionCode); mExpectingBetter.put(ps.name, ps.getPath()); } continue; Loading Loading @@ -3381,8 +3379,7 @@ public class PackageManagerService extends IPackageManager.Stub // We're expecting that the system app should remain disabled, but add // it to expecting better to recover in case the data version cannot // be scanned. expectBetter(disabledPs.name, disabledPs.getPath(), disabledPs.versionCode); mExpectingBetter.put(disabledPs.name, disabledPs.getPath()); } } } Loading Loading @@ -3483,16 +3480,11 @@ public class PackageManagerService extends IPackageManager.Stub for (int i = 0; i < mExpectingBetter.size(); i++) { final String packageName = mExpectingBetter.keyAt(i); if (!mPackages.containsKey(packageName)) { final File scanFile = mExpectingBetter.valueAt(i); logCriticalInfo(Log.WARN, "Expected better " + packageName + " but never showed up; reverting to system"); final List<Pair<File, Long>> scanFiles = mExpectingBetter.valueAt(i); // Sort ascending and iterate backwards to take highest version code Collections.sort(scanFiles, (first, second) -> Long.compare(first.second, second.second)); for (int index = scanFiles.size() - 1; index >= 0; index--) { File scanFile = scanFiles.get(index).first; @ParseFlags int reparseFlags = 0; @ScanFlags int rescanFlags = 0; for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) { Loading @@ -3515,19 +3507,14 @@ public class PackageManagerService extends IPackageManager.Stub } mSettings.enableSystemPackageLPw(packageName); rescanFlags |= SCAN_EXPECTED_BETTER; try { scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null); // Take first success and break out of for loop break; } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse original system package: " + e.getMessage()); } } } } // Uncompress and install any stubbed system applications. // This must be done last to ensure all stubs are replaced or disabled. Loading Loading @@ -3913,33 +3900,6 @@ public class PackageManagerService extends IPackageManager.Stub } } /** * Mark a package as skipped during initial scan, expecting a more up to date version to be * available on the scan of a higher priority partition. This can be either a system partition * or the data partition. * * If for some reason that newer version cannot be scanned successfully, the data structure * created here will be used to backtrack in the scanning process to try and take the highest * version code of the package left on disk that scans successfully. * * This can occur if an OTA adds a new system package which the user has already installed an * update on data for. Or if the device image includes multiple versions of the same package, * for cases where the maintainer of a higher priority partition wants to update an app on * a lower priority partition before shipping a device to users. * * @param pkgName the package name identifier to queue under * @param codePath the path to re-scan if needed * @param knownVersionCode the version of the package so that the set of files can be sorted */ private void expectBetter(String pkgName, File codePath, long knownVersionCode) { List<Pair<File, Long>> pairs = mExpectingBetter.get(pkgName); if (pairs == null) { pairs = new ArrayList<>(0); mExpectingBetter.put(pkgName, pairs); } pairs.add(Pair.create(codePath, knownVersionCode)); } /** * Extract, install and enable a stub package. * <p>If the compressed file can not be extracted / installed for any reason, the stub Loading Loading @@ -11311,23 +11271,7 @@ public class PackageManagerService extends IPackageManager.Stub isUpdatedSystemApp = disabledPkgSetting != null; } applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp); try { assertPackageIsValid(parsedPackage, pkgSetting, parseFlags, scanFlags); } catch (PackageManagerException e) { if (e.error == INSTALL_FAILED_VERSION_DOWNGRADE && ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) && ((scanFlags & SCAN_BOOTING) != 0)) { if (pkgSetting != null && pkgSetting.getPkg() == null) { // If a package for the pkgSetting hasn't already been found, this is // skipping a downgrade on a lower priority partition, and so a later scan // is expected to fill the package. expectBetter(pkgSetting.name, new File(parsedPackage.getPath()), parsedPackage.getLongVersionCode()); } } throw e; } assertPackageIsValid(parsedPackage, parseFlags, scanFlags); SharedUserSetting sharedUserSetting = null; if (parsedPackage.getSharedUserId() != null) { Loading Loading @@ -12179,9 +12123,9 @@ public class PackageManagerService extends IPackageManager.Stub * * @throws PackageManagerException If the package fails any of the validation checks */ private void assertPackageIsValid(AndroidPackage pkg, @Nullable PackageSetting existingPkgSetting, final @ParseFlags int parseFlags, final @ScanFlags int scanFlags) throws PackageManagerException { private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags, final @ScanFlags int scanFlags) throws PackageManagerException { if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { assertCodePolicy(pkg); } Loading @@ -12196,11 +12140,11 @@ public class PackageManagerService extends IPackageManager.Stub // after OTA. final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; String pkgName = pkg.getPackageName(); if ((isUserInstall || isFirstBootOrUpgrade) && mApexManager.isApexPackage(pkgName)) { && mApexManager.isApexPackage(pkg.getPackageName())) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, pkgName + " is an APEX package and can't be installed as an APK."); pkg.getPackageName() + " is an APEX package and can't be installed as an APK."); } // Make sure we're not adding any bogus keyset info Loading @@ -12209,7 +12153,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { // The special "android" package can only be defined once if (pkgName.equals("android")) { if (pkg.getPackageName().equals("android")) { if (mAndroidApplication != null) { Slog.w(TAG, "*************************************************"); Slog.w(TAG, "Core android package being redefined. Skipping."); Loading @@ -12220,47 +12164,13 @@ public class PackageManagerService extends IPackageManager.Stub } } final long newLongVersionCode = pkg.getLongVersionCode(); if ((scanFlags & SCAN_NEW_INSTALL) == 0) { boolean runDuplicateCheck = false; // It's possible to re-scan a package if an updated system app was expected, but // no update on /data could be found. To avoid infinitely looping, a flag is passed // in when re-scanning and this first branch is skipped if the flag is set. if ((scanFlags & SCAN_EXPECTED_BETTER) == 0 && existingPkgSetting != null) { long existingLongVersionCode = existingPkgSetting.versionCode; if (newLongVersionCode <= existingLongVersionCode) { // Must check that real name is equivalent, as it's possible to downgrade // version code if the package is actually a different package taking over // a package name through <original-package/>. It is assumed that this // migration is one time, one way, and that there is no failsafe if this // doesn't hold true. if (Objects.equals(existingPkgSetting.realName, pkg.getRealPackage())) { if (newLongVersionCode != existingLongVersionCode) { throw new PackageManagerException( INSTALL_FAILED_VERSION_DOWNGRADE, "Ignoring lower version " + newLongVersionCode + " for package " + pkgName + " with expected version " + existingLongVersionCode); } } } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && (scanFlags & SCAN_BOOTING) != 0) { // During system boot scan, if there's already a package known, but this // package is higher version, use it instead, ignoring the duplicate check. // This will store the higher version in the setting object, and the above // branch/exception will cause future scans to skip the lower versions. runDuplicateCheck = false; } } if (runDuplicateCheck && mPackages.containsKey(pkgName)) { // A package name must be unique; don't allow duplicates if ((scanFlags & SCAN_NEW_INSTALL) == 0 && mPackages.containsKey(pkg.getPackageName())) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, "Application package " + pkgName "Application package " + pkg.getPackageName() + " already installed. Skipping duplicate."); } } if (pkg.isStaticSharedLibrary()) { // Static libs have a synthetic package name containing the version Loading Loading @@ -12379,8 +12289,8 @@ public class PackageManagerService extends IPackageManager.Stub } } } if (newLongVersionCode < minVersionCode || newLongVersionCode > maxVersionCode) { if (pkg.getLongVersionCode() < minVersionCode || pkg.getLongVersionCode() > maxVersionCode) { throw new PackageManagerException("Static shared" + " lib version codes must be ordered as lib versions"); } Loading @@ -12395,10 +12305,11 @@ public class PackageManagerService extends IPackageManager.Stub // to the user-installed location. If we don't allow this change, any newer, // user-installed version of the application will be ignored. if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { if (mExpectingBetter.containsKey(pkgName)) { Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkgName); if (mExpectingBetter.containsKey(pkg.getPackageName())) { Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.getPackageName()); } else { PackageSetting known = mSettings.getPackageLPr(pkgName); PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName()); if (known != null) { if (DEBUG_PACKAGE_SCANNING) { Log.d(TAG, "Examining " + pkg.getPath() Loading @@ -12406,14 +12317,14 @@ public class PackageManagerService extends IPackageManager.Stub } if (!pkg.getPath().equals(known.getPathString())) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, "Application package " + pkgName "Application package " + pkg.getPackageName() + " found at " + pkg.getPath() + " but expected at " + known.getPathString() + "; ignoring."); } } else { throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION, "Application package " + pkgName "Application package " + pkg.getPackageName() + " not found; ignoring."); } } Loading @@ -12436,7 +12347,7 @@ public class PackageManagerService extends IPackageManager.Stub INSTALL_FAILED_PROCESS_NOT_DEFINED, "Can't install because application tag's process attribute " + pkg.getProcessName() + " (in package " + pkgName + " (in package " + pkg.getPackageName() + ") is not included in the <processes> list"); } assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity"); Loading @@ -12460,7 +12371,7 @@ public class PackageManagerService extends IPackageManager.Stub pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Apps that share a user with a " + "privileged app must themselves be marked as privileged. " + pkgName + " shares privileged user " + pkg.getPackageName() + " shares privileged user " + pkg.getSharedUserId() + "."); } } Loading @@ -12477,21 +12388,21 @@ public class PackageManagerService extends IPackageManager.Stub // upgraded. Objects.requireNonNull(mOverlayConfig, "Parsing non-system dir before overlay configs are initialized"); if (!mOverlayConfig.isMutable(pkgName)) { if (!mOverlayConfig.isMutable(pkg.getPackageName())) { throw new PackageManagerException("Overlay " + pkgName + pkg.getPackageName() + " is static and cannot be upgraded."); } } else { if ((scanFlags & SCAN_AS_VENDOR) != 0) { if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) { Slog.w(TAG, "System overlay " + pkgName Slog.w(TAG, "System overlay " + pkg.getPackageName() + " targets an SDK below the required SDK level of vendor" + " overlays (" + getVendorPartitionVersion() + ")." + " This will become an install error in a future release"); } } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) { Slog.w(TAG, "System overlay " + pkgName Slog.w(TAG, "System overlay " + pkg.getPackageName() + " targets an SDK below the required SDK level of system" + " overlays (" + Build.VERSION.SDK_INT + ")." + " This will become an install error in a future release"); Loading @@ -12507,7 +12418,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!comparePackageSignatures(platformPkgSetting, pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Overlay " + pkgName + pkg.getPackageName() + " must target Q or later, " + "or be signed with the platform certificate"); } Loading @@ -12529,7 +12440,7 @@ public class PackageManagerService extends IPackageManager.Stub // check reference signature if (mOverlayConfigSignaturePackage == null) { throw new PackageManagerException("Overlay " + pkgName + " and target " + pkg.getPackageName() + " and target " + pkg.getOverlayTarget() + " signed with" + " different certificates, and the overlay lacks" + " <overlay android:targetName>"); Loading @@ -12539,7 +12450,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!comparePackageSignatures(refPkgSetting, pkg.getSigningDetails().signatures)) { throw new PackageManagerException("Overlay " + pkgName + " signed with a different " + pkg.getPackageName() + " signed with a different " + "certificate than both the reference package and " + "target " + pkg.getOverlayTarget() + ", and the " + "overlay lacks <overlay android:targetName>"); Loading @@ -12559,7 +12470,7 @@ public class PackageManagerService extends IPackageManager.Stub if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) { throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, "No signature found in package of version " + minSignatureSchemeVersion + " or newer for package " + pkgName); + " or newer for package " + pkg.getPackageName()); } } }
services/core/java/com/android/server/pm/parsing/PackageCacher.java +1 −10 Original line number Diff line number Diff line Loading @@ -57,16 +57,7 @@ public class PackageCacher { * Returns the cache key for a specified {@code packageFile} and {@code flags}. */ private String getCacheKey(File packageFile, int flags) { StringBuilder sb = new StringBuilder(); // To support packages with the same file name across partitions, use the partition name // as a prefix. The cache should only be used for cases where the file paths have been // established using the unique partition names, without canonicalization, so any links // which would point to the same partition name should be handled separately. String cachePrefix = packageFile.toPath().getName(0).toString(); sb.append(cachePrefix); sb.append('-'); sb.append(packageFile.getName()); StringBuilder sb = new StringBuilder(packageFile.getName()); sb.append('-'); sb.append(flags); Loading
services/core/java/com/android/server/pm/parsing/PackageParser2.java +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ public class PackageParser2 implements AutoCloseable { } /** * TODO(b/155493909): Document new package parsing * TODO(b/135203078): Document new package parsing */ @AnyThread public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches) Loading
services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/FactoryPackageTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -17,8 +17,11 @@ import org.junit.runner.RunWith class FactoryPackageTest : BaseHostJUnit4Test() { companion object { private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app" private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk" private const val VERSION_TWO = "PackageManagerTestAppVersion2.apk" private const val DEVICE_SIDE = "PackageManagerServiceDeviceSideTests.apk" private const val DEVICE_SIDE_PKG_NAME = "com.android.server.pm.test.deviceside" @get:ClassRule val deviceRebootRule = SystemPreparer.TestRuleDelegate(true) Loading @@ -37,8 +40,7 @@ class FactoryPackageTest : BaseHostJUnit4Test() { @Before @After fun removeApk() { HostUtils.deleteAllTestPackages(device, preparer) device.uninstallPackage(DEVICE_SIDE_PKG_NAME) device.uninstallPackage(TEST_PKG_NAME) device.deleteFile(filePath.parent.toString()) device.reboot() } Loading
services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt +9 −52 File changed.Preview size limit exceeded, changes collapsed. Show changes