Loading core/java/android/os/FileUtils.java +15 −0 Original line number Diff line number Diff line Loading @@ -762,4 +762,19 @@ public class FileUtils { public static @Nullable File newFileOrNull(@Nullable String path) { return (path != null) ? new File(path) : null; } /** * Creates a directory with name {@code name} under an existing directory {@code baseDir}. * Returns a {@code File} object representing the directory on success, {@code null} on * failure. */ public static @Nullable File createDir(File baseDir, String name) { final File dir = new File(baseDir, name); if (dir.exists()) { return dir.isDirectory() ? dir : null; } return dir.mkdir() ? dir : null; } } services/core/java/com/android/server/pm/PackageManagerService.java +46 −2 Original line number Diff line number Diff line Loading @@ -102,7 +102,6 @@ import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCES import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.IActivityManager; Loading Loading @@ -566,6 +565,18 @@ public class PackageManagerService extends IPackageManager.Stub { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_NUMBER); /** * Version number for the package parser cache. Increment this whenever the format or * extent of cached data changes. See {@code PackageParser#setCacheDir}. */ private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; /** * Whether the package parser cache is enabled. */ private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = false; final ServiceThread mHandlerThread; final PackageHandler mHandler; Loading Loading @@ -804,6 +815,8 @@ public class PackageManagerService extends IPackageManager.Stub { private UserManagerInternal mUserManagerInternal; private File mCacheDir; private static class IFVerificationParams { PackageParser.Package pkg; boolean replacing; Loading Loading @@ -2353,6 +2366,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } mCacheDir = preparePackageParserCache(mIsUpgrade); // Set flag to monitor and not change apk file paths when // scanning install directories. int scanFlags = SCAN_BOOTING | SCAN_INITIAL; Loading Loading @@ -2815,6 +2830,35 @@ public class PackageManagerService extends IPackageManager.Stub { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } private static File preparePackageParserCache(boolean isUpgrade) { if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { return null; } if (SystemProperties.getBoolean("ro.boot.disable_package_cache", false)) { Slog.i(TAG, "Disabling package parser cache due to system property."); return null; } // The base directory for the package parser cache lives under /data/system/. final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), "package_cache"); if (cacheBaseDir == null) { return null; } // If this is a system upgrade scenario, delete the contents of the package cache dir. // This also serves to "GC" unused entries when the package cache version changes (which // can only happen during upgrades). if (isUpgrade) { FileUtils.deleteContents(cacheBaseDir); } // Return the versioned package cache directory. This is something like // "/data/system/package_cache/1" return FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); } @Override public boolean isFirstBoot() { return mFirstBoot; Loading Loading @@ -6938,7 +6982,7 @@ public class PackageManagerService extends IPackageManager.Stub { + " flags=0x" + Integer.toHexString(parseFlags)); } ParallelPackageParser parallelPackageParser = new ParallelPackageParser( mSeparateProcesses, mOnlyCore, mMetrics); mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir); // Submit files for parsing in parallel int fileCount = 0; Loading services/core/java/com/android/server/pm/ParallelPackageParser.java +5 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ class ParallelPackageParser implements AutoCloseable { private final String[] mSeparateProcesses; private final boolean mOnlyCore; private final DisplayMetrics mMetrics; private final File mCacheDir; private volatile String mInterruptedInThread; private final BlockingQueue<ParseResult> mQueue = new ArrayBlockingQueue<>(QUEUE_CAPACITY); Loading @@ -53,10 +54,11 @@ class ParallelPackageParser implements AutoCloseable { "package-parsing-thread", Process.THREAD_PRIORITY_FOREGROUND); ParallelPackageParser(String[] separateProcesses, boolean onlyCoreApps, DisplayMetrics metrics) { DisplayMetrics metrics, File cacheDir) { mSeparateProcesses = separateProcesses; mOnlyCore = onlyCoreApps; mMetrics = metrics; mCacheDir = cacheDir; } static class ParseResult { Loading Loading @@ -107,6 +109,7 @@ class ParallelPackageParser implements AutoCloseable { pp.setSeparateProcesses(mSeparateProcesses); pp.setOnlyCoreApps(mOnlyCore); pp.setDisplayMetrics(mMetrics); pp.setCacheDir(mCacheDir); pr.scanFile = scanFile; pr.pkg = parsePackage(pp, scanFile, parseFlags); } catch (Throwable e) { Loading @@ -129,7 +132,7 @@ class ParallelPackageParser implements AutoCloseable { @VisibleForTesting protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile, int parseFlags) throws PackageParser.PackageParserException { return packageParser.parsePackage(scanFile, parseFlags); return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */); } @Override Loading services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class ParallelPackageParserTest { class TestParallelPackageParser extends ParallelPackageParser { TestParallelPackageParser() { super(null, false, null); super(null, false, null, null); } @Override Loading Loading
core/java/android/os/FileUtils.java +15 −0 Original line number Diff line number Diff line Loading @@ -762,4 +762,19 @@ public class FileUtils { public static @Nullable File newFileOrNull(@Nullable String path) { return (path != null) ? new File(path) : null; } /** * Creates a directory with name {@code name} under an existing directory {@code baseDir}. * Returns a {@code File} object representing the directory on success, {@code null} on * failure. */ public static @Nullable File createDir(File baseDir, String name) { final File dir = new File(baseDir, name); if (dir.exists()) { return dir.isDirectory() ? dir : null; } return dir.mkdir() ? dir : null; } }
services/core/java/com/android/server/pm/PackageManagerService.java +46 −2 Original line number Diff line number Diff line Loading @@ -102,7 +102,6 @@ import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCES import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.IActivityManager; Loading Loading @@ -566,6 +565,18 @@ public class PackageManagerService extends IPackageManager.Stub { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_NUMBER); /** * Version number for the package parser cache. Increment this whenever the format or * extent of cached data changes. See {@code PackageParser#setCacheDir}. */ private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; /** * Whether the package parser cache is enabled. */ private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = false; final ServiceThread mHandlerThread; final PackageHandler mHandler; Loading Loading @@ -804,6 +815,8 @@ public class PackageManagerService extends IPackageManager.Stub { private UserManagerInternal mUserManagerInternal; private File mCacheDir; private static class IFVerificationParams { PackageParser.Package pkg; boolean replacing; Loading Loading @@ -2353,6 +2366,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } mCacheDir = preparePackageParserCache(mIsUpgrade); // Set flag to monitor and not change apk file paths when // scanning install directories. int scanFlags = SCAN_BOOTING | SCAN_INITIAL; Loading Loading @@ -2815,6 +2830,35 @@ public class PackageManagerService extends IPackageManager.Stub { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } private static File preparePackageParserCache(boolean isUpgrade) { if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { return null; } if (SystemProperties.getBoolean("ro.boot.disable_package_cache", false)) { Slog.i(TAG, "Disabling package parser cache due to system property."); return null; } // The base directory for the package parser cache lives under /data/system/. final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), "package_cache"); if (cacheBaseDir == null) { return null; } // If this is a system upgrade scenario, delete the contents of the package cache dir. // This also serves to "GC" unused entries when the package cache version changes (which // can only happen during upgrades). if (isUpgrade) { FileUtils.deleteContents(cacheBaseDir); } // Return the versioned package cache directory. This is something like // "/data/system/package_cache/1" return FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); } @Override public boolean isFirstBoot() { return mFirstBoot; Loading Loading @@ -6938,7 +6982,7 @@ public class PackageManagerService extends IPackageManager.Stub { + " flags=0x" + Integer.toHexString(parseFlags)); } ParallelPackageParser parallelPackageParser = new ParallelPackageParser( mSeparateProcesses, mOnlyCore, mMetrics); mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir); // Submit files for parsing in parallel int fileCount = 0; Loading
services/core/java/com/android/server/pm/ParallelPackageParser.java +5 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ class ParallelPackageParser implements AutoCloseable { private final String[] mSeparateProcesses; private final boolean mOnlyCore; private final DisplayMetrics mMetrics; private final File mCacheDir; private volatile String mInterruptedInThread; private final BlockingQueue<ParseResult> mQueue = new ArrayBlockingQueue<>(QUEUE_CAPACITY); Loading @@ -53,10 +54,11 @@ class ParallelPackageParser implements AutoCloseable { "package-parsing-thread", Process.THREAD_PRIORITY_FOREGROUND); ParallelPackageParser(String[] separateProcesses, boolean onlyCoreApps, DisplayMetrics metrics) { DisplayMetrics metrics, File cacheDir) { mSeparateProcesses = separateProcesses; mOnlyCore = onlyCoreApps; mMetrics = metrics; mCacheDir = cacheDir; } static class ParseResult { Loading Loading @@ -107,6 +109,7 @@ class ParallelPackageParser implements AutoCloseable { pp.setSeparateProcesses(mSeparateProcesses); pp.setOnlyCoreApps(mOnlyCore); pp.setDisplayMetrics(mMetrics); pp.setCacheDir(mCacheDir); pr.scanFile = scanFile; pr.pkg = parsePackage(pp, scanFile, parseFlags); } catch (Throwable e) { Loading @@ -129,7 +132,7 @@ class ParallelPackageParser implements AutoCloseable { @VisibleForTesting protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile, int parseFlags) throws PackageParser.PackageParserException { return packageParser.parsePackage(scanFile, parseFlags); return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */); } @Override Loading
services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ public class ParallelPackageParserTest { class TestParallelPackageParser extends ParallelPackageParser { TestParallelPackageParser() { super(null, false, null); super(null, false, null, null); } @Override Loading