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

Commit 65cde7d4 authored by Jeff Hao's avatar Jeff Hao
Browse files

Order apps by priority when performing boot dexopt.

Bug: 17641843
Change-Id: I16997b3b5241521e6bd995f2555864b4605edd17
parent a3d739d8
Loading
Loading
Loading
Loading
+107 −48
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;
@@ -4389,6 +4390,53 @@ 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 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)) {
                    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)) {
                    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)) {
                    sortedPkgs.add(pkg);
                    it.remove();
                }
            }
            // Filter out packages that aren't recently used.
            filterRecentlyUsedApps(pkgs);
            // Add all remaining apps.
            for (PackageParser.Package pkg : pkgs) {
                sortedPkgs.add(pkg);
            }
            int i = 0;
            int total = sortedPkgs.size();
            for (PackageParser.Package pkg : sortedPkgs) {
                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
@@ -4422,29 +4470,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 */);
        }
    }