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

Commit b1b3c303 authored by Patrick Baumann's avatar Patrick Baumann
Browse files

Refactors initial directory scan to be dryer

This change collapses a bunch of manual calls to scanDir with a map and
a loop. This makes things a little more readable and easier to update
going forward.

Bug: NA
Test: boots without issue.
Change-Id: I81fb7a9474894d0bceecb6b0ef7a64d047a40c14
parent a486c752
Loading
Loading
Loading
Loading
+117 −368
Original line number Original line Diff line number Diff line
@@ -581,16 +581,6 @@ public class PackageManagerService extends IPackageManager.Stub
    private static final String PACKAGE_SCHEME = "package";
    private static final String PACKAGE_SCHEME = "package";
    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
    private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
    private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
    private static final String ODM_OVERLAY_DIR = "/odm/overlay";
    private static final String OEM_OVERLAY_DIR = "/oem/overlay";
    /** Canonical intent used to identify what counts as a "web browser" app */
    /** Canonical intent used to identify what counts as a "web browser" app */
    private static final Intent sBrowserIntent;
    private static final Intent sBrowserIntent;
    static {
    static {
@@ -755,6 +745,26 @@ public class PackageManagerService extends IPackageManager.Stub
    private final Injector mInjector;
    private final Injector mInjector;
    /**
     * The list of all system partitions that may contain packages in ascending order of
     * specificity (the more generic, the earlier in the list a partition appears).
     */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    static final List<SystemPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
            Arrays.asList(
                    new SystemPartition(Environment.getRootDirectory(), 0 /* scanFlag */,
                            true /* hasPriv */, false /* hasOverlays */),
                    new SystemPartition(Environment.getVendorDirectory(), SCAN_AS_VENDOR,
                            true /* hasPriv */, true /* hasOverlays */),
                    new SystemPartition(Environment.getOdmDirectory(), SCAN_AS_ODM,
                            true /* hasPriv */, true /* hasOverlays */),
                    new SystemPartition(Environment.getOemDirectory(), SCAN_AS_OEM,
                            false /* hasPriv */, true /* hasOverlays */),
                    new SystemPartition(Environment.getProductDirectory(), SCAN_AS_PRODUCT,
                            true /* hasPriv */, true /* hasOverlays */),
                    new SystemPartition(Environment.getSystemExtDirectory(), SCAN_AS_SYSTEM_EXT,
                            true /* hasPriv */, true /* hasOverlays */)));
    /**
    /**
     * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
     * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
     *
     *
@@ -2552,6 +2562,51 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        }
    }
    }
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    static class SystemPartition {
        public final File folder;
        public final int scanFlag;
        public final File appFolder;
        @Nullable
        public final File privAppFolder;
        @Nullable
        public final File overlayFolder;
        private SystemPartition(File folder, int scanFlag, boolean hasPrivApps,
                boolean hasOverlays) {
            this.folder = folder;
            this.scanFlag = scanFlag;
            this.appFolder = toCanonical(new File(folder, "app"));
            this.privAppFolder = hasPrivApps ? toCanonical(new File(folder, "priv-app")) : null;
            this.overlayFolder = hasOverlays ? toCanonical(new File(folder, "overlay")) : null;
        }
        public boolean containsPrivApp(File scanFile) {
            return FileUtils.contains(privAppFolder, scanFile);
        }
        public boolean containsApp(File scanFile) {
            return FileUtils.contains(appFolder, scanFile);
        }
        public boolean containsPath(String path) {
            return path.startsWith(folder.getPath() + "/");
        }
        public boolean containsPrivPath(String path) {
            return privAppFolder != null && path.startsWith(privAppFolder.getPath() + "/");
        }
        private static File toCanonical(File dir) {
            try {
                return dir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
                return dir;
            }
        }
    }
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
                Trace.TRACE_TAG_PACKAGE_MANAGER);
@@ -2775,215 +2830,35 @@ public class PackageManagerService extends IPackageManager.Stub
            // any apps.)
            // any apps.)
            // For security and version matching reason, only consider overlay packages if they
            // For security and version matching reason, only consider overlay packages if they
            // reside in the right directory.
            // reside in the right directory.
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
            final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
                    mDefParseFlags
            final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
            for (int i = SYSTEM_PARTITIONS.size() - 1; i >= 0; i--) {
                    scanFlags
                final SystemPartition partition = SYSTEM_PARTITIONS.get(i);
                    | SCAN_AS_SYSTEM
                if (partition.overlayFolder == null) {
                    | SCAN_AS_VENDOR,
                    continue;
                    0);
                }
            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
                scanDirTracedLI(partition.overlayFolder, systemParseFlags,
                    mDefParseFlags
                        systemScanFlags | partition.scanFlag, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
            }
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT,
                    0);
            scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_SYSTEM_EXT,
                    0);
            scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_ODM,
                    0);
            scanDirTracedLI(new File(OEM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_OEM,
                    0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
            mParallelPackageParserCallback.findStaticOverlayPackages();
            // Find base frameworks (resource packages without code).
            scanDirTracedLI(frameworkDir, systemParseFlags,
            scanDirTracedLI(frameworkDir,
                    systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0);
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_NO_DEX
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRIVILEGED,
                    0);
            if (!mPackages.containsKey("android")) {
            if (!mPackages.containsKey("android")) {
                throw new IllegalStateException(
                throw new IllegalStateException(
                        "Failed to load frameworks package; check log for warnings");
                        "Failed to load frameworks package; check log for warnings");
            }
            }
            for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
            // Collect privileged system packages.
                final SystemPartition partition = SYSTEM_PARTITIONS.get(i);
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
                if (partition.privAppFolder != null) {
            scanDirTracedLI(privilegedAppDir,
                    scanDirTracedLI(partition.privAppFolder, systemParseFlags,
                    mDefParseFlags
                            systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRIVILEGED,
                    0);
            // Collect ordinary system packages.
            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
            scanDirTracedLI(systemAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM,
                    0);
            // Collect privileged vendor packages.
            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
            try {
                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedVendorAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR
                    | SCAN_AS_PRIVILEGED,
                    0);
            // Collect ordinary vendor packages.
            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
            try {
                vendorAppDir = vendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(vendorAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);
            // Collect privileged odm packages. /odm is another vendor partition
            // other than /vendor.
            File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
                        "priv-app");
            try {
                privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
                }
                }
            scanDirTracedLI(privilegedOdmAppDir,
                scanDirTracedLI(partition.appFolder, systemParseFlags,
                    mDefParseFlags
                        systemScanFlags | partition.scanFlag, 0);
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR
                    | SCAN_AS_PRIVILEGED,
                    0);
            // Collect ordinary odm packages. /odm is another vendor partition
            // other than /vendor.
            File odmAppDir = new File(Environment.getOdmDirectory(), "app");
            try {
                odmAppDir = odmAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            }
            scanDirTracedLI(odmAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);
            // Collect all OEM packages.
            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
            scanDirTracedLI(oemAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_OEM,
                    0);
            // Collected privileged /product packages.
            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
            try {
                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedProductAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT
                    | SCAN_AS_PRIVILEGED,
                    0);
            // Collect ordinary /product packages.
            File productAppDir = new File(Environment.getProductDirectory(), "app");
            try {
                productAppDir = productAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(productAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT,
                    0);
            // Collected privileged /system_ext packages.
            File privilegedSystemExtAppDir =
                    new File(Environment.getSystemExtDirectory(), "priv-app");
            try {
                privilegedSystemExtAppDir =
                        privilegedSystemExtAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(privilegedSystemExtAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_SYSTEM_EXT
                    | SCAN_AS_PRIVILEGED,
                    0);
            // Collect ordinary /system_ext packages.
            File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
            try {
                systemExtAppDir = systemExtAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            scanDirTracedLI(systemExtAppDir,
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_SYSTEM_EXT,
                    0);
            // Prune any system packages that no longer exist.
            // Prune any system packages that no longer exist.
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
@@ -3151,89 +3026,26 @@ public class PackageManagerService extends IPackageManager.Stub
                        logCriticalInfo(Log.WARN, "Expected better " + packageName
                        logCriticalInfo(Log.WARN, "Expected better " + packageName
                                + " but never showed up; reverting to system");
                                + " but never showed up; reverting to system");
                        final @ParseFlags int reparseFlags;
                        @ParseFlags int reparseFlags = 0;
                        final @ScanFlags int rescanFlags;
                        @ScanFlags int rescanFlags = 0;
                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
                        for (int i1 = 0, size = SYSTEM_PARTITIONS.size(); i1 < size; i1++) {
                            reparseFlags =
                            SystemPartition partition = SYSTEM_PARTITIONS.get(i1);
                                    mDefParseFlags |
                            if (partition.containsPrivApp(scanFile)) {
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                                reparseFlags = systemParseFlags;
                            rescanFlags =
                                rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
                                    scanFlags
                                        | partition.scanFlag;
                                    | SCAN_AS_SYSTEM
                                break;
                                    | SCAN_AS_PRIVILEGED;
                            }
                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
                            if (partition.containsApp(scanFile)) {
                            reparseFlags =
                                reparseFlags = systemParseFlags;
                                    mDefParseFlags |
                                rescanFlags = systemScanFlags | partition.scanFlag;
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                                break;
                            rescanFlags =
                            }
                                    scanFlags
                        }
                                    | SCAN_AS_SYSTEM;
                        if (rescanFlags == 0) {
                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
                                || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_VENDOR
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(vendorAppDir, scanFile)
                                || FileUtils.contains(odmAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_VENDOR;
                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_OEM;
                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(productAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT;
                        } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_SYSTEM_EXT
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_SYSTEM_EXT;
                        } else {
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            continue;
                            continue;
                        }
                        }
                        mSettings.enableSystemPackageLPw(packageName);
                        mSettings.enableSystemPackageLPw(packageName);
                        try {
                        try {
@@ -18080,70 +17892,15 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    }
    static boolean locationIsPrivileged(String path) {
    static boolean locationIsPrivileged(String path) {
        try {
        for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            SystemPartition partition = SYSTEM_PARTITIONS.get(i);
            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
            if (partition.containsPrivPath(path)) {
            final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
                return true;
            final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
            final File privilegedSystemExtAppDir =
                    new File(Environment.getSystemExtDirectory(), "priv-app");
            return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
                    || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
                    || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
                    || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        return false;
    }
    static boolean locationIsOem(String path) {
        try {
            return path.startsWith(Environment.getOemDirectory().getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        return false;
    }
    static boolean locationIsVendor(String path) {
        try {
            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath() + "/")
                    || path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        return false;
    }
    static boolean locationIsProduct(String path) {
        try {
            return path.startsWith(Environment.getProductDirectory().getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        return false;
            }
            }
    static boolean locationIsSystemExt(String path) {
        try {
            return path.startsWith(
              Environment.getSystemExtDirectory().getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        }
        return false;
        return false;
    }
    }
    static boolean locationIsOdm(String path) {
        try {
            return path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
        } catch (IOException e) {
            Slog.e(TAG, "Unable to access code path " + path);
        }
        return false;
    }
    /*
    /*
     * Tries to delete system package.
     * Tries to delete system package.
@@ -18254,23 +18011,15 @@ public class PackageManagerService extends IPackageManager.Stub
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_IS_SYSTEM_DIR;
                | PackageParser.PARSE_IS_SYSTEM_DIR;
        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
        if (locationIsPrivileged(codePathString)) {
        for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
            SystemPartition partition = SYSTEM_PARTITIONS.get(i);
            if (partition.containsPath(codePathString)) {
                scanFlags |= partition.scanFlag;
                if (partition.containsPrivPath(codePathString)) {
                    scanFlags |= SCAN_AS_PRIVILEGED;
                    scanFlags |= SCAN_AS_PRIVILEGED;
                }
                }
        if (locationIsOem(codePathString)) {
                break;
            scanFlags |= SCAN_AS_OEM;
        }
        if (locationIsVendor(codePathString)) {
            scanFlags |= SCAN_AS_VENDOR;
        }
        if (locationIsProduct(codePathString)) {
            scanFlags |= SCAN_AS_PRODUCT;
        }
        if (locationIsSystemExt(codePathString)) {
            scanFlags |= SCAN_AS_SYSTEM_EXT;
            }
            }
        if (locationIsOdm(codePathString)) {
            scanFlags |= SCAN_AS_ODM;
        }
        }
        final File codePath = new File(codePathString);
        final File codePath = new File(codePathString);
+9 −6

File changed.

Preview size limit exceeded, changes collapsed.