diff options
-rw-r--r-- | libartbase/base/file_utils.cc | 12 | ||||
-rw-r--r-- | libartbase/base/file_utils.h | 4 | ||||
-rw-r--r-- | libartbase/base/file_utils_test.cc | 11 | ||||
-rw-r--r-- | odrefresh/odrefresh.cc | 32 | ||||
-rw-r--r-- | runtime/runtime.cc | 12 |
5 files changed, 54 insertions, 17 deletions
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc index 8159b0cf66..bc08f309bb 100644 --- a/libartbase/base/file_utils.cc +++ b/libartbase/base/file_utils.cc @@ -661,6 +661,18 @@ bool LocationIsOnApex(std::string_view full_path) { return android::base::StartsWith(full_path, kApexDefaultPath); } +std::string_view ApexNameFromLocation(std::string_view full_path) { + if (!android::base::StartsWith(full_path, kApexDefaultPath)) { + return {}; + } + size_t start = strlen(kApexDefaultPath); + size_t end = full_path.find('/', start); + if (end == std::string_view::npos) { + return {}; + } + return full_path.substr(start, end - start); +} + bool LocationIsOnSystem(const std::string& location) { #ifdef _WIN32 UNUSED(location); diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h index d0d986b3ff..709ac12d14 100644 --- a/libartbase/base/file_utils.h +++ b/libartbase/base/file_utils.h @@ -168,6 +168,10 @@ bool LocationIsOnSystemExtFramework(std::string_view location); // Return whether the location is on /apex/. bool LocationIsOnApex(std::string_view location); +// If the given location is /apex/<apexname>/..., return <apexname>, otherwise return an empty +// string. Note that the result is a view into full_path and is valid only as long as it is. +std::string_view ApexNameFromLocation(std::string_view full_path); + // Returns whether the location is trusted for loading oat files. Trusted locations are protected // by dm-verity or fs-verity. The recognized locations are on /system or // /data/misc/apexdata/com.android.art. diff --git a/libartbase/base/file_utils_test.cc b/libartbase/base/file_utils_test.cc index 913eedee03..dff4478549 100644 --- a/libartbase/base/file_utils_test.cc +++ b/libartbase/base/file_utils_test.cc @@ -330,4 +330,15 @@ TEST_F(FileUtilsTest, GetSystemOdexFilenameForApex) { GetSystemOdexFilenameForApex(apex_jar.c_str(), InstructionSet::kArm)); } +TEST_F(FileUtilsTest, ApexNameFromLocation) { + EXPECT_EQ("", ApexNameFromLocation("")); + EXPECT_EQ("", ApexNameFromLocation("/apex/com.android.foo")); + EXPECT_EQ("", ApexNameFromLocation("/apex//something")); + EXPECT_EQ("com.android.foo", ApexNameFromLocation("/apex/com.android.foo/")); + EXPECT_EQ("", ApexNameFromLocation("apex/com.android.foo/")); + EXPECT_EQ("foo", ApexNameFromLocation("/apex/foo/something.jar")); + EXPECT_EQ("", ApexNameFromLocation("/bar/foo/baz")); + EXPECT_EQ("", ApexNameFromLocation("/apexx/foo/baz")); +} + } // namespace art diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc index d9c5f6f75c..ce80901643 100644 --- a/odrefresh/odrefresh.cc +++ b/odrefresh/odrefresh.cc @@ -583,11 +583,25 @@ std::optional<std::vector<apex::ApexInfo>> OnDeviceRefresh::GetApexInfoList() co return std::nullopt; } + // 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 (auto& jar : *jar_list) { + std::string_view apex = ApexNameFromLocation(jar); + if (!apex.empty()) { + relevant_apexes.insert(apex); + } + } + } + std::vector<apex::ApexInfo> filtered_info_list; std::copy_if(info_list->getApexInfo().begin(), info_list->getApexInfo().end(), std::back_inserter(filtered_info_list), - [](const apex::ApexInfo& info) { return info.getIsActive(); }); + [&](const apex::ApexInfo& info) { return info.getIsActive() + && relevant_apexes.count(info.getModuleName()) != 0; }); return filtered_info_list; } @@ -914,11 +928,15 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( cached_module_info_map[module_info.getName()] = &module_info; } + // Note that apex_info_list may omit APEXes that are included in cached_module_info - e.g. if an + // apex used to be compilable, but now isn't. That won't be detected by this loop, but will be + // detected below in CheckComponents. for (const apex::ApexInfo& current_apex_info : apex_info_list) { - auto it = cached_module_info_map.find(current_apex_info.getModuleName()); + auto& apex_name = current_apex_info.getModuleName(); + + auto it = cached_module_info_map.find(apex_name); if (it == cached_module_info_map.end()) { - LOG(INFO) << "Missing APEX info from cache-info (" << current_apex_info.getModuleName() - << ")."; + LOG(INFO) << "Missing APEX info from cache-info (" << apex_name << ")."; metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); return compile_all(); } @@ -926,7 +944,7 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( const art_apex::ModuleInfo* cached_module_info = it->second; if (cached_module_info->getVersionCode() != current_apex_info.getVersionCode()) { - LOG(INFO) << "APEX (" << current_apex_info.getModuleName() << ") version code mismatch (" + LOG(INFO) << "APEX (" << apex_name << ") version code mismatch (" << cached_module_info->getVersionCode() << " != " << current_apex_info.getVersionCode() << ")."; metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); @@ -934,7 +952,7 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( } if (cached_module_info->getVersionName() != current_apex_info.getVersionName()) { - LOG(INFO) << "APEX (" << current_apex_info.getModuleName() << ") version name mismatch (" + LOG(INFO) << "APEX (" << apex_name << ") version name mismatch (" << cached_module_info->getVersionName() << " != " << current_apex_info.getVersionName() << ")."; metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); @@ -943,7 +961,7 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( if (!cached_module_info->hasLastUpdateMillis() || cached_module_info->getLastUpdateMillis() != current_apex_info.getLastUpdateMillis()) { - LOG(INFO) << "APEX (" << current_apex_info.getModuleName() << ") last update time mismatch (" + LOG(INFO) << "APEX (" << apex_name << ") last update time mismatch (" << cached_module_info->getLastUpdateMillis() << " != " << current_apex_info.getLastUpdateMillis() << ")."; metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 64970e1f66..483e2abaf5 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1281,16 +1281,8 @@ static inline void CreatePreAllocatedException(Thread* self, void Runtime::InitializeApexVersions() { std::vector<std::string_view> bcp_apexes; for (std::string_view jar : Runtime::Current()->GetBootClassPathLocations()) { - if (LocationIsOnApex(jar)) { - size_t start = jar.find('/', 1); - if (start == std::string::npos) { - continue; - } - size_t end = jar.find('/', start + 1); - if (end == std::string::npos) { - continue; - } - std::string_view apex = jar.substr(start + 1, end - start - 1); + std::string_view apex = ApexNameFromLocation(jar); + if (!apex.empty()) { bcp_apexes.push_back(apex); } } |