Parse multiple packages from Omaha response.
The multi-payload info are stored in OmahaResponse and InstallPlan, but
we still can only apply the first payload for now.
Bug: 36252799
Test: mma -j
Test: update_engine_unittests
Change-Id: I5ca63944ae9082670d0e67888409374f140d4245
(cherry picked from commit 2aba8a87d4fac245a2e2d238b3159f8eabce630f)
diff --git a/payload_state.cc b/payload_state.cc
index 1da472f..287e24c 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -126,7 +126,8 @@
// we loaded from the persisted state is a valid value. If the response
// hasn't changed but the URL index is invalid, it's indicative of some
// tampering of the persisted state.
- if (static_cast<uint32_t>(url_index_) >= candidate_urls_.size()) {
+ if (payload_index_ >= candidate_urls_.size() ||
+ url_index_ >= candidate_urls_[payload_index_].size()) {
LOG(INFO) << "Resetting all payload state as the url index seems to have "
"been tampered with";
ResetPersistedState();
@@ -444,21 +445,23 @@
}
void PayloadState::IncrementUrlIndex() {
- uint32_t next_url_index = GetUrlIndex() + 1;
- if (next_url_index < candidate_urls_.size()) {
+ size_t next_url_index = url_index_ + 1;
+ size_t max_url_size = 0;
+ for (const auto& urls : candidate_urls_)
+ max_url_size = std::max(max_url_size, urls.size());
+ if (next_url_index < max_url_size) {
LOG(INFO) << "Incrementing the URL index for next attempt";
SetUrlIndex(next_url_index);
} else {
- LOG(INFO) << "Resetting the current URL index (" << GetUrlIndex() << ") to "
- << "0 as we only have " << candidate_urls_.size()
- << " candidate URL(s)";
+ LOG(INFO) << "Resetting the current URL index (" << url_index_ << ") to "
+ << "0 as we only have " << max_url_size << " candidate URL(s)";
SetUrlIndex(0);
IncrementPayloadAttemptNumber();
IncrementFullPayloadAttemptNumber();
}
// If we have multiple URLs, record that we just switched to another one
- if (candidate_urls_.size() > 1)
+ if (max_url_size > 1)
SetUrlSwitchCount(url_switch_count_ + 1);
// Whenever we update the URL index, we should also clear the URL failure
@@ -519,12 +522,14 @@
if (using_p2p_for_downloading_) {
current_download_source_ = kDownloadSourceHttpPeer;
- } else if (GetUrlIndex() < candidate_urls_.size()) {
- string current_url = candidate_urls_[GetUrlIndex()];
- if (base::StartsWith(current_url, "https://",
- base::CompareCase::INSENSITIVE_ASCII)) {
+ } else if (payload_index_ < candidate_urls_.size() &&
+ candidate_urls_[payload_index_].size() != 0) {
+ const string& current_url = candidate_urls_[payload_index_][GetUrlIndex()];
+ if (base::StartsWith(
+ current_url, "https://", base::CompareCase::INSENSITIVE_ASCII)) {
current_download_source_ = kDownloadSourceHttpsServer;
- } else if (base::StartsWith(current_url, "http://",
+ } else if (base::StartsWith(current_url,
+ "http://",
base::CompareCase::INSENSITIVE_ASCII)) {
current_download_source_ = kDownloadSourceHttpServer;
}
@@ -569,7 +574,7 @@
PayloadType payload_type = CalculatePayloadType();
- int64_t payload_size = response_.size;
+ int64_t payload_size = GetPayloadSize();
int64_t payload_bytes_downloaded = attempt_num_bytes_downloaded_;
@@ -715,7 +720,7 @@
PayloadType payload_type = CalculatePayloadType();
- int64_t payload_size = response_.size;
+ int64_t payload_size = GetPayloadSize();
int attempt_count = GetPayloadAttemptNumber();
@@ -803,26 +808,32 @@
}
string PayloadState::CalculateResponseSignature() {
- string response_sign = base::StringPrintf(
- "NumURLs = %d\n", static_cast<int>(candidate_urls_.size()));
+ string response_sign;
+ for (size_t i = 0; i < response_.packages.size(); i++) {
+ const auto& package = response_.packages[i];
+ response_sign += base::StringPrintf(
+ "Payload %zu:\n"
+ " Size = %ju\n"
+ " Sha256 Hash = %s\n"
+ " Metadata Size = %ju\n"
+ " Metadata Signature = %s\n"
+ " NumURLs = %zu\n",
+ i,
+ static_cast<uintmax_t>(package.size),
+ package.hash.c_str(),
+ static_cast<uintmax_t>(package.metadata_size),
+ package.metadata_signature.c_str(),
+ candidate_urls_[i].size());
- for (size_t i = 0; i < candidate_urls_.size(); i++)
- response_sign += base::StringPrintf("Candidate Url%d = %s\n",
- static_cast<int>(i),
- candidate_urls_[i].c_str());
+ for (size_t j = 0; j < candidate_urls_[i].size(); j++)
+ response_sign += base::StringPrintf(
+ " Candidate Url%zu = %s\n", j, candidate_urls_[i][j].c_str());
+ }
response_sign += base::StringPrintf(
- "Payload Size = %ju\n"
- "Payload Sha256 Hash = %s\n"
- "Metadata Size = %ju\n"
- "Metadata Signature = %s\n"
"Is Delta Payload = %d\n"
"Max Failure Count Per Url = %d\n"
"Disable Payload Backoff = %d\n",
- static_cast<uintmax_t>(response_.size),
- response_.hash.c_str(),
- static_cast<uintmax_t>(response_.metadata_size),
- response_.metadata_signature.c_str(),
response_.is_delta_payload,
response_.max_failure_count_per_url,
response_.disable_payload_backoff);
@@ -1172,20 +1183,22 @@
}
candidate_urls_.clear();
- for (size_t i = 0; i < response_.payload_urls.size(); i++) {
- string candidate_url = response_.payload_urls[i];
- if (base::StartsWith(candidate_url, "http://",
- base::CompareCase::INSENSITIVE_ASCII) &&
- !http_url_ok) {
- continue;
+ for (const auto& package : response_.packages) {
+ candidate_urls_.emplace_back();
+ for (const string& candidate_url : package.payload_urls) {
+ if (base::StartsWith(
+ candidate_url, "http://", base::CompareCase::INSENSITIVE_ASCII) &&
+ !http_url_ok) {
+ continue;
+ }
+ candidate_urls_.back().push_back(candidate_url);
+ LOG(INFO) << "Candidate Url" << (candidate_urls_.back().size() - 1)
+ << ": " << candidate_url;
}
- candidate_urls_.push_back(candidate_url);
- LOG(INFO) << "Candidate Url" << (candidate_urls_.size() - 1)
- << ": " << candidate_url;
+ LOG(INFO) << "Found " << candidate_urls_.back().size() << " candidate URLs "
+ << "out of " << package.payload_urls.size()
+ << " URLs supplied in package " << candidate_urls_.size() - 1;
}
-
- LOG(INFO) << "Found " << candidate_urls_.size() << " candidate URLs "
- << "out of " << response_.payload_urls.size() << " URLs supplied";
}
void PayloadState::CreateSystemUpdatedMarkerFile() {
@@ -1394,4 +1407,11 @@
return true;
}
+int64_t PayloadState::GetPayloadSize() {
+ int64_t payload_size = 0;
+ for (const auto& package : response_.packages)
+ payload_size += package.size;
+ return payload_size;
+}
+
} // namespace chromeos_update_engine