diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 7d4776285db08..13fd2f2616523 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -1509,29 +1509,34 @@ final class InstallPackageHelper { } else { // Enable SCAN_NO_DEX flag to skip dexopt at a later stage scanFlags |= SCAN_NO_DEX; + // The native libs of Apex is located in apex_payload.img, don't need to parse it from + // the original apex file + if (!isApex) { + try { + PackageSetting pkgSetting; + synchronized (mPm.mLock) { + pkgSetting = mPm.mSettings.getPackageLPr(pkgName); + } + boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null + && pkgSetting.isUpdatedSystemApp(); + final String abiOverride = deriveAbiOverride(request.getAbiOverride()); - try { - PackageSetting pkgSetting; - synchronized (mPm.mLock) { - pkgSetting = mPm.mSettings.getPackageLPr(pkgName); + // TODO: Are these system flags actually set properly at this stage? + boolean isUpdatedSystemAppInferred = + pkgSetting != null && pkgSetting.isSystem(); + final Pair + derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, + systemApp, (isUpdatedSystemAppFromExistingSetting + || isUpdatedSystemAppInferred), abiOverride, + ScanPackageUtils.getAppLib32InstallDir()); + derivedAbi.first.applyTo(parsedPackage); + derivedAbi.second.applyTo(parsedPackage); + } catch (PackageManagerException pme) { + Slog.e(TAG, "Error deriving application ABI", pme); + throw PrepareFailure.ofInternalError( + "Error deriving application ABI: " + pme.getMessage(), + PackageManagerException.INTERNAL_ERROR_DERIVING_ABI); } - boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null - && pkgSetting.isUpdatedSystemApp(); - final String abiOverride = deriveAbiOverride(request.getAbiOverride()); - - // TODO: Are these system flags actually set properly at this stage? - boolean isUpdatedSystemAppInferred = pkgSetting != null && pkgSetting.isSystem(); - final Pair - derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, systemApp, - isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred, - abiOverride, ScanPackageUtils.getAppLib32InstallDir()); - derivedAbi.first.applyTo(parsedPackage); - derivedAbi.second.applyTo(parsedPackage); - } catch (PackageManagerException pme) { - Slog.e(TAG, "Error deriving application ABI", pme); - throw PrepareFailure.ofInternalError( - "Error deriving application ABI: " + pme.getMessage(), - PackageManagerException.INTERNAL_ERROR_DERIVING_ABI); } } diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java index 80277d5c97757..1cd44e62e1f57 100644 --- a/services/core/java/com/android/server/pm/ScanPackageUtils.java +++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java @@ -149,6 +149,8 @@ final class ScanPackageUtils { String primaryCpuAbiFromSettings = null; String secondaryCpuAbiFromSettings = null; boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; + boolean isApex = (scanFlags & SCAN_AS_APEX) != 0; + if (!needToDeriveAbi) { if (pkgSetting != null) { // TODO(b/154610922): if it is not first boot or upgrade, we should directly use @@ -240,6 +242,7 @@ final class ScanPackageUtils { usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(), newDomainSetId); } + if (createNewPackage && originalPkgSetting != null) { // This is the initial transition from the original package, so, // fix up the new package's name now. We must do this after looking @@ -279,85 +282,91 @@ final class ScanPackageUtils { final boolean isUpdatedSystemApp = pkgSetting.isUpdatedSystemApp(); final File appLib32InstallDir = getAppLib32InstallDir(); - if ((scanFlags & SCAN_NEW_INSTALL) == 0) { - if (needToDeriveAbi) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); - try { - final Pair - derivedAbi = - packageAbiHelper.derivePackageAbi( - parsedPackage, - isSystemApp, - isUpdatedSystemApp, - cpuAbiOverride, - appLib32InstallDir); - derivedAbi.first.applyTo(parsedPackage); - derivedAbi.second.applyTo(parsedPackage); - } finally { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } + // The native libs of Apex is located in apex_payload.img, don't need to parse it from + // the original apex file + if (!isApex) { + if ((scanFlags & SCAN_NEW_INSTALL) == 0) { + if (needToDeriveAbi) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); + try { + final Pair + derivedAbi = + packageAbiHelper.derivePackageAbi( + parsedPackage, + isSystemApp, + isUpdatedSystemApp, + cpuAbiOverride, + appLib32InstallDir); + derivedAbi.first.applyTo(parsedPackage); + derivedAbi.second.applyTo(parsedPackage); + } finally { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } - // Some system apps still use directory structure for native libraries - // in which case we might end up not detecting abi solely based on apk - // structure. Try to detect abi based on directory structure. + // Some system apps still use directory structure for native libraries + // in which case we might end up not detecting abi solely based on apk + // structure. Try to detect abi based on directory structure. - String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage); - if (isSystemApp && !isUpdatedSystemApp && pkgRawPrimaryCpuAbi == null) { - final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis( + String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi( parsedPackage); - abis.applyTo(parsedPackage); - abis.applyTo(pkgSetting); + if (isSystemApp && !isUpdatedSystemApp && pkgRawPrimaryCpuAbi == null) { + final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis( + parsedPackage); + abis.applyTo(parsedPackage); + abis.applyTo(pkgSetting); + final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = + packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, + isSystemApp, isUpdatedSystemApp, appLib32InstallDir); + nativeLibraryPaths.applyTo(parsedPackage); + } + } else { + // This is not a first boot or an upgrade, don't bother deriving the + // ABI during the scan. Instead, trust the value that was stored in the + // package setting. + parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings) + .setSecondaryCpuAbi(secondaryCpuAbiFromSettings); + final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp, isUpdatedSystemApp, appLib32InstallDir); nativeLibraryPaths.applyTo(parsedPackage); + + if (DEBUG_ABI_SELECTION) { + Slog.i(TAG, "Using ABIS and native lib paths from settings : " + + parsedPackage.getPackageName() + " " + + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) + + ", " + + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage)); + } } } else { - // This is not a first boot or an upgrade, don't bother deriving the - // ABI during the scan. Instead, trust the value that was stored in the - // package setting. - parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings) - .setSecondaryCpuAbi(secondaryCpuAbiFromSettings); + if ((scanFlags & SCAN_MOVE) != 0) { + // We haven't run dex-opt for this move (since we've moved the compiled output + // too) but we already have this packages package info in the PackageSetting. + // We just use that and derive the native library path based on the new code + // path. + parsedPackage.setPrimaryCpuAbi(pkgSetting.getPrimaryCpuAbiLegacy()) + .setSecondaryCpuAbi(pkgSetting.getSecondaryCpuAbiLegacy()); + } + // Set native library paths again. For moves, the path will be updated based on the + // ABIs we've determined above. For non-moves, the path will be updated based on the + // ABIs we determined during compilation, but the path will depend on the final + // package path (after the rename away from the stage path). final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp, isUpdatedSystemApp, appLib32InstallDir); nativeLibraryPaths.applyTo(parsedPackage); - - if (DEBUG_ABI_SELECTION) { - Slog.i(TAG, "Using ABIS and native lib paths from settings : " - + parsedPackage.getPackageName() + " " - + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) - + ", " - + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage)); - } - } - } else { - if ((scanFlags & SCAN_MOVE) != 0) { - // We haven't run dex-opt for this move (since we've moved the compiled output too) - // but we already have this packages package info in the PackageSetting. We just - // use that and derive the native library path based on the new code path. - parsedPackage.setPrimaryCpuAbi(pkgSetting.getPrimaryCpuAbiLegacy()) - .setSecondaryCpuAbi(pkgSetting.getSecondaryCpuAbiLegacy()); } - // Set native library paths again. For moves, the path will be updated based on the - // ABIs we've determined above. For non-moves, the path will be updated based on the - // ABIs we determined during compilation, but the path will depend on the final - // package path (after the rename away from the stage path). - final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = - packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp, - isUpdatedSystemApp, appLib32InstallDir); - nativeLibraryPaths.applyTo(parsedPackage); - } - - // This is a special case for the "system" package, where the ABI is - // dictated by the zygote configuration (and init.rc). We should keep track - // of this ABI so that we can deal with "normal" applications that run under - // the same UID correctly. - if (isPlatformPackage) { - parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() - ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]); + // This is a special case for the "system" package, where the ABI is + // dictated by the zygote configuration (and init.rc). We should keep track + // of this ABI so that we can deal with "normal" applications that run under + // the same UID correctly. + if (isPlatformPackage) { + parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() + ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]); + } } // If there's a mismatch between the abi-override in the package setting diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java index b5bd86978455f..e2939c1aff3b5 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java @@ -21,6 +21,7 @@ import static android.content.pm.SharedLibraryInfo.TYPE_SDK_PACKAGE; import static android.content.pm.SharedLibraryInfo.TYPE_STATIC; import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED; +import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX; import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE; @@ -364,6 +365,46 @@ public class ScanTests { assertThat(scanResult.mPkgSetting.getVolumeUuid(), is(UUID_TWO.toString())); } + @Test + public void scanFirstBoot_apexDontDeriveAbis() throws Exception { + final PackageSetting pkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setPkgFlags(ApplicationInfo.FLAG_SYSTEM).build(); + + final String codePath = "/data/apex/" + DUMMY_PACKAGE_NAME + ".apex"; + + // Create the ParsedPackage for the apex + final ParsedPackage basicPackage = + ((ParsedPackage) new PackageImpl(DUMMY_PACKAGE_NAME, codePath, codePath, + mock(TypedArray.class), false) + .setVolumeUuid(UUID_ONE.toString()) + .hideAsParsed()) + .setVersionCodeMajor(1) + .setVersionCode(2345) + .setSystem(true); + + when(mMockInjector.getAbiHelper()).thenReturn(new PackageAbiHelperImpl()); + + // prepare the scan request with the scanflag (SCAN_FIRST_BOOT_OR_UPGRADE | SCAN_AS_APEX) + final ScanResult scanResult = executeScan(new ScanRequestBuilder(basicPackage) + .setPkgSetting(pkgSetting) + .addScanFlag(SCAN_FIRST_BOOT_OR_UPGRADE | SCAN_AS_APEX) + .build()); + + final PackageSetting resultSetting = scanResult.mPkgSetting; + final ApplicationInfo applicationInfo = PackageInfoUtils.generateApplicationInfo( + resultSetting.getPkg(), 0, pkgSetting.getUserStateOrDefault(0), 0, resultSetting); + assertThat(applicationInfo.primaryCpuAbi, nullValue()); + assertThat(applicationInfo.primaryCpuAbi, nullValue()); + assertThat(applicationInfo.secondaryCpuAbi, nullValue()); + + assertThat(applicationInfo.nativeLibraryRootDir, nullValue()); + assertThat(pkgSetting.getLegacyNativeLibraryPath(), nullValue()); + assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(false)); + assertThat(applicationInfo.nativeLibraryDir, nullValue()); + assertThat(applicationInfo.secondaryNativeLibraryDir, nullValue()); + } + @Test public void scanFirstBoot_derivesAbis() throws Exception { final PackageSetting pkgSetting =