From 03f72240fee75d9ef3a8203fabfaf6acdac13244 Mon Sep 17 00:00:00 2001 From: Winson Date: Mon, 24 Feb 2020 16:55:51 -0800 Subject: [PATCH] Use correct PackageSetting for dexopt calculation The PackageSetting object is sometimes copied during scan/install and will not match the reconciledPkg's pkgSetting. This meant the usesLibrary parsing assigned the values to one PackageSetting object, but dexopt read from the other, copied object. Unfortunately this copy logic leaves the two settings out of sync and thus the isUpdatedSystemApp flag has to be copied between them. All of this would be great to resolve in a future refactor. Bug: 150142306 Test: adb install -r {out_of_blueline_target}/product/app/CalculatorGooglePrebuilt/CalculatorGooglePrebuilt.apk installs correctly, with dexopt run with the correct paths Change-Id: Ifca3bafcea1b8858baf4a22ddd264d5e07a0f1e5 --- .../server/pm/PackageManagerService.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2d8808052864d..eb742e9a4a363 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -16345,7 +16345,27 @@ public class PackageManagerService extends IPackageManager.Stub REASON_INSTALL, DexoptOptions.DEXOPT_BOOT_COMPLETE | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE); - mPackageDexOptimizer.performDexOpt(pkg, reconciledPkg.pkgSetting, + ScanResult result = reconciledPkg.scanResult; + + // This mirrors logic from commitReconciledScanResultLocked, where the library files + // needed for dexopt are assigned. + // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous + // setting needs to be passed to have a comparison, hide it behind an immutable + // interface. There's no good reason to have 3 different ways to access the real + // PackageSetting object, only one of which is actually correct. + PackageSetting realPkgSetting = result.existingSettingCopied + ? result.request.pkgSetting : result.pkgSetting; + if (realPkgSetting == null) { + realPkgSetting = reconciledPkg.pkgSetting; + } + + // Unfortunately, the updated system app flag is only tracked on this PackageSetting + boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState() + .isUpdatedSystemApp(); + + realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp); + + mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting, null /* instructionSets */, getOrCreateCompilerPackageStats(pkg), mDexManager.getPackageUseInfoOrDefault(packageName),