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

Commit 01d8e8d3 authored by Rajeev Kumar's avatar Rajeev Kumar Committed by Android (Google) Code Review
Browse files

Merge "Exempt hibernating apps from dex optimization"

parents f9b15540 633d8e12
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -43,4 +43,9 @@ public abstract class AppHibernationManagerInternal {
     * @see AppHibernationService#setHibernatingGlobally
     */
    public abstract void setHibernatingGlobally(String packageName, boolean isHibernating);

    /**
     * @see AppHibernationService#isOatArtifactDeletionEnabled
     */
    public abstract boolean isOatArtifactDeletionEnabled();
}
+13 −0
Original line number Diff line number Diff line
@@ -199,6 +199,14 @@ public final class AppHibernationService extends SystemService {
        }
    }

    /**
     * Whether global hibernation should delete ART ahead-of-time compilation artifacts and prevent
     * package manager from re-optimizing the APK.
     */
    private boolean isOatArtifactDeletionEnabled() {
        return mOatArtifactDeletionEnabled;
    }

    /**
     * Whether a package is hibernating for a given user.
     *
@@ -730,6 +738,11 @@ public final class AppHibernationService extends SystemService {
        public boolean isHibernatingGlobally(String packageName) {
            return mService.isHibernatingGlobally(packageName);
        }

        @Override
        public boolean isOatArtifactDeletionEnabled() {
            return mService.isOatArtifactDeletionEnabled();
        }
    }

    private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this);
+2 −9
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@ import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.server.apphibernation.AppHibernationManagerInternal;
import com.android.server.apphibernation.AppHibernationService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -171,7 +169,7 @@ final class DexOptHelper {
                }
            }

            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
            if (!mPm.mPackageDexOptimizer.canOptimizePackage(pkg)) {
                if (DEBUG_DEXOPT) {
                    Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
                }
@@ -291,16 +289,11 @@ final class DexOptHelper {
        ArraySet<String> pkgs = new ArraySet<>();
        synchronized (mPm.mLock) {
            for (AndroidPackage p : mPm.mPackages.values()) {
                if (PackageDexOptimizer.canOptimizePackage(p)) {
                if (mPm.mPackageDexOptimizer.canOptimizePackage(p)) {
                    pkgs.add(p.getPackageName());
                }
            }
        }
        if (AppHibernationService.isAppHibernationEnabled()) {
            AppHibernationManagerInternal appHibernationManager =
                    mPm.mInjector.getLocalService(AppHibernationManagerInternal.class);
            pkgs.removeIf(pkgName -> appHibernationManager.isHibernatingGlobally(pkgName));
        }
        return pkgs;
    }

+1 −1
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
            }

            // Does the package have code? If not, there won't be any artifacts.
            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
            if (!mPackageManagerService.mPackageDexOptimizer.canOptimizePackage(pkg)) {
                continue;
            }
            if (pkg.getPath() == null) {
+44 −5
Original line number Diff line number Diff line
@@ -64,7 +64,10 @@ import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.apphibernation.AppHibernationManagerInternal;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.ArtStatsLogUtils;
@@ -134,16 +137,24 @@ public class PackageDexOptimizer {
    private volatile boolean mSystemReady;

    private final ArtStatsLogger mArtStatsLogger = new ArtStatsLogger();
    private final Injector mInjector;


    private static final Random sRandom = new Random();

    PackageDexOptimizer(Installer installer, Object installLock, Context context,
            String wakeLockTag) {
        this.mInstaller = installer;
        this.mInstallLock = installLock;
        this(new Injector() {
            @Override
            public AppHibernationManagerInternal getAppHibernationManagerInternal() {
                return LocalServices.getService(AppHibernationManagerInternal.class);
            }

        PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mDexoptWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakeLockTag);
            @Override
            public PowerManager getPowerManager(Context context) {
                return context.getSystemService(PowerManager.class);
            }
        }, installer, installLock, context, wakeLockTag);
    }

    protected PackageDexOptimizer(PackageDexOptimizer from) {
@@ -151,9 +162,21 @@ public class PackageDexOptimizer {
        this.mInstallLock = from.mInstallLock;
        this.mDexoptWakeLock = from.mDexoptWakeLock;
        this.mSystemReady = from.mSystemReady;
        this.mInjector = from.mInjector;
    }

    static boolean canOptimizePackage(AndroidPackage pkg) {
    @VisibleForTesting
    PackageDexOptimizer(@NonNull Injector injector, Installer installer, Object installLock,
            Context context, String wakeLockTag) {
        this.mInstaller = installer;
        this.mInstallLock = installLock;

        PowerManager powerManager = injector.getPowerManager(context);
        mDexoptWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakeLockTag);
        mInjector = injector;
    }

    boolean canOptimizePackage(AndroidPackage pkg) {
        // We do not dexopt a package with no code.
        // Note that the system package is marked as having no code, however we can
        // still optimize it via dexoptSystemServerPath.
@@ -161,6 +184,13 @@ public class PackageDexOptimizer {
            return false;
        }

        // We do not dexopt unused packages.
        AppHibernationManagerInternal ahm = mInjector.getAppHibernationManagerInternal();
        if (ahm.isHibernatingGlobally(pkg.getPackageName())
                && ahm.isOatArtifactDeletionEnabled()) {
            return false;
        }

        return true;
    }

@@ -1000,4 +1030,13 @@ public class PackageDexOptimizer {
    private Installer getInstallerWithoutLock() {
        return mInstaller;
    }

    /**
     * Injector for {@link PackageDexOptimizer} dependencies
     */
    interface Injector {
        AppHibernationManagerInternal getAppHibernationManagerInternal();

        PowerManager getPowerManager(Context context);
    }
}
Loading