Loading core/java/android/content/pm/PackageInfo.java +5 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,9 @@ public class PackageInfo implements Parcelable { */ public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY; /** @hide */ public boolean coreApp; /** @hide */ public boolean requiredForAllUsers; Loading Loading @@ -293,6 +296,7 @@ public class PackageInfo implements Parcelable { 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); Loading Loading @@ -337,6 +341,7 @@ public class PackageInfo implements Parcelable { 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(); Loading core/java/android/content/pm/PackageParser.java +5 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ public class PackageParser { 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; Loading Loading @@ -1384,6 +1385,8 @@ public class PackageParser { PARSE_DEFAULT_INSTALL_LOCATION); pkg.applicationInfo.installLocation = pkg.installLocation; pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false); sa.recycle(); /* Set the global "forward lock" flag */ Loading Loading @@ -4267,6 +4270,8 @@ public class PackageParser { public int installLocation; public boolean coreApp; /* An app that's required for all users and cannot be uninstalled for a user */ public boolean mRequiredForAllUsers; Loading services/core/java/com/android/server/pm/PackageManagerService.java +151 −45 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import org.xmlpull.v1.XmlSerializer; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.IActivityManager; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; Loading Loading @@ -4471,6 +4472,97 @@ public class PackageManagerService extends IPackageManager.Stub { } if (pkgs != null) { // 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(); } } // Give priority to system apps. for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { PackageParser.Package pkg = it.next(); 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(); } } // Give priority to apps that listen for boot complete. intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 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 boot app " + sortedPkgs.size() + ": " + pkg.packageName); } sortedPkgs.add(pkg); it.remove(); } } // Filter out packages that aren't recently used. filterRecentlyUsedApps(pkgs); // Add all remaining apps. for (PackageParser.Package pkg : pkgs) { if (DEBUG_DEXOPT) { Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); } sortedPkgs.add(pkg); } int i = 0; int total = sortedPkgs.size(); File dataDir = Environment.getDataDirectory(); long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); if (lowThreshold == 0) { throw new IllegalStateException("Invalid low memory threshold"); } for (PackageParser.Package pkg : sortedPkgs) { long usableSpace = dataDir.getUsableSpace(); if (usableSpace < lowThreshold) { Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); break; } performBootDexOpt(pkg, ++i, total); } } } private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) { // Filter out packages that aren't recently used. // // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which Loading Loading @@ -4504,29 +4596,40 @@ public class PackageManagerService extends IPackageManager.Stub { Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); } } } int i = 0; for (PackageParser.Package pkg : pkgs) { i++; private HashSet<String> getPackageNamesForIntent(Intent intent) { List<ResolveInfo> ris = null; try { ris = AppGlobals.getPackageManager().queryIntentReceivers( intent, null, 0, UserHandle.USER_OWNER); } catch (RemoteException e) { } HashSet<String> pkgNames = new HashSet<String>(); if (ris != null) { for (ResolveInfo ri : ris) { pkgNames.add(ri.activityInfo.packageName); } } return pkgNames; } private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { if (DEBUG_DEXOPT) { Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size() + ": " + pkg.packageName); Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); } if (!isFirstBoot()) { try { ActivityManagerNative.getDefault().showBootMessage( mContext.getResources().getString( R.string.android_upgrading_apk, i, pkgs.size()), true); mContext.getResources().getString(R.string.android_upgrading_apk, curr, total), true); } catch (RemoteException e) { } } PackageParser.Package p = pkg; synchronized (mInstallLock) { performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */, true /* include dependencies */); } } performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */, true /* include dependencies */); } } Loading Loading @@ -5077,6 +5180,9 @@ public class PackageManagerService extends IPackageManager.Stub { 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) { Loading Loading
core/java/android/content/pm/PackageInfo.java +5 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,9 @@ public class PackageInfo implements Parcelable { */ public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY; /** @hide */ public boolean coreApp; /** @hide */ public boolean requiredForAllUsers; Loading Loading @@ -293,6 +296,7 @@ public class PackageInfo implements Parcelable { 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); Loading Loading @@ -337,6 +341,7 @@ public class PackageInfo implements Parcelable { 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(); Loading
core/java/android/content/pm/PackageParser.java +5 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,7 @@ public class PackageParser { 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; Loading Loading @@ -1384,6 +1385,8 @@ public class PackageParser { PARSE_DEFAULT_INSTALL_LOCATION); pkg.applicationInfo.installLocation = pkg.installLocation; pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false); sa.recycle(); /* Set the global "forward lock" flag */ Loading Loading @@ -4267,6 +4270,8 @@ public class PackageParser { public int installLocation; public boolean coreApp; /* An app that's required for all users and cannot be uninstalled for a user */ public boolean mRequiredForAllUsers; Loading
services/core/java/com/android/server/pm/PackageManagerService.java +151 −45 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import org.xmlpull.v1.XmlSerializer; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.IActivityManager; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; Loading Loading @@ -4471,6 +4472,97 @@ public class PackageManagerService extends IPackageManager.Stub { } if (pkgs != null) { // 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(); } } // Give priority to system apps. for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { PackageParser.Package pkg = it.next(); 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(); } } // Give priority to apps that listen for boot complete. intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 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 boot app " + sortedPkgs.size() + ": " + pkg.packageName); } sortedPkgs.add(pkg); it.remove(); } } // Filter out packages that aren't recently used. filterRecentlyUsedApps(pkgs); // Add all remaining apps. for (PackageParser.Package pkg : pkgs) { if (DEBUG_DEXOPT) { Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); } sortedPkgs.add(pkg); } int i = 0; int total = sortedPkgs.size(); File dataDir = Environment.getDataDirectory(); long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); if (lowThreshold == 0) { throw new IllegalStateException("Invalid low memory threshold"); } for (PackageParser.Package pkg : sortedPkgs) { long usableSpace = dataDir.getUsableSpace(); if (usableSpace < lowThreshold) { Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); break; } performBootDexOpt(pkg, ++i, total); } } } private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) { // Filter out packages that aren't recently used. // // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which Loading Loading @@ -4504,29 +4596,40 @@ public class PackageManagerService extends IPackageManager.Stub { Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); } } } int i = 0; for (PackageParser.Package pkg : pkgs) { i++; private HashSet<String> getPackageNamesForIntent(Intent intent) { List<ResolveInfo> ris = null; try { ris = AppGlobals.getPackageManager().queryIntentReceivers( intent, null, 0, UserHandle.USER_OWNER); } catch (RemoteException e) { } HashSet<String> pkgNames = new HashSet<String>(); if (ris != null) { for (ResolveInfo ri : ris) { pkgNames.add(ri.activityInfo.packageName); } } return pkgNames; } private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { if (DEBUG_DEXOPT) { Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size() + ": " + pkg.packageName); Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); } if (!isFirstBoot()) { try { ActivityManagerNative.getDefault().showBootMessage( mContext.getResources().getString( R.string.android_upgrading_apk, i, pkgs.size()), true); mContext.getResources().getString(R.string.android_upgrading_apk, curr, total), true); } catch (RemoteException e) { } } PackageParser.Package p = pkg; synchronized (mInstallLock) { performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */, true /* include dependencies */); } } performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */, true /* include dependencies */); } } Loading Loading @@ -5077,6 +5180,9 @@ public class PackageManagerService extends IPackageManager.Stub { 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) { Loading