summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--artd/artd.cc18
-rw-r--r--artd/artd.h2
-rw-r--r--artd/artd_test.cc49
-rw-r--r--artd/binder/com/android/server/art/IArtd.aidl1
-rw-r--r--artd/path_utils.cc1
-rw-r--r--libartservice/service/java/com/android/server/art/ArtManagerLocal.java5
-rw-r--r--libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java55
7 files changed, 124 insertions, 7 deletions
diff --git a/artd/artd.cc b/artd/artd.cc
index 68574b2ce8..59f6b88d9f 100644
--- a/artd/artd.cc
+++ b/artd/artd.cc
@@ -1336,12 +1336,14 @@ ScopedAStatus Artd::createCancellationSignal(
return ScopedAStatus::ok();
}
-ScopedAStatus Artd::cleanup(const std::vector<ProfilePath>& in_profilesToKeep,
- const std::vector<ArtifactsPath>& in_artifactsToKeep,
- const std::vector<VdexPath>& in_vdexFilesToKeep,
- const std::vector<RuntimeArtifactsPath>& in_runtimeArtifactsToKeep,
- bool in_keepPreRebootStagedFiles,
- int64_t* _aidl_return) {
+ScopedAStatus Artd::cleanup(
+ const std::vector<ProfilePath>& in_profilesToKeep,
+ const std::vector<ArtifactsPath>& in_artifactsToKeep,
+ const std::vector<VdexPath>& in_vdexFilesToKeep,
+ const std::vector<SecureDexMetadataWithCompanionPaths>& in_SdmSdcFilesToKeep,
+ const std::vector<RuntimeArtifactsPath>& in_runtimeArtifactsToKeep,
+ bool in_keepPreRebootStagedFiles,
+ int64_t* _aidl_return) {
RETURN_FATAL_IF_PRE_REBOOT(options_);
std::unordered_set<std::string> files_to_keep;
for (const ProfilePath& profile : in_profilesToKeep) {
@@ -1359,6 +1361,10 @@ ScopedAStatus Artd::cleanup(const std::vector<ProfilePath>& in_profilesToKeep,
RETURN_FATAL_IF_ARG_IS_PRE_REBOOT(vdex, "vdexFilesToKeep");
files_to_keep.insert(OR_RETURN_FATAL(BuildVdexPath(vdex)));
}
+ for (const SecureDexMetadataWithCompanionPaths& sdm_sdc : in_SdmSdcFilesToKeep) {
+ files_to_keep.insert(OR_RETURN_FATAL(BuildSdmPath(sdm_sdc)));
+ files_to_keep.insert(OR_RETURN_FATAL(BuildSdcPath(sdm_sdc)));
+ }
std::string android_data = OR_RETURN_NON_FATAL(GetAndroidDataOrError());
std::string android_expand = OR_RETURN_NON_FATAL(GetAndroidExpandOrError());
for (const RuntimeArtifactsPath& runtime_image_path : in_runtimeArtifactsToKeep) {
diff --git a/artd/artd.h b/artd/artd.h
index affb180b08..f515e84408 100644
--- a/artd/artd.h
+++ b/artd/artd.h
@@ -245,6 +245,8 @@ class Artd : public aidl::com::android::server::art::BnArtd {
const std::vector<aidl::com::android::server::art::ProfilePath>& in_profilesToKeep,
const std::vector<aidl::com::android::server::art::ArtifactsPath>& in_artifactsToKeep,
const std::vector<aidl::com::android::server::art::VdexPath>& in_vdexFilesToKeep,
+ const std::vector<aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths>&
+ in_SdmSdcFilesToKeep,
const std::vector<aidl::com::android::server::art::RuntimeArtifactsPath>&
in_runtimeArtifactsToKeep,
bool in_keepPreRebootStagedFiles,
diff --git a/artd/artd_test.cc b/artd/artd_test.cc
index d6e383daf3..b7244451fa 100644
--- a/artd/artd_test.cc
+++ b/artd/artd_test.cc
@@ -2230,15 +2230,23 @@ TEST_F(ArtdTest, mergeProfilesWithOptionsDumpClassesAndMethods) {
CheckContent(output_profile.profilePath.tmpPath, "dump");
}
+static std::string EncodeLocationForDalvikCache(const std::string& location) {
+ std::string encoded = location.substr(/*pos=*/1); // Remove the leading '/';
+ std::replace(encoded.begin(), encoded.end(), '/', '@');
+ return encoded;
+}
+
class ArtdCleanupTest : public ArtdTest {
protected:
void SetUpForCleanup() {
// Unmanaged files.
CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/1.odex");
+ CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/1.arm64.sdm");
CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/oat/1.odex");
CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/oat/1.txt");
CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/oat/arm64/1.txt");
CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/oat/arm64/1.tmp");
+ CreateGcKeptFile(android_data_ + "/user_de/0/com.android.foo/oat/arm64/1.sdc");
// Files to keep.
CreateGcKeptFile(android_data_ + "/misc/profiles/cur/1/com.android.foo/primary.prof");
@@ -2266,6 +2274,15 @@ class ArtdCleanupTest : public ArtdTest {
"/123456-7890/user/1/com.android.foo/cache/oat_primary/arm64/base.art");
CreateGcKeptFile(android_data_ +
"/user/0/com.android.foo/cache/not_oat_dir/oat_primary/arm64/base.art");
+ CreateGcKeptFile(android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/base.arm64.sdm");
+ CreateGcKeptFile(android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/oat/arm64/base.sdc");
+ CreateGcKeptFile(android_data_ +
+ "/app/~~jhrwafasr==/com.android.qux-bredcweff==/base.arm64.sdm");
+ CreateGcKeptFile(android_data_ + "/dalvik-cache/arm64/" +
+ EncodeLocationForDalvikCache(android_data_) +
+ "@app@~~jhrwafasr==@com.android.qux-bredcweff==@base.apk@classes.sdc");
// Files to remove.
CreateGcRemovedFile(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof");
@@ -2307,6 +2324,26 @@ class ArtdCleanupTest : public ArtdTest {
"/user/0/com.android.foo/cache/oat_primary/arm64/different_dex.art");
CreateGcRemovedFile(android_data_ +
"/user/0/com.android.foo/cache/oat_primary/different_isa/base.art");
+ CreateGcRemovedFile(android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/different_dex.arm64.sdm");
+ CreateGcRemovedFile(
+ android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/oat/arm64/different_dex.sdc");
+ CreateGcRemovedFile(android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/base.different_isa.sdm");
+ CreateGcRemovedFile(
+ android_data_ +
+ "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/oat/different_isa/base.sdc");
+ CreateGcRemovedFile(android_data_ +
+ "/app/~~jhrwafasr==/com.android.qux-bredcweff==/different_dex.arm64.sdm");
+ CreateGcRemovedFile(
+ android_data_ + "/dalvik-cache/arm64/" + EncodeLocationForDalvikCache(android_data_) +
+ "@app@~~jhrwafasr==@com.android.qux-bredcweff==@different_dex.apk@classes.sdc");
+ CreateGcRemovedFile(android_data_ +
+ "/app/~~jhrwafasr==/com.android.qux-bredcweff==/base.different_isa.sdm");
+ CreateGcRemovedFile(android_data_ + "/dalvik-cache/different_isa/" +
+ EncodeLocationForDalvikCache(android_data_) +
+ "@app@~~jhrwafasr==@com.android.qux-bredcweff==@base.apk@classes.sdc");
}
void CreateGcRemovedFile(const std::string& path) {
@@ -2347,6 +2384,18 @@ class ArtdCleanupTest : public ArtdTest {
.isInDalvikCache = false}},
},
{
+ SecureDexMetadataWithCompanionPaths{
+ .dexPath =
+ android_data_ + "/app/~~fadsfgadg==/com.android.baz-fadsfgadg==/base.apk",
+ .isa = "arm64",
+ .isInDalvikCache = false},
+ SecureDexMetadataWithCompanionPaths{
+ .dexPath =
+ android_data_ + "/app/~~jhrwafasr==/com.android.qux-bredcweff==/base.apk",
+ .isa = "arm64",
+ .isInDalvikCache = true},
+ },
+ {
RuntimeArtifactsPath{
.packageName = "com.android.foo", .dexPath = "/a/b/base.apk", .isa = "arm64"},
},
diff --git a/artd/binder/com/android/server/art/IArtd.aidl b/artd/binder/com/android/server/art/IArtd.aidl
index 8b6ba8b94c..cf4db0341b 100644
--- a/artd/binder/com/android/server/art/IArtd.aidl
+++ b/artd/binder/com/android/server/art/IArtd.aidl
@@ -209,6 +209,7 @@ interface IArtd {
long cleanup(in List<com.android.server.art.ProfilePath> profilesToKeep,
in List<com.android.server.art.ArtifactsPath> artifactsToKeep,
in List<com.android.server.art.VdexPath> vdexFilesToKeep,
+ in List<com.android.server.art.SecureDexMetadataWithCompanionPaths> SdmSdcFilesToKeep,
in List<com.android.server.art.RuntimeArtifactsPath> runtimeArtifactsToKeep,
boolean keepPreRebootStagedFiles);
diff --git a/artd/path_utils.cc b/artd/path_utils.cc
index bb752d00c8..0f269e2dbb 100644
--- a/artd/path_utils.cc
+++ b/artd/path_utils.cc
@@ -108,6 +108,7 @@ std::vector<std::string> ListManagedFiles(const std::string& android_data,
for (const std::string& data_root : {android_data, android_expand + "/*"}) {
// Artifacts for primary dex files.
patterns.push_back(data_root + "/app/*/*/oat/**");
+ patterns.push_back(data_root + "/app/*/*/*.sdm");
for (const char* user_dir : {"/user", "/user_de"}) {
std::string data_dir = data_root + user_dir + "/*/*";
diff --git a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
index acd6063f11..e74a49c337 100644
--- a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
+++ b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
@@ -1123,6 +1123,7 @@ public final class ArtManagerLocal {
// - The dexopt artifacts, if they are up-to-date and the app is not hibernating.
// - Only the VDEX part of the dexopt artifacts, if the dexopt artifacts are outdated
// but the VDEX part is still usable and the app is not hibernating.
+ // - The SDM and SDC files, if they are up-to-date and the app is not hibernating.
// - The runtime artifacts, if dexopt artifacts are fully or partially usable and the
// usable parts don't contain AOT-compiled code. (This logic must be aligned with the
// one that determines when runtime images can be loaded in
@@ -1130,6 +1131,7 @@ public final class ArtManagerLocal {
List<ProfilePath> profilesToKeep = new ArrayList<>();
List<ArtifactsPath> artifactsToKeep = new ArrayList<>();
List<VdexPath> vdexFilesToKeep = new ArrayList<>();
+ List<SecureDexMetadataWithCompanionPaths> sdmSdcFilesToKeep = new ArrayList<>();
List<RuntimeArtifactsPath> runtimeArtifactsToKeep = new ArrayList<>();
for (PackageState pkgState : snapshot.getPackageStates().values()) {
@@ -1150,11 +1152,12 @@ public final class ArtManagerLocal {
mInjector.getArtFileManager().getUsableArtifacts(pkgState, pkg);
artifactsToKeep.addAll(artifactLists.artifacts());
vdexFilesToKeep.addAll(artifactLists.vdexFiles());
+ sdmSdcFilesToKeep.addAll(artifactLists.sdmFiles());
runtimeArtifactsToKeep.addAll(artifactLists.runtimeArtifacts());
}
}
return mInjector.getArtd().cleanup(profilesToKeep, artifactsToKeep, vdexFilesToKeep,
- runtimeArtifactsToKeep,
+ sdmSdcFilesToKeep, runtimeArtifactsToKeep,
SdkLevel.isAtLeastV() && mInjector.getPreRebootDexoptJob().hasStarted());
} catch (RemoteException e) {
Utils.logArtdException(e);
diff --git a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
index b17475480e..567de0acdc 100644
--- a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
+++ b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
@@ -1268,6 +1268,7 @@ public class ArtManagerLocalTest {
"arm64", true /* isInDalvikCache */)),
inAnyOrderDeepEquals(VdexPath.artifactsPath(AidlUtils.buildArtifactsPathAsInput(
"/somewhere/app/foo/split_0.apk", "arm", false /* isInDalvikCache */))),
+ inAnyOrderDeepEquals() /* sdmSdcFilesToKeep */,
inAnyOrderDeepEquals(AidlUtils.buildRuntimeArtifactsPath(
PKG_NAME_1, "/somewhere/app/foo/split_0.apk", "arm64"),
AidlUtils.buildRuntimeArtifactsPath(
@@ -1276,6 +1277,60 @@ public class ArtManagerLocalTest {
}
@Test
+ public void testCleanupDmAndSdm() throws Exception {
+ when(mPreRebootDexoptJob.hasStarted()).thenReturn(false);
+
+ // It should keep 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 keep 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 keep 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 keep 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());
+
+ when(mSnapshot.getPackageStates()).thenReturn(Map.of(PKG_NAME_1, mPkgState1));
+ mArtManagerLocal.cleanup(mSnapshot);
+
+ verify(mArtd).cleanup(any() /* profilesToKeep */,
+ inAnyOrderDeepEquals() /* artifactsToKeep */,
+ inAnyOrderDeepEquals() /* vdexFilesToKeep */,
+ inAnyOrderDeepEquals(AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ "/somewhere/app/foo/base.apk", "arm64",
+ false /* isInDalvikCache */),
+ AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ "/somewhere/app/foo/base.apk", "arm", true /* isInDalvikCache */),
+ AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ "/somewhere/app/foo/split_0.apk", "arm64",
+ false /* isInDalvikCache */)),
+ inAnyOrderDeepEquals(AidlUtils.buildRuntimeArtifactsPath(
+ PKG_NAME_1, "/somewhere/app/foo/split_0.apk", "arm64"),
+ AidlUtils.buildRuntimeArtifactsPath(
+ PKG_NAME_1, "/somewhere/app/foo/split_0.apk", "arm")),
+ eq(false) /* keepPreRebootStagedFiles */);
+ }
+
+ @Test
public void testGetArtManagedFileStatsSystem() throws Exception {
testGetArtManagedFileStats(true /* isSystemOrRootOrShell */);
}