@@ -5132,6 +5132,20 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
51325132 }
51335133 pkg.mScanPath = path;
51345134
5135+ if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5136+ // We don't do this here during boot because we can do it all
5137+ // at once after scanning all existing packages.
5138+ //
5139+ // We also do this *before* we perform dexopt on this package, so that
5140+ // we can avoid redundant dexopts, and also to make sure we've got the
5141+ // code and package path correct.
5142+ if (!adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5143+ pkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0)) {
5144+ mLastScanError = PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
5145+ return null;
5146+ }
5147+ }
5148+
51355149 if ((scanMode&SCAN_NO_DEX) == 0) {
51365150 if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
51375151 == DEX_OPT_FAILED) {
@@ -5251,16 +5265,6 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
52515265
52525266 // writer
52535267 synchronized (mPackages) {
5254- if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5255- // We don't do this here during boot because we can do it all
5256- // at once after scanning all existing packages.
5257- if (!adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5258- pkg.applicationInfo.cpuAbi,
5259- forceDex, (scanMode & SCAN_DEFER_DEX) != 0)) {
5260- mLastScanError = PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
5261- return null;
5262- }
5263- }
52645268 // We don't expect installation to fail beyond this point,
52655269 if ((scanMode&SCAN_MONITOR) != 0) {
52665270 mAppDirs.put(pkg.mPath, pkg);
@@ -5604,19 +5608,43 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
56045608 return pkg;
56055609 }
56065610
5611+ /**
5612+ * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
5613+ * i.e, so that all packages can be run inside a single process if required.
5614+ *
5615+ * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
5616+ * this function will either try and make the ABI for all packages in {@code packagesForUser}
5617+ * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
5618+ * the ABI selected for {@code packagesForUser}. This variant is used when installing or
5619+ * updating a package that belongs to a shared user.
5620+ */
56075621 private boolean adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
5608- String requiredInstructionSet, boolean forceDexOpt, boolean deferDexOpt) {
5622+ PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
5623+ String requiredInstructionSet = null;
5624+ if (scannedPackage != null && scannedPackage.applicationInfo.cpuAbi != null) {
5625+ requiredInstructionSet = VMRuntime.getInstructionSet(
5626+ scannedPackage.applicationInfo.cpuAbi);
5627+ }
5628+
56095629 PackageSetting requirer = null;
56105630 for (PackageSetting ps : packagesForUser) {
5611- if (ps.cpuAbiString != null) {
5631+ // If packagesForUser contains scannedPackage, we skip it. This will happen
5632+ // when scannedPackage is an update of an existing package. Without this check,
5633+ // we will never be able to change the ABI of any package belonging to a shared
5634+ // user, even if it's compatible with other packages.
5635+ if (scannedPackage == null || ! scannedPackage.packageName.equals(ps.name)) {
5636+ if (ps.cpuAbiString == null) {
5637+ continue;
5638+ }
5639+
56125640 final String instructionSet = VMRuntime.getInstructionSet(ps.cpuAbiString);
56135641 if (requiredInstructionSet != null) {
56145642 if (!instructionSet.equals(requiredInstructionSet)) {
56155643 // We have a mismatch between instruction sets (say arm vs arm64).
56165644 // bail out.
56175645 String errorMessage = "Instruction set mismatch, "
5618- + ((requirer == null) ? "[caller]" : requirer.pkg )
5619- + " requires " + requiredInstructionSet + " whereas " + ps.pkg
5646+ + ((requirer == null) ? "[caller]" : requirer)
5647+ + " requires " + requiredInstructionSet + " whereas " + ps
56205648 + " requires " + instructionSet;
56215649 Slog.e(TAG, errorMessage);
56225650
@@ -5632,20 +5660,37 @@ private boolean adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUse
56325660 }
56335661
56345662 if (requiredInstructionSet != null) {
5663+ String adjustedAbi;
5664+ if (requirer != null) {
5665+ // requirer != null implies that either scannedPackage was null or that scannedPackage
5666+ // did not require an ABI, in which case we have to adjust scannedPackage to match
5667+ // the ABI of the set (which is the same as requirer's ABI)
5668+ adjustedAbi = requirer.cpuAbiString;
5669+ if (scannedPackage != null) {
5670+ scannedPackage.applicationInfo.cpuAbi = adjustedAbi;
5671+ }
5672+ } else {
5673+ // requirer == null implies that we're updating all ABIs in the set to
5674+ // match scannedPackage.
5675+ adjustedAbi = scannedPackage.applicationInfo.cpuAbi;
5676+ }
5677+
56355678 for (PackageSetting ps : packagesForUser) {
5636- if (ps.cpuAbiString == null) {
5637- ps.cpuAbiString = requirer.cpuAbiString;
5638- if (ps.pkg != null) {
5639- ps.pkg.applicationInfo.cpuAbi = requirer.cpuAbiString;
5640- Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + ps.cpuAbiString);
5679+ if (scannedPackage == null || ! scannedPackage.packageName.equals(ps.name)) {
5680+ if (ps.cpuAbiString != null) {
5681+ continue;
5682+ }
56415683
5642- if (performDexOptLI(ps.pkg, forceDexOpt, deferDexOpt, true) == DEX_OPT_FAILED) {
5643- ps.cpuAbiString = null;
5644- ps.pkg.applicationInfo.cpuAbi = null;
5645- return false;
5646- } else {
5647- mInstaller.rmdex(ps.codePathString, getPreferredInstructionSet());
5648- }
5684+ ps.cpuAbiString = adjustedAbi;
5685+ ps.pkg.applicationInfo.cpuAbi = adjustedAbi;
5686+ Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
5687+
5688+ if (performDexOptLI(ps.pkg, forceDexOpt, deferDexOpt, true) == DEX_OPT_FAILED) {
5689+ ps.cpuAbiString = null;
5690+ ps.pkg.applicationInfo.cpuAbi = null;
5691+ return false;
5692+ } else {
5693+ mInstaller.rmdex(ps.codePathString, getPreferredInstructionSet());
56495694 }
56505695 }
56515696 }
0 commit comments