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

Commit 20ad4b92 authored by Mathieu Chartier's avatar Mathieu Chartier
Browse files

Add preopt profile logic for compiling during first boot

Allows pushing profiles on device that are used to optimize apps
during first boot.

Added logic to copy profiles to reference location for compressed APKs.

Bug: 38032017
Bug: 64503246
Test: adb shell rm -rf /data/app/*
Test: adb shell rm /data/system/package*
Test: adb shell stop && adb shell start
Test: look at apps in /data/app to make sure they are profile compiled

Change-Id: I30452098a19a65a331d098107d37498e5b10c10f
parent 8617e4ec
Loading
Loading
Loading
Loading
+49 −4
Original line number Diff line number Diff line
@@ -3312,6 +3312,24 @@ public class PackageManagerService extends IPackageManager.Stub
            removeCodePathLI(dstCodePath);
            return null;
        }
        // If we have a profile for a compressed APK, copy it to the reference location.
        // Since the package is the stub one, remove the stub suffix to get the normal package and
        // APK name.
        File profileFile = new File(getPrebuildProfilePath(pkg).replace(STUB_SUFFIX, ""));
        if (profileFile.exists()) {
            try {
                // We could also do this lazily before calling dexopt in
                // PackageDexOptimizer to prevent this happening on first boot. The issue
                // is that we don't have a good way to say "do this only once".
                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
                        pkg.applicationInfo.uid, pkg.packageName)) {
                    Log.e(TAG, "decompressPackage failed to copy system profile!");
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ", e);
            }
        }
        return dstCodePath;
    }
@@ -9723,7 +9741,7 @@ public class PackageManagerService extends IPackageManager.Stub
     * and {@code numberOfPackagesFailed}.
     */
    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
            String compilerFilter, boolean bootComplete) {
            final String compilerFilter, boolean bootComplete) {
        int numberOfPackagesVisited = 0;
        int numberOfPackagesOptimized = 0;
@@ -9734,6 +9752,8 @@ public class PackageManagerService extends IPackageManager.Stub
        for (PackageParser.Package pkg : pkgs) {
            numberOfPackagesVisited++;
            boolean useProfileForDexopt = false;
            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
                // Copy over initial preopt profiles since we won't get any JIT samples for methods
                // that are already compiled.
@@ -9747,11 +9767,28 @@ public class PackageManagerService extends IPackageManager.Stub
                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
                                pkg.applicationInfo.uid, pkg.packageName)) {
                            Log.e(TAG, "Installer failed to copy system profile!");
                        } else {
                            useProfileForDexopt = true;
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
                                e);
                    }
                } else {
                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
                    // minimize the number off apps being speed-profile compiled during first boot.
                    // The other paths will not change the filter.
                    if (disabledPs != null && disabledPs.pkg.isStub) {
                        // The package is the stub one, remove the stub suffix to get the normal
                        // package and APK names.
                        String systemProfilePath =
                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
                        File systemProfile = new File(systemProfilePath);
                        // Use the profile for compilation if there exists one for the same package
                        // in the system partition.
                        useProfileForDexopt = systemProfile.exists();
                    }
                }
            }
@@ -9780,6 +9817,14 @@ public class PackageManagerService extends IPackageManager.Stub
                }
            }
            String pkgCompilerFilter = compilerFilter;
            if (useProfileForDexopt) {
                // Use background dexopt mode to try and use the profile. Note that this does not
                // guarantee usage of the profile.
                pkgCompilerFilter =
                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
            }
            // If the OTA updates a system app which was previously preopted to a non-preopted state
            // the app might end up being verified at runtime. That's because by default the apps
            // are verify-profile but for preopted apps there's no profile.
@@ -9788,9 +9833,9 @@ public class PackageManagerService extends IPackageManager.Stub
            // filter (by default 'quicken').
            // Note that at this stage unused apps are already filtered.
            if (isSystemApp(pkg) &&
                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
                    DexFile.isProfileGuidedCompilerFilter(pkgCompilerFilter) &&
                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
                pkgCompilerFilter = getNonProfileGuidedCompilerFilter(pkgCompilerFilter);
            }
            // checkProfiles is false to avoid merging profiles during boot which
@@ -9801,7 +9846,7 @@ public class PackageManagerService extends IPackageManager.Stub
            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
                    pkg.packageName,
                    compilerFilter,
                    pkgCompilerFilter,
                    dexoptFlags));
            switch (primaryDexOptStaus) {