Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1201d2a0 authored by Jeff Hao's avatar Jeff Hao Committed by Android Git Automerger
Browse files

am dbfbb175: Backport of ordering apps for boot dexopt.

* commit 'dbfbb175':
  Backport of ordering apps for boot dexopt.
parents 60cdb909 dbfbb175
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -234,6 +234,9 @@ public class PackageInfo implements Parcelable {
     */
    public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;

    /** @hide */
    public boolean coreApp;

    /** @hide */
    public boolean requiredForAllUsers;

@@ -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);
@@ -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();
+5 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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 */
@@ -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;

+151 −45
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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 */);
        }
    }
@@ -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) {