summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ivan Chiang <chiangi@google.com> 2023-07-14 09:35:57 +0000
committer Ivan Chiang <chiangi@google.com> 2023-07-15 01:13:25 +0000
commit772c11783cd0dc6c26c6c6fa65ab06db76cbec4b (patch)
tree06acd2913f6535726392be6d8ab4a801531c3b9c
parent15d68f4163b7a4a5a5de9e24fade6729a0721fc3 (diff)
[pm] Skip parsing abis from the apex file in scan flow
From U, We merged the APK and APEX scan flows so that they run the same code branch, rather than having ApexManager maintain a separate parsing implementation. For parsing the abis in scan flow, because the native libs of an Apex is located in apex_payload.img, don't need to parse it from the original apex file when scanning the apex file. Test: atest ScanTests#scanFirstBoot_apexDontDeriveAbis --iterations 100 Test: atest ScanTests --iterations 100 Test: Manual. run atest BootTest, verified the logs Bug: 288167712 Change-Id: I3bd0d8250fd27e1aff2a16bef1495f1c9cfba472
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java49
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java135
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java41
3 files changed, 140 insertions, 85 deletions
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 7d4776285db0..13fd2f261652 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;
-
- try {
- PackageSetting pkgSetting;
- synchronized (mPm.mLock) {
- pkgSetting = mPm.mSettings.getPackageLPr(pkgName);
+ // 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());
+
+ // TODO: Are these system flags actually set properly at this stage?
+ boolean isUpdatedSystemAppInferred =
+ pkgSetting != null && pkgSetting.isSystem();
+ final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
+ 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<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
- 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 80277d5c9775..1cd44e62e1f5 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<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
- 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<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
+ 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 b5bd86978455..e2939c1aff3b 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;
@@ -365,6 +366,46 @@ public class ScanTests {
}
@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 =
createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build();