summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2025-03-21 09:41:03 -0700
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-03-21 09:41:03 -0700
commit57e243af5acfe4a20e17d4c0712cf5b48423063d (patch)
tree714c3d1a5009e9777469d09cdbd3a322abe28ea1
parent69982a895b80ce048a17a45216c3298ef091d354 (diff)
parent9126e6fb2137d43bf6363e82b38bbd3edf428f2c (diff)
Delete SDM and SDC files on a successful dexopt. am: 9126e6fb21
Original change: https://android-review.googlesource.com/c/platform/art/+/3545383 Change-Id: I115177d643ab57b4ac3c8af27280f1feaa6ff2e0 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--artd/artd.cc11
-rw-r--r--artd/artd.h4
-rw-r--r--artd/artd_test.cc13
-rw-r--r--artd/binder/com/android/server/art/IArtd.aidl10
-rw-r--r--libartservice/service/java/com/android/server/art/Dexopter.java24
-rw-r--r--libartservice/service/java/com/android/server/art/PrimaryDexopter.java13
-rw-r--r--libartservice/service/javatests/com/android/server/art/PrimaryDexopterParameterizedTest.java22
7 files changed, 88 insertions, 9 deletions
diff --git a/artd/artd.cc b/artd/artd.cc
index 4ef1036fe1..144b783a29 100644
--- a/artd/artd.cc
+++ b/artd/artd.cc
@@ -1432,6 +1432,17 @@ ScopedAStatus Artd::isInDalvikCache(const std::string& in_dexFile, bool* _aidl_r
return NonFatal(ART_FORMAT("Fstab entries not found for '{}'", in_dexFile));
}
+ScopedAStatus Artd::deleteSdmSdcFiles(const SecureDexMetadataWithCompanionPaths& in_SdmSdcPaths,
+ int64_t* _aidl_return) {
+ RETURN_FATAL_IF_PRE_REBOOT(options_);
+
+ std::string sdm_path = OR_RETURN_FATAL(BuildSdmPath(in_SdmSdcPaths));
+ std::string sdc_path = OR_RETURN_FATAL(BuildSdcPath(in_SdmSdcPaths));
+
+ *_aidl_return = GetSizeAndDeleteFile(sdm_path) + GetSizeAndDeleteFile(sdc_path);
+ return ScopedAStatus::ok();
+}
+
ScopedAStatus Artd::deleteRuntimeArtifacts(const RuntimeArtifactsPath& in_runtimeArtifactsPath,
int64_t* _aidl_return) {
RETURN_FATAL_IF_PRE_REBOOT(options_);
diff --git a/artd/artd.h b/artd/artd.h
index f515e84408..d48a209b0d 100644
--- a/artd/artd.h
+++ b/artd/artd.h
@@ -256,6 +256,10 @@ class Artd : public aidl::com::android::server::art::BnArtd {
ndk::ScopedAStatus isInDalvikCache(const std::string& in_dexFile, bool* _aidl_return) override;
+ ndk::ScopedAStatus deleteSdmSdcFiles(
+ const aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths& in_sdmSdcPaths,
+ int64_t* _aidl_return) override;
+
ndk::ScopedAStatus deleteRuntimeArtifacts(
const aidl::com::android::server::art::RuntimeArtifactsPath& in_runtimeArtifactsPath,
int64_t* _aidl_return) override;
diff --git a/artd/artd_test.cc b/artd/artd_test.cc
index b7244451fa..f6eeda7e57 100644
--- a/artd/artd_test.cc
+++ b/artd/artd_test.cc
@@ -2484,6 +2484,19 @@ TEST_F(ArtdTest, isInDalvikCache) {
EXPECT_THAT(is_in_dalvik_cache("/foo"), HasValue(true));
}
+TEST_F(ArtdTest, deleteSdmSdcFiles) {
+ CreateFile(scratch_path_ + "/a/b.arm64.sdm", "**"); // 2 bytes.
+ CreateFile(scratch_path_ + "/a/oat/arm64/b.sdc", "*"); // 1 byte.
+
+ int64_t result = -1;
+ ASSERT_STATUS_OK(artd_->deleteSdmSdcFiles(
+ {.dexPath = scratch_path_ + "/a/b.apk", .isa = "arm64", .isInDalvikCache = false}, &result));
+ EXPECT_EQ(result, 2 + 1);
+
+ EXPECT_FALSE(std::filesystem::exists(scratch_path_ + "/a/b.arm64.sdm"));
+ EXPECT_FALSE(std::filesystem::exists(scratch_path_ + "/a/oat/arm64/b.sdc"));
+}
+
TEST_F(ArtdTest, deleteRuntimeArtifacts) {
std::vector<std::string> removed_files;
std::vector<std::string> kept_files;
diff --git a/artd/binder/com/android/server/art/IArtd.aidl b/artd/binder/com/android/server/art/IArtd.aidl
index cf4db0341b..705076d0a6 100644
--- a/artd/binder/com/android/server/art/IArtd.aidl
+++ b/artd/binder/com/android/server/art/IArtd.aidl
@@ -231,6 +231,16 @@ interface IArtd {
boolean isInDalvikCache(@utf8InCpp String dexFile);
/**
+ * Deletes the SDM and SDC files and returns the released space, in bytes.
+ *
+ * Not supported in Pre-reboot Dexopt mode.
+ *
+ * Throws fatal errors. Logs and ignores non-fatal errors.
+ */
+ long deleteSdmSdcFiles(
+ in com.android.server.art.SecureDexMetadataWithCompanionPaths sdmSdcPaths);
+
+ /**
* Deletes runtime artifacts and returns the released space, in bytes.
*
* Not supported in Pre-reboot Dexopt mode.
diff --git a/libartservice/service/java/com/android/server/art/Dexopter.java b/libartservice/service/java/com/android/server/art/Dexopter.java
index d3bcdbb270..1c6abe6c41 100644
--- a/libartservice/service/java/com/android/server/art/Dexopter.java
+++ b/libartservice/service/java/com/android/server/art/Dexopter.java
@@ -201,14 +201,15 @@ public abstract class Dexopter<DexInfoType extends DetailedDexInfo> {
long sizeBeforeBytes = 0;
Dex2OatResult dex2OatResult = Dex2OatResult.notRun();
@DexoptResult.DexoptResultExtendedStatusFlags int extendedStatusFlags = 0;
+ DexoptTarget<DexInfoType> target = null;
try {
- var target = DexoptTarget.<DexInfoType>builder()
- .setDexInfo(dexInfo)
- .setIsa(abi.isa())
- .setIsInDalvikCache(isInDalvikCache)
- .setCompilerFilter(compilerFilter)
- .setDmPath(dmInfo.dmPath())
- .build();
+ target = DexoptTarget.<DexInfoType>builder()
+ .setDexInfo(dexInfo)
+ .setIsa(abi.isa())
+ .setIsInDalvikCache(isInDalvikCache)
+ .setCompilerFilter(compilerFilter)
+ .setDmPath(dmInfo.dmPath())
+ .build();
var options = GetDexoptNeededOptions.builder()
.setProfileMerged(profileMerged)
.setFlags(mParams.getFlags())
@@ -318,6 +319,9 @@ public abstract class Dexopter<DexInfoType extends DetailedDexInfo> {
AsLog.i(String.format("Dexopt result: [packageName = %s] %s",
mPkgState.getPackageName(), result));
results.add(result);
+
+ onDexoptTargetResult(target, status);
+
if (status != DexoptResult.DEXOPT_SKIPPED
&& status != DexoptResult.DEXOPT_PERFORMED) {
succeeded = false;
@@ -745,6 +749,12 @@ public abstract class Dexopter<DexInfoType extends DetailedDexInfo> {
*/
protected void onDexoptStart(@NonNull DexInfoType dexInfo) throws RemoteException {}
+ /**
+ * Called once for every dex file and every ABI when dexopt has a result.
+ */
+ protected void onDexoptTargetResult(@NonNull DexoptTarget<DexInfoType> target,
+ @DexoptResult.DexoptResultStatus int status) throws RemoteException {}
+
@AutoValue
abstract static class DexoptTarget<DexInfoType extends DetailedDexInfo> {
abstract @NonNull DexInfoType dexInfo();
diff --git a/libartservice/service/java/com/android/server/art/PrimaryDexopter.java b/libartservice/service/java/com/android/server/art/PrimaryDexopter.java
index 70b0713d6d..94ab94e213 100644
--- a/libartservice/service/java/com/android/server/art/PrimaryDexopter.java
+++ b/libartservice/service/java/com/android/server/art/PrimaryDexopter.java
@@ -38,6 +38,7 @@ import com.android.modules.utils.pm.PackageStateModulesUtils;
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.Config;
import com.android.server.art.model.DexoptParams;
+import com.android.server.art.model.DexoptResult;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
@@ -204,6 +205,18 @@ public class PrimaryDexopter extends Dexopter<DetailedPrimaryDexInfo> {
}
}
+ @Override
+ protected void onDexoptTargetResult(@NonNull DexoptTarget<DetailedPrimaryDexInfo> target,
+ @DexoptResult.DexoptResultStatus int status) throws RemoteException {
+ // An optimization to release disk space as soon as possible. The SDM and SDC files would be
+ // deleted by the file GC anyway if not deleted here.
+ if (status == DexoptResult.DEXOPT_PERFORMED && !mInjector.isPreReboot()) {
+ mInjector.getArtd().deleteSdmSdcFiles(
+ AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ target.dexInfo().dexPath(), target.isa(), target.isInDalvikCache()));
+ }
+ }
+
private boolean isSharedLibrary() {
return PackageStateModulesUtils.isLoadableInOtherProcesses(mPkgState, true /* codeOnly */);
}
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterParameterizedTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterParameterizedTest.java
index 10f9f59e91..9c3f87e92e 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterParameterizedTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterParameterizedTest.java
@@ -202,6 +202,7 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
params.mIsPreReboot = true;
params.mExpectedOutputIsPreReboot = true;
params.mExpectedDeletesRuntimeArtifacts = false;
+ params.mExpectedDeletesSdmSdcFiles = false;
list.add(params);
params = new Params();
@@ -385,6 +386,17 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
PKG_NAME, "/somewhere/app/foo/split_0.apk", "arm")));
}
+ if (mParams.mExpectedDeletesSdmSdcFiles) {
+ // Only delete SDM and SDC files for successful dexopt operations, namely the first one
+ // and the fourth one.
+ doReturn(1l).when(mArtd).deleteSdmSdcFiles(
+ deepEq(AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ "/somewhere/app/foo/base.apk", "arm64", mParams.mIsInDalvikCache)));
+ doReturn(1l).when(mArtd).deleteSdmSdcFiles(
+ deepEq(AidlUtils.buildSecureDexMetadataWithCompanionPaths(
+ "/somewhere/app/foo/split_0.apk", "arm", mParams.mIsInDalvikCache)));
+ }
+
assertThat(mPrimaryDexopter.dexopt())
.comparingElementsUsing(TestingUtils.<DexContainerFileDexoptResult>deepEquality())
.containsExactly(
@@ -416,6 +428,10 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
if (!mParams.mExpectedDeletesRuntimeArtifacts) {
verify(mArtd, times(0)).deleteRuntimeArtifacts(any());
}
+
+ if (!mParams.mExpectedDeletesSdmSdcFiles) {
+ verify(mArtd, times(0)).deleteSdmSdcFiles(any());
+ }
}
private static class Params {
@@ -451,6 +467,7 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
public boolean mExpectedIsHiddenApiPolicyEnabled = true;
public boolean mExpectedOutputIsPreReboot = false;
public boolean mExpectedDeletesRuntimeArtifacts = true;
+ public boolean mExpectedDeletesSdmSdcFiles = true;
public String toString() {
return String.format("isInDalvikCache=%b,"
@@ -477,7 +494,8 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
+ "expectedIsDebuggable=%b,"
+ "expectedIsHiddenApiPolicyEnabled=%b,"
+ "expectedOutputIsPreReboot=%b,"
- + "expectedDeleteRuntimeArtifacts=%b",
+ + "expectedDeletesRuntimeArtifacts=%b,"
+ + "expectedDeletesSdmSdcFiles=%b",
mIsInDalvikCache, mHiddenApiEnforcementPolicy, mIsVmSafeMode, mIsDebuggable,
mIsSystemUi, mIsLauncher, mIsUseEmbeddedDex, mIsSanboxSdkLib,
mRequestedCompilerFilter, mCallbackReturnedCompilerFilter, mForce,
@@ -485,7 +503,7 @@ public class PrimaryDexopterParameterizedTest extends PrimaryDexopterTestBase {
mForceCompilerFilter, mAlwaysDebuggable, mExpectedCallbackInputCompilerFilter,
mExpectedCompilerFilter, mExpectedDexoptTrigger, mExpectedIsDebuggable,
mExpectedIsHiddenApiPolicyEnabled, mExpectedOutputIsPreReboot,
- mExpectedDeletesRuntimeArtifacts);
+ mExpectedDeletesRuntimeArtifacts, mExpectedDeletesSdmSdcFiles);
}
}
}