diff options
Diffstat (limited to 'odrefresh/odrefresh.cc')
| -rw-r--r-- | odrefresh/odrefresh.cc | 134 |
1 files changed, 121 insertions, 13 deletions
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc index 1d12b94fce..70cf48e918 100644 --- a/odrefresh/odrefresh.cc +++ b/odrefresh/odrefresh.cc @@ -648,6 +648,11 @@ Result<void> OnDeviceRefresh::WriteCacheInfo() const { return Errorf("Could not create directory {}", QuotePath(dir_name)); } + std::vector<art_apex::KeyValuePair> system_properties; + for (const auto& [key, value] : config_.GetSystemProperties()) { + system_properties.emplace_back(key, value); + } + std::optional<std::vector<apex::ApexInfo>> apex_info_list = GetApexInfoList(); if (!apex_info_list.has_value()) { return Errorf("Could not update {}: no APEX info", QuotePath(cache_info_filename_)); @@ -685,15 +690,16 @@ Result<void> OnDeviceRefresh::WriteCacheInfo() const { return Errorf("Cannot open {} for writing.", QuotePath(cache_info_filename_)); } - art_apex::CacheInfo info( + std::unique_ptr<art_apex::CacheInfo> info(new art_apex::CacheInfo( + {art_apex::KeyValuePairList(system_properties)}, {art_module_info}, {art_apex::ModuleInfoList(module_info_list)}, {art_apex::Classpath(bcp_components.value())}, {art_apex::Classpath(bcp_compilable_components.value())}, {art_apex::SystemServerComponents(system_server_components.value())}, - config_.GetCompilationOsMode() ? std::make_optional(true) : std::nullopt); + config_.GetCompilationOsMode() ? std::make_optional(true) : std::nullopt)); - art_apex::write(out, info); + art_apex::write(out, *info); out.close(); if (out.fail()) { return Errorf("Cannot write to {}", QuotePath(cache_info_filename_)); @@ -836,16 +842,106 @@ WARN_UNUSED bool OnDeviceRefresh::SystemServerArtifactsExist( return jars_missing_artifacts->empty(); } +WARN_UNUSED bool OnDeviceRefresh::CheckSystemPropertiesAreDefault() const { + const std::unordered_map<std::string, std::string>& system_properties = + config_.GetSystemProperties(); + + for (const SystemPropertyConfig& system_property_config : *kSystemProperties.get()) { + auto property = system_properties.find(system_property_config.name); + DCHECK(property != system_properties.end()); + + if (property->second != system_property_config.default_value) { + LOG(INFO) << "System property " << system_property_config.name << " has a non-default value (" + << property->second << ")."; + return false; + } + } + + return true; +} + +WARN_UNUSED bool OnDeviceRefresh::CheckSystemPropertiesHaveNotChanged( + const art_apex::CacheInfo& cache_info) const { + std::unordered_map<std::string, std::string> cached_system_properties; + const art_apex::KeyValuePairList* list = cache_info.getFirstSystemProperties(); + if (list == nullptr) { + // This should never happen. We have already checked the ART module version, and the cache + // info is generated by the latest version of the ART module if it exists. + LOG(ERROR) << "Missing system properties from cache-info."; + return false; + } + + for (const art_apex::KeyValuePair& pair : list->getItem()) { + cached_system_properties[pair.getK()] = pair.getV(); + } + + const std::unordered_map<std::string, std::string>& system_properties = + config_.GetSystemProperties(); + + for (const SystemPropertyConfig& system_property_config : *kSystemProperties.get()) { + auto property = system_properties.find(system_property_config.name); + DCHECK(property != system_properties.end()); + + auto cached_property = cached_system_properties.find(system_property_config.name); + if (cached_property == cached_system_properties.end()) { + // This should never happen. We have already checked the ART module version, and the cache + // info is generated by the latest version of the ART module if it exists. + LOG(ERROR) << "Missing system property from cache-info (" << system_property_config.name + << ")"; + return false; + } + + if (property->second != cached_property->second) { + LOG(INFO) << "System property " << system_property_config.name + << " value changed (before: " << cached_property->second + << ", now: " << property->second << ")."; + return false; + } + } + + return true; +} + +WARN_UNUSED bool OnDeviceRefresh::BootClasspathArtifactsOnSystemUsable( + const apex::ApexInfo& art_apex_info) const { + if (!art_apex_info.getIsFactory()) { + return false; + } + LOG(INFO) << "Factory ART APEX mounted."; + + if (!CheckSystemPropertiesAreDefault()) { + return false; + } + LOG(INFO) << "System properties are set to default values."; + + return true; +} + +WARN_UNUSED bool OnDeviceRefresh::SystemServerArtifactsOnSystemUsable( + const std::vector<apex::ApexInfo>& apex_info_list) const { + if (std::any_of(apex_info_list.begin(), + apex_info_list.end(), + [](const apex::ApexInfo& apex_info) { return !apex_info.getIsFactory(); })) { + return false; + } + LOG(INFO) << "Factory APEXes mounted."; + + if (!CheckSystemPropertiesAreDefault()) { + return false; + } + LOG(INFO) << "System properties are set to default values."; + + return true; +} + WARN_UNUSED bool OnDeviceRefresh::CheckBootClasspathArtifactsAreUpToDate( OdrMetrics& metrics, const InstructionSet isa, const apex::ApexInfo& art_apex_info, const std::optional<art_apex::CacheInfo>& cache_info, /*out*/ std::vector<std::string>* checked_artifacts) const { - if (art_apex_info.getIsFactory()) { - LOG(INFO) << "Factory ART APEX mounted."; - - // ART is not updated, so we can use the artifacts on /system. Check if they exist. + if (BootClasspathArtifactsOnSystemUsable(art_apex_info)) { + // We can use the artifacts on /system. Check if they exist. std::string error_msg; if (BootClasspathArtifactsExist(/*on_system=*/true, /*minimal=*/false, isa, &error_msg)) { return true; @@ -900,6 +996,14 @@ WARN_UNUSED bool OnDeviceRefresh::CheckBootClasspathArtifactsAreUpToDate( return false; } + if (!CheckSystemPropertiesHaveNotChanged(cache_info.value())) { + // We don't have a trigger kind for system property changes. For now, we reuse + // `kApexVersionMismatch` as it implies the expected behavior: re-compile regardless of the last + // compilation attempt. + metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); + return false; + } + // Check boot class components. // // This checks the size and checksums of odrefresh compilable files on the DEX2OATBOOTCLASSPATH @@ -961,12 +1065,8 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( std::set<std::string> jars_missing_artifacts_on_system; bool artifacts_on_system_up_to_date = false; - if (std::all_of(apex_info_list.begin(), - apex_info_list.end(), - [](const apex::ApexInfo& apex_info) { return apex_info.getIsFactory(); })) { - LOG(INFO) << "Factory APEXes mounted."; - - // APEXes are not updated, so we can use the artifacts on /system. Check if they exist. + if (SystemServerArtifactsOnSystemUsable(apex_info_list)) { + // We can use the artifacts on /system. Check if they exist. std::string error_msg; if (SystemServerArtifactsExist( /*on_system=*/true, &error_msg, &jars_missing_artifacts_on_system)) { @@ -1052,6 +1152,14 @@ bool OnDeviceRefresh::CheckSystemServerArtifactsAreUpToDate( } } + if (!CheckSystemPropertiesHaveNotChanged(cache_info.value())) { + // We don't have a trigger kind for system property changes. For now, we reuse + // `kApexVersionMismatch` as it implies the expected behavior: re-compile regardless of the last + // compilation attempt. + metrics.SetTrigger(OdrMetrics::Trigger::kApexVersionMismatch); + return false; + } + // Check system server components. // // This checks the size and checksums of odrefresh compilable files on the |