Loading services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -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(); } services/core/java/com/android/server/apphibernation/AppHibernationService.java +13 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); Loading services/core/java/com/android/server/pm/DexOptHelper.java +2 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); } Loading Loading @@ -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; } Loading services/core/java/com/android/server/pm/OtaDexoptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +44 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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
services/core/java/com/android/server/apphibernation/AppHibernationManagerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -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(); }
services/core/java/com/android/server/apphibernation/AppHibernationService.java +13 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); Loading
services/core/java/com/android/server/pm/DexOptHelper.java +2 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); } Loading Loading @@ -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; } Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +44 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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); } }