diff options
author | 2025-03-14 21:55:58 +0000 | |
---|---|---|
committer | 2025-03-21 09:37:10 -0700 | |
commit | 9126e6fb2137d43bf6363e82b38bbd3edf428f2c (patch) | |
tree | 0587621dbefe0c73a1a39c7c3403541ad2dfab1b /libartservice | |
parent | f1cf622ecc1a27d95236dd0ec1da0936182ecafd (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')
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); } } } |