1 // 2 // Copyright (C) 2016 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "update_engine/update_attempter_android.h" 18 19 #include <algorithm> 20 #include <map> 21 #include <memory> 22 #include <utility> 23 24 #include <android-base/properties.h> 25 #include <android-base/unique_fd.h> 26 #include <base/bind.h> 27 #include <base/logging.h> 28 #include <base/strings/string_number_conversions.h> 29 #include <brillo/data_encoding.h> 30 #include <brillo/message_loops/message_loop.h> 31 #include <brillo/strings/string_utils.h> 32 #include <log/log_safetynet.h> 33 34 #include "update_engine/cleanup_previous_update_action.h" 35 #include "update_engine/common/constants.h" 36 #include "update_engine/common/error_code_utils.h" 37 #include "update_engine/common/file_fetcher.h" 38 #include "update_engine/common/utils.h" 39 #include "update_engine/daemon_state_interface.h" 40 #include "update_engine/metrics_reporter_interface.h" 41 #include "update_engine/metrics_utils.h" 42 #include "update_engine/network_selector.h" 43 #include "update_engine/payload_consumer/certificate_parser_interface.h" 44 #include "update_engine/payload_consumer/delta_performer.h" 45 #include "update_engine/payload_consumer/download_action.h" 46 #include "update_engine/payload_consumer/file_descriptor.h" 47 #include "update_engine/payload_consumer/file_descriptor_utils.h" 48 #include "update_engine/payload_consumer/filesystem_verifier_action.h" 49 #include "update_engine/payload_consumer/payload_constants.h" 50 #include "update_engine/payload_consumer/payload_metadata.h" 51 #include "update_engine/payload_consumer/payload_verifier.h" 52 #include "update_engine/payload_consumer/postinstall_runner_action.h" 53 #include "update_engine/update_boot_flags_action.h" 54 #include "update_engine/update_status_utils.h" 55 56 #ifndef _UE_SIDELOAD 57 // Do not include support for external HTTP(s) urls when building 58 // update_engine_sideload. 59 #include "update_engine/libcurl_http_fetcher.h" 60 #endif 61 62 using android::base::unique_fd; 63 using base::Bind; 64 using base::Time; 65 using base::TimeDelta; 66 using base::TimeTicks; 67 using std::shared_ptr; 68 using std::string; 69 using std::vector; 70 using update_engine::UpdateEngineStatus; 71 72 namespace chromeos_update_engine { 73 74 namespace { 75 76 // Minimum threshold to broadcast an status update in progress and time. 77 const double kBroadcastThresholdProgress = 0.01; // 1% 78 const int kBroadcastThresholdSeconds = 10; 79 80 const char* const kErrorDomain = "update_engine"; 81 // TODO(deymo): Convert the different errors to a numeric value to report them 82 // back on the service error. 83 const char* const kGenericError = "generic_error"; 84 85 // Log and set the error on the passed ErrorPtr. 86 bool LogAndSetError(brillo::ErrorPtr* error, 87 const base::Location& location, 88 const string& reason) { 89 brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason); 90 LOG(ERROR) << "Replying with failure: " << location.ToString() << ": " 91 << reason; 92 return false; 93 } 94 95 bool GetHeaderAsBool(const string& header, bool default_value) { 96 int value = 0; 97 if (base::StringToInt(header, &value) && (value == 0 || value == 1)) 98 return value == 1; 99 return default_value; 100 } 101 102 bool ParseKeyValuePairHeaders(const vector<string>& key_value_pair_headers, 103 std::map<string, string>* headers, 104 brillo::ErrorPtr* error) { 105 for (const string& key_value_pair : key_value_pair_headers) { 106 string key; 107 string value; 108 if (!brillo::string_utils::SplitAtFirst( 109 key_value_pair, "=", &key, &value, false)) { 110 return LogAndSetError( 111 error, FROM_HERE, "Passed invalid header: " + key_value_pair); 112 } 113 if (!headers->emplace(key, value).second) 114 return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key); 115 } 116 return true; 117 } 118 119 // Unique identifier for the payload. An empty string means that the payload 120 // can't be resumed. 121 string GetPayloadId(const std::map<string, string>& headers) { 122 return (headers.count(kPayloadPropertyFileHash) 123 ? headers.at(kPayloadPropertyFileHash) 124 : "") + 125 (headers.count(kPayloadPropertyMetadataHash) 126 ? headers.at(kPayloadPropertyMetadataHash) 127 : ""); 128 } 129 130 } // namespace 131 132 UpdateAttempterAndroid::UpdateAttempterAndroid( 133 DaemonStateInterface* daemon_state, 134 PrefsInterface* prefs, 135 BootControlInterface* boot_control, 136 HardwareInterface* hardware) 137 : daemon_state_(daemon_state), 138 prefs_(prefs), 139 boot_control_(boot_control), 140 hardware_(hardware), 141 processor_(new ActionProcessor()), 142 clock_(new Clock()) { 143 metrics_reporter_ = metrics::CreateMetricsReporter(); 144 network_selector_ = network::CreateNetworkSelector(); 145 } 146 147 UpdateAttempterAndroid::~UpdateAttempterAndroid() { 148 // Release ourselves as the ActionProcessor's delegate to prevent 149 // re-scheduling the updates due to the processing stopped. 150 processor_->set_delegate(nullptr); 151 } 152 153 void UpdateAttempterAndroid::Init() { 154 // In case of update_engine restart without a reboot we need to restore the 155 // reboot needed state. 156 if (UpdateCompletedOnThisBoot()) { 157 SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT); 158 } else { 159 SetStatusAndNotify(UpdateStatus::IDLE); 160 UpdatePrefsAndReportUpdateMetricsOnReboot(); 161 #ifdef _UE_SIDELOAD 162 LOG(INFO) << "Skip ScheduleCleanupPreviousUpdate in sideload because " 163 << "ApplyPayload will call it later."; 164 #else 165 ScheduleCleanupPreviousUpdate(); 166 #endif 167 } 168 } 169 170 bool UpdateAttempterAndroid::ApplyPayload( 171 const string& payload_url, 172 int64_t payload_offset, 173 int64_t payload_size, 174 const vector<string>& key_value_pair_headers, 175 brillo::ErrorPtr* error) { 176 if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) { 177 return LogAndSetError( 178 error, FROM_HERE, "An update already applied, waiting for reboot"); 179 } 180 if (processor_->IsRunning()) { 181 return LogAndSetError( 182 error, FROM_HERE, "Already processing an update, cancel it first."); 183 } 184 DCHECK(status_ == UpdateStatus::IDLE); 185 186 std::map<string, string> headers; 187 if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) { 188 return false; 189 } 190 191 string payload_id = GetPayloadId(headers); 192 193 // Setup the InstallPlan based on the request. 194 install_plan_ = InstallPlan(); 195 196 install_plan_.download_url = payload_url; 197 install_plan_.version = ""; 198 base_offset_ = payload_offset; 199 InstallPlan::Payload payload; 200 payload.size = payload_size; 201 if (!payload.size) { 202 if (!base::StringToUint64(headers[kPayloadPropertyFileSize], 203 &payload.size)) { 204 payload.size = 0; 205 } 206 } 207 if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash], 208 &payload.hash)) { 209 LOG(WARNING) << "Unable to decode base64 file hash: " 210 << headers[kPayloadPropertyFileHash]; 211 } 212 if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize], 213 &payload.metadata_size)) { 214 payload.metadata_size = 0; 215 } 216 // The |payload.type| is not used anymore since minor_version 3. 217 payload.type = InstallPayloadType::kUnknown; 218 install_plan_.payloads.push_back(payload); 219 220 // The |public_key_rsa| key would override the public key stored on disk. 221 install_plan_.public_key_rsa = ""; 222 223 install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild(); 224 install_plan_.is_resume = !payload_id.empty() && 225 DeltaPerformer::CanResumeUpdate(prefs_, payload_id); 226 if (!install_plan_.is_resume) { 227 // No need to reset dynamic_partititon_metadata_updated. If previous calls 228 // to AllocateSpaceForPayload uses the same payload_id, reuse preallocated 229 // space. Otherwise, DeltaPerformer re-allocates space when the payload is 230 // applied. 231 if (!DeltaPerformer::ResetUpdateProgress( 232 prefs_, 233 false /* quick */, 234 true /* skip_dynamic_partititon_metadata_updated */)) { 235 LOG(WARNING) << "Unable to reset the update progress."; 236 } 237 if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) { 238 LOG(WARNING) << "Unable to save the update check response hash."; 239 } 240 } 241 install_plan_.source_slot = GetCurrentSlot(); 242 install_plan_.target_slot = GetTargetSlot(); 243 244 install_plan_.powerwash_required = 245 GetHeaderAsBool(headers[kPayloadPropertyPowerwash], false); 246 247 install_plan_.switch_slot_on_reboot = 248 GetHeaderAsBool(headers[kPayloadPropertySwitchSlotOnReboot], true); 249 250 install_plan_.run_post_install = 251 GetHeaderAsBool(headers[kPayloadPropertyRunPostInstall], true); 252 253 // Skip writing verity if we're resuming and verity has already been written. 254 install_plan_.write_verity = true; 255 if (install_plan_.is_resume && prefs_->Exists(kPrefsVerityWritten)) { 256 bool verity_written = false; 257 if (prefs_->GetBoolean(kPrefsVerityWritten, &verity_written) && 258 verity_written) { 259 install_plan_.write_verity = false; 260 } 261 } 262 263 NetworkId network_id = kDefaultNetworkId; 264 if (!headers[kPayloadPropertyNetworkId].empty()) { 265 if (!base::StringToUint64(headers[kPayloadPropertyNetworkId], 266 &network_id)) { 267 return LogAndSetError( 268 error, 269 FROM_HERE, 270 "Invalid network_id: " + headers[kPayloadPropertyNetworkId]); 271 } 272 if (!network_selector_->SetProcessNetwork(network_id)) { 273 return LogAndSetError( 274 error, 275 FROM_HERE, 276 "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]); 277 } 278 } 279 280 LOG(INFO) << "Using this install plan:"; 281 install_plan_.Dump(); 282 283 HttpFetcher* fetcher = nullptr; 284 if (FileFetcher::SupportedUrl(payload_url)) { 285 DLOG(INFO) << "Using FileFetcher for file URL."; 286 fetcher = new FileFetcher(); 287 } else { 288 #ifdef _UE_SIDELOAD 289 LOG(FATAL) << "Unsupported sideload URI: " << payload_url; 290 #else 291 LibcurlHttpFetcher* libcurl_fetcher = 292 new LibcurlHttpFetcher(&proxy_resolver_, hardware_); 293 libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload); 294 fetcher = libcurl_fetcher; 295 #endif // _UE_SIDELOAD 296 } 297 // Setup extra headers. 298 if (!headers[kPayloadPropertyAuthorization].empty()) 299 fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]); 300 if (!headers[kPayloadPropertyUserAgent].empty()) 301 fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]); 302 303 BuildUpdateActions(fetcher); 304 305 SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE); 306 307 UpdatePrefsOnUpdateStart(install_plan_.is_resume); 308 // TODO(xunchang) report the metrics for unresumable updates 309 310 ScheduleProcessingStart(); 311 return true; 312 } 313 314 bool UpdateAttempterAndroid::ApplyPayload( 315 int fd, 316 int64_t payload_offset, 317 int64_t payload_size, 318 const vector<string>& key_value_pair_headers, 319 brillo::ErrorPtr* error) { 320 payload_fd_.reset(dup(fd)); 321 const string payload_url = "fd://" + std::to_string(payload_fd_.get()); 322 323 return ApplyPayload( 324 payload_url, payload_offset, payload_size, key_value_pair_headers, error); 325 } 326 327 bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) { 328 if (!processor_->IsRunning()) 329 return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend."); 330 processor_->SuspendProcessing(); 331 return true; 332 } 333 334 bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) { 335 if (!processor_->IsRunning()) 336 return LogAndSetError(error, FROM_HERE, "No ongoing update to resume."); 337 processor_->ResumeProcessing(); 338 return true; 339 } 340 341 bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) { 342 if (!processor_->IsRunning()) 343 return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel."); 344 processor_->StopProcessing(); 345 return true; 346 } 347 348 bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) { 349 LOG(INFO) << "Attempting to reset state from " 350 << UpdateStatusToString(status_) << " to UpdateStatus::IDLE"; 351 352 switch (status_) { 353 case UpdateStatus::IDLE: { 354 if (!boot_control_->GetDynamicPartitionControl()->ResetUpdate(prefs_)) { 355 LOG(WARNING) << "Failed to reset snapshots. UpdateStatus is IDLE but" 356 << "space might not be freed."; 357 } 358 return true; 359 } 360 361 case UpdateStatus::UPDATED_NEED_REBOOT: { 362 bool ret_value = true; 363 364 // Update the boot flags so the current slot has higher priority. 365 if (!boot_control_->SetActiveBootSlot(GetCurrentSlot())) 366 ret_value = false; 367 368 // Mark the current slot as successful again, since marking it as active 369 // may reset the successful bit. We ignore the result of whether marking 370 // the current slot as successful worked. 371 if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful) {}))) 372 ret_value = false; 373 374 // Resets the warm reset property since we won't switch the slot. 375 hardware_->SetWarmReset(false); 376 377 // Remove update progress for DeltaPerformer and remove snapshots. 378 if (!boot_control_->GetDynamicPartitionControl()->ResetUpdate(prefs_)) 379 ret_value = false; 380 381 // Remove the reboot marker so that if the machine is rebooted 382 // after resetting to idle state, it doesn't go back to 383 // UpdateStatus::UPDATED_NEED_REBOOT state. 384 if (!prefs_->Delete(kPrefsUpdateCompletedOnBootId)) 385 ret_value = false; 386 ClearMetricsPrefs(); 387 388 if (!ret_value) { 389 return LogAndSetError( 390 error, FROM_HERE, "Failed to reset the status to "); 391 } 392 393 SetStatusAndNotify(UpdateStatus::IDLE); 394 LOG(INFO) << "Reset status successful"; 395 return true; 396 } 397 398 default: 399 return LogAndSetError( 400 error, 401 FROM_HERE, 402 "Reset not allowed in this state. Cancel the ongoing update first"); 403 } 404 } 405 406 bool UpdateAttempterAndroid::VerifyPayloadParseManifest( 407 const std::string& metadata_filename, 408 DeltaArchiveManifest* manifest, 409 brillo::ErrorPtr* error) { 410 FileDescriptorPtr fd(new EintrSafeFileDescriptor); 411 if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) { 412 return LogAndSetError( 413 error, FROM_HERE, "Failed to open " + metadata_filename); 414 } 415 brillo::Blob metadata(kMaxPayloadHeaderSize); 416 if (!fd->Read(metadata.data(), metadata.size())) { 417 return LogAndSetError( 418 error, 419 FROM_HERE, 420 "Failed to read payload header from " + metadata_filename); 421 } 422 ErrorCode errorcode; 423 PayloadMetadata payload_metadata; 424 if (payload_metadata.ParsePayloadHeader(metadata, &errorcode) != 425 MetadataParseResult::kSuccess) { 426 return LogAndSetError(error, 427 FROM_HERE, 428 "Failed to parse payload header: " + 429 utils::ErrorCodeToString(errorcode)); 430 } 431 uint64_t metadata_size = payload_metadata.GetMetadataSize() + 432 payload_metadata.GetMetadataSignatureSize(); 433 if (metadata_size < kMaxPayloadHeaderSize || 434 metadata_size > 435 static_cast<uint64_t>(utils::FileSize(metadata_filename))) { 436 return LogAndSetError( 437 error, 438 FROM_HERE, 439 "Invalid metadata size: " + std::to_string(metadata_size)); 440 } 441 metadata.resize(metadata_size); 442 if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize, 443 metadata.size() - kMaxPayloadHeaderSize)) { 444 return LogAndSetError( 445 error, 446 FROM_HERE, 447 "Failed to read metadata and signature from " + metadata_filename); 448 } 449 fd->Close(); 450 451 auto payload_verifier = PayloadVerifier::CreateInstanceFromZipPath( 452 constants::kUpdateCertificatesPath); 453 if (!payload_verifier) { 454 return LogAndSetError(error, 455 FROM_HERE, 456 "Failed to create the payload verifier from " + 457 std::string(constants::kUpdateCertificatesPath)); 458 } 459 errorcode = payload_metadata.ValidateMetadataSignature( 460 metadata, "", *payload_verifier); 461 if (errorcode != ErrorCode::kSuccess) { 462 return LogAndSetError(error, 463 FROM_HERE, 464 "Failed to validate metadata signature: " + 465 utils::ErrorCodeToString(errorcode)); 466 } 467 if (!payload_metadata.GetManifest(metadata, manifest)) { 468 return LogAndSetError(error, FROM_HERE, "Failed to parse manifest."); 469 } 470 471 return true; 472 } 473 474 bool UpdateAttempterAndroid::VerifyPayloadApplicable( 475 const std::string& metadata_filename, brillo::ErrorPtr* error) { 476 DeltaArchiveManifest manifest; 477 TEST_AND_RETURN_FALSE( 478 VerifyPayloadParseManifest(metadata_filename, &manifest, error)); 479 480 FileDescriptorPtr fd(new EintrSafeFileDescriptor); 481 ErrorCode errorcode; 482 483 BootControlInterface::Slot current_slot = GetCurrentSlot(); 484 for (const PartitionUpdate& partition : manifest.partitions()) { 485 if (!partition.has_old_partition_info()) 486 continue; 487 string partition_path; 488 if (!boot_control_->GetPartitionDevice( 489 partition.partition_name(), current_slot, &partition_path)) { 490 return LogAndSetError( 491 error, 492 FROM_HERE, 493 "Failed to get partition device for " + partition.partition_name()); 494 } 495 if (!fd->Open(partition_path.c_str(), O_RDONLY)) { 496 return LogAndSetError( 497 error, FROM_HERE, "Failed to open " + partition_path); 498 } 499 for (const InstallOperation& operation : partition.operations()) { 500 if (!operation.has_src_sha256_hash()) 501 continue; 502 brillo::Blob source_hash; 503 if (!fd_utils::ReadAndHashExtents(fd, 504 operation.src_extents(), 505 manifest.block_size(), 506 &source_hash)) { 507 return LogAndSetError( 508 error, FROM_HERE, "Failed to hash " + partition_path); 509 } 510 if (!DeltaPerformer::ValidateSourceHash( 511 source_hash, operation, fd, &errorcode)) { 512 return false; 513 } 514 } 515 fd->Close(); 516 } 517 return true; 518 } 519 520 void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor, 521 ErrorCode code) { 522 LOG(INFO) << "Processing Done."; 523 524 if (status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE) { 525 TerminateUpdateAndNotify(code); 526 return; 527 } 528 529 switch (code) { 530 case ErrorCode::kSuccess: 531 // Update succeeded. 532 WriteUpdateCompletedMarker(); 533 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); 534 535 LOG(INFO) << "Update successfully applied, waiting to reboot."; 536 break; 537 538 case ErrorCode::kFilesystemCopierError: 539 case ErrorCode::kNewRootfsVerificationError: 540 case ErrorCode::kNewKernelVerificationError: 541 case ErrorCode::kFilesystemVerifierError: 542 case ErrorCode::kDownloadStateInitializationError: 543 // Reset the ongoing update for these errors so it starts from the 544 // beginning next time. 545 DeltaPerformer::ResetUpdateProgress(prefs_, false); 546 LOG(INFO) << "Resetting update progress."; 547 break; 548 549 case ErrorCode::kPayloadTimestampError: 550 // SafetyNet logging, b/36232423 551 android_errorWriteLog(0x534e4554, "36232423"); 552 break; 553 554 default: 555 // Ignore all other error codes. 556 break; 557 } 558 559 TerminateUpdateAndNotify(code); 560 } 561 562 void UpdateAttempterAndroid::ProcessingStopped( 563 const ActionProcessor* processor) { 564 TerminateUpdateAndNotify(ErrorCode::kUserCanceled); 565 } 566 567 void UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor, 568 AbstractAction* action, 569 ErrorCode code) { 570 // Reset download progress regardless of whether or not the download 571 // action succeeded. 572 const string type = action->Type(); 573 if (type == CleanupPreviousUpdateAction::StaticType() || 574 (type == NoOpAction::StaticType() && 575 status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE)) { 576 cleanup_previous_update_code_ = code; 577 NotifyCleanupPreviousUpdateCallbacksAndClear(); 578 } 579 if (type == DownloadAction::StaticType()) { 580 download_progress_ = 0; 581 } 582 if (type == PostinstallRunnerAction::StaticType()) { 583 bool succeeded = 584 code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive; 585 prefs_->SetBoolean(kPrefsPostInstallSucceeded, succeeded); 586 } 587 if (code != ErrorCode::kSuccess) { 588 // If an action failed, the ActionProcessor will cancel the whole thing. 589 return; 590 } 591 if (type == UpdateBootFlagsAction::StaticType()) { 592 SetStatusAndNotify(UpdateStatus::CLEANUP_PREVIOUS_UPDATE); 593 } 594 if (type == DownloadAction::StaticType()) { 595 SetStatusAndNotify(UpdateStatus::FINALIZING); 596 } else if (type == FilesystemVerifierAction::StaticType()) { 597 prefs_->SetBoolean(kPrefsVerityWritten, true); 598 } 599 } 600 601 void UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed, 602 uint64_t bytes_received, 603 uint64_t total) { 604 double progress = 0; 605 if (total) 606 progress = static_cast<double>(bytes_received) / static_cast<double>(total); 607 if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) { 608 download_progress_ = progress; 609 SetStatusAndNotify(UpdateStatus::DOWNLOADING); 610 } else { 611 ProgressUpdate(progress); 612 } 613 614 // Update the bytes downloaded in prefs. 615 int64_t current_bytes_downloaded = 616 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_); 617 int64_t total_bytes_downloaded = 618 metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_); 619 prefs_->SetInt64(kPrefsCurrentBytesDownloaded, 620 current_bytes_downloaded + bytes_progressed); 621 prefs_->SetInt64(kPrefsTotalBytesDownloaded, 622 total_bytes_downloaded + bytes_progressed); 623 } 624 625 bool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) { 626 // TODO(deymo): Notify the DownloadAction that it should cancel the update 627 // download. 628 return false; 629 } 630 631 void UpdateAttempterAndroid::DownloadComplete() { 632 // Nothing needs to be done when the download completes. 633 } 634 635 void UpdateAttempterAndroid::ProgressUpdate(double progress) { 636 // Self throttle based on progress. Also send notifications if progress is 637 // too slow. 638 if (progress == 1.0 || 639 progress - download_progress_ >= kBroadcastThresholdProgress || 640 TimeTicks::Now() - last_notify_time_ >= 641 TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) { 642 download_progress_ = progress; 643 SetStatusAndNotify(status_); 644 } 645 } 646 647 void UpdateAttempterAndroid::ScheduleProcessingStart() { 648 LOG(INFO) << "Scheduling an action processor start."; 649 brillo::MessageLoop::current()->PostTask( 650 FROM_HERE, 651 Bind([](ActionProcessor* processor) { processor->StartProcessing(); }, 652 base::Unretained(processor_.get()))); 653 } 654 655 void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) { 656 if (status_ == UpdateStatus::IDLE) { 657 LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called."; 658 return; 659 } 660 661 if (status_ == UpdateStatus::CLEANUP_PREVIOUS_UPDATE) { 662 LOG(INFO) << "Terminating cleanup previous update."; 663 SetStatusAndNotify(UpdateStatus::IDLE); 664 for (auto observer : daemon_state_->service_observers()) 665 observer->SendPayloadApplicationComplete(error_code); 666 return; 667 } 668 669 boot_control_->GetDynamicPartitionControl()->Cleanup(); 670 671 download_progress_ = 0; 672 UpdateStatus new_status = 673 (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT 674 : UpdateStatus::IDLE); 675 SetStatusAndNotify(new_status); 676 payload_fd_.reset(); 677 678 // The network id is only applicable to one download attempt and once it's 679 // done the network id should not be re-used anymore. 680 if (!network_selector_->SetProcessNetwork(kDefaultNetworkId)) { 681 LOG(WARNING) << "Unable to unbind network."; 682 } 683 684 for (auto observer : daemon_state_->service_observers()) 685 observer->SendPayloadApplicationComplete(error_code); 686 687 CollectAndReportUpdateMetricsOnUpdateFinished(error_code); 688 ClearMetricsPrefs(); 689 if (error_code == ErrorCode::kSuccess) { 690 // We should only reset the PayloadAttemptNumber if the update succeeds, or 691 // we switch to a different payload. 692 prefs_->Delete(kPrefsPayloadAttemptNumber); 693 metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_); 694 // Clear the total bytes downloaded if and only if the update succeeds. 695 prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0); 696 } 697 } 698 699 void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) { 700 status_ = status; 701 size_t payload_size = 702 install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size; 703 UpdateEngineStatus status_to_send = {.status = status_, 704 .progress = download_progress_, 705 .new_size_bytes = payload_size}; 706 707 for (auto observer : daemon_state_->service_observers()) { 708 observer->SendStatusUpdate(status_to_send); 709 } 710 last_notify_time_ = TimeTicks::Now(); 711 } 712 713 void UpdateAttempterAndroid::BuildUpdateActions(HttpFetcher* fetcher) { 714 CHECK(!processor_->IsRunning()); 715 processor_->set_delegate(this); 716 717 // Actions: 718 auto update_boot_flags_action = 719 std::make_unique<UpdateBootFlagsAction>(boot_control_); 720 auto cleanup_previous_update_action = 721 boot_control_->GetDynamicPartitionControl() 722 ->GetCleanupPreviousUpdateAction(boot_control_, prefs_, this); 723 auto install_plan_action = std::make_unique<InstallPlanAction>(install_plan_); 724 auto download_action = 725 std::make_unique<DownloadAction>(prefs_, 726 boot_control_, 727 hardware_, 728 nullptr, // system_state, not used. 729 fetcher, // passes ownership 730 true /* interactive */); 731 download_action->set_delegate(this); 732 download_action->set_base_offset(base_offset_); 733 auto filesystem_verifier_action = 734 std::make_unique<FilesystemVerifierAction>(); 735 auto postinstall_runner_action = 736 std::make_unique<PostinstallRunnerAction>(boot_control_, hardware_); 737 postinstall_runner_action->set_delegate(this); 738 739 // Bond them together. We have to use the leaf-types when calling 740 // BondActions(). 741 BondActions(install_plan_action.get(), download_action.get()); 742 BondActions(download_action.get(), filesystem_verifier_action.get()); 743 BondActions(filesystem_verifier_action.get(), 744 postinstall_runner_action.get()); 745 746 processor_->EnqueueAction(std::move(update_boot_flags_action)); 747 processor_->EnqueueAction(std::move(cleanup_previous_update_action)); 748 processor_->EnqueueAction(std::move(install_plan_action)); 749 processor_->EnqueueAction(std::move(download_action)); 750 processor_->EnqueueAction(std::move(filesystem_verifier_action)); 751 processor_->EnqueueAction(std::move(postinstall_runner_action)); 752 } 753 754 bool UpdateAttempterAndroid::WriteUpdateCompletedMarker() { 755 string boot_id; 756 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 757 prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id); 758 return true; 759 } 760 761 bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() { 762 // In case of an update_engine restart without a reboot, we stored the boot_id 763 // when the update was completed by setting a pref, so we can check whether 764 // the last update was on this boot or a previous one. 765 string boot_id; 766 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 767 768 string update_completed_on_boot_id; 769 return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) && 770 prefs_->GetString(kPrefsUpdateCompletedOnBootId, 771 &update_completed_on_boot_id) && 772 update_completed_on_boot_id == boot_id); 773 } 774 775 // Collect and report the android metrics when we terminate the update. 776 void UpdateAttempterAndroid::CollectAndReportUpdateMetricsOnUpdateFinished( 777 ErrorCode error_code) { 778 int64_t attempt_number = 779 metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_); 780 PayloadType payload_type = kPayloadTypeFull; 781 int64_t payload_size = 0; 782 for (const auto& p : install_plan_.payloads) { 783 if (p.type == InstallPayloadType::kDelta) 784 payload_type = kPayloadTypeDelta; 785 payload_size += p.size; 786 } 787 788 metrics::AttemptResult attempt_result = 789 metrics_utils::GetAttemptResult(error_code); 790 Time boot_time_start = Time::FromInternalValue( 791 metrics_utils::GetPersistedValue(kPrefsUpdateBootTimestampStart, prefs_)); 792 Time monotonic_time_start = Time::FromInternalValue( 793 metrics_utils::GetPersistedValue(kPrefsUpdateTimestampStart, prefs_)); 794 TimeDelta duration = clock_->GetBootTime() - boot_time_start; 795 TimeDelta duration_uptime = clock_->GetMonotonicTime() - monotonic_time_start; 796 797 metrics_reporter_->ReportUpdateAttemptMetrics( 798 nullptr, // system_state 799 static_cast<int>(attempt_number), 800 payload_type, 801 duration, 802 duration_uptime, 803 payload_size, 804 attempt_result, 805 error_code); 806 807 int64_t current_bytes_downloaded = 808 metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_); 809 metrics_reporter_->ReportUpdateAttemptDownloadMetrics( 810 current_bytes_downloaded, 811 0, 812 DownloadSource::kNumDownloadSources, 813 metrics::DownloadErrorCode::kUnset, 814 metrics::ConnectionType::kUnset); 815 816 if (error_code == ErrorCode::kSuccess) { 817 int64_t reboot_count = 818 metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_); 819 string build_version; 820 prefs_->GetString(kPrefsPreviousVersion, &build_version); 821 822 // For android metrics, we only care about the total bytes downloaded 823 // for all sources; for now we assume the only download source is 824 // HttpsServer. 825 int64_t total_bytes_downloaded = 826 metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_); 827 int64_t num_bytes_downloaded[kNumDownloadSources] = {}; 828 num_bytes_downloaded[DownloadSource::kDownloadSourceHttpsServer] = 829 total_bytes_downloaded; 830 831 int download_overhead_percentage = 0; 832 if (total_bytes_downloaded >= payload_size) { 833 CHECK_GT(payload_size, 0); 834 download_overhead_percentage = 835 (total_bytes_downloaded - payload_size) * 100ull / payload_size; 836 } else { 837 LOG(WARNING) << "Downloaded bytes " << total_bytes_downloaded 838 << " is smaller than the payload size " << payload_size; 839 } 840 841 metrics_reporter_->ReportSuccessfulUpdateMetrics( 842 static_cast<int>(attempt_number), 843 0, // update abandoned count 844 payload_type, 845 payload_size, 846 num_bytes_downloaded, 847 download_overhead_percentage, 848 duration, 849 duration_uptime, 850 static_cast<int>(reboot_count), 851 0); // url_switch_count 852 } 853 } 854 855 void UpdateAttempterAndroid::UpdatePrefsAndReportUpdateMetricsOnReboot() { 856 string current_boot_id; 857 TEST_AND_RETURN(utils::GetBootId(¤t_boot_id)); 858 // Example: [ro.build.version.incremental]: [4292972] 859 string current_version = 860 android::base::GetProperty("ro.build.version.incremental", ""); 861 TEST_AND_RETURN(!current_version.empty()); 862 863 // If there's no record of previous version (e.g. due to a data wipe), we 864 // save the info of current boot and skip the metrics report. 865 if (!prefs_->Exists(kPrefsPreviousVersion)) { 866 prefs_->SetString(kPrefsBootId, current_boot_id); 867 prefs_->SetString(kPrefsPreviousVersion, current_version); 868 ClearMetricsPrefs(); 869 return; 870 } 871 string previous_version; 872 // update_engine restarted under the same build. 873 // TODO(xunchang) identify and report rollback by checking UpdateMarker. 874 if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) && 875 previous_version == current_version) { 876 string last_boot_id; 877 bool is_reboot = prefs_->Exists(kPrefsBootId) && 878 (prefs_->GetString(kPrefsBootId, &last_boot_id) && 879 last_boot_id != current_boot_id); 880 // Increment the reboot number if |kPrefsNumReboots| exists. That pref is 881 // set when we start a new update. 882 if (is_reboot && prefs_->Exists(kPrefsNumReboots)) { 883 prefs_->SetString(kPrefsBootId, current_boot_id); 884 int64_t reboot_count = 885 metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_); 886 metrics_utils::SetNumReboots(reboot_count + 1, prefs_); 887 } 888 return; 889 } 890 891 // Now that the build version changes, report the update metrics. 892 // TODO(xunchang) check the build version is larger than the previous one. 893 prefs_->SetString(kPrefsBootId, current_boot_id); 894 prefs_->SetString(kPrefsPreviousVersion, current_version); 895 896 bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber); 897 // |kPrefsPayloadAttemptNumber| should be cleared upon successful update. 898 if (previous_attempt_exists) { 899 metrics_reporter_->ReportAbnormallyTerminatedUpdateAttemptMetrics(); 900 } 901 902 metrics_utils::LoadAndReportTimeToReboot( 903 metrics_reporter_.get(), prefs_, clock_.get()); 904 ClearMetricsPrefs(); 905 906 // Also reset the update progress if the build version has changed. 907 if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) { 908 LOG(WARNING) << "Unable to reset the update progress."; 909 } 910 } 911 912 // Save the update start time. Reset the reboot count and attempt number if the 913 // update isn't a resume; otherwise increment the attempt number. 914 void UpdateAttempterAndroid::UpdatePrefsOnUpdateStart(bool is_resume) { 915 if (!is_resume) { 916 metrics_utils::SetNumReboots(0, prefs_); 917 metrics_utils::SetPayloadAttemptNumber(1, prefs_); 918 } else { 919 int64_t attempt_number = 920 metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_); 921 metrics_utils::SetPayloadAttemptNumber(attempt_number + 1, prefs_); 922 } 923 metrics_utils::SetUpdateTimestampStart(clock_->GetMonotonicTime(), prefs_); 924 metrics_utils::SetUpdateBootTimestampStart(clock_->GetBootTime(), prefs_); 925 } 926 927 void UpdateAttempterAndroid::ClearMetricsPrefs() { 928 CHECK(prefs_); 929 prefs_->Delete(kPrefsCurrentBytesDownloaded); 930 prefs_->Delete(kPrefsNumReboots); 931 prefs_->Delete(kPrefsSystemUpdatedMarker); 932 prefs_->Delete(kPrefsUpdateTimestampStart); 933 prefs_->Delete(kPrefsUpdateBootTimestampStart); 934 } 935 936 BootControlInterface::Slot UpdateAttempterAndroid::GetCurrentSlot() const { 937 return boot_control_->GetCurrentSlot(); 938 } 939 940 BootControlInterface::Slot UpdateAttempterAndroid::GetTargetSlot() const { 941 return GetCurrentSlot() == 0 ? 1 : 0; 942 } 943 944 uint64_t UpdateAttempterAndroid::AllocateSpaceForPayload( 945 const std::string& metadata_filename, 946 const vector<string>& key_value_pair_headers, 947 brillo::ErrorPtr* error) { 948 DeltaArchiveManifest manifest; 949 if (!VerifyPayloadParseManifest(metadata_filename, &manifest, error)) { 950 return 0; 951 } 952 std::map<string, string> headers; 953 if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) { 954 return 0; 955 } 956 957 string payload_id = GetPayloadId(headers); 958 uint64_t required_size = 0; 959 if (!DeltaPerformer::PreparePartitionsForUpdate(prefs_, 960 boot_control_, 961 GetTargetSlot(), 962 manifest, 963 payload_id, 964 &required_size)) { 965 if (required_size == 0) { 966 LogAndSetError(error, FROM_HERE, "Failed to allocate space for payload."); 967 return 0; 968 } else { 969 LOG(ERROR) << "Insufficient space for payload: " << required_size 970 << " bytes"; 971 return required_size; 972 } 973 } 974 975 LOG(INFO) << "Successfully allocated space for payload."; 976 return 0; 977 } 978 979 void UpdateAttempterAndroid::CleanupSuccessfulUpdate( 980 std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback, 981 brillo::ErrorPtr* error) { 982 if (cleanup_previous_update_code_.has_value()) { 983 LOG(INFO) << "CleanupSuccessfulUpdate has previously completed with " 984 << utils::ErrorCodeToString(*cleanup_previous_update_code_); 985 if (callback) { 986 callback->OnCleanupComplete( 987 static_cast<int32_t>(*cleanup_previous_update_code_)); 988 } 989 return; 990 } 991 if (callback) { 992 auto callback_ptr = callback.get(); 993 cleanup_previous_update_callbacks_.emplace_back(std::move(callback)); 994 callback_ptr->RegisterForDeathNotifications( 995 base::Bind(&UpdateAttempterAndroid::RemoveCleanupPreviousUpdateCallback, 996 base::Unretained(this), 997 base::Unretained(callback_ptr))); 998 } 999 ScheduleCleanupPreviousUpdate(); 1000 } 1001 1002 void UpdateAttempterAndroid::ScheduleCleanupPreviousUpdate() { 1003 // If a previous CleanupSuccessfulUpdate call has not finished, or an update 1004 // is in progress, skip enqueueing the action. 1005 if (processor_->IsRunning()) { 1006 LOG(INFO) << "Already processing an update. CleanupPreviousUpdate should " 1007 << "be done when the current update finishes."; 1008 return; 1009 } 1010 LOG(INFO) << "Scheduling CleanupPreviousUpdateAction."; 1011 auto action = 1012 boot_control_->GetDynamicPartitionControl() 1013 ->GetCleanupPreviousUpdateAction(boot_control_, prefs_, this); 1014 processor_->EnqueueAction(std::move(action)); 1015 processor_->set_delegate(this); 1016 SetStatusAndNotify(UpdateStatus::CLEANUP_PREVIOUS_UPDATE); 1017 processor_->StartProcessing(); 1018 } 1019 1020 void UpdateAttempterAndroid::OnCleanupProgressUpdate(double progress) { 1021 for (auto&& callback : cleanup_previous_update_callbacks_) { 1022 callback->OnCleanupProgressUpdate(progress); 1023 } 1024 } 1025 1026 void UpdateAttempterAndroid::NotifyCleanupPreviousUpdateCallbacksAndClear() { 1027 CHECK(cleanup_previous_update_code_.has_value()); 1028 for (auto&& callback : cleanup_previous_update_callbacks_) { 1029 callback->OnCleanupComplete( 1030 static_cast<int32_t>(*cleanup_previous_update_code_)); 1031 } 1032 cleanup_previous_update_callbacks_.clear(); 1033 } 1034 1035 void UpdateAttempterAndroid::RemoveCleanupPreviousUpdateCallback( 1036 CleanupSuccessfulUpdateCallbackInterface* callback) { 1037 auto end_it = 1038 std::remove_if(cleanup_previous_update_callbacks_.begin(), 1039 cleanup_previous_update_callbacks_.end(), 1040 [&](const auto& e) { return e.get() == callback; }); 1041 cleanup_previous_update_callbacks_.erase( 1042 end_it, cleanup_previous_update_callbacks_.end()); 1043 } 1044 1045 } // namespace chromeos_update_engine 1046