summaryrefslogtreecommitdiff
path: root/libartservice
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2025-03-14 21:55:58 +0000
committer Jiakai Zhang <jiakaiz@google.com> 2025-03-21 09:37:10 -0700
commit9126e6fb2137d43bf6363e82b38bbd3edf428f2c (patch)
tree0587621dbefe0c73a1a39c7c3403541ad2dfab1b /libartservice
parentf1cf622ecc1a27d95236dd0ec1da0936182ecafd (diff)
Delete SDM and SDC files on a successful dexopt.
After a successful dexopt (typically during background dexopt job), the SDM and SDC files become obsolete, so we delete them as an optimization, to release disk space as soon as possible. Bug: 377474232 Test: atest ArtServiceTests Test: atest art_standalone_artd_tests Change-Id: I9598e3b6d71a2575d73885cc4d772737f9bfb2b6
Diffstat (limited to 'libartservice')
-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
3 files changed, 50 insertions, 9 deletions
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);
}
}
}