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

Commit 0b0d664c authored by Pedro Loureiro's avatar Pedro Loureiro Committed by Android (Google) Code Review
Browse files

Merge "Revert framework-res splits from apexes"

parents 71cb599d ad7bf540
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -28,16 +28,16 @@ import androidx.test.filters.LargeTest
import com.android.internal.util.ConcurrentUtils
import com.android.server.pm.parsing.pkg.PackageImpl
import com.android.server.pm.pkg.parsing.ParsingPackageUtils
import java.io.File
import java.io.FileOutputStream
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit
import libcore.io.IoUtils
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.File
import java.io.FileOutputStream
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit

@LargeTest
@RunWith(Parameterized::class)
@@ -180,8 +180,8 @@ public class PackageParsingPerfTest {
        protected abstract fun parseImpl(file: File): PackageType
    }

    class ParallelParser1(private val cacher: PackageCacher1? = null)
        : ParallelParser<PackageParser.Package>(cacher) {
    class ParallelParser1(private val cacher: PackageCacher1? = null) :
        ParallelParser<PackageParser.Package>(cacher) {
        val parser = PackageParser().apply {
            setCallback { true }
        }
@@ -189,8 +189,8 @@ public class PackageParsingPerfTest {
        override fun parseImpl(file: File) = parser.parsePackage(file, 0, cacher != null)
    }

    class ParallelParser2(cacher: PackageCacher2? = null)
        : ParallelParser<PackageImpl>(cacher) {
    class ParallelParser2(cacher: PackageCacher2? = null) :
        ParallelParser<PackageImpl>(cacher) {
        val input = ThreadLocal.withInitial {
            // For testing, just disable enforcement to avoid hooking up to compat framework
            ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
@@ -218,7 +218,7 @@ public class PackageParsingPerfTest {
            })

        override fun parseImpl(file: File) =
                parser.parsePackage(input.get()!!.reset(), file, 0, null).result
                parser.parsePackage(input.get()!!.reset(), file, 0).result
                        as PackageImpl
    }

+13 −42
Original line number Diff line number Diff line
@@ -78,7 +78,6 @@ public class ApkLiteParseUtils {
    public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
    private static final int PARSE_IS_SYSTEM_DIR = 1 << 4;
    private static final int PARSE_COLLECT_CERTIFICATES = 1 << 5;
    private static final int PARSE_FRAMEWORK_RES_SPLITS = 1 << 8;
    private static final String TAG_APPLICATION = "application";
    private static final String TAG_PACKAGE_VERIFIER = "package-verifier";
    private static final String TAG_PROFILEABLE = "profileable";
@@ -103,7 +102,7 @@ public class ApkLiteParseUtils {
    public static ParseResult<PackageLite> parsePackageLite(ParseInput input,
            File packageFile, int flags) {
        if (packageFile.isDirectory()) {
            return parseClusterPackageLite(input, packageFile, /* frameworkSplits= */ null, flags);
            return parseClusterPackageLite(input, packageFile, flags);
        } else {
            return parseMonolithicPackageLite(input, packageFile, flags);
        }
@@ -137,38 +136,19 @@ public class ApkLiteParseUtils {
    /**
     * Parse lightweight details about a directory of APKs.
     *
     * @param packageDirOrApk is the folder that contains split apks for a regular app or the
     *                        framework-res.apk for framwork-res splits (in which case the
     *                        splits come in the <code>frameworkSplits</code> parameter)
     * @param packageDir is the folder that contains split apks for a regular app
     */
    public static ParseResult<PackageLite> parseClusterPackageLite(ParseInput input,
            File packageDirOrApk, List<File> frameworkSplits, int flags) {
            File packageDir, int flags) {
        final File[] files;
        final boolean parsingFrameworkSplits = (flags & PARSE_FRAMEWORK_RES_SPLITS) != 0;
        if (parsingFrameworkSplits) {
            if (ArrayUtils.isEmpty(frameworkSplits)) {
                return input.error(PackageManager.INSTALL_PARSE_FAILED_NOT_APK,
                        "No packages found in split");
            }
            files = frameworkSplits.toArray(new File[frameworkSplits.size() + 1]);
            // we also want to process the base apk so add it to the array
            files[files.length - 1] = packageDirOrApk;
        } else {
            files = packageDirOrApk.listFiles();
        files = packageDir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
            return input.error(PackageManager.INSTALL_PARSE_FAILED_NOT_APK,
                    "No packages found in split");
        }
        // Apk directory is directly nested under the current directory
        if (files.length == 1 && files[0].isDirectory()) {
                return parseClusterPackageLite(input, files[0], frameworkSplits, flags);
            }
        }

        if (parsingFrameworkSplits) {
            // disable the flag for checking the certificates of the splits. We know they
            // won't match, but we rely on the mainline apex to be safe if it was installed
            flags = flags & ~PARSE_COLLECT_CERTIFICATES;
            return parseClusterPackageLite(input, files[0], flags);
        }

        String packageName = null;
@@ -186,10 +166,6 @@ public class ApkLiteParseUtils {
                    }

                    final ApkLite lite = result.getResult();
                    if (parsingFrameworkSplits && file == files[files.length - 1]) {
                        baseApk = lite;
                        break;
                    }
                    // Assert that all package names and version codes are
                    // consistent with the first one we encounter.
                    if (packageName == null) {
@@ -201,8 +177,7 @@ public class ApkLiteParseUtils {
                                    "Inconsistent package " + lite.getPackageName() + " in " + file
                                            + "; expected " + packageName);
                        }
                        // we allow version codes that do not match for framework splits
                        if (!parsingFrameworkSplits && versionCode != lite.getVersionCode()) {
                        if (versionCode != lite.getVersionCode()) {
                            return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                    "Inconsistent version " + lite.getVersionCode() + " in " + file
                                            + "; expected " + versionCode);
@@ -217,15 +192,11 @@ public class ApkLiteParseUtils {
                    }
                }
            }
            // baseApk is set in the last iteration of the for each loop when we are parsing
            // frameworkRes splits or needs to be done now otherwise
            if (!parsingFrameworkSplits) {
            baseApk = apks.remove(null);
            }
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
        return composePackageLiteFromApks(input, packageDirOrApk, baseApk, apks);
        return composePackageLiteFromApks(input, packageDir, baseApk, apks);
    }

    /**
+8 −35
Original line number Diff line number Diff line
@@ -33,11 +33,9 @@ import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_APK_IN_APEX;
import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_FRAMEWORK_RES_SPLITS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.os.Environment;
import android.os.SystemClock;
import android.os.Trace;
@@ -121,29 +119,6 @@ final class InitAppsHelper {
        mExecutorService = ParallelPackageParser.makeExecutorService();
    }

    private List<File> getFrameworkResApkSplitFiles() {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanFrameworkResApkSplits");
        try {
            final List<File> splits = new ArrayList<>();
            final List<ApexManager.ActiveApexInfo> activeApexInfos =
                    mPm.mApexManager.getActiveApexInfos();
            for (int i = 0; i < activeApexInfos.size(); i++) {
                ApexManager.ActiveApexInfo apexInfo = activeApexInfos.get(i);
                File splitsFolder = new File(apexInfo.apexDirectory, "etc/splits");
                if (splitsFolder.isDirectory()) {
                    for (File file : splitsFolder.listFiles()) {
                        if (ApkLiteParseUtils.isApkFile(file)) {
                            splits.add(file);
                        }
                    }
                }
            }
            return splits;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    private List<ScanPartition> getSystemScanPartitions() {
        final List<ScanPartition> scanPartitions = new ArrayList<>();
        scanPartitions.addAll(mSystemPartitions);
@@ -270,7 +245,7 @@ final class InitAppsHelper {
            long startTime) {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());
        scanDirTracedLI(mPm.getAppInstallDir(), /* frameworkSplits= */ null, 0,
        scanDirTracedLI(mPm.getAppInstallDir(), 0,
                mScanFlags | SCAN_REQUIRE_KNOWN, packageParser, mExecutorService);

        List<Runnable> unfinishedTasks = mExecutorService.shutdownNow();
@@ -338,15 +313,13 @@ final class InitAppsHelper {
            if (partition.getOverlayFolder() == null) {
                continue;
            }
            scanDirTracedLI(partition.getOverlayFolder(), /* frameworkSplits= */ null,
            scanDirTracedLI(partition.getOverlayFolder(),
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService);
        }

        List<File> frameworkSplits = getFrameworkResApkSplitFiles();
        scanDirTracedLI(frameworkDir, frameworkSplits,
                mSystemParseFlags | PARSE_FRAMEWORK_RES_SPLITS,
                mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
        scanDirTracedLI(frameworkDir,
                mSystemParseFlags, mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
                packageParser, executorService);
        if (!mPm.mPackages.containsKey("android")) {
            throw new IllegalStateException(
@@ -356,12 +329,12 @@ final class InitAppsHelper {
        for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
            final ScanPartition partition = mDirsToScanAsSystem.get(i);
            if (partition.getPrivAppFolder() != null) {
                scanDirTracedLI(partition.getPrivAppFolder(), /* frameworkSplits= */ null,
                scanDirTracedLI(partition.getPrivAppFolder(),
                        mSystemParseFlags,
                        mSystemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag,
                        packageParser, executorService);
            }
            scanDirTracedLI(partition.getAppFolder(), /* frameworkSplits= */ null,
            scanDirTracedLI(partition.getAppFolder(),
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService);
        }
@@ -379,7 +352,7 @@ final class InitAppsHelper {
    }

    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
    private void scanDirTracedLI(File scanDir,
            int parseFlags, int scanFlags,
            PackageParser2 packageParser, ExecutorService executorService) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
@@ -388,7 +361,7 @@ final class InitAppsHelper {
                // when scanning apk in apexes, we want to check the maxSdkVersion
                parseFlags |= PARSE_APK_IN_APEX;
            }
            mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
            mInstallPackageHelper.installPackagesFromDir(scanDir, parseFlags,
                    scanFlags, packageParser, executorService);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+2 −2
Original line number Diff line number Diff line
@@ -3472,7 +3472,7 @@ final class InstallPackageHelper {
    }

    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags,
    public void installPackagesFromDir(File scanDir, int parseFlags,
            int scanFlags, PackageParser2 packageParser,
            ExecutorService executorService) {
        final File[] files = scanDir.listFiles();
@@ -3486,7 +3486,7 @@ final class InstallPackageHelper {
                    + " flags=0x" + Integer.toHexString(parseFlags));
        }
        ParallelPackageParser parallelPackageParser =
                new ParallelPackageParser(packageParser, executorService, frameworkSplits);
                new ParallelPackageParser(packageParser, executorService);

        // Submit files for parsing in parallel
        int fileCount = 0;
+1 −10
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.ParsedPackage;

import java.io.File;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
@@ -55,17 +54,9 @@ class ParallelPackageParser {

    private final ExecutorService mExecutorService;

    private final List<File> mFrameworkSplits;

    ParallelPackageParser(PackageParser2 packageParser, ExecutorService executorService) {
        this(packageParser, executorService, /* frameworkSplits= */ null);
    }

    ParallelPackageParser(PackageParser2 packageParser, ExecutorService executorService,
            List<File> frameworkSplits) {
        mPackageParser = packageParser;
        mExecutorService = executorService;
        mFrameworkSplits = frameworkSplits;
    }

    static class ParseResult {
@@ -134,6 +125,6 @@ class ParallelPackageParser {
    @VisibleForTesting
    protected ParsedPackage parsePackage(File scanFile, int parseFlags)
            throws PackageManagerException {
        return mPackageParser.parsePackage(scanFile, parseFlags, true, mFrameworkSplits);
        return mPackageParser.parsePackage(scanFile, parseFlags, true);
    }
}
Loading