summaryrefslogtreecommitdiff
path: root/libartservice
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2025-03-21 09:40:32 -0700
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-03-21 09:40:32 -0700
commit4ba4dd0501dd3f44cf0846b5b56997e879966f48 (patch)
tree25c24476dc0b2f5e0aedc875b77f340401ac73c9 /libartservice
parentd706aef736e03487a96b22be6f7524406a5161d7 (diff)
parent0f7d94bd99bb554d663a4a527155eee6192780ee (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')
-rw-r--r--libartservice/service/java/com/android/server/art/ArtFileManager.java100
-rw-r--r--libartservice/service/java/com/android/server/art/ArtManagerLocal.java4
-rw-r--r--libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java58
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));