Merge "Change app selection policy for post-OTA verification" into nyc-dev am: 3eaf72d

am: 9ada71d

* commit '9ada71dccf73c7d5ab810d9280fc57c8a51bbe18':
  Change app selection policy for post-OTA verification

Change-Id: I6234555ac68127753b071770986f512e48ca30f7
This commit is contained in:
David Brazdil
2016-04-26 12:30:20 +00:00
committed by android-build-merger
3 changed files with 62 additions and 29 deletions

View File

@@ -5096,6 +5096,19 @@ public class PackageParser {
return latestUse;
}
public long getLatestForegroundPackageUseTimeInMills() {
int[] foregroundReasons = {
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY,
PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE
};
long latestUse = 0L;
for (int reason : foregroundReasons) {
latestUse = Math.max(latestUse, mLastPackageUsageTimeInMills[reason]);
}
return latestUse;
}
public String toString() {
return "Package{"
+ Integer.toHexString(System.identityHashCode(this))

View File

@@ -137,21 +137,14 @@ class PackageDexOptimizer {
boolean isProfileGuidedFilter = DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter);
// If any part of the app is used by other apps, we cannot use profile-guided
// compilation.
// Skip the check for forward locked packages since they don't share their code.
if (isProfileGuidedFilter && !pkg.isForwardLocked()) {
for (String path : paths) {
if (isUsedByOtherApps(path)) {
checkProfiles = false;
if (isProfileGuidedFilter && isUsedByOtherApps(pkg)) {
checkProfiles = false;
targetCompilerFilter = getNonProfileGuidedCompilerFilter(targetCompilerFilter);
if (DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter)) {
throw new IllegalStateException(targetCompilerFilter);
}
isProfileGuidedFilter = false;
break;
}
targetCompilerFilter = getNonProfileGuidedCompilerFilter(targetCompilerFilter);
if (DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter)) {
throw new IllegalStateException(targetCompilerFilter);
}
isProfileGuidedFilter = false;
}
// If we're asked to take profile updates into account, check now.
@@ -281,20 +274,34 @@ class PackageDexOptimizer {
mSystemReady = true;
}
private boolean isUsedByOtherApps(String apkPath) {
try {
apkPath = new File(apkPath).getCanonicalPath();
} catch (IOException e) {
// Log an error but continue without it.
Slog.w(TAG, "Failed to get canonical path", e);
/**
* 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;
}
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;
for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) {
try {
apkPath = new File(apkPath).getCanonicalPath();
} catch (IOException e) {
// Log an error but continue without it.
Slog.w(TAG, "Failed to get canonical path", e);
}
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;

View File

@@ -69,11 +69,12 @@ public class PackageManagerServiceUtils {
long now = System.currentTimeMillis();
for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
PackageParser.Package pkg = i.next();
long then = pkg.getLatestPackageUseTimeInMills();
long then = pkg.getLatestForegroundPackageUseTimeInMills();
if (then + dexOptLRUThresholdInMills < now) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
((then == 0) ? "never" : new Date(then)));
Log.i(TAG, "Skipping dexopt of " + pkg.packageName +
" last used in foreground: " +
((then == 0) ? "never" : new Date(then)));
}
i.remove();
skipped++;
@@ -117,6 +118,18 @@ public class PackageManagerServiceUtils {
}
remainingPkgs.removeAll(result);
// Give priority to apps used by other apps.
for (PackageParser.Package pkg : remainingPkgs) {
if (PackageDexOptimizer.isUsedByOtherApps(pkg)) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding app used by other apps " + result.size() + ": " +
pkg.packageName);
}
result.add(pkg);
}
}
remainingPkgs.removeAll(result);
// Filter out packages that aren't recently used, add all remaining apps.
// TODO: add a property to control this?
if (packageManagerService.isHistoricalPackageUsageAvailable()) {