Don't copy reference profile beforehand.

It's better to copy the reference profile during the merge. If the
reference profile is copied beforehand, it's hard to make the remaining
logic fluent.

Bug: 248318911
Test: atest ArtServiceTests
Ignore-AOSP-First: ART Services.
Change-Id: Ib961944286be946ae1cd9a503faf12d9e14afd14
diff --git a/artd/artd.cc b/artd/artd.cc
index 8e55194..20dbe16 100644
--- a/artd/artd.cc
+++ b/artd/artd.cc
@@ -90,11 +90,9 @@
 using ::android::base::Error;
 using ::android::base::Join;
 using ::android::base::make_scope_guard;
-using ::android::base::ReadFileToString;
 using ::android::base::Result;
 using ::android::base::Split;
 using ::android::base::StringReplace;
-using ::android::base::WriteStringToFd;
 using ::art::tools::CmdlineBuilder;
 using ::ndk::ScopedAStatus;
 
@@ -422,29 +420,6 @@
   return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Artd::copyProfile(const ProfilePath& in_src, OutputProfile* in_dst) {
-  std::string src_path = OR_RETURN_FATAL(BuildProfileOrDmPath(in_src));
-  if (in_src.getTag() == ProfilePath::dexMetadataPath) {
-    return Fatal("Does not support DM file, got '{}'"_format(src_path));
-  }
-  std::string dst_path = OR_RETURN_FATAL(BuildRefProfilePath(in_dst->profilePath.refProfilePath));
-
-  std::string content;
-  if (!ReadFileToString(src_path, &content)) {
-    return NonFatal("Failed to read file '{}': {}"_format(src_path, strerror(errno)));
-  }
-
-  std::unique_ptr<NewFile> dst =
-      OR_RETURN_NON_FATAL(NewFile::Create(dst_path, in_dst->fsPermission));
-  if (!WriteStringToFd(content, dst->Fd())) {
-    return NonFatal("Failed to write file '{}': {}"_format(dst_path, strerror(errno)));
-  }
-
-  OR_RETURN_NON_FATAL(dst->Keep());
-  in_dst->profilePath.id = dst->TempId();
-  return ScopedAStatus::ok();
-}
-
 ndk::ScopedAStatus Artd::copyAndRewriteProfile(const ProfilePath& in_src,
                                                OutputProfile* in_dst,
                                                const std::string& in_dexFile,
diff --git a/artd/artd.h b/artd/artd.h
index d2952a2..dd4b022 100644
--- a/artd/artd.h
+++ b/artd/artd.h
@@ -88,9 +88,6 @@
                                      const std::string& in_dexFile,
                                      bool* _aidl_return) override;
 
-  ndk::ScopedAStatus copyProfile(const aidl::com::android::server::art::ProfilePath& in_src,
-                                 ::aidl::com::android::server::art::OutputProfile* in_dst) override;
-
   ndk::ScopedAStatus copyAndRewriteProfile(
       const aidl::com::android::server::art::ProfilePath& in_src,
       aidl::com::android::server::art::OutputProfile* in_dst,
diff --git a/artd/artd_test.cc b/artd/artd_test.cc
index f39e2cd..63d13c2 100644
--- a/artd/artd_test.cc
+++ b/artd/artd_test.cc
@@ -979,32 +979,6 @@
   EXPECT_THAT(status.getMessage(), HasSubstr("profman returned an unexpected code: 100"));
 }
 
-TEST_F(ArtdTest, copyProfile) {
-  const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
-  std::string src_file = OR_FATAL(BuildTmpRefProfilePath(src));
-  CreateFile(src_file, "abc");
-  OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
-  dst.profilePath.id = "";
-
-  EXPECT_TRUE(artd_->copyProfile(src, &dst).isOk());
-
-  EXPECT_THAT(dst.profilePath.id, Not(IsEmpty()));
-  CheckContent(OR_FATAL(BuildTmpRefProfilePath(dst.profilePath)), "abc");
-}
-
-TEST_F(ArtdTest, copyProfileFailed) {
-  const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
-  OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
-  dst.profilePath.id = "";
-
-  ndk::ScopedAStatus status = artd_->copyProfile(src, &dst);
-
-  EXPECT_FALSE(status.isOk());
-  EXPECT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
-  EXPECT_THAT(status.getMessage(),
-              ContainsRegex(R"re(Failed to read file .*primary\.prof\.12345\.tmp)re"));
-}
-
 TEST_F(ArtdTest, copyAndRewriteProfile) {
   const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
   std::string src_file = OR_FATAL(BuildTmpRefProfilePath(src));
diff --git a/artd/binder/com/android/server/art/IArtd.aidl b/artd/binder/com/android/server/art/IArtd.aidl
index 04ab0b5..04de116 100644
--- a/artd/binder/com/android/server/art/IArtd.aidl
+++ b/artd/binder/com/android/server/art/IArtd.aidl
@@ -46,16 +46,6 @@
             @utf8InCpp String dexFile);
 
     /**
-     * Copies the profile. Throws if `src` does not exist. Fills `dst.profilePath.id` on success.
-     *
-     * Does not operate on a DM file.
-     *
-     * Throws fatal and non-fatal errors.
-     */
-    void copyProfile(in com.android.server.art.ProfilePath src,
-            inout com.android.server.art.OutputProfile dst);
-
-    /**
      * Copies the profile and rewrites it for the given dex file. Returns true and fills
      * `dst.profilePath.id` if the operation succeeds and `src` exists and contains entries that
      * match the given dex file.
diff --git a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
index f30fe0b..fa2af7a 100644
--- a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
+++ b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
@@ -38,6 +38,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.art.model.ArtFlags;
@@ -99,7 +100,7 @@
         boolean isInDalvikCache = Utils.isInDalvikCache(pkgState);
 
         for (DetailedPrimaryDexInfo dexInfo : PrimaryDexUtils.getDetailedDexInfo(pkgState, pkg)) {
-            OutputProfile profile = null;
+            ProfilePath profile = null;
             boolean succeeded = true;
             try {
                 if (!dexInfo.hasCode()) {
@@ -112,13 +113,19 @@
 
                 boolean needsToBeShared = isSharedLibrary(pkg)
                         || mInjector.isUsedByOtherApps(pkgState.getPackageName());
+                boolean isOtherReadable = true;
                 // If true, implies that the profile has changed since the last compilation.
                 boolean profileMerged = false;
                 if (DexFile.isProfileGuidedCompilerFilter(compilerFilter)) {
                     if (needsToBeShared) {
                         profile = initReferenceProfile(pkgState, dexInfo, uid, sharedGid);
                     } else {
-                        profile = copyOrInitReferenceProfile(pkgState, dexInfo, uid, sharedGid);
+                        Pair<ProfilePath, Boolean> pair =
+                                getOrInitReferenceProfile(pkgState, dexInfo, uid, sharedGid);
+                        if (pair != null) {
+                            profile = pair.first;
+                            isOtherReadable = pair.second;
+                        }
                         // TODO(jiakaiz): Merge profiles.
                     }
                     if (profile == null) {
@@ -135,8 +142,7 @@
                         DexFile.isProfileGuidedCompilerFilter(compilerFilter);
                 assert isProfileGuidedCompilerFilter == (profile != null);
 
-                boolean canBePublic =
-                        !isProfileGuidedCompilerFilter || profile.fsPermission.isOtherReadable;
+                boolean canBePublic = !isProfileGuidedCompilerFilter || isOtherReadable;
                 assert Utils.implies(needsToBeShared, canBePublic);
                 PermissionSettings permissionSettings =
                         getPermissionSettings(sharedGid, canBePublic);
@@ -169,10 +175,6 @@
                             continue;
                         }
 
-                        ProfilePath inputProfile = profile != null
-                                ? ProfilePath.tmpRefProfilePath(profile.profilePath)
-                                : null;
-
                         IArtdCancellationSignal artdCancellationSignal =
                                 mInjector.getArtd().createCancellationSignal();
                         cancellationSignal.setOnCancelListener(() -> {
@@ -184,7 +186,7 @@
                             }
                         });
 
-                        DexoptResult dexoptResult = dexoptFile(target, inputProfile,
+                        DexoptResult dexoptResult = dexoptFile(target, profile,
                                 getDexoptNeededResult, permissionSettings,
                                 params.getPriorityClass(), dexoptOptions, artdCancellationSignal);
                         status = dexoptResult.cancelled ? OptimizeResult.OPTIMIZE_CANCELLED
@@ -219,16 +221,17 @@
                 }
 
                 if (profile != null && succeeded) {
-                    // Commit the profile only if dexopt succeeds.
-                    if (commitProfileChanges(profile)) {
-                        profile = null;
+                    if (profile.getTag() == ProfilePath.tmpRefProfilePath) {
+                        // Commit the profile only if dexopt succeeds.
+                        if (commitProfileChanges(profile.getTmpRefProfilePath())) {
+                            profile = null;
+                        }
                     }
                     // TODO(jiakaiz): If profileMerged is true, clear current profiles.
                 }
             } finally {
-                if (profile != null) {
-                    mInjector.getArtd().deleteProfile(
-                            ProfilePath.tmpRefProfilePath(profile.profilePath));
+                if (profile != null && profile.getTag() == ProfilePath.tmpRefProfilePath) {
+                    mInjector.getArtd().deleteProfile(profile);
                 }
             }
         }
@@ -283,7 +286,7 @@
      * null otherwise.
      */
     @Nullable
-    private OutputProfile initReferenceProfile(@NonNull PackageState pkgState,
+    private ProfilePath initReferenceProfile(@NonNull PackageState pkgState,
             @NonNull DetailedPrimaryDexInfo dexInfo, int uid, int gid) throws RemoteException {
         String profileName = getProfileName(dexInfo.splitName());
         OutputProfile output = AidlUtils.buildOutputProfile(
@@ -298,7 +301,7 @@
             // case is necessary.
             if (mInjector.getArtd().copyAndRewriteProfile(
                         prebuiltProfile, output, dexInfo.dexPath())) {
-                return output;
+                return ProfilePath.tmpRefProfilePath(output.profilePath);
             }
         } catch (ServiceSpecificException e) {
             Log.e(TAG,
@@ -311,7 +314,7 @@
         ProfilePath dmProfile = AidlUtils.buildProfilePathForDm(dexInfo.dexPath());
         try {
             if (mInjector.getArtd().copyAndRewriteProfile(dmProfile, output, dexInfo.dexPath())) {
-                return output;
+                return ProfilePath.tmpRefProfilePath(output.profilePath);
             }
         } catch (ServiceSpecificException e) {
             Log.e(TAG,
@@ -325,11 +328,15 @@
     }
 
     /**
-     * Copies the existing reference profile if exists, or initializes a reference profile
-     * otherwise.
+     * Gets the existing reference profile if exists, or initializes a reference profile from an
+     * external profile.
+     *
+     * @return A pair where the first element is the found or initialized profile, and the second
+     *         element is true if the profile is readable by others. Or null if there is no
+     *         reference profile or external profile to use.
      */
     @Nullable
-    private OutputProfile copyOrInitReferenceProfile(@NonNull PackageState pkgState,
+    private Pair<ProfilePath, Boolean> getOrInitReferenceProfile(@NonNull PackageState pkgState,
             @NonNull DetailedPrimaryDexInfo dexInfo, int uid, int gid) throws RemoteException {
         String profileName = getProfileName(dexInfo.splitName());
         ProfilePath refProfile =
@@ -338,10 +345,7 @@
             if (mInjector.getArtd().isProfileUsable(refProfile, dexInfo.dexPath())) {
                 boolean isOtherReadable = mInjector.getArtd().getProfileVisibility(refProfile)
                         == FileVisibility.OTHER_READABLE;
-                OutputProfile output = AidlUtils.buildOutputProfile(pkgState.getPackageName(),
-                        getProfileName(dexInfo.splitName()), uid, gid, isOtherReadable);
-                mInjector.getArtd().copyProfile(refProfile, output);
-                return output;
+                return Pair.create(refProfile, isOtherReadable);
             }
         } catch (ServiceSpecificException e) {
             Log.e(TAG,
@@ -351,7 +355,8 @@
                     e);
         }
 
-        return initReferenceProfile(pkgState, dexInfo, uid, gid);
+        ProfilePath initializedProfile = initReferenceProfile(pkgState, dexInfo, uid, gid);
+        return initializedProfile != null ? Pair.create(initializedProfile, true) : null;
     }
 
     @NonNull
@@ -498,12 +503,12 @@
         }
     }
 
-    boolean commitProfileChanges(@NonNull OutputProfile profile) throws RemoteException {
+    boolean commitProfileChanges(@NonNull TmpRefProfilePath profile) throws RemoteException {
         try {
-            mInjector.getArtd().commitTmpProfile(profile.profilePath);
+            mInjector.getArtd().commitTmpProfile(profile);
             return true;
         } catch (ServiceSpecificException e) {
-            RefProfilePath refProfilePath = profile.profilePath.refProfilePath;
+            RefProfilePath refProfilePath = profile.refProfilePath;
             Log.e(TAG,
                     String.format(
                             "Failed to commit profile changes [packageName = %s, profileName = %s]",
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
index 8eb0bfe..7cce870 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
@@ -78,8 +78,6 @@
     private final String mSplit0DexPath = "/data/app/foo/split_0.apk";
     private final ProfilePath mSplit0RefProfile =
             AidlUtils.buildProfilePathForRef(PKG_NAME, "split_0.split");
-    private final OutputProfile mSplit0PrivateOutputProfile = AidlUtils.buildOutputProfile(
-            PKG_NAME, "split_0.split", UID, SHARED_GID, false /* isOtherReadable */);
 
     private final int mDefaultDexoptTrigger = DexoptTrigger.COMPILER_FILTER_IS_BETTER
             | DexoptTrigger.PRIMARY_BOOT_IMAGE_BECOMES_USABLE;
@@ -175,30 +173,22 @@
 
         mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
 
-        InOrder inOrder = inOrder(mArtd);
-
-        inOrder.verify(mArtd).copyProfile(deepEq(mRefProfile), deepEq(mPrivateOutputProfile));
-
-        inOrder.verify(mArtd).getDexoptNeeded(
+        verify(mArtd).getDexoptNeeded(
                 eq(mDexPath), eq("arm64"), any(), eq("speed-profile"), eq(mDefaultDexoptTrigger));
-        checkDexoptWithPrivateProfile(
-                inOrder.verify(mArtd), mDexPath, "arm64", mPrivateOutputProfile);
+        checkDexoptWithPrivateProfile(verify(mArtd), mDexPath, "arm64", mRefProfile);
 
-        inOrder.verify(mArtd).getDexoptNeeded(
+        verify(mArtd).getDexoptNeeded(
                 eq(mDexPath), eq("arm"), any(), eq("speed-profile"), eq(mDefaultDexoptTrigger));
-        checkDexoptWithPrivateProfile(
-                inOrder.verify(mArtd), mDexPath, "arm", mPrivateOutputProfile);
-
-        inOrder.verify(mArtd).commitTmpProfile(deepEq(mPrivateOutputProfile.profilePath));
+        checkDexoptWithPrivateProfile(verify(mArtd), mDexPath, "arm", mRefProfile);
 
         // There is no profile for split 0, so it should fall back to "verify".
-        inOrder.verify(mArtd).getDexoptNeeded(
+        verify(mArtd).getDexoptNeeded(
                 eq(mSplit0DexPath), eq("arm64"), any(), eq("verify"), eq(mDefaultDexoptTrigger));
-        checkDexoptWithNoProfile(inOrder.verify(mArtd), mSplit0DexPath, "arm64", "verify");
+        checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm64", "verify");
 
-        inOrder.verify(mArtd).getDexoptNeeded(
+        verify(mArtd).getDexoptNeeded(
                 eq(mSplit0DexPath), eq("arm"), any(), eq("verify"), eq(mDefaultDexoptTrigger));
-        checkDexoptWithNoProfile(inOrder.verify(mArtd), mSplit0DexPath, "arm", "verify");
+        checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm", "verify");
 
         verifyProfileNotUsed(mPrebuiltProfile);
         verifyProfileNotUsed(mDmProfile);
@@ -217,10 +207,8 @@
 
         mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
 
-        verify(mArtd).copyProfile(deepEq(mRefProfile), deepEq(mPublicOutputProfile));
-
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64", mPublicOutputProfile);
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm", mPublicOutputProfile);
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64", mRefProfile);
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm", mRefProfile);
 
         verifyProfileNotUsed(mPrebuiltProfile);
         verifyProfileNotUsed(mDmProfile);
@@ -234,11 +222,17 @@
 
         mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
 
-        verify(mArtd).copyAndRewriteProfile(
+        InOrder inOrder = inOrder(mArtd);
+
+        inOrder.verify(mArtd).copyAndRewriteProfile(
                 deepEq(mPrebuiltProfile), deepEq(mPublicOutputProfile), eq(mDexPath));
 
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64", mPublicOutputProfile);
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm", mPublicOutputProfile);
+        checkDexoptWithPublicProfile(inOrder.verify(mArtd), mDexPath, "arm64",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+        checkDexoptWithPublicProfile(inOrder.verify(mArtd), mDexPath, "arm",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+
+        inOrder.verify(mArtd).commitTmpProfile(deepEq(mPublicOutputProfile.profilePath));
 
         verifyProfileNotUsed(mRefProfile);
         verifyProfileNotUsed(mDmProfile);
@@ -255,8 +249,10 @@
         verify(mArtd).copyAndRewriteProfile(
                 deepEq(mDmProfile), deepEq(mPublicOutputProfile), eq(mDexPath));
 
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64", mPublicOutputProfile);
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm", mPublicOutputProfile);
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
 
         verifyProfileNotUsed(mRefProfile);
         verifyProfileNotUsed(mPrebuiltProfile);
@@ -264,9 +260,9 @@
 
     @Test
     public void testDexoptDeletesProfileOnFailure() throws Exception {
-        makeProfileUsable(mRefProfile);
-        when(mArtd.getProfileVisibility(deepEq(mRefProfile)))
-                .thenReturn(FileVisibility.NOT_OTHER_READABLE);
+        makeProfileNotUsable(mRefProfile);
+        makeProfileNotUsable(mPrebuiltProfile);
+        makeProfileUsable(mDmProfile);
 
         when(mArtd.dexopt(any(), eq(mDexPath), any(), any(), any(), any(), any(), anyInt(), any(),
                      any()))
@@ -275,8 +271,8 @@
         mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
 
         verify(mArtd).deleteProfile(
-                deepEq(ProfilePath.tmpRefProfilePath(mPrivateOutputProfile.profilePath)));
-        verify(mArtd, never()).commitTmpProfile(deepEq(mPrivateOutputProfile.profilePath));
+                deepEq(ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath)));
+        verify(mArtd, never()).commitTmpProfile(deepEq(mPublicOutputProfile.profilePath));
     }
 
     @Test
@@ -302,11 +298,13 @@
         // It should re-compile anyway.
         verify(mArtd).getDexoptNeeded(
                 eq(mDexPath), eq("arm64"), any(), eq("speed-profile"), eq(mForceDexoptTrigger));
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64", mPublicOutputProfile);
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
 
         verify(mArtd).getDexoptNeeded(
                 eq(mDexPath), eq("arm"), any(), eq("speed-profile"), eq(mForceDexoptTrigger));
-        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm", mPublicOutputProfile);
+        checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm",
+                ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
 
         checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm64", "speed");
         checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm", "speed");
@@ -343,17 +341,13 @@
 
         mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
 
-        verify(mArtd).copyProfile(deepEq(mSplit0RefProfile), deepEq(mSplit0PrivateOutputProfile));
-
         verify(mArtd).getDexoptNeeded(eq(mSplit0DexPath), eq("arm64"), any(), eq("speed-profile"),
                 eq(mDefaultDexoptTrigger));
-        checkDexoptWithPrivateProfile(
-                verify(mArtd), mSplit0DexPath, "arm64", mSplit0PrivateOutputProfile);
+        checkDexoptWithPrivateProfile(verify(mArtd), mSplit0DexPath, "arm64", mSplit0RefProfile);
 
         verify(mArtd).getDexoptNeeded(eq(mSplit0DexPath), eq("arm"), any(), eq("speed-profile"),
                 eq(mDefaultDexoptTrigger));
-        checkDexoptWithPrivateProfile(
-                verify(mArtd), mSplit0DexPath, "arm", mSplit0PrivateOutputProfile);
+        checkDexoptWithPrivateProfile(verify(mArtd), mSplit0DexPath, "arm", mSplit0RefProfile);
     }
 
     @Test
@@ -435,22 +429,20 @@
     }
 
     private void checkDexoptWithPublicProfile(
-            IArtd artd, String dexPath, String isa, OutputProfile profile) throws Exception {
+            IArtd artd, String dexPath, String isa, ProfilePath profile) throws Exception {
         artd.dexopt(
                 argThat(artifacts
                         -> artifacts.permissionSettings.fileFsPermission.isOtherReadable == true),
-                eq(dexPath), eq(isa), any(), eq("speed-profile"),
-                deepEq(ProfilePath.tmpRefProfilePath(profile.profilePath)), any(), anyInt(),
+                eq(dexPath), eq(isa), any(), eq("speed-profile"), deepEq(profile), any(), anyInt(),
                 argThat(dexoptOptions -> dexoptOptions.generateAppImage == true), any());
     }
 
     private void checkDexoptWithPrivateProfile(
-            IArtd artd, String dexPath, String isa, OutputProfile profile) throws Exception {
+            IArtd artd, String dexPath, String isa, ProfilePath profile) throws Exception {
         artd.dexopt(
                 argThat(artifacts
                         -> artifacts.permissionSettings.fileFsPermission.isOtherReadable == false),
-                eq(dexPath), eq(isa), any(), eq("speed-profile"),
-                deepEq(ProfilePath.tmpRefProfilePath(profile.profilePath)), any(), anyInt(),
+                eq(dexPath), eq(isa), any(), eq("speed-profile"), deepEq(profile), any(), anyInt(),
                 argThat(dexoptOptions -> dexoptOptions.generateAppImage == true), any());
     }