Merge "[pm] Skip parsing abis from the apex file in scan flow" into main
This commit is contained in:
@@ -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<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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user