Compile the entire bootclasspath on device.
Most of the changes in this CL are renaming and comment changes. The
main behavior changes are:
1. Adding all bootclasspath jars (including the ones in the ART APEX) to
`--dex-file` and `--dex-fd`.
2. Adding both the ART boot profile and the framework profile to
`--profile-fd`.
3. Replacing the `--boot-image` flag with `--base` for compiling boot
classpath jars.
4. Renaming the boot image on /data from `boot-framework.art` to
`boot.art`.
5. Updating the `--boot-image` flag for compiling system_server jars.
6. Updating the default boot image location that the runtime uses.
Bug: 203492478
Test: atest art_standalone_odrefresh_tests
Test: atest art_standalone_artd_tests
Test: atest odsign_e2e_tests
Change-Id: If56bc96ec6f38335f3e8e1ad3085e231baacb6fc
diff --git a/artd/binder/private/com/android/art/DexoptBcpExtArgs.aidl b/artd/binder/private/com/android/art/DexoptBcpExtArgs.aidl
index 43fd922..8253ead 100644
--- a/artd/binder/private/com/android/art/DexoptBcpExtArgs.aidl
+++ b/artd/binder/private/com/android/art/DexoptBcpExtArgs.aidl
@@ -44,7 +44,7 @@
// manually.
String[] bootClasspaths;
int[] bootClasspathFds;
- int profileFd = -1;
+ int[] profileFds;
int dirtyImageObjectsFd = -1;
// Output file descriptors
int oatFd = -1;
diff --git a/artd/binder/private/com/android/art/DexoptSystemServerArgs.aidl b/artd/binder/private/com/android/art/DexoptSystemServerArgs.aidl
index bfb94e1..54aa867 100644
--- a/artd/binder/private/com/android/art/DexoptSystemServerArgs.aidl
+++ b/artd/binder/private/com/android/art/DexoptSystemServerArgs.aidl
@@ -60,7 +60,7 @@
String dexPath;
String oatLocation;
String[] classloaderContext;
- boolean isBootImageOnSystem;
+ String bootImage;
boolean classloaderContextAsParent;
// SECURITY: The server may accept the request to produce code for the specified architecture,
diff --git a/artd/libdexopt.cc b/artd/libdexopt.cc
index 853f950..b6982c1 100644
--- a/artd/libdexopt.cc
+++ b/artd/libdexopt.cc
@@ -43,11 +43,6 @@
using android::base::Error;
using android::base::Result;
-std::string GetBootImage() {
- // Typically "/apex/com.android.art/javalib/boot.art".
- return art::GetArtRoot() + "/javalib/boot.art";
-}
-
std::string GetEnvironmentVariableOrDie(const char* name) {
const char* value = getenv(name);
LOG_ALWAYS_FATAL_IF(value == nullptr, "%s is not defined.", name);
@@ -206,8 +201,10 @@
cmdline.emplace_back("--instruction-set=" + ToInstructionSetString(args.isa));
- if (args.profileFd >= 0) {
- cmdline.emplace_back(android::base::StringPrintf("--profile-file-fd=%d", args.profileFd));
+ if (!args.profileFds.empty()) {
+ for (int fd : args.profileFds) {
+ cmdline.emplace_back(android::base::StringPrintf("--profile-file-fd=%d", fd));
+ }
cmdline.emplace_back("--compiler-filter=speed-profile");
} else {
cmdline.emplace_back("--compiler-filter=speed");
@@ -216,8 +213,7 @@
// Compile as a single image for fewer files and slightly less memory overhead.
cmdline.emplace_back("--single-image");
- // Set boot-image and expectation of compiling boot classpath extensions.
- cmdline.emplace_back("--boot-image=" + GetBootImage());
+ cmdline.emplace_back(android::base::StringPrintf("--base=0x%08x", ART_BASE_ADDRESS));
if (args.dirtyImageObjectsFd >= 0) {
cmdline.emplace_back(android::base::StringPrintf("--dirty-image-objects-fd=%d",
@@ -321,23 +317,7 @@
android::base::Join(args.classloaderFds, ':'));
}
- // Derive boot image
- // b/197176583
- // If the boot extension artifacts are not on /data, then boot extensions are not re-compiled
- // and the artifacts must exist on /system.
- std::vector<std::string> jar_paths = android::base::Split(GetDex2oatBootClasspath(), ":");
- auto iter = std::find_if_not(jar_paths.begin(), jar_paths.end(), &LocationIsOnArtModule);
- if (iter == jar_paths.end()) {
- return Error() << "Missing BCP extension compatible JAR";
- }
- const std::string& first_boot_extension_compatible_jars = *iter;
- // TODO(197176583): Support compiling against BCP extension in /system.
- const std::string extension_image = GetBootImagePath(args.isBootImageOnSystem,
- first_boot_extension_compatible_jars);
- if (extension_image.empty()) {
- return Error() << "Can't identify the first boot extension compatible jar";
- }
- cmdline.emplace_back("--boot-image=" + GetBootImage() + ":" + extension_image);
+ cmdline.emplace_back("--boot-image=" + args.bootImage);
AddDex2OatConcurrencyArguments(cmdline, args.threads, args.cpuSet);
diff --git a/artd/libdexopt_test.cc b/artd/libdexopt_test.cc
index e73c5d6..3cc340b 100644
--- a/artd/libdexopt_test.cc
+++ b/artd/libdexopt_test.cc
@@ -58,7 +58,7 @@
default_bcp_ext_args_.bootClasspaths = android::base::Split(
GetEnvironmentVariableOrDie("DEX2OATBOOTCLASSPATH"), ":"); // from art_artd_tests.xml
default_bcp_ext_args_.bootClasspathFds = {21, 22};
- default_bcp_ext_args_.profileFd = 30;
+ default_bcp_ext_args_.profileFds = {30, 31};
default_bcp_ext_args_.dirtyImageObjectsFd = 31;
default_bcp_ext_args_.imageFd = 90;
default_bcp_ext_args_.vdexFd = 91;
@@ -90,7 +90,7 @@
default_system_server_args_.compilerFilter = CompilerFilter::SPEED_PROFILE;
default_system_server_args_.cpuSet = {0, 1};
default_system_server_args_.threads = 42;
- default_system_server_args_.isBootImageOnSystem = true;
+ default_system_server_args_.bootImage = "/path/to/boot.art";
ASSERT_EQ(default_system_server_args_.bootClasspaths.size(),
default_system_server_args_.bootClasspathFds.size());
}
@@ -134,32 +134,35 @@
{
std::vector<std::string> cmdline = Dex2oatArgsFromBcpExtensionArgs(default_bcp_ext_args_);
- EXPECT_THAT(cmdline, AllOf(
- Contains("--dex-fd=10"),
- Contains("--dex-fd=11"),
- Contains("--dex-file=/path/to/foo.jar"),
- Contains("--dex-file=/path/to/bar.jar"),
- Contains(HasSubstr("-Xbootclasspath:")),
- Contains("-Xbootclasspathfds:21:22"),
+ EXPECT_THAT(cmdline,
+ AllOf(Contains("--dex-fd=10"),
+ Contains("--dex-fd=11"),
+ Contains("--dex-file=/path/to/foo.jar"),
+ Contains("--dex-file=/path/to/bar.jar"),
+ Contains(HasSubstr("-Xbootclasspath:")),
+ Contains("-Xbootclasspathfds:21:22"),
- Contains("--profile-file-fd=30"),
- Contains("--compiler-filter=speed-profile"),
+ Contains("--profile-file-fd=30"),
+ Contains("--profile-file-fd=31"),
+ Contains("--compiler-filter=speed-profile"),
- Contains("--image-fd=90"),
- Contains("--output-vdex-fd=91"),
- Contains("--oat-fd=92"),
- Contains("--oat-location=/oat/location/bar.odex"),
+ Contains("--image-fd=90"),
+ Contains("--output-vdex-fd=91"),
+ Contains("--oat-fd=92"),
+ Contains("--oat-location=/oat/location/bar.odex"),
- Contains("--dirty-image-objects-fd=31"),
- Contains("--instruction-set=x86_64"),
- Contains("--cpu-set=0,1"),
- Contains("-j42")));
+ Contains("--dirty-image-objects-fd=31"),
+ Contains("--instruction-set=x86_64"),
+ Contains("--cpu-set=0,1"),
+ Contains("-j42"),
+
+ Contains(HasSubstr("--base="))));
}
// No profile
{
auto args = default_bcp_ext_args_;
- args.profileFd = -1;
+ args.profileFds = {};
std::vector<std::string> cmdline = Dex2oatArgsFromBcpExtensionArgs(args);
EXPECT_THAT(cmdline, AllOf(
@@ -224,29 +227,31 @@
{
std::vector<std::string> cmdline = Dex2oatArgsFromSystemServerArgs(default_system_server_args_);
- EXPECT_THAT(cmdline, AllOf(
- Contains("--dex-fd=10"),
- Contains("--dex-file=/path/to/foo.jar"),
- Contains(HasSubstr("-Xbootclasspath:")),
- Contains("-Xbootclasspathfds:21:22:23"),
- Contains("-Xbootclasspathimagefds:-1:31:-1"),
- Contains("-Xbootclasspathvdexfds:-1:32:-1"),
- Contains("-Xbootclasspathoatfds:-1:33:-1"),
+ EXPECT_THAT(cmdline,
+ AllOf(Contains("--dex-fd=10"),
+ Contains("--dex-file=/path/to/foo.jar"),
+ Contains(HasSubstr("-Xbootclasspath:")),
+ Contains("-Xbootclasspathfds:21:22:23"),
+ Contains("-Xbootclasspathimagefds:-1:31:-1"),
+ Contains("-Xbootclasspathvdexfds:-1:32:-1"),
+ Contains("-Xbootclasspathoatfds:-1:33:-1"),
- Contains("--profile-file-fd=11"),
- Contains("--compiler-filter=speed-profile"),
+ Contains("--profile-file-fd=11"),
+ Contains("--compiler-filter=speed-profile"),
- Contains("--app-image-fd=90"),
- Contains("--output-vdex-fd=91"),
- Contains("--oat-fd=92"),
- Contains("--oat-location=/oat/location/bar.odex"),
+ Contains("--app-image-fd=90"),
+ Contains("--output-vdex-fd=91"),
+ Contains("--oat-fd=92"),
+ Contains("--oat-location=/oat/location/bar.odex"),
- Contains("--class-loader-context-fds=40:41"),
- Contains("--class-loader-context=PCL[/cl/abc.jar:/cl/def.jar]"),
+ Contains("--class-loader-context-fds=40:41"),
+ Contains("--class-loader-context=PCL[/cl/abc.jar:/cl/def.jar]"),
- Contains("--instruction-set=x86_64"),
- Contains("--cpu-set=0,1"),
- Contains("-j42")));
+ Contains("--instruction-set=x86_64"),
+ Contains("--cpu-set=0,1"),
+ Contains("-j42"),
+
+ Contains("--boot-image=/path/to/boot.art")));
}
// Test different compiler filters
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index bc08f30..07402a3 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -283,65 +283,33 @@
return GetAndroidDir(kArtApexDataEnvVar, kArtApexDataDefaultPath, /*must_exist=*/false);
}
-static std::string GetFirstBootClasspathExtensionJar(const std::string& android_root) {
- DCHECK(kIsTargetBuild);
-
- // This method finds the first non-APEX DEX file in the boot class path as defined by the
- // DEX2OATBOOTCLASSPATH environment variable. This corresponds to the first boot classpath
- // extension (see IMAGE SECTION documentation in image.h). When on-device signing is used the
- // boot class extensions are compiled together as a single image with a name derived from the
- // first extension. This first boot classpath extension is usually
- // '/system/framework/framework.jar'.
- //
- // DEX2OATBOOTCLASSPATH is generated at build time by in the init.environ.rc.in:
- // ${ANDROID_BUILD_TOP}/system/core/rootdir/Android.mk
- // and initialized on Android by init in init.environ.rc:
- // ${ANDROID_BUILD_TOP}/system/core/rootdir/init.environ.rc.in.
- // It is used by installd too.
- const char* bcp = getenv("DEX2OATBOOTCLASSPATH");
- const std::string kDefaultBcpExtensionJar = android_root + "/framework/framework.jar";
- if (bcp != nullptr) {
- for (std::string_view component : SplitString(bcp, ':')) {
- if (component.empty()) {
- continue;
- }
- if (!LocationIsOnApex(component)) {
- return std::string{component};
- }
- }
- }
- return kDefaultBcpExtensionJar;
-}
-
std::string GetDefaultBootImageLocation(const std::string& android_root,
bool deny_art_apex_data_files) {
constexpr static const char* kJavalibBootArt = "javalib/boot.art";
constexpr static const char* kEtcBootImageProf = "etc/boot-image.prof";
- // Boot image consists of two parts:
- // - the primary boot image in the ART APEX (contains the Core Libraries)
- // - the boot image extensions (contains framework libraries) on the system partition, or
- // in the ART APEX data directory, if an update for the ART module has been been installed.
+ // If an update for the ART module has been been installed, a single boot image for the entire
+ // bootclasspath is in the ART APEX data directory.
if (kIsTargetBuild && !deny_art_apex_data_files) {
- // If the ART APEX has been updated, the compiled boot image extension will be in the ART APEX
- // data directory (assuming there is space and we trust the artifacts there). Otherwise, for a factory installed ART APEX it is
- // under $ANDROID_ROOT/framework/.
- const std::string first_extension_jar{GetFirstBootClasspathExtensionJar(android_root)};
- const std::string boot_extension_image = GetApexDataBootImage(first_extension_jar);
- const std::string boot_extension_filename =
- GetSystemImageFilename(boot_extension_image.c_str(), kRuntimeISA);
- if (OS::FileExists(boot_extension_filename.c_str(), /*check_file_type=*/true)) {
- return StringPrintf("%s/%s:%s!%s/%s",
+ const std::string boot_image =
+ GetApexDataDalvikCacheDirectory(InstructionSet::kNone) + "/boot.art";
+ const std::string boot_image_filename = GetSystemImageFilename(boot_image.c_str(), kRuntimeISA);
+ if (OS::FileExists(boot_image_filename.c_str(), /*check_file_type=*/true)) {
+ return StringPrintf("%s!%s/%s!%s/%s",
+ boot_image.c_str(),
kAndroidArtApexDefaultPath,
- kJavalibBootArt,
- boot_extension_image.c_str(),
+ kEtcBootImageProf,
android_root.c_str(),
kEtcBootImageProf);
} else if (errno == EACCES) {
// Additional warning for potential SELinux misconfiguration.
- PLOG(ERROR) << "Default boot image check failed, could not stat: " << boot_extension_image;
+ PLOG(ERROR) << "Default boot image check failed, could not stat: " << boot_image_filename;
}
}
+ // Boot image consists of two parts:
+ // - the primary boot image in the ART APEX (contains the Core Libraries)
+ // - the boot image extensions (contains framework libraries) on the system partition
+ // TODO(b/211973309): Update this once the primary boot image is moved.
return StringPrintf("%s/%s:%s/framework/boot-framework.art!%s/%s",
kAndroidArtApexDefaultPath,
kJavalibBootArt,
@@ -358,18 +326,6 @@
return GetDefaultBootImageLocation(android_root, /*deny_art_apex_data_files=*/false);
}
-std::string GetBootImagePath(bool on_system, const std::string& jar_path) {
- if (on_system) {
- const std::string jar_name = android::base::Basename(jar_path);
- const std::string image_name = ReplaceFileExtension(jar_name, "art");
- // Typically "/system/framework/boot-framework.art".
- return StringPrintf("%s/framework/boot-%s", GetAndroidRoot().c_str(), image_name.c_str());
- } else {
- // Typically "/data/misc/apexdata/com.android.art/dalvik-cache/boot-framework.art".
- return GetApexDataBootImage(jar_path);
- }
-}
-
static /*constinit*/ std::string_view dalvik_cache_sub_dir = "dalvik-cache";
void OverrideDalvikCacheSubDirectory(std::string sub_dir) {
diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h
index 709ac12..97abc73 100644
--- a/libartbase/base/file_utils.h
+++ b/libartbase/base/file_utils.h
@@ -77,9 +77,6 @@
std::string GetDefaultBootImageLocation(const std::string& android_root,
bool deny_art_apex_data_files);
-// Returns the boot image path of the provided jar, on /system or /data.
-std::string GetBootImagePath(bool on_system, const std::string& jar_path);
-
// Allows the name to be used for the dalvik cache directory (normally "dalvik-cache") to be
// overridden with a new value.
void OverrideDalvikCacheSubDirectory(std::string sub_dir);
diff --git a/odrefresh/odr_artifacts.h b/odrefresh/odr_artifacts.h
index 66d76f0..30932e2 100644
--- a/odrefresh/odr_artifacts.h
+++ b/odrefresh/odr_artifacts.h
@@ -28,7 +28,7 @@
// A grouping of odrefresh generated artifacts.
class OdrArtifacts {
public:
- static OdrArtifacts ForBootImageExtension(const std::string& image_path) {
+ static OdrArtifacts ForBootImage(const std::string& image_path) {
return OdrArtifacts(image_path, "oat");
}
diff --git a/odrefresh/odr_artifacts_test.cc b/odrefresh/odr_artifacts_test.cc
index 76f2c28..b47f2a7 100644
--- a/odrefresh/odr_artifacts_test.cc
+++ b/odrefresh/odr_artifacts_test.cc
@@ -27,7 +27,7 @@
static constexpr const char* kOdrefreshArtifactDirectory = "/test/dir";
-TEST(OdrArtifactsTest, ForBootImageExtension) {
+TEST(OdrArtifactsTest, ForBootImage) {
ScopedUnsetEnvironmentVariable no_env("ART_APEX_DATA");
setenv("ART_APEX_DATA", kOdrefreshArtifactDirectory, /* overwrite */ 1);
@@ -37,7 +37,7 @@
const std::string image_filename =
GetSystemImageFilename(image_location.c_str(), InstructionSet::kArm64);
- const auto artifacts = OdrArtifacts::ForBootImageExtension(image_filename);
+ const auto artifacts = OdrArtifacts::ForBootImage(image_filename);
CHECK_EQ(std::string(kOdrefreshArtifactDirectory) + "/dalvik-cache/arm64/boot-framework.art",
artifacts.ImagePath());
CHECK_EQ(std::string(kOdrefreshArtifactDirectory) + "/dalvik-cache/arm64/boot-framework.oat",
diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h
index f5676e1..7b89a83 100644
--- a/odrefresh/odr_config.h
+++ b/odrefresh/odr_config.h
@@ -87,7 +87,7 @@
const std::string& GetApexInfoListFile() const { return apex_info_list_file_; }
- std::vector<InstructionSet> GetBootExtensionIsas() const {
+ std::vector<InstructionSet> GetBootClasspathIsas() const {
const auto [isa32, isa64] = GetPotentialInstructionSets();
switch (zygote_kind_) {
case ZygoteKind::kZygote32:
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index d3cffc6..857e8ba 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -112,6 +112,8 @@
constexpr mode_t kFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+constexpr const char* kFirstBootImageBasename = "boot.art";
+
void EraseFiles(const std::vector<std::unique_ptr<File>>& files) {
for (auto& file : files) {
file->Erase(/*unlink=*/true);
@@ -208,7 +210,7 @@
}
// Returns a rewritten path based on ANDROID_ROOT if the path starts with "/system/".
-std::string AndroidRootRewrite(const std::string &path) {
+std::string AndroidRootRewrite(const std::string& path) {
if (StartsWith(path, "/system/")) {
return Concatenate({GetAndroidRoot(), path.substr(7)});
} else {
@@ -414,20 +416,30 @@
return true;
}
+std::string GetBootImageComponentBasename(const std::string& jar_path, bool is_first_jar) {
+ if (is_first_jar) {
+ return kFirstBootImageBasename;
+ }
+ const std::string jar_name = android::base::Basename(jar_path);
+ return "boot-" + ReplaceFileExtension(jar_name, "art");
+}
+
void PrepareCompiledBootClasspathFdsIfAny(
/*inout*/ DexoptSystemServerArgs& dexopt_args,
/*inout*/ std::vector<std::unique_ptr<File>>& output_files,
const std::vector<std::string>& bcp_jars,
const InstructionSet isa,
- bool on_system) {
+ const std::string& artifact_dir) {
std::vector<int> bcp_image_fds;
std::vector<int> bcp_oat_fds;
std::vector<int> bcp_vdex_fds;
std::vector<std::unique_ptr<File>> opened_files;
bool added_any = false;
- for (const std::string& jar : bcp_jars) {
- std::string image_path = GetBootImagePath(on_system, jar);
- image_path = image_path.empty() ? "" : GetSystemImageFilename(image_path.c_str(), isa);
+ for (size_t i = 0; i < bcp_jars.size(); i++) {
+ const std::string& jar = bcp_jars[i];
+ std::string image_path =
+ artifact_dir + "/" + GetBootImageComponentBasename(jar, /*is_first_jar=*/i == 0);
+ image_path = GetSystemImageFilename(image_path.c_str(), isa);
std::unique_ptr<File> image_file(OS::OpenFileForReading(image_path.c_str()));
if (image_file && image_file->IsValid()) {
bcp_image_fds.push_back(image_file->Fd());
@@ -527,6 +539,10 @@
}
}
+std::string GetArtBootImageDir() { return GetArtRoot() + "/javalib"; }
+
+std::string GetSystemBootImageDir() { return GetAndroidRoot() + "/framework"; }
+
} // namespace
OnDeviceRefresh::OnDeviceRefresh(const OdrConfig& config)
@@ -545,12 +561,9 @@
exec_utils_{std::move(exec_utils)},
odr_dexopt_{std::move(odr_dexopt)} {
for (const std::string& jar : android::base::Split(config_.GetDex2oatBootClasspath(), ":")) {
- // Boot class path extensions are those not in the ART APEX. Updatable APEXes should not
- // have DEX files in the DEX2OATBOOTCLASSPATH. At the time of writing i18n is a non-updatable
- // APEX and so does appear in the DEX2OATBOOTCLASSPATH.
- if (!LocationIsOnArtModule(jar)) {
- boot_extension_compilable_jars_.emplace_back(jar);
- }
+ // Updatable APEXes should not have DEX files in the DEX2OATBOOTCLASSPATH. At the time of
+ // writing i18n is a non-updatable APEX and so does appear in the DEX2OATBOOTCLASSPATH.
+ boot_classpath_compilable_jars_.emplace_back(jar);
}
all_systemserver_jars_ = android::base::Split(config_.GetSystemServerClasspath(), ":");
@@ -566,9 +579,7 @@
}
}
-time_t OnDeviceRefresh::GetExecutionTimeUsed() const {
- return time(nullptr) - start_time_;
-}
+time_t OnDeviceRefresh::GetExecutionTimeUsed() const { return time(nullptr) - start_time_; }
time_t OnDeviceRefresh::GetExecutionTimeRemaining() const {
return std::max(static_cast<time_t>(0),
@@ -589,8 +600,8 @@
// We are only interested in active APEXes that contain compilable JARs.
std::unordered_set<std::string_view> relevant_apexes;
relevant_apexes.reserve(info_list->getApexInfo().size());
- for (const std::vector<std::string>* jar_list : { &boot_extension_compilable_jars_,
- &all_systemserver_jars_, &boot_classpath_jars_}) {
+ for (const std::vector<std::string>* jar_list :
+ {&boot_classpath_compilable_jars_, &all_systemserver_jars_, &boot_classpath_jars_}) {
for (auto& jar : *jar_list) {
std::string_view apex = ApexNameFromLocation(jar);
if (!apex.empty()) {
@@ -606,8 +617,9 @@
std::copy_if(info_list->getApexInfo().begin(),
info_list->getApexInfo().end(),
std::back_inserter(filtered_info_list),
- [&](const apex::ApexInfo& info) { return info.getIsActive()
- && relevant_apexes.count(info.getModuleName()) != 0; });
+ [&](const apex::ApexInfo& info) {
+ return info.getIsActive() && relevant_apexes.count(info.getModuleName()) != 0;
+ });
return filtered_info_list;
}
@@ -652,15 +664,15 @@
}
std::optional<std::vector<art_apex::Component>> bcp_compilable_components =
- GenerateBootExtensionCompilableComponents();
+ GenerateBootClasspathCompilableComponents();
if (!bcp_compilable_components.has_value()) {
- return Errorf("No boot classpath extension compilable components.");
+ return Errorf("No boot classpath compilable components.");
}
std::optional<std::vector<art_apex::SystemServerComponent>> system_server_components =
GenerateSystemServerComponents();
if (!system_server_components.has_value()) {
- return Errorf("No system_server extension components.");
+ return Errorf("No system_server components.");
}
std::ofstream out(cache_info_filename_.c_str());
@@ -697,9 +709,9 @@
return GenerateComponents(boot_classpath_jars_);
}
-std::vector<art_apex::Component> OnDeviceRefresh::GenerateBootExtensionCompilableComponents()
+std::vector<art_apex::Component> OnDeviceRefresh::GenerateBootClasspathCompilableComponents()
const {
- return GenerateComponents(boot_extension_compilable_jars_);
+ return GenerateComponents(boot_classpath_compilable_jars_);
}
std::vector<art_apex::SystemServerComponent> OnDeviceRefresh::GenerateSystemServerComponents()
@@ -712,16 +724,37 @@
});
}
-std::string OnDeviceRefresh::GetBootImageExtensionImage(bool on_system) const {
- CHECK(!boot_extension_compilable_jars_.empty());
- const std::string leading_jar = boot_extension_compilable_jars_[0];
- return GetBootImagePath(on_system, leading_jar);
+std::string OnDeviceRefresh::GetBootImage(bool on_system) const {
+ if (on_system) {
+ // Typically "/apex/com.android.art/javalib/boot.art".
+ // TODO(b/211973309): Update this once the primary boot image is moved.
+ return GetArtBootImageDir() + "/" + kFirstBootImageBasename;
+ } else {
+ // Typically "/data/misc/apexdata/com.android.art/dalvik-cache/boot.art".
+ return config_.GetArtifactDirectory() + "/" + kFirstBootImageBasename;
+ }
}
-std::string OnDeviceRefresh::GetBootImageExtensionImagePath(bool on_system,
- const InstructionSet isa) const {
- // Typically "/data/misc/apexdata/com.android.art/dalvik-cache/<isa>/boot-framework.art".
- return GetSystemImageFilename(GetBootImageExtensionImage(on_system).c_str(), isa);
+std::string OnDeviceRefresh::GetBootImagePath(bool on_system, const InstructionSet isa) const {
+ // Typically "/data/misc/apexdata/com.android.art/dalvik-cache/<isa>/boot.art".
+ return GetSystemImageFilename(GetBootImage(on_system).c_str(), isa);
+}
+
+std::string OnDeviceRefresh::GetSystemBootImageExtension() const {
+ std::string art_root = GetArtRoot() + "/";
+ // Find the first boot extension jar.
+ auto it = std::find_if_not(
+ boot_classpath_compilable_jars_.begin(),
+ boot_classpath_compilable_jars_.end(),
+ [&](const std::string& jar) { return android::base::StartsWith(jar, art_root); });
+ CHECK(it != boot_classpath_compilable_jars_.end());
+ // Typically "/system/framework/boot-framework.art".
+ return GetSystemBootImageDir() + "/" + GetBootImageComponentBasename(*it, /*is_first_jar=*/false);
+}
+
+std::string OnDeviceRefresh::GetSystemBootImageExtensionPath(const InstructionSet isa) const {
+ // Typically "/system/framework/<isa>/boot-framework.art".
+ return GetSystemImageFilename(GetSystemBootImageExtension().c_str(), isa);
}
std::string OnDeviceRefresh::GetSystemServerImagePath(bool on_system,
@@ -752,14 +785,27 @@
return RemoveDirectory(config_.GetArtifactDirectory());
}
-WARN_UNUSED bool OnDeviceRefresh::BootExtensionArtifactsExist(
+WARN_UNUSED bool OnDeviceRefresh::BootClasspathArtifactsExist(
bool on_system,
const InstructionSet isa,
/*out*/ std::string* error_msg,
/*out*/ std::vector<std::string>* checked_artifacts) const {
- const std::string apexdata_image_location = GetBootImageExtensionImagePath(on_system, isa);
- const OdrArtifacts artifacts = OdrArtifacts::ForBootImageExtension(apexdata_image_location);
- return ArtifactsExist(artifacts, /*check_art_file=*/true, error_msg, checked_artifacts);
+ std::string path = GetBootImagePath(on_system, isa);
+ OdrArtifacts artifacts = OdrArtifacts::ForBootImage(path);
+ if (!ArtifactsExist(artifacts, /*check_art_file=*/true, error_msg, checked_artifacts)) {
+ return false;
+ }
+ // There is a split between the primary boot image and the extension on /system, so they need to
+ // be checked separately. This does not apply to the boot image on /data.
+ if (on_system) {
+ std::string extension_path = GetSystemBootImageExtensionPath(isa);
+ OdrArtifacts extension_artifacts = OdrArtifacts::ForBootImage(extension_path);
+ if (!ArtifactsExist(
+ extension_artifacts, /*check_art_file=*/true, error_msg, checked_artifacts)) {
+ return false;
+ }
+ }
+ return true;
}
WARN_UNUSED bool OnDeviceRefresh::SystemServerArtifactsExist(
@@ -781,7 +827,7 @@
return jars_missing_artifacts->empty();
}
-WARN_UNUSED bool OnDeviceRefresh::CheckBootExtensionArtifactsAreUpToDate(
+WARN_UNUSED bool OnDeviceRefresh::CheckBootClasspathArtifactsAreUpToDate(
OdrMetrics& metrics,
const InstructionSet isa,
const apex::ApexInfo& art_apex_info,
@@ -792,11 +838,11 @@
// ART is not updated, so we can use the artifacts on /system. Check if they exist.
std::string error_msg;
- if (BootExtensionArtifactsExist(/*on_system=*/true, isa, &error_msg)) {
+ if (BootClasspathArtifactsExist(/*on_system=*/true, isa, &error_msg)) {
return true;
}
- LOG(INFO) << "Incomplete boot extension artifacts on /system. " << error_msg;
+ LOG(INFO) << "Incomplete boot classpath artifacts on /system. " << error_msg;
LOG(INFO) << "Checking cache.";
}
@@ -857,7 +903,7 @@
// The boot class components may change unexpectedly, for example an OTA could update
// framework.jar.
const std::vector<art_apex::Component> expected_bcp_compilable_components =
- GenerateBootExtensionCompilableComponents();
+ GenerateBootClasspathCompilableComponents();
if (expected_bcp_compilable_components.size() != 0 &&
(!cache_info->hasDex2oatBootClasspath() ||
!cache_info->getFirstDex2oatBootClasspath()->hasComponent())) {
@@ -878,8 +924,8 @@
// Cache info looks good, check all compilation artifacts exist.
std::string error_msg;
- if (!BootExtensionArtifactsExist(/*on_system=*/false, isa, &error_msg, checked_artifacts)) {
- LOG(INFO) << "Incomplete boot extension artifacts. " << error_msg;
+ if (!BootClasspathArtifactsExist(/*on_system=*/false, isa, &error_msg, checked_artifacts)) {
+ LOG(INFO) << "Incomplete boot classpath artifacts. " << error_msg;
metrics.SetTrigger(OdrMetrics::Trigger::kMissingArtifacts);
return false;
}
@@ -1165,7 +1211,7 @@
// Clean-up helper used to simplify clean-ups and handling failures there.
auto cleanup_and_compile_all = [&, this]() {
- compilation_options->compile_boot_extensions_for_isas = config_.GetBootExtensionIsas();
+ compilation_options->compile_boot_classpath_for_isas = config_.GetBootClasspathIsas();
compilation_options->system_server_jars_to_compile = AllSystemServerJars();
return RemoveArtifactsDirectory() ? ExitCode::kCompilationRequired : ExitCode::kCleanupFailed;
};
@@ -1215,11 +1261,11 @@
InstructionSet system_server_isa = config_.GetSystemServerIsa();
std::vector<std::string> checked_artifacts;
- for (const InstructionSet isa : config_.GetBootExtensionIsas()) {
- if (!CheckBootExtensionArtifactsAreUpToDate(
+ for (const InstructionSet isa : config_.GetBootClasspathIsas()) {
+ if (!CheckBootClasspathArtifactsAreUpToDate(
metrics, isa, art_apex_info.value(), cache_info, &checked_artifacts)) {
- compilation_options->compile_boot_extensions_for_isas.push_back(isa);
- // system_server artifacts are invalid without valid boot extension artifacts.
+ compilation_options->compile_boot_classpath_for_isas.push_back(isa);
+ // system_server artifacts are invalid without valid boot classpath artifacts.
if (isa == system_server_isa) {
compilation_options->system_server_jars_to_compile = AllSystemServerJars();
}
@@ -1234,7 +1280,7 @@
&checked_artifacts);
}
- bool compilation_required = (!compilation_options->compile_boot_extensions_for_isas.empty() ||
+ bool compilation_required = (!compilation_options->compile_boot_classpath_for_isas.empty() ||
!compilation_options->system_server_jars_to_compile.empty());
// If partial compilation is disabled, we should compile everything regardless of what's in
@@ -1269,7 +1315,7 @@
return compilation_required ? ExitCode::kCompilationRequired : ExitCode::kOkay;
}
-WARN_UNUSED bool OnDeviceRefresh::CompileBootExtensionArtifacts(
+WARN_UNUSED bool OnDeviceRefresh::CompileBootClasspathArtifacts(
const InstructionSet isa,
const std::string& staging_dir,
OdrMetrics& metrics,
@@ -1281,10 +1327,17 @@
dexopt_args.isa = InstructionSetToAidlIsa(isa);
std::vector<std::unique_ptr<File>> readonly_files_raii;
- const std::string boot_profile_file(GetAndroidRoot() + "/etc/boot-image.prof");
+ dexopt_args.profileFds.resize(2);
+ const std::string art_boot_profile_file = GetArtRoot() + "/etc/boot-image.prof";
if (!PrepareDex2OatProfileIfExists(
- &dexopt_args.profileFd, &readonly_files_raii, boot_profile_file)) {
- LOG(ERROR) << "Missing expected profile for boot extension: " << boot_profile_file;
+ &dexopt_args.profileFds[0], &readonly_files_raii, art_boot_profile_file)) {
+ LOG(ERROR) << "Missing expected ART boot profile: " << art_boot_profile_file;
+ return false;
+ }
+ const std::string framework_boot_profile_file = GetAndroidRoot() + "/etc/boot-image.prof";
+ if (!PrepareDex2OatProfileIfExists(
+ &dexopt_args.profileFds[1], &readonly_files_raii, framework_boot_profile_file)) {
+ LOG(ERROR) << "Missing expected framework boot profile: " << framework_boot_profile_file;
return false;
}
@@ -1297,8 +1350,8 @@
LOG(WARNING) << "Missing dirty objects file : " << QuotePath(dirty_image_objects_file);
}
- // Add boot extensions to compile.
- for (const std::string& component : boot_extension_compilable_jars_) {
+ // Add boot classpath jars to compile.
+ for (const std::string& component : boot_classpath_compilable_jars_) {
std::string actual_path = AndroidRootRewrite(component);
std::unique_ptr<File> file(OS::OpenFileForReading(actual_path.c_str()));
dexopt_args.dexPaths.emplace_back(component);
@@ -1312,10 +1365,8 @@
return false;
}
- const std::string image_location = GetBootImageExtensionImagePath(/*on_system=*/false, isa);
- const OdrArtifacts artifacts = OdrArtifacts::ForBootImageExtension(image_location);
- CHECK_EQ(GetApexDataOatFilename(boot_extension_compilable_jars_.front().c_str(), isa),
- artifacts.OatPath());
+ const std::string image_location = GetBootImagePath(/*on_system=*/false, isa);
+ const OdrArtifacts artifacts = OdrArtifacts::ForBootImage(image_location);
dexopt_args.oatLocation = artifacts.OatPath();
const std::pair<const std::string, int*> location_kind_pairs[] = {
@@ -1356,7 +1407,7 @@
}
const time_t timeout = GetSubprocessTimeout();
- LOG(INFO) << "Compiling boot extensions (" << isa << "): " << dexopt_args.toString()
+ LOG(INFO) << "Compiling boot classpath (" << isa << "): " << dexopt_args.toString()
<< " [timeout " << timeout << "s]";
if (config_.GetDryRun()) {
LOG(INFO) << "Compilation skipped (dry-run).";
@@ -1364,6 +1415,9 @@
}
bool timed_out = false;
+ // NOTE: The method `DexoptBcpExtension` actually compiles the entire boot classpath. We don't
+ // rename this method because it will eventually go away.
+ // TODO(b/211977683): Call dex2oat directly.
int dex2oat_exit_code =
odr_dexopt_->DexoptBcpExtension(dexopt_args, timeout, &timed_out, error_msg);
@@ -1471,13 +1525,19 @@
return false;
}
std::string unused_error_msg;
- // If the boot extension artifacts are not on /data, then boot extensions are not re-compiled
+ // If the boot classpath artifacts are not on /data, then the boot classpath are not re-compiled
// and the artifacts must exist on /system.
bool boot_image_on_system =
- !BootExtensionArtifactsExist(/*on_system=*/false, isa, &unused_error_msg);
+ !BootClasspathArtifactsExist(/*on_system=*/false, isa, &unused_error_msg);
PrepareCompiledBootClasspathFdsIfAny(
- dexopt_args, readonly_files_raii, bcp_jars, isa, boot_image_on_system);
- dexopt_args.isBootImageOnSystem = boot_image_on_system;
+ dexopt_args,
+ readonly_files_raii,
+ bcp_jars,
+ isa,
+ boot_image_on_system ? GetSystemBootImageDir() : config_.GetArtifactDirectory());
+ dexopt_args.bootImage = boot_image_on_system ? GetBootImage(/*on_system=*/true) + ":" +
+ GetSystemBootImageExtension() :
+ GetBootImage(/*on_system=*/false);
dexopt_args.classloaderContext = classloader_context;
if (!classloader_context.empty()) {
@@ -1575,16 +1635,16 @@
uint32_t dex2oat_invocation_count = 0;
uint32_t total_dex2oat_invocation_count =
- compilation_options.compile_boot_extensions_for_isas.size() +
+ compilation_options.compile_boot_classpath_for_isas.size() +
compilation_options.system_server_jars_to_compile.size();
ReportNextBootAnimationProgress(dex2oat_invocation_count, total_dex2oat_invocation_count);
auto advance_animation_progress = [&]() {
ReportNextBootAnimationProgress(++dex2oat_invocation_count, total_dex2oat_invocation_count);
};
- const auto& bcp_instruction_sets = config_.GetBootExtensionIsas();
+ const auto& bcp_instruction_sets = config_.GetBootClasspathIsas();
DCHECK(!bcp_instruction_sets.empty() && bcp_instruction_sets.size() <= 2);
- for (const InstructionSet isa : compilation_options.compile_boot_extensions_for_isas) {
+ for (const InstructionSet isa : compilation_options.compile_boot_classpath_for_isas) {
auto stage = (isa == bcp_instruction_sets.front()) ? OdrMetrics::Stage::kPrimaryBootClasspath :
OdrMetrics::Stage::kSecondaryBootClasspath;
metrics.SetStage(stage);
@@ -1595,7 +1655,7 @@
return ExitCode::kCompilationFailed;
}
- if (!CompileBootExtensionArtifacts(
+ if (!CompileBootClasspathArtifacts(
isa, staging_dir, metrics, advance_animation_progress, &error_msg)) {
LOG(ERROR) << "Compilation of BCP failed: " << error_msg;
if (!config_.GetDryRun() && !RemoveDirectory(staging_dir)) {
diff --git a/odrefresh/odrefresh.h b/odrefresh/odrefresh.h
index 88162a3..d749b2b 100644
--- a/odrefresh/odrefresh.h
+++ b/odrefresh/odrefresh.h
@@ -43,8 +43,8 @@
// If true, update the cache info only and do not compile anything.
bool update_cache_info_only = false;
- // If not empty, compile the bootclasspath extensions for ISAs in the list.
- std::vector<InstructionSet> compile_boot_extensions_for_isas;
+ // If not empty, compile the bootclasspath jars for ISAs in the list.
+ std::vector<InstructionSet> compile_boot_classpath_for_isas;
// If not empty, compile the system server jars in the list.
std::set<std::string> system_server_jars_to_compile;
@@ -60,8 +60,7 @@
std::unique_ptr<ExecUtils> exec_utils,
std::unique_ptr<OdrDexopt> odr_dexopt);
- // Returns the exit code, a list of ISAs that boot extensions should be compiled for, and a
- // boolean indicating whether the system server should be compiled.
+ // Returns the exit code and specifies what should be compiled in `compilation_options`.
WARN_UNUSED ExitCode
CheckArtifactsAreUpToDate(OdrMetrics& metrics,
/*out*/ CompilationOptions* compilation_options) const;
@@ -94,13 +93,23 @@
std::vector<com::android::art::Component> GenerateBootClasspathComponents() const;
- std::vector<com::android::art::Component> GenerateBootExtensionCompilableComponents() const;
+ std::vector<com::android::art::Component> GenerateBootClasspathCompilableComponents() const;
std::vector<com::android::art::SystemServerComponent> GenerateSystemServerComponents() const;
- std::string GetBootImageExtensionImage(bool on_system) const;
+ // Returns the symbolic boot image location (without ISA).
+ std::string GetBootImage(bool on_system) const;
- std::string GetBootImageExtensionImagePath(bool on_system, const InstructionSet isa) const;
+ // Returns the real boot image location (with ISA).
+ std::string GetBootImagePath(bool on_system, const InstructionSet isa) const;
+
+ // Returns the symbolic boot image extension location (without ISA). Note that this only applies
+ // to boot images on /system.
+ std::string GetSystemBootImageExtension() const;
+
+ // Returns the real boot image location extension (with ISA). Note that this only applies to boot
+ // images on /system.
+ std::string GetSystemBootImageExtensionPath(const InstructionSet isa) const;
std::string GetSystemServerImagePath(bool on_system, const std::string& jar_path) const;
@@ -113,10 +122,10 @@
// artifacts to fs-verity.
android::base::Result<void> RefreshExistingArtifacts() const;
- // Checks whether all boot extension artifacts are present. Returns true if all are present, false
+ // Checks whether all boot classpath artifacts are present. Returns true if all are present, false
// otherwise.
// If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`.
- WARN_UNUSED bool BootExtensionArtifactsExist(
+ WARN_UNUSED bool BootClasspathArtifactsExist(
bool on_system,
const InstructionSet isa,
/*out*/ std::string* error_msg,
@@ -132,10 +141,10 @@
/*out*/ std::set<std::string>* jars_missing_artifacts,
/*out*/ std::vector<std::string>* checked_artifacts = nullptr) const;
- // Checks whether all boot extension artifacts are up to date. Returns true if all are present,
+ // Checks whether all boot classpath artifacts are up to date. Returns true if all are present,
// false otherwise.
// If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`.
- WARN_UNUSED bool CheckBootExtensionArtifactsAreUpToDate(
+ WARN_UNUSED bool CheckBootClasspathArtifactsAreUpToDate(
OdrMetrics& metrics,
const InstructionSet isa,
const com::android::apex::ApexInfo& art_apex_info,
@@ -153,7 +162,7 @@
/*out*/ std::set<std::string>* jars_to_compile,
/*out*/ std::vector<std::string>* checked_artifacts) const;
- WARN_UNUSED bool CompileBootExtensionArtifacts(const InstructionSet isa,
+ WARN_UNUSED bool CompileBootClasspathArtifacts(const InstructionSet isa,
const std::string& staging_dir,
OdrMetrics& metrics,
const std::function<void()>& on_dex2oat_success,
@@ -172,8 +181,8 @@
// Path to cache information file that is used to speed up artifact checking.
const std::string cache_info_filename_;
- // List of boot extension components that should be compiled.
- std::vector<std::string> boot_extension_compilable_jars_;
+ // List of boot classpath components that should be compiled.
+ std::vector<std::string> boot_classpath_compilable_jars_;
// Set of system_server components in SYSTEMSERVERCLASSPATH that should be compiled.
std::unordered_set<std::string> systemserver_classpath_jars_;
diff --git a/odrefresh/odrefresh_main.cc b/odrefresh/odrefresh_main.cc
index 8262805..f93ee93 100644
--- a/odrefresh/odrefresh_main.cc
+++ b/odrefresh/odrefresh_main.cc
@@ -185,16 +185,14 @@
NO_RETURN void UsageHelp(const char* argv0) {
std::string name(android::base::Basename(argv0));
UsageMsg("Usage: %s [OPTION...] ACTION", name.c_str());
- UsageMsg("On-device refresh tool for boot class path extensions and system server");
+ UsageMsg("On-device refresh tool for boot classpath and system server");
UsageMsg("following an update of the ART APEX.");
UsageMsg("");
UsageMsg("Valid ACTION choices are:");
UsageMsg("");
UsageMsg("--check Check compilation artifacts are up-to-date based on metadata.");
- UsageMsg("--compile Compile boot class path extensions and system_server jars");
- UsageMsg(" when necessary.");
- UsageMsg("--force-compile Unconditionally compile the boot class path extensions and");
- UsageMsg(" system_server jars.");
+ UsageMsg("--compile Compile boot classpath and system_server jars when necessary.");
+ UsageMsg("--force-compile Unconditionally compile the bootclass path and system_server jars.");
UsageMsg("--help Display this help information.");
UsageMsg("");
UsageMsg("Available OPTIONs are:");
@@ -270,8 +268,8 @@
}
return odr.Compile(metrics,
CompilationOptions{
- .compile_boot_extensions_for_isas = config.GetBootExtensionIsas(),
- .system_server_jars_to_compile = odr.AllSystemServerJars(),
+ .compile_boot_classpath_for_isas = config.GetBootClasspathIsas(),
+ .system_server_jars_to_compile = odr.AllSystemServerJars(),
});
} else if (action == "--help") {
UsageHelp(argv[0]);
diff --git a/odrefresh/odrefresh_test.cc b/odrefresh/odrefresh_test.cc
index 7494084..370fd0d 100644
--- a/odrefresh/odrefresh_test.cc
+++ b/odrefresh/odrefresh_test.cc
@@ -159,8 +159,12 @@
std::string system_etc_dir = Concatenate({android_root_path, "/etc"});
ASSERT_TRUE(EnsureDirectoryExists(system_etc_dir));
- boot_profile_file_ = system_etc_dir + "/boot-image.prof";
- CreateEmptyFile(boot_profile_file_);
+ framework_profile_ = system_etc_dir + "/boot-image.prof";
+ CreateEmptyFile(framework_profile_);
+ std::string art_etc_dir = Concatenate({android_art_root_path, "/etc"});
+ ASSERT_TRUE(EnsureDirectoryExists(art_etc_dir));
+ art_profile_ = art_etc_dir + "/boot-image.prof";
+ CreateEmptyFile(art_profile_);
framework_dir_ = android_root_path + "/framework";
framework_jar_ = framework_dir_ + "/framework.jar";
@@ -169,8 +173,8 @@
services_foo_jar_ = framework_dir_ + "/services-foo.jar";
services_bar_jar_ = framework_dir_ + "/services-bar.jar";
std::string services_jar_prof = framework_dir_ + "/services.jar.prof";
- std::string javalib_dir = android_art_root_path + "/javalib";
- std::string boot_art = javalib_dir + "/boot.art";
+ art_javalib_dir_ = android_art_root_path + "/javalib";
+ core_oj_jar_ = art_javalib_dir_ + "/core-oj.jar";
// Create placeholder files.
ASSERT_TRUE(EnsureDirectoryExists(framework_dir_ + "/x86_64"));
@@ -180,16 +184,16 @@
CreateEmptyFile(services_foo_jar_);
CreateEmptyFile(services_bar_jar_);
CreateEmptyFile(services_jar_prof);
- ASSERT_TRUE(EnsureDirectoryExists(javalib_dir));
- CreateEmptyFile(boot_art);
+ ASSERT_TRUE(EnsureDirectoryExists(art_javalib_dir_));
+ CreateEmptyFile(core_oj_jar_);
std::string apex_info_filename = Concatenate({temp_dir_path, "/apex-info-list.xml"});
WriteFakeApexInfoList(apex_info_filename);
config_.SetApexInfoListFile(apex_info_filename);
config_.SetArtBinDir(Concatenate({temp_dir_path, "/bin"}));
- config_.SetBootClasspath(framework_jar_);
- config_.SetDex2oatBootclasspath(framework_jar_);
+ config_.SetBootClasspath(Concatenate({core_oj_jar_, ":", framework_jar_}));
+ config_.SetDex2oatBootclasspath(Concatenate({core_oj_jar_, ":", framework_jar_}));
config_.SetSystemServerClasspath(Concatenate({location_provider_jar_, ":", services_jar_}));
config_.SetStandaloneSystemServerJars(Concatenate({services_foo_jar_, ":", services_bar_jar_}));
config_.SetIsa(InstructionSet::kX86_64);
@@ -230,6 +234,7 @@
std::unique_ptr<ScopedUnsetEnvironmentVariable> art_apex_data_env_;
OdrConfig config_;
std::unique_ptr<OdrMetrics> metrics_;
+ std::string core_oj_jar_;
std::string framework_jar_;
std::string location_provider_jar_;
std::string services_jar_;
@@ -237,9 +242,32 @@
std::string services_bar_jar_;
std::string dalvik_cache_dir_;
std::string framework_dir_;
- std::string boot_profile_file_;
+ std::string art_javalib_dir_;
+ std::string framework_profile_;
+ std::string art_profile_;
};
+TEST_F(OdRefreshTest, BootClasspathJars) {
+ auto [odrefresh, mock_odr_dexopt] = CreateOdRefresh();
+
+ EXPECT_CALL(*mock_odr_dexopt,
+ DoDexoptBcpExtension(AllOf(
+ Field(&DexoptBcpExtArgs::dexPaths, ElementsAre(core_oj_jar_, framework_jar_)),
+ AllOf(Field(&DexoptBcpExtArgs::dexFds,
+ ElementsAre(FdOf(core_oj_jar_), FdOf(framework_jar_))),
+ Field(&DexoptBcpExtArgs::profileFds,
+ ElementsAre(FdOf(art_profile_), FdOf(framework_profile_))),
+ Field(&DexoptBcpExtArgs::oatLocation,
+ Eq(dalvik_cache_dir_ + "/x86_64/boot.oat"))))))
+ .WillOnce(Return(0));
+
+ EXPECT_EQ(odrefresh->Compile(*metrics_,
+ CompilationOptions{
+ .compile_boot_classpath_for_isas = {InstructionSet::kX86_64},
+ }),
+ ExitCode::kCompilationSuccess);
+}
+
TEST_F(OdRefreshTest, AllSystemServerJars) {
auto [odrefresh, mock_odr_dexopt] = CreateOdRefresh();
@@ -442,7 +470,7 @@
EXPECT_EQ(
odrefresh->Compile(*metrics_,
CompilationOptions{
- .compile_boot_extensions_for_isas = {InstructionSet::kX86_64},
+ .compile_boot_classpath_for_isas = {InstructionSet::kX86_64},
.system_server_jars_to_compile = odrefresh->AllSystemServerJars(),
}),
ExitCode::kCompilationSuccess);
@@ -453,21 +481,20 @@
auto [odrefresh, mock_odr_dexopt] = CreateOdRefresh();
// Boot image is on /data.
- OdrArtifacts artifacts =
- OdrArtifacts::ForBootImageExtension(dalvik_cache_dir_ + "/x86_64/boot-framework.art");
+ OdrArtifacts artifacts = OdrArtifacts::ForBootImage(dalvik_cache_dir_ + "/x86_64/boot.art");
auto file1 = ScopedCreateEmptyFile(artifacts.ImagePath());
auto file2 = ScopedCreateEmptyFile(artifacts.VdexPath());
auto file3 = ScopedCreateEmptyFile(artifacts.OatPath());
- EXPECT_CALL(
- *mock_odr_dexopt,
- DoDexoptSystemServer(AllOf(Field(&DexoptSystemServerArgs::isBootImageOnSystem, Eq(false)),
- Field(&DexoptSystemServerArgs::bootClasspathImageFds,
- Contains(FdOf(artifacts.ImagePath()))),
- Field(&DexoptSystemServerArgs::bootClasspathVdexFds,
- Contains(FdOf(artifacts.VdexPath()))),
- Field(&DexoptSystemServerArgs::bootClasspathOatFds,
- Contains(FdOf(artifacts.OatPath()))))))
+ EXPECT_CALL(*mock_odr_dexopt,
+ DoDexoptSystemServer(AllOf(
+ Field(&DexoptSystemServerArgs::bootImage, Eq(dalvik_cache_dir_ + "/boot.art")),
+ Field(&DexoptSystemServerArgs::bootClasspathImageFds,
+ Contains(FdOf(artifacts.ImagePath()))),
+ Field(&DexoptSystemServerArgs::bootClasspathVdexFds,
+ Contains(FdOf(artifacts.VdexPath()))),
+ Field(&DexoptSystemServerArgs::bootClasspathOatFds,
+ Contains(FdOf(artifacts.OatPath()))))))
.Times(odrefresh->AllSystemServerJars().size())
.WillRepeatedly(Return(0));
EXPECT_EQ(
@@ -483,20 +510,23 @@
// Boot image is on /system.
OdrArtifacts artifacts =
- OdrArtifacts::ForBootImageExtension(framework_dir_ + "/x86_64/boot-framework.art");
+ OdrArtifacts::ForBootImage(framework_dir_ + "/x86_64/boot-framework.art");
auto file1 = ScopedCreateEmptyFile(artifacts.ImagePath());
auto file2 = ScopedCreateEmptyFile(artifacts.VdexPath());
auto file3 = ScopedCreateEmptyFile(artifacts.OatPath());
- EXPECT_CALL(
- *mock_odr_dexopt,
- DoDexoptSystemServer(AllOf(Field(&DexoptSystemServerArgs::isBootImageOnSystem, Eq(true)),
- Field(&DexoptSystemServerArgs::bootClasspathImageFds,
- Contains(FdOf(artifacts.ImagePath()))),
- Field(&DexoptSystemServerArgs::bootClasspathVdexFds,
- Contains(FdOf(artifacts.VdexPath()))),
- Field(&DexoptSystemServerArgs::bootClasspathOatFds,
- Contains(FdOf(artifacts.OatPath()))))))
+ EXPECT_CALL(*mock_odr_dexopt,
+ DoDexoptSystemServer(
+ AllOf(Field(&DexoptSystemServerArgs::bootImage,
+ Eq(android::base::StringPrintf("%s/boot.art:%s/boot-framework.art",
+ art_javalib_dir_.c_str(),
+ framework_dir_.c_str()))),
+ Field(&DexoptSystemServerArgs::bootClasspathImageFds,
+ Contains(FdOf(artifacts.ImagePath()))),
+ Field(&DexoptSystemServerArgs::bootClasspathVdexFds,
+ Contains(FdOf(artifacts.VdexPath()))),
+ Field(&DexoptSystemServerArgs::bootClasspathOatFds,
+ Contains(FdOf(artifacts.OatPath()))))))
.Times(odrefresh->AllSystemServerJars().size())
.WillRepeatedly(Return(0));
EXPECT_EQ(
diff --git a/test/odsign/src/com/android/tests/odsign/ArtifactsSignedTest.java b/test/odsign/src/com/android/tests/odsign/ArtifactsSignedTest.java
index 25a46e3..f29baa7 100644
--- a/test/odsign/src/com/android/tests/odsign/ArtifactsSignedTest.java
+++ b/test/odsign/src/com/android/tests/odsign/ArtifactsSignedTest.java
@@ -43,9 +43,9 @@
// Verifying that they are generated for the correct architectures is currently out of
// scope for this test.
private static final String[] REQUIRED_ARTIFACT_NAMES = {
- "boot-framework.art",
- "boot-framework.oat",
- "boot-framework.vdex",
+ "boot.art",
+ "boot.oat",
+ "boot.vdex",
"system@framework@services.jar@classes.vdex",
"system@framework@services.jar@classes.odex",
"system@framework@services.jar@classes.art",
diff --git a/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java b/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
index 101e5e2..f00ff14 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
@@ -106,7 +106,7 @@
final String zygotePid = result.getStdout().trim().split("\\s+")[0];
assertTrue(!zygotePid.isEmpty());
- final String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + ".*boot-framework";
+ final String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + ".*boot";
return Optional.of(getMappedArtifacts(zygotePid, grepPattern));
}
diff --git a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
index bcce9a0..9c1949c 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
@@ -118,8 +118,6 @@
private String getSystemServerIsa(String mappedArtifact) {
// Artifact path for system server artifacts has the form:
// ART_APEX_DALVIK_CACHE_DIRNAME + "/<arch>/system@framework@some.jar@classes.odex"
- // `mappedArtifacts` may include other artifacts, such as boot-framework.oat that are not
- // prefixed by the architecture.
String[] pathComponents = mappedArtifact.split("/");
return pathComponents[pathComponents.length - 2];
}
@@ -161,13 +159,13 @@
private void verifyZygoteLoadedArtifacts(String zygoteName, Set<String> mappedArtifacts)
throws Exception {
- final String bootExtensionName = "boot-framework";
+ final String bootImageStem = "boot";
- assertTrue("Expect 3 boot-framework artifacts", mappedArtifacts.size() == 3);
+ assertTrue("Expect 3 bootclasspath artifacts", mappedArtifacts.size() == 3);
String allArtifacts = mappedArtifacts.stream().collect(Collectors.joining(","));
for (String extension : OdsignTestUtils.BCP_ARTIFACT_EXTENSIONS) {
- final String artifact = bootExtensionName + extension;
+ final String artifact = bootImageStem + extension;
final boolean found = mappedArtifacts.stream().anyMatch(a -> a.endsWith(artifact));
assertTrue(zygoteName + " " + artifact + " not found: '" + allArtifacts + "'", found);
}