Improve priority ordering of apps when performing boot dexopt.
Added core apps and updated system apps.
Bug: 17641843
Change-Id: Ia00ea3399cf1e1acaef45ff8df8f754442de5185
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 765b2a9..b66bd01 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -235,6 +235,9 @@
public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
/** @hide */
+ public boolean coreApp;
+
+ /** @hide */
public boolean requiredForAllUsers;
/** @hide */
@@ -293,6 +296,7 @@
dest.writeTypedArray(reqFeatures, parcelableFlags);
dest.writeTypedArray(featureGroups, parcelableFlags);
dest.writeInt(installLocation);
+ dest.writeInt(coreApp ? 1 : 0);
dest.writeInt(requiredForAllUsers ? 1 : 0);
dest.writeString(restrictedAccountType);
dest.writeString(requiredAccountType);
@@ -337,6 +341,7 @@
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
featureGroups = source.createTypedArray(FeatureGroupInfo.CREATOR);
installLocation = source.readInt();
+ coreApp = source.readInt() != 0;
requiredForAllUsers = source.readInt() != 0;
restrictedAccountType = source.readString();
requiredAccountType = source.readString();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3364741..ca4ff6a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -415,6 +415,7 @@
pi.sharedUserLabel = p.mSharedUserLabel;
pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
pi.installLocation = p.installLocation;
+ pi.coreApp = p.coreApp;
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = p.mRequiredForAllUsers;
@@ -1384,6 +1385,8 @@
PARSE_DEFAULT_INSTALL_LOCATION);
pkg.applicationInfo.installLocation = pkg.installLocation;
+ pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false);
+
sa.recycle();
/* Set the global "forward lock" flag */
@@ -4267,6 +4270,8 @@
public int installLocation;
+ public boolean coreApp;
+
/* An app that's required for all users and cannot be uninstalled for a user */
public boolean mRequiredForAllUsers;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d8be6b6..1059f0b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4475,12 +4475,26 @@
// Sort apps by importance for dexopt ordering. Important apps are given more priority
// in case the device runs out of space.
ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
+ // Give priority to core apps.
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (pkg.coreApp) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
// Give priority to system apps that listen for pre boot complete.
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
HashSet<String> pkgNames = getPackageNamesForIntent(intent);
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
sortedPkgs.add(pkg);
it.remove();
}
@@ -4488,7 +4502,21 @@
// Give priority to system apps.
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
- if (isSystemApp(pkg)) {
+ if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
+ sortedPkgs.add(pkg);
+ it.remove();
+ }
+ }
+ // Give priority to updated system apps.
+ for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
+ PackageParser.Package pkg = it.next();
+ if (isUpdatedSystemApp(pkg)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
sortedPkgs.add(pkg);
it.remove();
}
@@ -4499,6 +4527,9 @@
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
sortedPkgs.add(pkg);
it.remove();
}
@@ -4513,6 +4544,9 @@
int i = 0;
int total = sortedPkgs.size();
for (PackageParser.Package pkg : sortedPkgs) {
+ if (DEBUG_DEXOPT) {
+ Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
+ }
performBootDexOpt(pkg, ++i, total);
}
}
@@ -5136,6 +5170,9 @@
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ } else {
+ // Only allow system apps to be flagged as core apps.
+ pkg.coreApp = false;
}
if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {