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 @@ -742,6 +750,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/OtaDexoptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -381,7 +381,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 +48 −5 Original line number Diff line number Diff line Loading @@ -63,7 +63,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 @@ -107,16 +110,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 @@ -124,9 +135,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 @@ -134,6 +157,17 @@ public class PackageDexOptimizer { return false; } // We do not dexopt unused packages. // It's possible for this to be called before app hibernation service is ready due to // an OTA dexopt. In this case, we ignore the hibernation check here. This is fine since // a hibernating app should have no artifacts to copy in the first place. AppHibernationManagerInternal ahm = mInjector.getAppHibernationManagerInternal(); if (ahm != null && ahm.isHibernatingGlobally(pkg.getPackageName()) && ahm.isOatArtifactDeletionEnabled()) { return false; } return true; } Loading Loading @@ -921,4 +955,13 @@ public class PackageDexOptimizer { return flags | DEXOPT_FORCE; } } /** * Injector for {@link PackageDexOptimizer} dependencies */ interface Injector { AppHibernationManagerInternal getAppHibernationManagerInternal(); PowerManager getPowerManager(Context context); } } services/core/java/com/android/server/pm/PackageManagerService.java +3 −9 Original line number Diff line number Diff line Loading @@ -367,7 +367,6 @@ import com.android.server.SystemConfig; import com.android.server.SystemServerInitThreadPool; import com.android.server.Watchdog; import com.android.server.apphibernation.AppHibernationManagerInternal; import com.android.server.apphibernation.AppHibernationService; import com.android.server.compat.CompatChange; import com.android.server.compat.PlatformCompat; import com.android.server.net.NetworkPolicyManagerInternal; Loading Loading @@ -1458,7 +1457,7 @@ public class PackageManagerService extends IPackageManager.Stub final ArtManagerService mArtManagerService; private final PackageDexOptimizer mPackageDexOptimizer; final PackageDexOptimizer mPackageDexOptimizer; // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package // is used by other apps). private final DexManager mDexManager; Loading Loading @@ -12741,7 +12740,7 @@ public class PackageManagerService extends IPackageManager.Stub } } if (!PackageDexOptimizer.canOptimizePackage(pkg)) { if (!mPackageDexOptimizer.canOptimizePackage(pkg)) { if (DEBUG_DEXOPT) { Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName()); } Loading Loading @@ -12992,16 +12991,11 @@ public class PackageManagerService extends IPackageManager.Stub ArraySet<String> pkgs = new ArraySet<>(); synchronized (mLock) { for (AndroidPackage p : mPackages.values()) { if (PackageDexOptimizer.canOptimizePackage(p)) { if (mPackageDexOptimizer.canOptimizePackage(p)) { pkgs.add(p.getPackageName()); } } } if (AppHibernationService.isAppHibernationEnabled()) { AppHibernationManagerInternal appHibernationManager = mInjector.getLocalService(AppHibernationManagerInternal.class); pkgs.removeIf(pkgName -> appHibernationManager.isHibernatingGlobally(pkgName)); } return pkgs; } 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 @@ -742,6 +750,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/OtaDexoptService.java +1 −1 Original line number Diff line number Diff line Loading @@ -381,7 +381,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 +48 −5 Original line number Diff line number Diff line Loading @@ -63,7 +63,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 @@ -107,16 +110,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 @@ -124,9 +135,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 @@ -134,6 +157,17 @@ public class PackageDexOptimizer { return false; } // We do not dexopt unused packages. // It's possible for this to be called before app hibernation service is ready due to // an OTA dexopt. In this case, we ignore the hibernation check here. This is fine since // a hibernating app should have no artifacts to copy in the first place. AppHibernationManagerInternal ahm = mInjector.getAppHibernationManagerInternal(); if (ahm != null && ahm.isHibernatingGlobally(pkg.getPackageName()) && ahm.isOatArtifactDeletionEnabled()) { return false; } return true; } Loading Loading @@ -921,4 +955,13 @@ public class PackageDexOptimizer { return flags | DEXOPT_FORCE; } } /** * Injector for {@link PackageDexOptimizer} dependencies */ interface Injector { AppHibernationManagerInternal getAppHibernationManagerInternal(); PowerManager getPowerManager(Context context); } }
services/core/java/com/android/server/pm/PackageManagerService.java +3 −9 Original line number Diff line number Diff line Loading @@ -367,7 +367,6 @@ import com.android.server.SystemConfig; import com.android.server.SystemServerInitThreadPool; import com.android.server.Watchdog; import com.android.server.apphibernation.AppHibernationManagerInternal; import com.android.server.apphibernation.AppHibernationService; import com.android.server.compat.CompatChange; import com.android.server.compat.PlatformCompat; import com.android.server.net.NetworkPolicyManagerInternal; Loading Loading @@ -1458,7 +1457,7 @@ public class PackageManagerService extends IPackageManager.Stub final ArtManagerService mArtManagerService; private final PackageDexOptimizer mPackageDexOptimizer; final PackageDexOptimizer mPackageDexOptimizer; // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package // is used by other apps). private final DexManager mDexManager; Loading Loading @@ -12741,7 +12740,7 @@ public class PackageManagerService extends IPackageManager.Stub } } if (!PackageDexOptimizer.canOptimizePackage(pkg)) { if (!mPackageDexOptimizer.canOptimizePackage(pkg)) { if (DEBUG_DEXOPT) { Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName()); } Loading Loading @@ -12992,16 +12991,11 @@ public class PackageManagerService extends IPackageManager.Stub ArraySet<String> pkgs = new ArraySet<>(); synchronized (mLock) { for (AndroidPackage p : mPackages.values()) { if (PackageDexOptimizer.canOptimizePackage(p)) { if (mPackageDexOptimizer.canOptimizePackage(p)) { pkgs.add(p.getPackageName()); } } } if (AppHibernationService.isAppHibernationEnabled()) { AppHibernationManagerInternal appHibernationManager = mInjector.getLocalService(AppHibernationManagerInternal.class); pkgs.removeIf(pkgName -> appHibernationManager.isHibernatingGlobally(pkgName)); } return pkgs; }