Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 772c1178 authored by Ivan Chiang's avatar Ivan Chiang
Browse files

[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
parent 15d68f41
Loading
Loading
Loading
Loading
+27 −22
Original line number Diff line number Diff line
@@ -1509,7 +1509,9 @@ 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) {
@@ -1520,11 +1522,13 @@ final class InstallPackageHelper {
                    final String abiOverride = deriveAbiOverride(request.getAbiOverride());

                    // TODO: Are these system flags actually set properly at this stage?
                boolean isUpdatedSystemAppInferred = pkgSetting != null && pkgSetting.isSystem();
                    boolean isUpdatedSystemAppInferred =
                            pkgSetting != null && pkgSetting.isSystem();
                    final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                        derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, systemApp,
                        isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
                        abiOverride, ScanPackageUtils.getAppLib32InstallDir());
                            derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage,
                            systemApp, (isUpdatedSystemAppFromExistingSetting
                                    || isUpdatedSystemAppInferred), abiOverride,
                            ScanPackageUtils.getAppLib32InstallDir());
                    derivedAbi.first.applyTo(parsedPackage);
                    derivedAbi.second.applyTo(parsedPackage);
                } catch (PackageManagerException pme) {
@@ -1534,6 +1538,7 @@ final class InstallPackageHelper {
                            PackageManagerException.INTERNAL_ERROR_DERIVING_ABI);
                }
            }
        }

        if (!isApex) {
            doRenameLI(request, parsedPackage);
+72 −63
Original line number Diff line number Diff line
@@ -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,6 +282,9 @@ final class ScanPackageUtils {
        final boolean isUpdatedSystemApp = pkgSetting.isUpdatedSystemApp();

        final File appLib32InstallDir = getAppLib32InstallDir();
        // 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");
@@ -301,15 +307,16 @@ final class ScanPackageUtils {
                    // 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);
                    String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(
                            parsedPackage);
                    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);
                                packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
                                        isSystemApp, isUpdatedSystemApp, appLib32InstallDir);
                        nativeLibraryPaths.applyTo(parsedPackage);
                    }
                } else {
@@ -334,9 +341,10 @@ final class ScanPackageUtils {
                }
            } 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.
                    // 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());
                }
@@ -359,6 +367,7 @@ final class ScanPackageUtils {
                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
        // and the abiOverride specified for the install. Warn about this because we
+41 −0
Original line number Diff line number Diff line
@@ -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 =