diff options
author | 2025-03-21 09:40:32 -0700 | |
---|---|---|
committer | 2025-03-21 09:40:32 -0700 | |
commit | 4ba4dd0501dd3f44cf0846b5b56997e879966f48 (patch) | |
tree | 25c24476dc0b2f5e0aedc875b77f340401ac73c9 /libartservice | |
parent | d706aef736e03487a96b22be6f7524406a5161d7 (diff) | |
parent | 0f7d94bd99bb554d663a4a527155eee6192780ee (diff) |
Count SDM files into TYPE_DEXOPT_ARTIFACT in ART-managed file stats. am: 0f7d94bd99
Original change: https://android-review.googlesource.com/c/platform/art/+/3545381
Change-Id: Iaa9e62c175e688450429793264318bdacf671a99
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'libartservice')
3 files changed, 95 insertions, 67 deletions
diff --git a/libartservice/service/java/com/android/server/art/ArtFileManager.java b/libartservice/service/java/com/android/server/art/ArtFileManager.java index 754b9ec1dd..8e382aa1d8 100644 --- a/libartservice/service/java/com/android/server/art/ArtFileManager.java +++ b/libartservice/service/java/com/android/server/art/ArtFileManager.java @@ -45,7 +45,6 @@ import dalvik.system.DexFile; import com.google.auto.value.AutoValue; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; @@ -126,7 +125,7 @@ public class ArtFileManager { } } - return WritableArtifactLists.create(artifacts, runtimeArtifacts); + return new WritableArtifactLists(artifacts, runtimeArtifacts); } /** Returns artifacts that are usable, regardless of whether they are writable. */ @@ -135,6 +134,7 @@ public class ArtFileManager { @NonNull PackageState pkgState, @NonNull AndroidPackage pkg) throws RemoteException { List<ArtifactsPath> artifacts = new ArrayList<>(); List<VdexPath> vdexFiles = new ArrayList<>(); + List<SecureDexMetadataWithCompanionPaths> sdmFiles = new ArrayList<>(); List<RuntimeArtifactsPath> runtimeArtifacts = new ArrayList<>(); var options = ArtFileManager.Options.builder() @@ -159,9 +159,30 @@ public class ArtFileManager { } else { artifacts.add(thisArtifacts); } + } else if (result.artifactsLocation == ArtifactsLocation.SDM_DALVIK_CACHE + || result.artifactsLocation == ArtifactsLocation.SDM_NEXT_TO_DEX) { + sdmFiles.add(AidlUtils.buildSecureDexMetadataWithCompanionPaths( + dexInfo.dexPath(), abi.isa(), + result.artifactsLocation == ArtifactsLocation.SDM_DALVIK_CACHE)); + } + + if (result.artifactsLocation != ArtifactsLocation.NONE_OR_ERROR) { // Runtime images are only generated for primary dex files. if (dexInfo instanceof DetailedPrimaryDexInfo && !DexFile.isOptimizedCompilerFilter(result.compilerFilter)) { + // Those not added to the list are definitely unusable, but those added to + // the list are not necessarily usable. For example, runtime artifacts can + // be outdated when the corresponding dex file is updated, but they may + // still show up in this list. + // + // However, this is not a severe problem. For `ArtManagerLocal.cleanup`, the + // worst result is only that we are keeping more runtime artifacts than + // needed. For `ArtManagerLocal.getArtManagedFileStats`, this is an edge + // case because the API call is transitively initiated by the app itself, + // and the runtime refreshes unusable runtime artifacts as soon as the app + // starts. + // + // TODO(jiakaiz): Improve this. runtimeArtifacts.add(AidlUtils.buildRuntimeArtifactsPath( pkgState.getPackageName(), dexInfo.dexPath(), abi.isa())); } @@ -176,7 +197,7 @@ public class ArtFileManager { } } - return UsableArtifactLists.create(artifacts, vdexFiles, runtimeArtifacts); + return new UsableArtifactLists(artifacts, vdexFiles, sdmFiles, runtimeArtifacts); } @NonNull @@ -209,7 +230,7 @@ public class ArtFileManager { } } - return ProfileLists.create(refProfiles, curProfiles); + return new ProfileLists(refProfiles, curProfiles); } @NonNull @@ -221,71 +242,16 @@ public class ArtFileManager { : mInjector.getDexUseManager().getSecondaryDexInfo(pkgState.getPackageName()); } - @Immutable - @AutoValue - @SuppressWarnings("AutoValueImmutableFields") // Can't use ImmutableList because it's in Guava. - public abstract static class WritableArtifactLists { - protected WritableArtifactLists() {} - - public static @NonNull WritableArtifactLists create(@NonNull List<ArtifactsPath> artifacts, - @NonNull List<RuntimeArtifactsPath> runtimeArtifacts) { - return new AutoValue_ArtFileManager_WritableArtifactLists( - Collections.unmodifiableList(artifacts), - Collections.unmodifiableList(runtimeArtifacts)); - } - - public abstract @NonNull List<ArtifactsPath> artifacts(); - public abstract @NonNull List<RuntimeArtifactsPath> runtimeArtifacts(); - } - - @Immutable - @AutoValue - @SuppressWarnings("AutoValueImmutableFields") // Can't use ImmutableList because it's in Guava. - public abstract static class UsableArtifactLists { - protected UsableArtifactLists() {} - - public static @NonNull UsableArtifactLists create(@NonNull List<ArtifactsPath> artifacts, - @NonNull List<VdexPath> vdexFiles, - @NonNull List<RuntimeArtifactsPath> runtimeArtifacts) { - return new AutoValue_ArtFileManager_UsableArtifactLists( - Collections.unmodifiableList(artifacts), - Collections.unmodifiableList(vdexFiles), - Collections.unmodifiableList(runtimeArtifacts)); - } - - public abstract @NonNull List<ArtifactsPath> artifacts(); - public abstract @NonNull List<VdexPath> vdexFiles(); - - // Those not added to the list are definitely unusable, but those added to the list are not - // necessarily usable. For example, runtime artifacts can be outdated when the corresponding - // dex file is updated, but they may still show up in this list. - // - // However, this is not a severe problem. For `ArtManagerLocal.cleanup`, the worst result is - // only that we are keeping more runtime artifacts than needed. For - // `ArtManagerLocal.getArtManagedFileStats`, this is an edge case because the API call is - // transitively initiated by the app itself, and the runtime refreshes unusable runtime - // artifacts as soon as the app starts. - // - // TODO(jiakaiz): Improve this. - public abstract @NonNull List<RuntimeArtifactsPath> runtimeArtifacts(); - } - - @Immutable - @AutoValue - @SuppressWarnings("AutoValueImmutableFields") // Can't use ImmutableList because it's in Guava. - public abstract static class ProfileLists { - protected ProfileLists() {} - - public static @NonNull ProfileLists create( - @NonNull List<ProfilePath> refProfiles, @NonNull List<ProfilePath> curProfiles) { - return new AutoValue_ArtFileManager_ProfileLists( - Collections.unmodifiableList(refProfiles), - Collections.unmodifiableList(curProfiles)); - } + public record WritableArtifactLists(@NonNull List<ArtifactsPath> artifacts, + @NonNull List<RuntimeArtifactsPath> runtimeArtifacts) {} - public abstract @NonNull List<ProfilePath> refProfiles(); - public abstract @NonNull List<ProfilePath> curProfiles(); + public record UsableArtifactLists(@NonNull List<ArtifactsPath> artifacts, + @NonNull List<VdexPath> vdexFiles, + @NonNull List<SecureDexMetadataWithCompanionPaths> sdmFiles, + @NonNull List<RuntimeArtifactsPath> runtimeArtifacts) {} + public record ProfileLists( + @NonNull List<ProfilePath> refProfiles, @NonNull List<ProfilePath> curProfiles) { public @NonNull List<ProfilePath> allProfiles() { List<ProfilePath> profiles = new ArrayList<>(); profiles.addAll(refProfiles()); diff --git a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java index 735da25fbb..acd6063f11 100644 --- a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java +++ b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java @@ -1056,6 +1056,10 @@ public final class ArtManagerLocal { for (RuntimeArtifactsPath runtimeArtifacts : artifactLists.runtimeArtifacts()) { artifactsSize += artd.getRuntimeArtifactsSize(runtimeArtifacts); } + for (SecureDexMetadataWithCompanionPaths sdmFile : artifactLists.sdmFiles()) { + // We don't count SDC files because they are presumed to be tiny. + artifactsSize += artd.getSdmFileSize(sdmFile); + } ProfileLists profileLists = mInjector.getArtFileManager().getProfiles(pkgState, pkg, ArtFileManager.Options.builder() diff --git a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java index a791211705..b17475480e 100644 --- a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java +++ b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java @@ -1426,6 +1426,64 @@ public class ArtManagerLocalTest { } @Test + public void testGetArtManagedFileStatsDmAndSdm() throws Exception { + // It should count the SDM file, but not runtime images. + doReturn(createGetDexoptStatusResult( + "speed-profile", "cloud", "location", ArtifactsLocation.SDM_NEXT_TO_DEX)) + .when(mArtd) + .getDexoptStatus(eq("/somewhere/app/foo/base.apk"), eq("arm64"), any()); + + // It should count the SDM file, but not runtime images. + doReturn(createGetDexoptStatusResult( + "speed-profile", "cloud", "location", ArtifactsLocation.SDM_DALVIK_CACHE)) + .when(mArtd) + .getDexoptStatus(eq("/somewhere/app/foo/base.apk"), eq("arm"), any()); + + // It should count the SDM file and runtime images. + doReturn(createGetDexoptStatusResult( + "verify", "cloud", "location", ArtifactsLocation.SDM_NEXT_TO_DEX)) + .when(mArtd) + .getDexoptStatus(eq("/somewhere/app/foo/split_0.apk"), eq("arm64"), any()); + + // It should only count runtime images. + doReturn(createGetDexoptStatusResult("verify", "vdex", "location", ArtifactsLocation.DM)) + .when(mArtd) + .getDexoptStatus(eq("/somewhere/app/foo/split_0.apk"), eq("arm"), any()); + + // This file is uninteresting in this test. + doReturn(createGetDexoptStatusResult( + "run-from-apk", "unknown", "unknown", ArtifactsLocation.NONE_OR_ERROR)) + .when(mArtd) + .getDexoptStatus(eq("/data/user/0/foo/1.apk"), eq("arm64"), any()); + + // These are counted as TYPE_DEXOPT_ARTIFACT. + doReturn(1l << 0).when(mArtd).getSdmFileSize( + deepEq(AidlUtils.buildSecureDexMetadataWithCompanionPaths( + "/somewhere/app/foo/base.apk", "arm64", false /* isInDalvikCache */))); + doReturn(1l << 1).when(mArtd).getSdmFileSize( + deepEq(AidlUtils.buildSecureDexMetadataWithCompanionPaths( + "/somewhere/app/foo/base.apk", "arm", true /* isInDalvikCache */))); + doReturn(1l << 2).when(mArtd).getSdmFileSize( + deepEq(AidlUtils.buildSecureDexMetadataWithCompanionPaths( + "/somewhere/app/foo/split_0.apk", "arm64", false /* isInDalvikCache */))); + doReturn(1l << 3).when(mArtd).getRuntimeArtifactsSize( + deepEq(AidlUtils.buildRuntimeArtifactsPath( + PKG_NAME_1, "/somewhere/app/foo/split_0.apk", "arm64"))); + doReturn(1l << 4).when(mArtd).getRuntimeArtifactsSize( + deepEq(AidlUtils.buildRuntimeArtifactsPath( + PKG_NAME_1, "/somewhere/app/foo/split_0.apk", "arm"))); + + ArtManagedFileStats stats = mArtManagerLocal.getArtManagedFileStats(mSnapshot, PKG_NAME_1); + assertThat(stats.getTotalSizeBytesByType(ArtManagedFileStats.TYPE_DEXOPT_ARTIFACT)) + .isEqualTo((1l << 0) + (1l << 1) + (1l << 2) + (1l << 3) + (1l << 4)); + + verify(mArtd, never()).getArtifactsSize(any()); + verify(mArtd, never()).getVdexFileSize(any()); + verify(mArtd, times(3)).getSdmFileSize(any()); + verify(mArtd, times(2)).getRuntimeArtifactsSize(any()); + } + + @Test public void testCommitPreRebootStagedFiles() throws Exception { when(mSnapshot.getPackageStates()).thenReturn(Map.of(PKG_NAME_1, mPkgState1)); |