Update artd to support profiles for secondary dex files.
Bug: 249984283
Test: atest ArtServiceTests
Test: m test-art-host-gtest-art_artd_tests
Ignore-AOSP-First: ART Services.
Change-Id: I35e19e7fa2147717754feddbc72a46983dc0d9d8
diff --git a/artd/artd.cc b/artd/artd.cc
index bf2f7b3..ce42a86 100644
--- a/artd/artd.cc
+++ b/artd/artd.cc
@@ -102,7 +102,7 @@
using ::fmt::literals::operator""_format; // NOLINT
using ArtifactsLocation = GetDexoptNeededResult::ArtifactsLocation;
-using TmpRefProfilePath = ProfilePath::TmpRefProfilePath;
+using TmpProfilePath = ProfilePath::TmpProfilePath;
constexpr const char* kServiceName = "artd";
constexpr const char* kArtdCancellationSignalType = "ArtdCancellationSignal";
@@ -448,7 +448,7 @@
const std::string& in_dexFile,
bool* _aidl_return) {
std::string src_path = OR_RETURN_FATAL(BuildProfileOrDmPath(in_src));
- std::string dst_path = OR_RETURN_FATAL(BuildRefProfilePath(in_dst->profilePath.refProfilePath));
+ std::string dst_path = OR_RETURN_FATAL(BuildFinalProfilePath(in_dst->profilePath));
OR_RETURN_FATAL(ValidateDexPath(in_dexFile));
CmdlineBuilder args;
@@ -504,9 +504,9 @@
return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Artd::commitTmpProfile(const TmpRefProfilePath& in_profile) {
- std::string tmp_profile_path = OR_RETURN_FATAL(BuildTmpRefProfilePath(in_profile));
- std::string ref_profile_path = OR_RETURN_FATAL(BuildRefProfilePath(in_profile.refProfilePath));
+ndk::ScopedAStatus Artd::commitTmpProfile(const TmpProfilePath& in_profile) {
+ std::string tmp_profile_path = OR_RETURN_FATAL(BuildTmpProfilePath(in_profile));
+ std::string ref_profile_path = OR_RETURN_FATAL(BuildFinalProfilePath(in_profile));
std::error_code ec;
std::filesystem::rename(tmp_profile_path, ref_profile_path, ec);
@@ -557,7 +557,7 @@
profile_paths.push_back(std::move(profile_path));
}
std::string output_profile_path =
- OR_RETURN_FATAL(BuildRefProfilePath(in_outputProfile->profilePath.refProfilePath));
+ OR_RETURN_FATAL(BuildFinalProfilePath(in_outputProfile->profilePath));
OR_RETURN_FATAL(ValidateDexPath(in_dexFile));
CmdlineBuilder args;
diff --git a/artd/artd.h b/artd/artd.h
index 9c65ed2..c775c4a 100644
--- a/artd/artd.h
+++ b/artd/artd.h
@@ -95,7 +95,7 @@
bool* _aidl_return) override;
ndk::ScopedAStatus commitTmpProfile(
- const aidl::com::android::server::art::ProfilePath::TmpRefProfilePath& in_profile) override;
+ const aidl::com::android::server::art::ProfilePath::TmpProfilePath& in_profile) override;
ndk::ScopedAStatus deleteProfile(
const aidl::com::android::server::art::ProfilePath& in_profile) override;
diff --git a/artd/artd_test.cc b/artd/artd_test.cc
index 6b54517..76cba88 100644
--- a/artd/artd_test.cc
+++ b/artd/artd_test.cc
@@ -97,9 +97,9 @@
using ::testing::SetArgPointee;
using ::testing::WithArg;
-using CurProfilePath = ProfilePath::CurProfilePath;
-using RefProfilePath = ProfilePath::RefProfilePath;
-using TmpRefProfilePath = ProfilePath::TmpRefProfilePath;
+using PrimaryCurProfilePath = ProfilePath::PrimaryCurProfilePath;
+using PrimaryRefProfilePath = ProfilePath::PrimaryRefProfilePath;
+using TmpProfilePath = ProfilePath::TmpProfilePath;
using ::fmt::literals::operator""_format; // NOLINT
@@ -294,14 +294,13 @@
clc_2_ = GetTestDexFileName("Nested");
class_loader_context_ = "PCL[{}:{}]"_format(clc_1_, clc_2_);
compiler_filter_ = "speed";
- TmpRefProfilePath tmp_ref_profile_path{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+ TmpProfilePath tmp_profile_path{
+ .finalPath =
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
.id = "12345"};
- profile_path_ = tmp_ref_profile_path;
+ profile_path_ = tmp_profile_path;
std::filesystem::create_directories(
- std::filesystem::path(OR_FATAL(BuildTmpRefProfilePath(tmp_ref_profile_path)))
- .parent_path());
+ std::filesystem::path(OR_FATAL(BuildFinalProfilePath(tmp_profile_path))).parent_path());
}
void TearDown() override {
@@ -1019,8 +1018,8 @@
}
TEST_F(ArtdTest, copyAndRewriteProfile) {
- const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string src_file = OR_FATAL(BuildTmpRefProfilePath(src));
+ const TmpProfilePath& src = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string src_file = OR_FATAL(BuildTmpProfilePath(src));
CreateFile(src_file, "abc");
OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
dst.profilePath.id = "";
@@ -1045,12 +1044,12 @@
EXPECT_TRUE(artd_->copyAndRewriteProfile(src, &dst, dex_file_, &result).isOk());
EXPECT_TRUE(result);
EXPECT_THAT(dst.profilePath.id, Not(IsEmpty()));
- CheckContent(OR_FATAL(BuildTmpRefProfilePath(dst.profilePath)), "def");
+ CheckContent(OR_FATAL(BuildTmpProfilePath(dst.profilePath)), "def");
}
TEST_F(ArtdTest, copyAndRewriteProfileFalse) {
- const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string src_file = OR_FATAL(BuildTmpRefProfilePath(src));
+ const TmpProfilePath& src = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string src_file = OR_FATAL(BuildTmpProfilePath(src));
CreateFile(src_file, "abc");
OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
dst.profilePath.id = "";
@@ -1068,7 +1067,7 @@
TEST_F(ArtdTest, copyAndRewriteProfileNotFound) {
CreateFile(dex_file_);
- const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
+ const TmpProfilePath& src = profile_path_->get<ProfilePath::tmpProfilePath>();
OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
dst.profilePath.id = "";
@@ -1078,8 +1077,8 @@
}
TEST_F(ArtdTest, copyAndRewriteProfileFailed) {
- const TmpRefProfilePath& src = profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string src_file = OR_FATAL(BuildTmpRefProfilePath(src));
+ const TmpProfilePath& src = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string src_file = OR_FATAL(BuildTmpProfilePath(src));
CreateFile(src_file, "abc");
OutputProfile dst{.profilePath = src, .fsPermission = FsPermission{.uid = -1, .gid = -1}};
dst.profilePath.id = "";
@@ -1097,19 +1096,18 @@
}
TEST_F(ArtdTest, commitTmpProfile) {
- const TmpRefProfilePath& tmp_profile_path = profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string tmp_profile_file = OR_FATAL(BuildTmpRefProfilePath(tmp_profile_path));
+ const TmpProfilePath& tmp_profile_path = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string tmp_profile_file = OR_FATAL(BuildTmpProfilePath(tmp_profile_path));
CreateFile(tmp_profile_file);
EXPECT_TRUE(artd_->commitTmpProfile(tmp_profile_path).isOk());
EXPECT_FALSE(std::filesystem::exists(tmp_profile_file));
- EXPECT_TRUE(
- std::filesystem::exists(OR_FATAL(BuildProfileOrDmPath(tmp_profile_path.refProfilePath))));
+ EXPECT_TRUE(std::filesystem::exists(OR_FATAL(BuildFinalProfilePath(tmp_profile_path))));
}
TEST_F(ArtdTest, commitTmpProfileFailed) {
- const TmpRefProfilePath& tmp_profile_path = profile_path_->get<ProfilePath::tmpRefProfilePath>();
+ const TmpProfilePath& tmp_profile_path = profile_path_->get<ProfilePath::tmpProfilePath>();
ndk::ScopedAStatus status = artd_->commitTmpProfile(tmp_profile_path);
EXPECT_FALSE(status.isOk());
@@ -1118,8 +1116,7 @@
status.getMessage(),
ContainsRegex(R"re(Failed to move .*primary\.prof\.12345\.tmp.* to .*primary\.prof)re"));
- EXPECT_FALSE(
- std::filesystem::exists(OR_FATAL(BuildProfileOrDmPath(tmp_profile_path.refProfilePath))));
+ EXPECT_FALSE(std::filesystem::exists(OR_FATAL(BuildFinalProfilePath(tmp_profile_path))));
}
TEST_F(ArtdTest, deleteProfile) {
@@ -1231,19 +1228,18 @@
}
TEST_F(ArtdTest, mergeProfiles) {
- const TmpRefProfilePath& reference_profile_path =
- profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string reference_profile_file = OR_FATAL(BuildTmpRefProfilePath(reference_profile_path));
+ const TmpProfilePath& reference_profile_path = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string reference_profile_file = OR_FATAL(BuildTmpProfilePath(reference_profile_path));
CreateFile(reference_profile_file, "abc");
// Doesn't exist.
- CurProfilePath profile_0_path{
+ PrimaryCurProfilePath profile_0_path{
.userId = 0, .packageName = "com.android.foo", .profileName = "primary"};
- std::string profile_0_file = OR_FATAL(BuildCurProfilePath(profile_0_path));
+ std::string profile_0_file = OR_FATAL(BuildPrimaryCurProfilePath(profile_0_path));
- CurProfilePath profile_1_path{
+ PrimaryCurProfilePath profile_1_path{
.userId = 1, .packageName = "com.android.foo", .profileName = "primary"};
- std::string profile_1_file = OR_FATAL(BuildCurProfilePath(profile_1_path));
+ std::string profile_1_file = OR_FATAL(BuildPrimaryCurProfilePath(profile_1_path));
CreateFile(profile_1_file, "def");
OutputProfile output_profile{.profilePath = reference_profile_path,
@@ -1277,16 +1273,16 @@
.isOk());
EXPECT_TRUE(result);
EXPECT_THAT(output_profile.profilePath.id, Not(IsEmpty()));
- CheckContent(OR_FATAL(BuildTmpRefProfilePath(output_profile.profilePath)), "merged");
+ CheckContent(OR_FATAL(BuildTmpProfilePath(output_profile.profilePath)), "merged");
}
TEST_F(ArtdTest, mergeProfilesEmptyReferenceProfile) {
- CurProfilePath profile_0_path{
+ PrimaryCurProfilePath profile_0_path{
.userId = 0, .packageName = "com.android.foo", .profileName = "primary"};
- std::string profile_0_file = OR_FATAL(BuildCurProfilePath(profile_0_path));
+ std::string profile_0_file = OR_FATAL(BuildPrimaryCurProfilePath(profile_0_path));
CreateFile(profile_0_file, "def");
- OutputProfile output_profile{.profilePath = profile_path_->get<ProfilePath::tmpRefProfilePath>(),
+ OutputProfile output_profile{.profilePath = profile_path_->get<ProfilePath::tmpProfilePath>(),
.fsPermission = FsPermission{.uid = -1, .gid = -1}};
output_profile.profilePath.id = "";
@@ -1312,24 +1308,23 @@
.isOk());
EXPECT_TRUE(result);
EXPECT_THAT(output_profile.profilePath.id, Not(IsEmpty()));
- CheckContent(OR_FATAL(BuildTmpRefProfilePath(output_profile.profilePath)), "merged");
+ CheckContent(OR_FATAL(BuildTmpProfilePath(output_profile.profilePath)), "merged");
}
TEST_F(ArtdTest, mergeProfilesProfilesDontExist) {
- const TmpRefProfilePath& reference_profile_path =
- profile_path_->get<ProfilePath::tmpRefProfilePath>();
- std::string reference_profile_file = OR_FATAL(BuildTmpRefProfilePath(reference_profile_path));
+ const TmpProfilePath& reference_profile_path = profile_path_->get<ProfilePath::tmpProfilePath>();
+ std::string reference_profile_file = OR_FATAL(BuildTmpProfilePath(reference_profile_path));
CreateFile(reference_profile_file, "abc");
// Doesn't exist.
- CurProfilePath profile_0_path{
+ PrimaryCurProfilePath profile_0_path{
.userId = 0, .packageName = "com.android.foo", .profileName = "primary"};
- std::string profile_0_file = OR_FATAL(BuildCurProfilePath(profile_0_path));
+ std::string profile_0_file = OR_FATAL(BuildPrimaryCurProfilePath(profile_0_path));
// Doesn't exist.
- CurProfilePath profile_1_path{
+ PrimaryCurProfilePath profile_1_path{
.userId = 1, .packageName = "com.android.foo", .profileName = "primary"};
- std::string profile_1_file = OR_FATAL(BuildCurProfilePath(profile_1_path));
+ std::string profile_1_file = OR_FATAL(BuildPrimaryCurProfilePath(profile_1_path));
OutputProfile output_profile{.profilePath = reference_profile_path,
.fsPermission = FsPermission{.uid = -1, .gid = -1}};
diff --git a/artd/binder/com/android/server/art/IArtd.aidl b/artd/binder/com/android/server/art/IArtd.aidl
index 7bed2ff..782334b 100644
--- a/artd/binder/com/android/server/art/IArtd.aidl
+++ b/artd/binder/com/android/server/art/IArtd.aidl
@@ -60,7 +60,7 @@
*
* Throws fatal and non-fatal errors.
*/
- void commitTmpProfile(in com.android.server.art.ProfilePath.TmpRefProfilePath profile);
+ void commitTmpProfile(in com.android.server.art.ProfilePath.TmpProfilePath profile);
/**
* Deletes the profile. Does nothing of the profile doesn't exist.
diff --git a/artd/binder/com/android/server/art/OutputProfile.aidl b/artd/binder/com/android/server/art/OutputProfile.aidl
index cd9627b..50efda2 100644
--- a/artd/binder/com/android/server/art/OutputProfile.aidl
+++ b/artd/binder/com/android/server/art/OutputProfile.aidl
@@ -27,7 +27,7 @@
*
* Only outputing to a temporary file is supported to avoid race condition.
*/
- com.android.server.art.ProfilePath.TmpRefProfilePath profilePath;
+ com.android.server.art.ProfilePath.TmpProfilePath profilePath;
/** The permission of the file. */
com.android.server.art.FsPermission fsPermission;
diff --git a/artd/binder/com/android/server/art/ProfilePath.aidl b/artd/binder/com/android/server/art/ProfilePath.aidl
index afd0fd6..fd413a9 100644
--- a/artd/binder/com/android/server/art/ProfilePath.aidl
+++ b/artd/binder/com/android/server/art/ProfilePath.aidl
@@ -22,29 +22,24 @@
* @hide
*/
union ProfilePath {
- RefProfilePath refProfilePath;
- TmpRefProfilePath tmpRefProfilePath;
+ PrimaryRefProfilePath primaryRefProfilePath;
PrebuiltProfilePath prebuiltProfilePath;
- CurProfilePath curProfilePath;
+ PrimaryCurProfilePath primaryCurProfilePath;
+ SecondaryRefProfilePath secondaryRefProfilePath;
+ SecondaryCurProfilePath secondaryCurProfilePath;
+ TmpProfilePath tmpProfilePath;
+
/** Represents a profile in the dex metadata file. */
com.android.server.art.DexMetadataPath dexMetadataPath;
/** Represents a reference profile. */
- parcelable RefProfilePath {
+ parcelable PrimaryRefProfilePath {
/** The name of the package. */
@utf8InCpp String packageName;
/** The stem of the profile file */
@utf8InCpp String profileName;
}
- /** Represents a temporary reference profile. */
- parcelable TmpRefProfilePath {
- /** The reference profile that this temporary file is for. */
- RefProfilePath refProfilePath;
- /** A unique identifier to distinguish this temporary file from others. Filled by artd. */
- @utf8InCpp String id;
- }
-
/**
* Represents a profile next to a dex file. This is usually a prebuilt profile in the system
* image, but it can also be a profile that package manager can potentially put along with the
@@ -57,7 +52,7 @@
}
/** Represents a current profile. */
- parcelable CurProfilePath {
+ parcelable PrimaryCurProfilePath {
/** The user ID of the user that owns the profile. */
int userId;
/** The name of the package. */
@@ -65,4 +60,35 @@
/** The stem of the profile file */
@utf8InCpp String profileName;
}
+
+ /** Represents a reference profile of a secondary dex file. */
+ parcelable SecondaryRefProfilePath {
+ /**
+ * The path to the dex file that the profile is next to.
+ *
+ * Currently, possible paths are in the format of
+ * `{/data,/mnt/expand/<volume-uuid>}/{user,user_de}/<user-id>/<package-name>/...`.
+ */
+ @utf8InCpp String dexPath;
+ }
+
+ /** Represents a current profile of a secondary dex file. */
+ parcelable SecondaryCurProfilePath {
+ /** The path to the dex file that the profile is next to. */
+ @utf8InCpp String dexPath;
+ }
+
+ /** All types of profile paths that artd can write to. */
+ union WritableProfilePath {
+ PrimaryRefProfilePath forPrimary;
+ SecondaryRefProfilePath forSecondary;
+ }
+
+ /** Represents a temporary profile. */
+ parcelable TmpProfilePath {
+ /** The path that this temporary file will eventually be committed to. */
+ WritableProfilePath finalPath;
+ /** A unique identifier to distinguish this temporary file from others. Filled by artd. */
+ @utf8InCpp String id;
+ }
}
diff --git a/artd/path_utils.cc b/artd/path_utils.cc
index 8314241..8dcc1e9 100644
--- a/artd/path_utils.cc
+++ b/artd/path_utils.cc
@@ -43,10 +43,13 @@
using ::fmt::literals::operator""_format; // NOLINT
-using CurProfilePath = ProfilePath::CurProfilePath;
using PrebuiltProfilePath = ProfilePath::PrebuiltProfilePath;
-using RefProfilePath = ProfilePath::RefProfilePath;
-using TmpRefProfilePath = ProfilePath::TmpRefProfilePath;
+using PrimaryCurProfilePath = ProfilePath::PrimaryCurProfilePath;
+using PrimaryRefProfilePath = ProfilePath::PrimaryRefProfilePath;
+using SecondaryCurProfilePath = ProfilePath::SecondaryCurProfilePath;
+using SecondaryRefProfilePath = ProfilePath::SecondaryRefProfilePath;
+using TmpProfilePath = ProfilePath::TmpProfilePath;
+using WritableProfilePath = ProfilePath::WritableProfilePath;
Result<void> ValidateAbsoluteNormalPath(const std::string& path_str) {
if (path_str.empty()) {
@@ -145,19 +148,13 @@
}
}
-Result<std::string> BuildRefProfilePath(const RefProfilePath& ref_profile_path) {
- OR_RETURN(ValidatePathElement(ref_profile_path.packageName, "packageName"));
- OR_RETURN(ValidatePathElementSubstring(ref_profile_path.profileName, "profileName"));
+Result<std::string> BuildPrimaryRefProfilePath(
+ const PrimaryRefProfilePath& primary_ref_profile_path) {
+ OR_RETURN(ValidatePathElement(primary_ref_profile_path.packageName, "packageName"));
+ OR_RETURN(ValidatePathElementSubstring(primary_ref_profile_path.profileName, "profileName"));
return "{}/misc/profiles/ref/{}/{}.prof"_format(OR_RETURN(GetAndroidDataOrError()),
- ref_profile_path.packageName,
- ref_profile_path.profileName);
-}
-
-Result<std::string> BuildTmpRefProfilePath(const TmpRefProfilePath& tmp_ref_profile_path) {
- OR_RETURN(ValidatePathElementSubstring(tmp_ref_profile_path.id, "id"));
- return NewFile::BuildTempPath(
- OR_RETURN(BuildRefProfilePath(tmp_ref_profile_path.refProfilePath)).c_str(),
- tmp_ref_profile_path.id.c_str());
+ primary_ref_profile_path.packageName,
+ primary_ref_profile_path.profileName);
}
Result<std::string> BuildPrebuiltProfilePath(const PrebuiltProfilePath& prebuilt_profile_path) {
@@ -165,13 +162,47 @@
return prebuilt_profile_path.dexPath + ".prof";
}
-Result<std::string> BuildCurProfilePath(const CurProfilePath& cur_profile_path) {
- OR_RETURN(ValidatePathElement(cur_profile_path.packageName, "packageName"));
- OR_RETURN(ValidatePathElementSubstring(cur_profile_path.profileName, "profileName"));
+Result<std::string> BuildPrimaryCurProfilePath(
+ const PrimaryCurProfilePath& primary_cur_profile_path) {
+ OR_RETURN(ValidatePathElement(primary_cur_profile_path.packageName, "packageName"));
+ OR_RETURN(ValidatePathElementSubstring(primary_cur_profile_path.profileName, "profileName"));
return "{}/misc/profiles/cur/{}/{}/{}.prof"_format(OR_RETURN(GetAndroidDataOrError()),
- cur_profile_path.userId,
- cur_profile_path.packageName,
- cur_profile_path.profileName);
+ primary_cur_profile_path.userId,
+ primary_cur_profile_path.packageName,
+ primary_cur_profile_path.profileName);
+}
+
+Result<std::string> BuildSecondaryRefProfilePath(
+ const SecondaryRefProfilePath& secondary_ref_profile_path) {
+ OR_RETURN(ValidateDexPath(secondary_ref_profile_path.dexPath));
+ std::filesystem::path dex_path(secondary_ref_profile_path.dexPath);
+ return "{}/oat/{}.prof"_format(dex_path.parent_path().string(), dex_path.filename().string());
+}
+
+Result<std::string> BuildSecondaryCurProfilePath(
+ const SecondaryCurProfilePath& secondary_cur_profile_path) {
+ OR_RETURN(ValidateDexPath(secondary_cur_profile_path.dexPath));
+ std::filesystem::path dex_path(secondary_cur_profile_path.dexPath);
+ return "{}/oat/{}.cur.prof"_format(dex_path.parent_path().string(), dex_path.filename().string());
+}
+
+Result<std::string> BuildFinalProfilePath(const TmpProfilePath& tmp_profile_path) {
+ const WritableProfilePath& final_path = tmp_profile_path.finalPath;
+ switch (final_path.getTag()) {
+ case WritableProfilePath::forPrimary:
+ return BuildPrimaryRefProfilePath(final_path.get<WritableProfilePath::forPrimary>());
+ case WritableProfilePath::forSecondary:
+ return BuildSecondaryRefProfilePath(final_path.get<WritableProfilePath::forSecondary>());
+ // No default. All cases should be explicitly handled, or the compilation will fail.
+ }
+ // This should never happen. Just in case we get a non-enumerator value.
+ LOG(FATAL) << "Unexpected writable profile path type {}"_format(final_path.getTag());
+}
+
+Result<std::string> BuildTmpProfilePath(const TmpProfilePath& tmp_profile_path) {
+ OR_RETURN(ValidatePathElementSubstring(tmp_profile_path.id, "id"));
+ return NewFile::BuildTempPath(OR_RETURN(BuildFinalProfilePath(tmp_profile_path)),
+ tmp_profile_path.id);
}
Result<std::string> BuildDexMetadataPath(const DexMetadataPath& dex_metadata_path) {
@@ -186,14 +217,18 @@
Result<std::string> BuildProfileOrDmPath(const ProfilePath& profile_path) {
switch (profile_path.getTag()) {
- case ProfilePath::refProfilePath:
- return BuildRefProfilePath(profile_path.get<ProfilePath::refProfilePath>());
- case ProfilePath::tmpRefProfilePath:
- return BuildTmpRefProfilePath(profile_path.get<ProfilePath::tmpRefProfilePath>());
+ case ProfilePath::primaryRefProfilePath:
+ return BuildPrimaryRefProfilePath(profile_path.get<ProfilePath::primaryRefProfilePath>());
case ProfilePath::prebuiltProfilePath:
return BuildPrebuiltProfilePath(profile_path.get<ProfilePath::prebuiltProfilePath>());
- case ProfilePath::curProfilePath:
- return BuildCurProfilePath(profile_path.get<ProfilePath::curProfilePath>());
+ case ProfilePath::primaryCurProfilePath:
+ return BuildPrimaryCurProfilePath(profile_path.get<ProfilePath::primaryCurProfilePath>());
+ case ProfilePath::secondaryRefProfilePath:
+ return BuildSecondaryRefProfilePath(profile_path.get<ProfilePath::secondaryRefProfilePath>());
+ case ProfilePath::secondaryCurProfilePath:
+ return BuildSecondaryCurProfilePath(profile_path.get<ProfilePath::secondaryCurProfilePath>());
+ case ProfilePath::tmpProfilePath:
+ return BuildTmpProfilePath(profile_path.get<ProfilePath::tmpProfilePath>());
case ProfilePath::dexMetadataPath:
return BuildDexMetadataPath(profile_path.get<ProfilePath::dexMetadataPath>());
// No default. All cases should be explicitly handled, or the compilation will fail.
diff --git a/artd/path_utils.h b/artd/path_utils.h
index 5b2b1d3..bfbbd80 100644
--- a/artd/path_utils.h
+++ b/artd/path_utils.h
@@ -42,17 +42,30 @@
return ReplaceFileExtension(oat_path, "art");
}
-android::base::Result<std::string> BuildRefProfilePath(
- const aidl::com::android::server::art::ProfilePath::RefProfilePath& ref_profile_path);
-
-android::base::Result<std::string> BuildTmpRefProfilePath(
- const aidl::com::android::server::art::ProfilePath::TmpRefProfilePath& tmp_ref_profile_path);
+android::base::Result<std::string> BuildPrimaryRefProfilePath(
+ const aidl::com::android::server::art::ProfilePath::PrimaryRefProfilePath&
+ primary_ref_profile_path);
android::base::Result<std::string> BuildPrebuiltProfilePath(
const aidl::com::android::server::art::ProfilePath::PrebuiltProfilePath& prebuilt_profile_path);
-android::base::Result<std::string> BuildCurProfilePath(
- const aidl::com::android::server::art::ProfilePath::CurProfilePath& cur_profile_path);
+android::base::Result<std::string> BuildPrimaryCurProfilePath(
+ const aidl::com::android::server::art::ProfilePath::PrimaryCurProfilePath&
+ primary_cur_profile_path);
+
+android::base::Result<std::string> BuildSecondaryRefProfilePath(
+ const aidl::com::android::server::art::ProfilePath::SecondaryRefProfilePath&
+ secondary_ref_profile_path);
+
+android::base::Result<std::string> BuildSecondaryCurProfilePath(
+ const aidl::com::android::server::art::ProfilePath::SecondaryCurProfilePath&
+ secondary_cur_profile_path);
+
+android::base::Result<std::string> BuildFinalProfilePath(
+ const aidl::com::android::server::art::ProfilePath::TmpProfilePath& tmp_profile_path);
+
+android::base::Result<std::string> BuildTmpProfilePath(
+ const aidl::com::android::server::art::ProfilePath::TmpProfilePath& tmp_profile_path);
android::base::Result<std::string> BuildDexMetadataPath(
const aidl::com::android::server::art::DexMetadataPath& dex_metadata_path);
diff --git a/artd/path_utils_test.cc b/artd/path_utils_test.cc
index 8188000..508d8c2 100644
--- a/artd/path_utils_test.cc
+++ b/artd/path_utils_test.cc
@@ -33,10 +33,12 @@
using ::android::base::testing::HasValue;
using ::android::base::testing::WithMessage;
-using CurProfilePath = ProfilePath::CurProfilePath;
using PrebuiltProfilePath = ProfilePath::PrebuiltProfilePath;
-using RefProfilePath = ProfilePath::RefProfilePath;
-using TmpRefProfilePath = ProfilePath::TmpRefProfilePath;
+using PrimaryCurProfilePath = ProfilePath::PrimaryCurProfilePath;
+using PrimaryRefProfilePath = ProfilePath::PrimaryRefProfilePath;
+using SecondaryCurProfilePath = ProfilePath::SecondaryCurProfilePath;
+using SecondaryRefProfilePath = ProfilePath::SecondaryRefProfilePath;
+using TmpProfilePath = ProfilePath::TmpProfilePath;
using std::literals::operator""s; // NOLINT
@@ -104,80 +106,110 @@
EXPECT_EQ(OatPathToArtPath("/a/oat/arm64/b.odex"), "/a/oat/arm64/b.art");
}
-TEST_F(PathUtilsTest, BuildRefProfilePath) {
- EXPECT_THAT(BuildRefProfilePath(
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"}),
+TEST_F(PathUtilsTest, BuildPrimaryRefProfilePath) {
+ EXPECT_THAT(BuildPrimaryRefProfilePath(PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof"));
}
-TEST_F(PathUtilsTest, BuildRefProfilePathPackageNameOk) {
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "...", .profileName = "primary"}),
+TEST_F(PathUtilsTest, BuildPrimaryRefProfilePathPackageNameOk) {
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "...", .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/ref/.../primary.prof"));
- EXPECT_THAT(BuildRefProfilePath(
- RefProfilePath{.packageName = "!@#$%^&*()_+-=", .profileName = "primary"}),
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "!@#$%^&*()_+-=", .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/ref/!@#$%^&*()_+-=/primary.prof"));
}
-TEST_F(PathUtilsTest, BuildRefProfilePathPackageNameWrong) {
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "", .profileName = "primary"}),
+TEST_F(PathUtilsTest, BuildPrimaryRefProfilePathPackageNameWrong) {
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "", .profileName = "primary"}),
HasError(WithMessage("packageName is empty")));
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = ".", .profileName = "primary"}),
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = ".", .profileName = "primary"}),
HasError(WithMessage("Invalid packageName '.'")));
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "..", .profileName = "primary"}),
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "..", .profileName = "primary"}),
HasError(WithMessage("Invalid packageName '..'")));
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "a/b", .profileName = "primary"}),
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "a/b", .profileName = "primary"}),
HasError(WithMessage("packageName 'a/b' has invalid character '/'")));
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "a\0b"s, .profileName = "primary"}),
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "a\0b"s, .profileName = "primary"}),
HasError(WithMessage("packageName 'a\0b' has invalid character '\\0'"s)));
}
-TEST_F(PathUtilsTest, BuildRefProfilePathProfileNameOk) {
- EXPECT_THAT(
- BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo", .profileName = "."}),
- HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/..prof"));
- EXPECT_THAT(
- BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo", .profileName = ".."}),
- HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/...prof"));
- EXPECT_THAT(BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo",
- .profileName = "!@#$%^&*()_+-="}),
+TEST_F(PathUtilsTest, BuildPrimaryRefProfilePathProfileNameOk) {
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "."}),
+ HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/..prof"));
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = ".."}),
+ HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/...prof"));
+ EXPECT_THAT(BuildPrimaryRefProfilePath(PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "!@#$%^&*()_+-="}),
HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/!@#$%^&*()_+-=.prof"));
}
-TEST_F(PathUtilsTest, BuildRefProfilePathProfileNameWrong) {
- EXPECT_THAT(
- BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo", .profileName = ""}),
- HasError(WithMessage("profileName is empty")));
- EXPECT_THAT(
- BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo", .profileName = "a/b"}),
- HasError(WithMessage("profileName 'a/b' has invalid character '/'")));
- EXPECT_THAT(
- BuildRefProfilePath(RefProfilePath{.packageName = "com.android.foo", .profileName = "a\0b"s}),
- HasError(WithMessage("profileName 'a\0b' has invalid character '\\0'"s)));
+TEST_F(PathUtilsTest, BuildPrimaryRefProfilePathProfileNameWrong) {
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = ""}),
+ HasError(WithMessage("profileName is empty")));
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "a/b"}),
+ HasError(WithMessage("profileName 'a/b' has invalid character '/'")));
+ EXPECT_THAT(BuildPrimaryRefProfilePath(
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "a\0b"s}),
+ HasError(WithMessage("profileName 'a\0b' has invalid character '\\0'"s)));
}
-TEST_F(PathUtilsTest, BuildTmpRefProfilePath) {
+TEST_F(PathUtilsTest, BuildFinalProfilePathForPrimary) {
+ EXPECT_THAT(BuildFinalProfilePath(TmpProfilePath{
+ .finalPath = PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"},
+ .id = "12345"}),
+ HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof"));
+}
+
+TEST_F(PathUtilsTest, BuildFinalProfilePathForSecondary) {
+ EXPECT_THAT(BuildFinalProfilePath(TmpProfilePath{
+ .finalPath = SecondaryRefProfilePath{.dexPath = android_data_ +
+ "/user/0/com.android.foo/a.apk"},
+ .id = "12345"}),
+ HasValue(android_data_ + "/user/0/com.android.foo/oat/a.apk.prof"));
+}
+
+TEST_F(PathUtilsTest, BuildTmpProfilePathForPrimary) {
EXPECT_THAT(
- BuildTmpRefProfilePath(TmpRefProfilePath{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+ BuildTmpProfilePath(TmpProfilePath{
+ .finalPath =
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
.id = "12345"}),
HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof.12345.tmp"));
}
-TEST_F(PathUtilsTest, BuildTmpRefProfilePathIdWrong) {
- EXPECT_THAT(BuildTmpRefProfilePath(TmpRefProfilePath{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+TEST_F(PathUtilsTest, BuildTmpProfilePathForSecondary) {
+ EXPECT_THAT(BuildTmpProfilePath(TmpProfilePath{
+ .finalPath = SecondaryRefProfilePath{.dexPath = android_data_ +
+ "/user/0/com.android.foo/a.apk"},
+ .id = "12345"}),
+ HasValue(android_data_ + "/user/0/com.android.foo/oat/a.apk.prof.12345.tmp"));
+}
+
+TEST_F(PathUtilsTest, BuildTmpProfilePathIdWrong) {
+ EXPECT_THAT(BuildTmpProfilePath(TmpProfilePath{
+ .finalPath = PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"},
.id = ""}),
HasError(WithMessage("id is empty")));
- EXPECT_THAT(BuildTmpRefProfilePath(TmpRefProfilePath{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+ EXPECT_THAT(BuildTmpProfilePath(TmpProfilePath{
+ .finalPath = PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"},
.id = "123/45"}),
HasError(WithMessage("id '123/45' has invalid character '/'")));
- EXPECT_THAT(BuildTmpRefProfilePath(TmpRefProfilePath{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+ EXPECT_THAT(BuildTmpProfilePath(TmpProfilePath{
+ .finalPath = PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"},
.id = "123\0a"s}),
HasError(WithMessage("id '123\0a' has invalid character '\\0'"s)));
}
@@ -187,12 +219,24 @@
HasValue("/a/b.apk.prof"));
}
-TEST_F(PathUtilsTest, BuildCurProfilePath) {
- EXPECT_THAT(BuildCurProfilePath(CurProfilePath{
+TEST_F(PathUtilsTest, BuildPrimaryCurProfilePath) {
+ EXPECT_THAT(BuildPrimaryCurProfilePath(PrimaryCurProfilePath{
.userId = 1, .packageName = "com.android.foo", .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/cur/1/com.android.foo/primary.prof"));
}
+TEST_F(PathUtilsTest, BuildSecondaryRefProfilePath) {
+ EXPECT_THAT(BuildSecondaryRefProfilePath(SecondaryRefProfilePath{
+ .dexPath = android_data_ + "/user/0/com.android.foo/a.apk"}),
+ HasValue(android_data_ + "/user/0/com.android.foo/oat/a.apk.prof"));
+}
+
+TEST_F(PathUtilsTest, BuildSecondaryCurProfilePath) {
+ EXPECT_THAT(BuildSecondaryCurProfilePath(SecondaryCurProfilePath{
+ .dexPath = android_data_ + "/user/0/com.android.foo/a.apk"}),
+ HasValue(android_data_ + "/user/0/com.android.foo/oat/a.apk.cur.prof"));
+}
+
TEST_F(PathUtilsTest, BuildDexMetadataPath) {
EXPECT_THAT(BuildDexMetadataPath(DexMetadataPath{.dexPath = "/a/b.apk"}), HasValue("/a/b.dm"));
}
@@ -203,18 +247,18 @@
}
TEST_F(PathUtilsTest, BuildProfilePath) {
- EXPECT_THAT(BuildProfileOrDmPath(
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"}),
+ EXPECT_THAT(BuildProfileOrDmPath(PrimaryRefProfilePath{.packageName = "com.android.foo",
+ .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof"));
EXPECT_THAT(
- BuildProfileOrDmPath(TmpRefProfilePath{
- .refProfilePath =
- RefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
+ BuildProfileOrDmPath(TmpProfilePath{
+ .finalPath =
+ PrimaryRefProfilePath{.packageName = "com.android.foo", .profileName = "primary"},
.id = "12345"}),
HasValue(android_data_ + "/misc/profiles/ref/com.android.foo/primary.prof.12345.tmp"));
EXPECT_THAT(BuildProfileOrDmPath(PrebuiltProfilePath{.dexPath = "/a/b.apk"}),
HasValue("/a/b.apk.prof"));
- EXPECT_THAT(BuildProfileOrDmPath(CurProfilePath{
+ EXPECT_THAT(BuildProfileOrDmPath(PrimaryCurProfilePath{
.userId = 1, .packageName = "com.android.foo", .profileName = "primary"}),
HasValue(android_data_ + "/misc/profiles/cur/1/com.android.foo/primary.prof"));
EXPECT_THAT(BuildProfileOrDmPath(DexMetadataPath{.dexPath = "/a/b.apk"}), HasValue("/a/b.dm"));
diff --git a/libartservice/service/java/com/android/server/art/AidlUtils.java b/libartservice/service/java/com/android/server/art/AidlUtils.java
index 26d5df8..f7df305 100644
--- a/libartservice/service/java/com/android/server/art/AidlUtils.java
+++ b/libartservice/service/java/com/android/server/art/AidlUtils.java
@@ -18,10 +18,13 @@
import static com.android.server.art.OutputArtifacts.PermissionSettings;
import static com.android.server.art.OutputArtifacts.PermissionSettings.SeContext;
-import static com.android.server.art.ProfilePath.CurProfilePath;
import static com.android.server.art.ProfilePath.PrebuiltProfilePath;
-import static com.android.server.art.ProfilePath.RefProfilePath;
-import static com.android.server.art.ProfilePath.TmpRefProfilePath;
+import static com.android.server.art.ProfilePath.PrimaryCurProfilePath;
+import static com.android.server.art.ProfilePath.PrimaryRefProfilePath;
+import static com.android.server.art.ProfilePath.SecondaryCurProfilePath;
+import static com.android.server.art.ProfilePath.SecondaryRefProfilePath;
+import static com.android.server.art.ProfilePath.TmpProfilePath;
+import static com.android.server.art.ProfilePath.WritableProfilePath;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -83,18 +86,26 @@
}
@NonNull
- public static RefProfilePath buildRefProfilePath(
+ public static PrimaryRefProfilePath buildPrimaryRefProfilePath(
@NonNull String packageName, @NonNull String profileName) {
- var refProfilePath = new RefProfilePath();
- refProfilePath.packageName = packageName;
- refProfilePath.profileName = profileName;
- return refProfilePath;
+ var primaryRefProfilePath = new PrimaryRefProfilePath();
+ primaryRefProfilePath.packageName = packageName;
+ primaryRefProfilePath.profileName = profileName;
+ return primaryRefProfilePath;
}
@NonNull
- public static ProfilePath buildProfilePathForRef(
+ public static SecondaryRefProfilePath buildSecondaryRefProfilePath(@NonNull String dexPath) {
+ var secondaryRefProfilePath = new SecondaryRefProfilePath();
+ secondaryRefProfilePath.dexPath = dexPath;
+ return secondaryRefProfilePath;
+ }
+
+ @NonNull
+ public static ProfilePath buildProfilePathForPrimaryRef(
@NonNull String packageName, @NonNull String profileName) {
- return ProfilePath.refProfilePath(buildRefProfilePath(packageName, profileName));
+ return ProfilePath.primaryRefProfilePath(
+ buildPrimaryRefProfilePath(packageName, profileName));
}
@NonNull
@@ -110,23 +121,89 @@
}
@NonNull
- public static ProfilePath buildProfilePathForCur(
+ public static ProfilePath buildProfilePathForPrimaryCur(
int userId, @NonNull String packageName, @NonNull String profileName) {
- var curProfilePath = new CurProfilePath();
- curProfilePath.userId = userId;
- curProfilePath.packageName = packageName;
- curProfilePath.profileName = profileName;
- return ProfilePath.curProfilePath(curProfilePath);
+ var primaryCurProfilePath = new PrimaryCurProfilePath();
+ primaryCurProfilePath.userId = userId;
+ primaryCurProfilePath.packageName = packageName;
+ primaryCurProfilePath.profileName = profileName;
+ return ProfilePath.primaryCurProfilePath(primaryCurProfilePath);
}
@NonNull
- public static OutputProfile buildOutputProfile(@NonNull String packageName,
- @NonNull String profileName, int uid, int gid, boolean isPublic) {
+ public static ProfilePath buildProfilePathForSecondaryRef(@NonNull String dexPath) {
+ return ProfilePath.secondaryRefProfilePath(buildSecondaryRefProfilePath(dexPath));
+ }
+
+ @NonNull
+ public static ProfilePath buildProfilePathForSecondaryCur(@NonNull String dexPath) {
+ var secondaryCurProfilePath = new SecondaryCurProfilePath();
+ secondaryCurProfilePath.dexPath = dexPath;
+ return ProfilePath.secondaryCurProfilePath(secondaryCurProfilePath);
+ }
+
+ @NonNull
+ private static OutputProfile buildOutputProfile(
+ @NonNull WritableProfilePath finalPath, int uid, int gid, boolean isPublic) {
var outputProfile = new OutputProfile();
- outputProfile.profilePath = new TmpRefProfilePath();
- outputProfile.profilePath.refProfilePath = buildRefProfilePath(packageName, profileName);
+ outputProfile.profilePath = new TmpProfilePath();
+ outputProfile.profilePath.finalPath = finalPath;
outputProfile.profilePath.id = ""; // Will be filled by artd.
outputProfile.fsPermission = buildFsPermission(uid, gid, isPublic);
return outputProfile;
}
+
+ @NonNull
+ public static OutputProfile buildOutputProfileForPrimary(@NonNull String packageName,
+ @NonNull String profileName, int uid, int gid, boolean isPublic) {
+ return buildOutputProfile(WritableProfilePath.forPrimary(
+ buildPrimaryRefProfilePath(packageName, profileName)),
+ uid, gid, isPublic);
+ }
+
+ @NonNull
+ public static OutputProfile buildOutputProfileForSecondary(
+ @NonNull String dexPath, int uid, int gid, boolean isPublic) {
+ return buildOutputProfile(
+ WritableProfilePath.forSecondary(buildSecondaryRefProfilePath(dexPath)), uid, gid,
+ isPublic);
+ }
+
+ @NonNull
+ public static String toString(@NonNull PrimaryRefProfilePath profile) {
+ return String.format(
+ "[packageName = %s, profileName = %s]", profile.packageName, profile.profileName);
+ }
+
+ @NonNull
+ public static String toString(@NonNull SecondaryRefProfilePath profile) {
+ return String.format("[dexPath = %s]", profile.dexPath);
+ }
+
+ @NonNull
+ public static String toString(@NonNull WritableProfilePath profile) {
+ switch (profile.getTag()) {
+ case WritableProfilePath.forPrimary:
+ return toString(profile.getForPrimary());
+ case WritableProfilePath.forSecondary:
+ return toString(profile.getForSecondary());
+ default:
+ throw new IllegalStateException(
+ "Unknown WritableProfilePath tag " + profile.getTag());
+ }
+ }
+
+ @NonNull
+ public static String toString(@NonNull ProfilePath profile) {
+ switch (profile.getTag()) {
+ case ProfilePath.primaryRefProfilePath:
+ return toString(profile.getPrimaryRefProfilePath());
+ case ProfilePath.secondaryRefProfilePath:
+ return toString(profile.getSecondaryRefProfilePath());
+ default:
+ throw new UnsupportedOperationException(
+ "Only reference profile paths are supported to be converted to string, got "
+ + profile.getTag());
+ }
+ }
}
diff --git a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
index a80bb05..ef7d659 100644
--- a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
+++ b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
@@ -20,8 +20,8 @@
import static com.android.server.art.OutputArtifacts.PermissionSettings;
import static com.android.server.art.OutputArtifacts.PermissionSettings.SeContext;
import static com.android.server.art.PrimaryDexUtils.DetailedPrimaryDexInfo;
-import static com.android.server.art.ProfilePath.RefProfilePath;
-import static com.android.server.art.ProfilePath.TmpRefProfilePath;
+import static com.android.server.art.ProfilePath.TmpProfilePath;
+import static com.android.server.art.ProfilePath.WritableProfilePath;
import static com.android.server.art.Utils.Abi;
import static com.android.server.art.model.ArtFlags.OptimizeFlags;
import static com.android.server.art.model.OptimizeResult.DexContainerFileOptimizeResult;
@@ -134,8 +134,7 @@
ProfilePath mergedProfile =
mergeProfiles(pkgState, dexInfo, appId, sharedGid, profile);
if (mergedProfile != null) {
- if (profile != null
- && profile.getTag() == ProfilePath.tmpRefProfilePath) {
+ if (profile != null && profile.getTag() == ProfilePath.tmpProfilePath) {
mInjector.getArtd().deleteProfile(profile);
}
profile = mergedProfile;
@@ -236,9 +235,9 @@
}
if (profile != null && succeeded) {
- if (profile.getTag() == ProfilePath.tmpRefProfilePath) {
+ if (profile.getTag() == ProfilePath.tmpProfilePath) {
// Commit the profile only if dexopt succeeds.
- if (commitProfileChanges(profile.getTmpRefProfilePath())) {
+ if (commitProfileChanges(profile.getTmpProfilePath())) {
profile = null;
}
}
@@ -256,7 +255,7 @@
}
}
} finally {
- if (profile != null && profile.getTag() == ProfilePath.tmpRefProfilePath) {
+ if (profile != null && profile.getTag() == ProfilePath.tmpProfilePath) {
mInjector.getArtd().deleteProfile(profile);
}
}
@@ -315,7 +314,7 @@
private ProfilePath initReferenceProfile(@NonNull PackageState pkgState,
@NonNull DetailedPrimaryDexInfo dexInfo, int uid, int gid) throws RemoteException {
String profileName = getProfileName(dexInfo.splitName());
- OutputProfile output = AidlUtils.buildOutputProfile(
+ OutputProfile output = AidlUtils.buildOutputProfileForPrimary(
pkgState.getPackageName(), profileName, uid, gid, true /* isPublic */);
ProfilePath prebuiltProfile = AidlUtils.buildProfilePathForPrebuilt(dexInfo.dexPath());
@@ -327,26 +326,24 @@
// case is necessary.
if (mInjector.getArtd().copyAndRewriteProfile(
prebuiltProfile, output, dexInfo.dexPath())) {
- return ProfilePath.tmpRefProfilePath(output.profilePath);
+ return ProfilePath.tmpProfilePath(output.profilePath);
}
} catch (ServiceSpecificException e) {
Log.e(TAG,
- String.format(
- "Failed to use prebuilt profile [packageName = %s, profileName = %s]",
- pkgState.getPackageName(), profileName),
+ "Failed to use prebuilt profile "
+ + AidlUtils.toString(output.profilePath.finalPath),
e);
}
ProfilePath dmProfile = AidlUtils.buildProfilePathForDm(dexInfo.dexPath());
try {
if (mInjector.getArtd().copyAndRewriteProfile(dmProfile, output, dexInfo.dexPath())) {
- return ProfilePath.tmpRefProfilePath(output.profilePath);
+ return ProfilePath.tmpProfilePath(output.profilePath);
}
} catch (ServiceSpecificException e) {
Log.e(TAG,
- String.format("Failed to use profile in dex metadata file "
- + "[packageName = %s, profileName = %s]",
- pkgState.getPackageName(), profileName),
+ "Failed to use profile in dex metadata file "
+ + AidlUtils.toString(output.profilePath.finalPath),
e);
}
@@ -366,7 +363,7 @@
@NonNull DetailedPrimaryDexInfo dexInfo, int uid, int gid) throws RemoteException {
String profileName = getProfileName(dexInfo.splitName());
ProfilePath refProfile =
- AidlUtils.buildProfilePathForRef(pkgState.getPackageName(), profileName);
+ AidlUtils.buildProfilePathForPrimaryRef(pkgState.getPackageName(), profileName);
try {
if (mInjector.getArtd().isProfileUsable(refProfile, dexInfo.dexPath())) {
boolean isOtherReadable = mInjector.getArtd().getProfileVisibility(refProfile)
@@ -375,9 +372,8 @@
}
} catch (ServiceSpecificException e) {
Log.e(TAG,
- String.format("Failed to use the existing reference profile "
- + "[packageName = %s, profileName = %s]",
- pkgState.getPackageName(), profileName),
+ "Failed to use the existing reference profile "
+ + AidlUtils.toString(refProfile),
e);
}
@@ -529,17 +525,12 @@
}
}
- private boolean commitProfileChanges(@NonNull TmpRefProfilePath profile)
- throws RemoteException {
+ private boolean commitProfileChanges(@NonNull TmpProfilePath profile) throws RemoteException {
try {
mInjector.getArtd().commitTmpProfile(profile);
return true;
} catch (ServiceSpecificException e) {
- RefProfilePath refProfilePath = profile.refProfilePath;
- Log.e(TAG,
- String.format(
- "Failed to commit profile changes [packageName = %s, profileName = %s]",
- refProfilePath.packageName, refProfilePath.profileName),
+ Log.e(TAG, "Failed to commit profile changes " + AidlUtils.toString(profile.finalPath),
e);
return false;
}
@@ -550,18 +541,17 @@
@NonNull DetailedPrimaryDexInfo dexInfo, int uid, int gid,
@Nullable ProfilePath referenceProfile) throws RemoteException {
String profileName = getProfileName(dexInfo.splitName());
- OutputProfile output = AidlUtils.buildOutputProfile(
+ OutputProfile output = AidlUtils.buildOutputProfileForPrimary(
pkgState.getPackageName(), profileName, uid, gid, false /* isPublic */);
try {
if (mInjector.getArtd().mergeProfiles(getCurProfiles(pkgState, dexInfo),
referenceProfile, output, dexInfo.dexPath())) {
- return ProfilePath.tmpRefProfilePath(output.profilePath);
+ return ProfilePath.tmpProfilePath(output.profilePath);
}
} catch (ServiceSpecificException e) {
Log.e(TAG,
- String.format("Failed to merge profiles [packageName = %s, profileName = %s]",
- pkgState.getPackageName(), getProfileName(dexInfo.splitName())),
+ "Failed to merge profiles " + AidlUtils.toString(output.profilePath.finalPath),
e);
}
@@ -584,7 +574,7 @@
int userId = handle.getIdentifier();
PackageUserState userState = pkgState.getStateForUser(handle);
if (userState.isInstalled()) {
- profiles.add(AidlUtils.buildProfilePathForCur(
+ profiles.add(AidlUtils.buildProfilePathForPrimaryCur(
userId, pkgState.getPackageName(), getProfileName(dexInfo.splitName())));
}
}
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
index 2eae691..504be90 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
@@ -68,17 +68,18 @@
new OptimizeParams.Builder("install").setCompilerFilter("speed-profile").build();
private final String mDexPath = "/data/app/foo/base.apk";
- private final ProfilePath mRefProfile = AidlUtils.buildProfilePathForRef(PKG_NAME, "primary");
+ private final ProfilePath mRefProfile =
+ AidlUtils.buildProfilePathForPrimaryRef(PKG_NAME, "primary");
private final ProfilePath mPrebuiltProfile = AidlUtils.buildProfilePathForPrebuilt(mDexPath);
private final ProfilePath mDmProfile = AidlUtils.buildProfilePathForDm(mDexPath);
- private final OutputProfile mPublicOutputProfile = AidlUtils.buildOutputProfile(
+ private final OutputProfile mPublicOutputProfile = AidlUtils.buildOutputProfileForPrimary(
PKG_NAME, "primary", UID, SHARED_GID, true /* isOtherReadable */);
- private final OutputProfile mPrivateOutputProfile = AidlUtils.buildOutputProfile(
+ private final OutputProfile mPrivateOutputProfile = AidlUtils.buildOutputProfileForPrimary(
PKG_NAME, "primary", UID, SHARED_GID, false /* isOtherReadable */);
private final String mSplit0DexPath = "/data/app/foo/split_0.apk";
private final ProfilePath mSplit0RefProfile =
- AidlUtils.buildProfilePathForRef(PKG_NAME, "split_0.split");
+ AidlUtils.buildProfilePathForPrimaryRef(PKG_NAME, "split_0.split");
private final int mDefaultDexoptTrigger = DexoptTrigger.COMPILER_FILTER_IS_BETTER
| DexoptTrigger.PRIMARY_BOOT_IMAGE_BECOMES_USABLE;
@@ -232,9 +233,9 @@
deepEq(mPrebuiltProfile), deepEq(mPublicOutputProfile), eq(mDexPath));
checkDexoptWithPublicProfile(inOrder.verify(mArtd), mDexPath, "arm64",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
checkDexoptWithPublicProfile(inOrder.verify(mArtd), mDexPath, "arm",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
inOrder.verify(mArtd).commitTmpProfile(deepEq(mPublicOutputProfile.profilePath));
@@ -258,28 +259,29 @@
InOrder inOrder = inOrder(mArtd);
inOrder.verify(mArtd).mergeProfiles(
- deepEq(List.of(
- AidlUtils.buildProfilePathForCur(0 /* userId */, PKG_NAME, "primary"),
- AidlUtils.buildProfilePathForCur(2 /* userId */, PKG_NAME, "primary"))),
+ deepEq(List.of(AidlUtils.buildProfilePathForPrimaryCur(
+ 0 /* userId */, PKG_NAME, "primary"),
+ AidlUtils.buildProfilePathForPrimaryCur(
+ 2 /* userId */, PKG_NAME, "primary"))),
deepEq(mRefProfile), deepEq(mPrivateOutputProfile), eq(mDexPath));
// It should use `mBetterOrSameDexoptTrigger` and the merged profile for both ISAs.
inOrder.verify(mArtd).getDexoptNeeded(eq(mDexPath), eq("arm64"), any(), eq("speed-profile"),
eq(mBetterOrSameDexoptTrigger));
checkDexoptWithPrivateProfile(inOrder.verify(mArtd), mDexPath, "arm64",
- ProfilePath.tmpRefProfilePath(mPrivateOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPrivateOutputProfile.profilePath));
inOrder.verify(mArtd).getDexoptNeeded(eq(mDexPath), eq("arm"), any(), eq("speed-profile"),
eq(mBetterOrSameDexoptTrigger));
checkDexoptWithPrivateProfile(inOrder.verify(mArtd), mDexPath, "arm",
- ProfilePath.tmpRefProfilePath(mPrivateOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPrivateOutputProfile.profilePath));
inOrder.verify(mArtd).commitTmpProfile(deepEq(mPrivateOutputProfile.profilePath));
- inOrder.verify(mArtd).deleteProfile(
- deepEq(AidlUtils.buildProfilePathForCur(0 /* userId */, PKG_NAME, "primary")));
- inOrder.verify(mArtd).deleteProfile(
- deepEq(AidlUtils.buildProfilePathForCur(2 /* userId */, PKG_NAME, "primary")));
+ inOrder.verify(mArtd).deleteProfile(deepEq(
+ AidlUtils.buildProfilePathForPrimaryCur(0 /* userId */, PKG_NAME, "primary")));
+ inOrder.verify(mArtd).deleteProfile(deepEq(
+ AidlUtils.buildProfilePathForPrimaryCur(2 /* userId */, PKG_NAME, "primary")));
}
@Test
@@ -320,9 +322,9 @@
deepEq(mDmProfile), deepEq(mPublicOutputProfile), eq(mDexPath));
checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
verifyProfileNotUsed(mRefProfile);
verifyProfileNotUsed(mPrebuiltProfile);
@@ -341,7 +343,7 @@
mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams, mCancellationSignal);
verify(mArtd).deleteProfile(
- deepEq(ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath)));
+ deepEq(ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath)));
verify(mArtd, never()).commitTmpProfile(deepEq(mPublicOutputProfile.profilePath));
}
@@ -372,12 +374,12 @@
verify(mArtd).getDexoptNeeded(
eq(mDexPath), eq("arm64"), any(), eq("speed-profile"), eq(mForceDexoptTrigger));
checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm64",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
verify(mArtd).getDexoptNeeded(
eq(mDexPath), eq("arm"), any(), eq("speed-profile"), eq(mForceDexoptTrigger));
checkDexoptWithPublicProfile(verify(mArtd), mDexPath, "arm",
- ProfilePath.tmpRefProfilePath(mPublicOutputProfile.profilePath));
+ ProfilePath.tmpProfilePath(mPublicOutputProfile.profilePath));
checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm64", "speed");
checkDexoptWithNoProfile(verify(mArtd), mSplit0DexPath, "arm", "speed");