From 83c903104027639944b52b2eb80537f69e07e4b2 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Wed, 18 Jan 2023 00:12:24 +0800 Subject: [PATCH] Notify Pinner Service and write FrameworkStatsLog. Bug: 255738375 Bug: 255566429 Test: Presubmit Change-Id: I1e20201706a2eb2d8b12f9bef744e0ccd006c9d0 --- .../server/pm/BackgroundDexOptService.java | 5 +++ .../com/android/server/pm/DexOptHelper.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index 5c4c7c92b57da..faa06f70d4114 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -331,6 +331,7 @@ public final class BackgroundDexOptService { /** Adds listener for package update */ public void addPackagesUpdatedListener(PackagesUpdatedListener listener) throws LegacyDexoptDisabledException { + // TODO(b/251903639): Evaluate whether this needs to support ART Service or not. Installer.checkLegacyDexoptDisabled(); synchronized (mLock) { mPackagesUpdatedListeners.add(listener); @@ -629,6 +630,8 @@ public final class BackgroundDexOptService { /** Gets the size of a package. */ private long getPackageSize(@NonNull Computer snapshot, String pkg) { + // TODO(b/251903639): Make this in line with the calculation in + // `DexOptHelper.DexoptDoneHandler`. PackageInfo info = snapshot.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM); long size = 0; if (info != null && info.applicationInfo != null) { @@ -723,6 +726,8 @@ public final class BackgroundDexOptService { return optimizePackages(pkgs, lowStorageThreshold, updatedPackages, isPostBootUpdate); } finally { // Always let the pinner service know about changes. + // TODO(b/251903639): ART Service does this for all dexopts, while the code below only + // runs for background jobs. We should try to make them behave the same. notifyPinService(updatedPackages); // Only notify IORap the primary dex opt, because we don't want to // invalidate traces unnecessary due to b/161633001 and that it's diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index 382ae26e59ec0..de37080d02556 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -57,8 +57,11 @@ import android.util.Log; import android.util.Slog; import com.android.internal.logging.MetricsLogger; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalManagerRegistry; +import com.android.server.LocalServices; +import com.android.server.PinnerService; import com.android.server.art.ArtManagerLocal; import com.android.server.art.DexUseManagerLocal; import com.android.server.art.ReasonMapping; @@ -970,6 +973,35 @@ public final class DexOptHelper { mPm.getPackageUsage().maybeWriteAsync(mPm.mSettings.getPackagesLocked()); mPm.mCompilerStats.maybeWriteAsync(); } + + if (result.getReason().equals(ReasonMapping.REASON_INACTIVE)) { + for (DexoptResult.PackageDexoptResult pkgRes : result.getPackageDexoptResults()) { + if (pkgRes.getStatus() == DexoptResult.DEXOPT_PERFORMED) { + long pkgSizeBytes = 0; + long pkgSizeBeforeBytes = 0; + for (DexoptResult.DexContainerFileDexoptResult dexRes : + pkgRes.getDexContainerFileDexoptResults()) { + long dexContainerSize = new File(dexRes.getDexContainerFile()).length(); + pkgSizeBytes += dexRes.getSizeBytes() + dexContainerSize; + pkgSizeBeforeBytes += dexRes.getSizeBeforeBytes() + dexContainerSize; + } + FrameworkStatsLog.write(FrameworkStatsLog.APP_DOWNGRADED, + pkgRes.getPackageName(), pkgSizeBeforeBytes, pkgSizeBytes, + false /* aggressive */); + } + } + } + + var updatedPackages = new ArraySet(); + for (DexoptResult.PackageDexoptResult pkgRes : result.getPackageDexoptResults()) { + if (pkgRes.hasUpdatedArtifacts()) { + updatedPackages.add(pkgRes.getPackageName()); + } + } + if (!updatedPackages.isEmpty()) { + LocalServices.getService(PinnerService.class) + .update(updatedPackages, false /* force */); + } } }