Loading services/core/java/com/android/server/pm/OtaDexoptService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -313,7 +313,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { optimizer.performDexOpt(pkg, libraryDependencies, optimizer.performDexOpt(pkg, libraryDependencies, null /* ISAs */, false /* checkProfiles */, null /* ISAs */, false /* checkProfiles */, getCompilerFilterForReason(compilationReason), getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */); null /* CompilerStats.PackageStats */, mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName)); return commands; return commands; } } Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +9 −39 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,9 @@ public class PackageDexOptimizer { public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_FAILED = -1; public static final int DEX_OPT_FAILED = -1; /** Special library name that skips shared libraries check during compilation. */ public static final String SKIP_SHARED_LIBRARY_CHECK = "&"; private final Installer mInstaller; private final Installer mInstaller; private final Object mInstallLock; private final Object mInstallLock; Loading Loading @@ -101,7 +104,7 @@ public class PackageDexOptimizer { */ */ int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries, int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries, String[] instructionSets, boolean checkProfiles, String targetCompilationFilter, String[] instructionSets, boolean checkProfiles, String targetCompilationFilter, CompilerStats.PackageStats packageStats) { CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) { if (!canOptimizePackage(pkg)) { if (!canOptimizePackage(pkg)) { return DEX_OPT_SKIPPED; return DEX_OPT_SKIPPED; } } Loading @@ -116,7 +119,7 @@ public class PackageDexOptimizer { } } try { try { return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles, return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles, targetCompilationFilter, packageStats); targetCompilationFilter, packageStats, isUsedByOtherApps); } finally { } finally { if (useLock) { if (useLock) { mDexoptWakeLock.release(); mDexoptWakeLock.release(); Loading @@ -132,7 +135,8 @@ public class PackageDexOptimizer { @GuardedBy("mInstallLock") @GuardedBy("mInstallLock") private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries, private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries, String[] targetInstructionSets, boolean checkForProfileUpdates, String[] targetInstructionSets, boolean checkForProfileUpdates, String targetCompilerFilter, CompilerStats.PackageStats packageStats) { String targetCompilerFilter, CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) { final String[] instructionSets = targetInstructionSets != null ? final String[] instructionSets = targetInstructionSets != null ? targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); Loading @@ -140,7 +144,7 @@ public class PackageDexOptimizer { final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, targetCompilerFilter, isUsedByOtherApps(pkg)); targetCompilerFilter, isUsedByOtherApps); final boolean profileUpdated = checkForProfileUpdates && final boolean profileUpdated = checkForProfileUpdates && isProfileUpdated(pkg, sharedGid, compilerFilter); isProfileUpdated(pkg, sharedGid, compilerFilter); Loading Loading @@ -274,7 +278,7 @@ public class PackageDexOptimizer { // TODO(calin): maybe add a separate call. // TODO(calin): maybe add a separate call. mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, /*oatDir*/ null, dexoptFlags, /*oatDir*/ null, dexoptFlags, compilerFilter, info.volumeUuid, /*sharedLibrariesPath*/ null); compilerFilter, info.volumeUuid, SKIP_SHARED_LIBRARY_CHECK); } } return DEX_OPT_PERFORMED; return DEX_OPT_PERFORMED; Loading Loading @@ -474,40 +478,6 @@ public class PackageDexOptimizer { mSystemReady = true; mSystemReady = true; } } /** * Returns true if the profiling data collected for the given app indicate * that the apps's APK has been loaded by another app. * Note that this returns false for all forward-locked apps and apps without * any collected profiling data. */ public static boolean isUsedByOtherApps(PackageParser.Package pkg) { if (pkg.isForwardLocked()) { // Skip the check for forward locked packages since they don't share their code. return false; } for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) { try { apkPath = PackageManagerServiceUtils.realpath(new File(apkPath)); } catch (IOException e) { // Log an error but continue without it. Slog.w(TAG, "Failed to get canonical path", e); continue; } String useMarker = apkPath.replace('/', '@'); final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); for (int i = 0; i < currentUserIds.length; i++) { File profileDir = Environment.getDataProfilesDeForeignDexDirectory(currentUserIds[i]); File foreignUseMark = new File(profileDir, useMarker); if (foreignUseMark.exists()) { return true; } } } return false; } private String printDexoptFlags(int flags) { private String printDexoptFlags(int flags) { ArrayList<String> flagsList = new ArrayList<>(); ArrayList<String> flagsList = new ArrayList<>(); Loading services/core/java/com/android/server/pm/PackageManagerService.java +7 −7 Original line number Original line Diff line number Diff line Loading @@ -524,9 +524,6 @@ public class PackageManagerService extends IPackageManager.Stub { public static final int REASON_LAST = REASON_CORE_APP; public static final int REASON_LAST = REASON_CORE_APP; /** Special library name that skips shared libraries check during compilation. */ private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; final ServiceThread mHandlerThread; final ServiceThread mHandlerThread; final PackageHandler mHandler; final PackageHandler mHandler; Loading Loading @@ -2272,7 +2269,7 @@ public class PackageManagerService extends IPackageManager.Stub { DEXOPT_PUBLIC, DEXOPT_PUBLIC, getCompilerFilterForReason(REASON_SHARED_APK), getCompilerFilterForReason(REASON_SHARED_APK), StorageManager.UUID_PRIVATE_INTERNAL, StorageManager.UUID_PRIVATE_INTERNAL, SKIP_SHARED_LIBRARY_CHECK); PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK); } } } catch (FileNotFoundException e) { } catch (FileNotFoundException e) { Slog.w(TAG, "Library not found: " + lib); Slog.w(TAG, "Library not found: " + lib); Loading Loading @@ -7533,11 +7530,13 @@ public class PackageManagerService extends IPackageManager.Stub { pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, false /* checkProfiles */, false /* checkProfiles */, getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), getOrCreateCompilerPackageStats(depPackage)); getOrCreateCompilerPackageStats(depPackage), mDexManager.isUsedByOtherApps(p.packageName)); } } } } return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, targetCompilerFilter, getOrCreateCompilerPackageStats(p)); targetCompilerFilter, getOrCreateCompilerPackageStats(p), mDexManager.isUsedByOtherApps(p.packageName)); } } // Performs dexopt on the used secondary dex files belonging to the given package. // Performs dexopt on the used secondary dex files belonging to the given package. Loading Loading @@ -15374,7 +15373,8 @@ public class PackageManagerService extends IPackageManager.Stub { mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, null /* instructionSets */, false /* checkProfiles */, null /* instructionSets */, false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL), getCompilerFilterForReason(REASON_INSTALL), getOrCreateCompilerPackageStats(pkg)); getOrCreateCompilerPackageStats(pkg), mDexManager.isUsedByOtherApps(pkg.packageName)); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); // Notify BackgroundDexOptService that the package has been changed. // Notify BackgroundDexOptService that the package has been changed. services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -133,7 +133,8 @@ public class PackageManagerServiceUtils { sortTemp, packageManagerService); sortTemp, packageManagerService); // Give priority to apps used by other apps. // Give priority to apps used by other apps. applyPackageFilter((pkg) -> PackageDexOptimizer.isUsedByOtherApps(pkg), result, applyPackageFilter((pkg) -> packageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), result, remainingPkgs, sortTemp, packageManagerService); remainingPkgs, sortTemp, packageManagerService); // Filter out packages that aren't recently used, add all remaining apps. // Filter out packages that aren't recently used, add all remaining apps. Loading services/core/java/com/android/server/pm/dex/DexManager.java +17 −0 Original line number Original line Diff line number Diff line Loading @@ -358,6 +358,23 @@ public class DexManager { return mPackageDexUsage.getAllPackagesWithSecondaryDexFiles(); return mPackageDexUsage.getAllPackagesWithSecondaryDexFiles(); } } /** * Return true if the profiling data collected for the given app indicate * that the apps's APK has been loaded by another app. * Note that this returns false for all apps without any collected profiling data. */ public boolean isUsedByOtherApps(String packageName) { PackageUseInfo useInfo = getPackageUseInfo(packageName); if (useInfo == null) { // No use info, means the package was not used or it was used but not by other apps. // Note that right now we might prune packages which are not used by other apps. // TODO(calin): maybe we should not (prune) so we can have an accurate view when we try // to access the package use. return false; } return useInfo.isUsedByOtherApps(); } /** /** * Retrieves the package which owns the given dexPath. * Retrieves the package which owns the given dexPath. */ */ Loading Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -313,7 +313,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { optimizer.performDexOpt(pkg, libraryDependencies, optimizer.performDexOpt(pkg, libraryDependencies, null /* ISAs */, false /* checkProfiles */, null /* ISAs */, false /* checkProfiles */, getCompilerFilterForReason(compilationReason), getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */); null /* CompilerStats.PackageStats */, mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName)); return commands; return commands; } } Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +9 −39 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,9 @@ public class PackageDexOptimizer { public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_FAILED = -1; public static final int DEX_OPT_FAILED = -1; /** Special library name that skips shared libraries check during compilation. */ public static final String SKIP_SHARED_LIBRARY_CHECK = "&"; private final Installer mInstaller; private final Installer mInstaller; private final Object mInstallLock; private final Object mInstallLock; Loading Loading @@ -101,7 +104,7 @@ public class PackageDexOptimizer { */ */ int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries, int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries, String[] instructionSets, boolean checkProfiles, String targetCompilationFilter, String[] instructionSets, boolean checkProfiles, String targetCompilationFilter, CompilerStats.PackageStats packageStats) { CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) { if (!canOptimizePackage(pkg)) { if (!canOptimizePackage(pkg)) { return DEX_OPT_SKIPPED; return DEX_OPT_SKIPPED; } } Loading @@ -116,7 +119,7 @@ public class PackageDexOptimizer { } } try { try { return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles, return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles, targetCompilationFilter, packageStats); targetCompilationFilter, packageStats, isUsedByOtherApps); } finally { } finally { if (useLock) { if (useLock) { mDexoptWakeLock.release(); mDexoptWakeLock.release(); Loading @@ -132,7 +135,8 @@ public class PackageDexOptimizer { @GuardedBy("mInstallLock") @GuardedBy("mInstallLock") private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries, private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries, String[] targetInstructionSets, boolean checkForProfileUpdates, String[] targetInstructionSets, boolean checkForProfileUpdates, String targetCompilerFilter, CompilerStats.PackageStats packageStats) { String targetCompilerFilter, CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) { final String[] instructionSets = targetInstructionSets != null ? final String[] instructionSets = targetInstructionSets != null ? targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); Loading @@ -140,7 +144,7 @@ public class PackageDexOptimizer { final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, targetCompilerFilter, isUsedByOtherApps(pkg)); targetCompilerFilter, isUsedByOtherApps); final boolean profileUpdated = checkForProfileUpdates && final boolean profileUpdated = checkForProfileUpdates && isProfileUpdated(pkg, sharedGid, compilerFilter); isProfileUpdated(pkg, sharedGid, compilerFilter); Loading Loading @@ -274,7 +278,7 @@ public class PackageDexOptimizer { // TODO(calin): maybe add a separate call. // TODO(calin): maybe add a separate call. mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, /*oatDir*/ null, dexoptFlags, /*oatDir*/ null, dexoptFlags, compilerFilter, info.volumeUuid, /*sharedLibrariesPath*/ null); compilerFilter, info.volumeUuid, SKIP_SHARED_LIBRARY_CHECK); } } return DEX_OPT_PERFORMED; return DEX_OPT_PERFORMED; Loading Loading @@ -474,40 +478,6 @@ public class PackageDexOptimizer { mSystemReady = true; mSystemReady = true; } } /** * Returns true if the profiling data collected for the given app indicate * that the apps's APK has been loaded by another app. * Note that this returns false for all forward-locked apps and apps without * any collected profiling data. */ public static boolean isUsedByOtherApps(PackageParser.Package pkg) { if (pkg.isForwardLocked()) { // Skip the check for forward locked packages since they don't share their code. return false; } for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) { try { apkPath = PackageManagerServiceUtils.realpath(new File(apkPath)); } catch (IOException e) { // Log an error but continue without it. Slog.w(TAG, "Failed to get canonical path", e); continue; } String useMarker = apkPath.replace('/', '@'); final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); for (int i = 0; i < currentUserIds.length; i++) { File profileDir = Environment.getDataProfilesDeForeignDexDirectory(currentUserIds[i]); File foreignUseMark = new File(profileDir, useMarker); if (foreignUseMark.exists()) { return true; } } } return false; } private String printDexoptFlags(int flags) { private String printDexoptFlags(int flags) { ArrayList<String> flagsList = new ArrayList<>(); ArrayList<String> flagsList = new ArrayList<>(); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +7 −7 Original line number Original line Diff line number Diff line Loading @@ -524,9 +524,6 @@ public class PackageManagerService extends IPackageManager.Stub { public static final int REASON_LAST = REASON_CORE_APP; public static final int REASON_LAST = REASON_CORE_APP; /** Special library name that skips shared libraries check during compilation. */ private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; final ServiceThread mHandlerThread; final ServiceThread mHandlerThread; final PackageHandler mHandler; final PackageHandler mHandler; Loading Loading @@ -2272,7 +2269,7 @@ public class PackageManagerService extends IPackageManager.Stub { DEXOPT_PUBLIC, DEXOPT_PUBLIC, getCompilerFilterForReason(REASON_SHARED_APK), getCompilerFilterForReason(REASON_SHARED_APK), StorageManager.UUID_PRIVATE_INTERNAL, StorageManager.UUID_PRIVATE_INTERNAL, SKIP_SHARED_LIBRARY_CHECK); PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK); } } } catch (FileNotFoundException e) { } catch (FileNotFoundException e) { Slog.w(TAG, "Library not found: " + lib); Slog.w(TAG, "Library not found: " + lib); Loading Loading @@ -7533,11 +7530,13 @@ public class PackageManagerService extends IPackageManager.Stub { pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, false /* checkProfiles */, false /* checkProfiles */, getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), getOrCreateCompilerPackageStats(depPackage)); getOrCreateCompilerPackageStats(depPackage), mDexManager.isUsedByOtherApps(p.packageName)); } } } } return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, targetCompilerFilter, getOrCreateCompilerPackageStats(p)); targetCompilerFilter, getOrCreateCompilerPackageStats(p), mDexManager.isUsedByOtherApps(p.packageName)); } } // Performs dexopt on the used secondary dex files belonging to the given package. // Performs dexopt on the used secondary dex files belonging to the given package. Loading Loading @@ -15374,7 +15373,8 @@ public class PackageManagerService extends IPackageManager.Stub { mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, null /* instructionSets */, false /* checkProfiles */, null /* instructionSets */, false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL), getCompilerFilterForReason(REASON_INSTALL), getOrCreateCompilerPackageStats(pkg)); getOrCreateCompilerPackageStats(pkg), mDexManager.isUsedByOtherApps(pkg.packageName)); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); // Notify BackgroundDexOptService that the package has been changed. // Notify BackgroundDexOptService that the package has been changed.
services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -133,7 +133,8 @@ public class PackageManagerServiceUtils { sortTemp, packageManagerService); sortTemp, packageManagerService); // Give priority to apps used by other apps. // Give priority to apps used by other apps. applyPackageFilter((pkg) -> PackageDexOptimizer.isUsedByOtherApps(pkg), result, applyPackageFilter((pkg) -> packageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), result, remainingPkgs, sortTemp, packageManagerService); remainingPkgs, sortTemp, packageManagerService); // Filter out packages that aren't recently used, add all remaining apps. // Filter out packages that aren't recently used, add all remaining apps. Loading
services/core/java/com/android/server/pm/dex/DexManager.java +17 −0 Original line number Original line Diff line number Diff line Loading @@ -358,6 +358,23 @@ public class DexManager { return mPackageDexUsage.getAllPackagesWithSecondaryDexFiles(); return mPackageDexUsage.getAllPackagesWithSecondaryDexFiles(); } } /** * Return true if the profiling data collected for the given app indicate * that the apps's APK has been loaded by another app. * Note that this returns false for all apps without any collected profiling data. */ public boolean isUsedByOtherApps(String packageName) { PackageUseInfo useInfo = getPackageUseInfo(packageName); if (useInfo == null) { // No use info, means the package was not used or it was used but not by other apps. // Note that right now we might prune packages which are not used by other apps. // TODO(calin): maybe we should not (prune) so we can have an accurate view when we try // to access the package use. return false; } return useInfo.isUsedByOtherApps(); } /** /** * Retrieves the package which owns the given dexPath. * Retrieves the package which owns the given dexPath. */ */ Loading