Merge changes from topic 'secondary-dex1'
* changes: Use DexManager logic to decide if a package is used by other apps Skip class path checking for secondary dex files
This commit is contained in:
@@ -313,7 +313,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
|
||||
optimizer.performDexOpt(pkg, libraryDependencies,
|
||||
null /* ISAs */, false /* checkProfiles */,
|
||||
getCompilerFilterForReason(compilationReason),
|
||||
null /* CompilerStats.PackageStats */);
|
||||
null /* CompilerStats.PackageStats */,
|
||||
mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName));
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ public class PackageDexOptimizer {
|
||||
public static final int DEX_OPT_PERFORMED = 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 Object mInstallLock;
|
||||
|
||||
@@ -101,7 +104,7 @@ public class PackageDexOptimizer {
|
||||
*/
|
||||
int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
|
||||
String[] instructionSets, boolean checkProfiles, String targetCompilationFilter,
|
||||
CompilerStats.PackageStats packageStats) {
|
||||
CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) {
|
||||
if (!canOptimizePackage(pkg)) {
|
||||
return DEX_OPT_SKIPPED;
|
||||
}
|
||||
@@ -116,7 +119,7 @@ public class PackageDexOptimizer {
|
||||
}
|
||||
try {
|
||||
return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
|
||||
targetCompilationFilter, packageStats);
|
||||
targetCompilationFilter, packageStats, isUsedByOtherApps);
|
||||
} finally {
|
||||
if (useLock) {
|
||||
mDexoptWakeLock.release();
|
||||
@@ -132,7 +135,8 @@ public class PackageDexOptimizer {
|
||||
@GuardedBy("mInstallLock")
|
||||
private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
|
||||
String[] targetInstructionSets, boolean checkForProfileUpdates,
|
||||
String targetCompilerFilter, CompilerStats.PackageStats packageStats) {
|
||||
String targetCompilerFilter, CompilerStats.PackageStats packageStats,
|
||||
boolean isUsedByOtherApps) {
|
||||
final String[] instructionSets = targetInstructionSets != null ?
|
||||
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
|
||||
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
|
||||
@@ -140,7 +144,7 @@ public class PackageDexOptimizer {
|
||||
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
|
||||
|
||||
final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
|
||||
targetCompilerFilter, isUsedByOtherApps(pkg));
|
||||
targetCompilerFilter, isUsedByOtherApps);
|
||||
final boolean profileUpdated = checkForProfileUpdates &&
|
||||
isProfileUpdated(pkg, sharedGid, compilerFilter);
|
||||
|
||||
@@ -274,7 +278,7 @@ public class PackageDexOptimizer {
|
||||
// TODO(calin): maybe add a separate call.
|
||||
mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0,
|
||||
/*oatDir*/ null, dexoptFlags,
|
||||
compilerFilter, info.volumeUuid, /*sharedLibrariesPath*/ null);
|
||||
compilerFilter, info.volumeUuid, SKIP_SHARED_LIBRARY_CHECK);
|
||||
}
|
||||
|
||||
return DEX_OPT_PERFORMED;
|
||||
@@ -474,40 +478,6 @@ public class PackageDexOptimizer {
|
||||
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) {
|
||||
ArrayList<String> flagsList = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -524,9 +524,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
|
||||
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 PackageHandler mHandler;
|
||||
@@ -2260,7 +2257,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
DEXOPT_PUBLIC,
|
||||
getCompilerFilterForReason(REASON_SHARED_APK),
|
||||
StorageManager.UUID_PRIVATE_INTERNAL,
|
||||
SKIP_SHARED_LIBRARY_CHECK);
|
||||
PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Slog.w(TAG, "Library not found: " + lib);
|
||||
@@ -7501,11 +7498,13 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
|
||||
false /* checkProfiles */,
|
||||
getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
|
||||
getOrCreateCompilerPackageStats(depPackage));
|
||||
getOrCreateCompilerPackageStats(depPackage),
|
||||
mDexManager.isUsedByOtherApps(p.packageName));
|
||||
}
|
||||
}
|
||||
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.
|
||||
@@ -15324,7 +15323,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
|
||||
null /* instructionSets */, false /* checkProfiles */,
|
||||
getCompilerFilterForReason(REASON_INSTALL),
|
||||
getOrCreateCompilerPackageStats(pkg));
|
||||
getOrCreateCompilerPackageStats(pkg),
|
||||
mDexManager.isUsedByOtherApps(pkg.packageName));
|
||||
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
||||
|
||||
// Notify BackgroundDexOptService that the package has been changed.
|
||||
|
||||
@@ -133,7 +133,8 @@ public class PackageManagerServiceUtils {
|
||||
sortTemp, packageManagerService);
|
||||
|
||||
// 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);
|
||||
|
||||
// Filter out packages that aren't recently used, add all remaining apps.
|
||||
|
||||
@@ -358,6 +358,23 @@ public class DexManager {
|
||||
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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user