Home | History | Annotate | Download | only in update_engine
      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 <base/bind.h>
     26 #include <base/logging.h>
     27 #include <base/strings/string_number_conversions.h>
     28 #include <brillo/bind_lambda.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/common/constants.h"
     35 #include "update_engine/common/error_code_utils.h"
     36 #include "update_engine/common/file_fetcher.h"
     37 #include "update_engine/common/utils.h"
     38 #include "update_engine/daemon_state_interface.h"
     39 #include "update_engine/metrics_reporter_interface.h"
     40 #include "update_engine/metrics_utils.h"
     41 #include "update_engine/network_selector.h"
     42 #include "update_engine/payload_consumer/delta_performer.h"
     43 #include "update_engine/payload_consumer/download_action.h"
     44 #include "update_engine/payload_consumer/file_descriptor.h"
     45 #include "update_engine/payload_consumer/file_descriptor_utils.h"
     46 #include "update_engine/payload_consumer/filesystem_verifier_action.h"
     47 #include "update_engine/payload_consumer/payload_constants.h"
     48 #include "update_engine/payload_consumer/payload_metadata.h"
     49 #include "update_engine/payload_consumer/postinstall_runner_action.h"
     50 #include "update_engine/update_status_utils.h"
     51 
     52 #ifndef _UE_SIDELOAD
     53 // Do not include support for external HTTP(s) urls when building
     54 // update_engine_sideload.
     55 #include "update_engine/libcurl_http_fetcher.h"
     56 #endif
     57 
     58 using base::Bind;
     59 using base::Time;
     60 using base::TimeDelta;
     61 using base::TimeTicks;
     62 using std::shared_ptr;
     63 using std::string;
     64 using std::vector;
     65 using update_engine::UpdateEngineStatus;
     66 
     67 namespace chromeos_update_engine {
     68 
     69 namespace {
     70 
     71 // Minimum threshold to broadcast an status update in progress and time.
     72 const double kBroadcastThresholdProgress = 0.01;  // 1%
     73 const int kBroadcastThresholdSeconds = 10;
     74 
     75 const char* const kErrorDomain = "update_engine";
     76 // TODO(deymo): Convert the different errors to a numeric value to report them
     77 // back on the service error.
     78 const char* const kGenericError = "generic_error";
     79 
     80 // Log and set the error on the passed ErrorPtr.
     81 bool LogAndSetError(brillo::ErrorPtr* error,
     82                     const tracked_objects::Location& location,
     83                     const string& reason) {
     84   brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason);
     85   LOG(ERROR) << "Replying with failure: " << location.ToString() << ": "
     86              << reason;
     87   return false;
     88 }
     89 
     90 bool GetHeaderAsBool(const string& header, bool default_value) {
     91   int value = 0;
     92   if (base::StringToInt(header, &value) && (value == 0 || value == 1))
     93     return value == 1;
     94   return default_value;
     95 }
     96 
     97 }  // namespace
     98 
     99 UpdateAttempterAndroid::UpdateAttempterAndroid(
    100     DaemonStateInterface* daemon_state,
    101     PrefsInterface* prefs,
    102     BootControlInterface* boot_control,
    103     HardwareInterface* hardware)
    104     : daemon_state_(daemon_state),
    105       prefs_(prefs),
    106       boot_control_(boot_control),
    107       hardware_(hardware),
    108       processor_(new ActionProcessor()),
    109       clock_(new Clock()) {
    110   metrics_reporter_ = metrics::CreateMetricsReporter();
    111   network_selector_ = network::CreateNetworkSelector();
    112 }
    113 
    114 UpdateAttempterAndroid::~UpdateAttempterAndroid() {
    115   // Release ourselves as the ActionProcessor's delegate to prevent
    116   // re-scheduling the updates due to the processing stopped.
    117   processor_->set_delegate(nullptr);
    118 }
    119 
    120 void UpdateAttempterAndroid::Init() {
    121   // In case of update_engine restart without a reboot we need to restore the
    122   // reboot needed state.
    123   if (UpdateCompletedOnThisBoot()) {
    124     SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
    125   } else {
    126     SetStatusAndNotify(UpdateStatus::IDLE);
    127     UpdatePrefsAndReportUpdateMetricsOnReboot();
    128   }
    129 }
    130 
    131 bool UpdateAttempterAndroid::ApplyPayload(
    132     const string& payload_url,
    133     int64_t payload_offset,
    134     int64_t payload_size,
    135     const vector<string>& key_value_pair_headers,
    136     brillo::ErrorPtr* error) {
    137   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
    138     return LogAndSetError(
    139         error, FROM_HERE, "An update already applied, waiting for reboot");
    140   }
    141   if (ongoing_update_) {
    142     return LogAndSetError(
    143         error, FROM_HERE, "Already processing an update, cancel it first.");
    144   }
    145   DCHECK(status_ == UpdateStatus::IDLE);
    146 
    147   std::map<string, string> headers;
    148   for (const string& key_value_pair : key_value_pair_headers) {
    149     string key;
    150     string value;
    151     if (!brillo::string_utils::SplitAtFirst(
    152             key_value_pair, "=", &key, &value, false)) {
    153       return LogAndSetError(
    154           error, FROM_HERE, "Passed invalid header: " + key_value_pair);
    155     }
    156     if (!headers.emplace(key, value).second)
    157       return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key);
    158   }
    159 
    160   // Unique identifier for the payload. An empty string means that the payload
    161   // can't be resumed.
    162   string payload_id = (headers[kPayloadPropertyFileHash] +
    163                        headers[kPayloadPropertyMetadataHash]);
    164 
    165   // Setup the InstallPlan based on the request.
    166   install_plan_ = InstallPlan();
    167 
    168   install_plan_.download_url = payload_url;
    169   install_plan_.version = "";
    170   base_offset_ = payload_offset;
    171   InstallPlan::Payload payload;
    172   payload.size = payload_size;
    173   if (!payload.size) {
    174     if (!base::StringToUint64(headers[kPayloadPropertyFileSize],
    175                               &payload.size)) {
    176       payload.size = 0;
    177     }
    178   }
    179   if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash],
    180                                            &payload.hash)) {
    181     LOG(WARNING) << "Unable to decode base64 file hash: "
    182                  << headers[kPayloadPropertyFileHash];
    183   }
    184   if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize],
    185                             &payload.metadata_size)) {
    186     payload.metadata_size = 0;
    187   }
    188   // The |payload.type| is not used anymore since minor_version 3.
    189   payload.type = InstallPayloadType::kUnknown;
    190   install_plan_.payloads.push_back(payload);
    191 
    192   // The |public_key_rsa| key would override the public key stored on disk.
    193   install_plan_.public_key_rsa = "";
    194 
    195   install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild();
    196   install_plan_.is_resume = !payload_id.empty() &&
    197                             DeltaPerformer::CanResumeUpdate(prefs_, payload_id);
    198   if (!install_plan_.is_resume) {
    199     if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) {
    200       LOG(WARNING) << "Unable to reset the update progress.";
    201     }
    202     if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) {
    203       LOG(WARNING) << "Unable to save the update check response hash.";
    204     }
    205   }
    206   install_plan_.source_slot = boot_control_->GetCurrentSlot();
    207   install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0;
    208 
    209   install_plan_.powerwash_required =
    210       GetHeaderAsBool(headers[kPayloadPropertyPowerwash], false);
    211 
    212   install_plan_.switch_slot_on_reboot =
    213       GetHeaderAsBool(headers[kPayloadPropertySwitchSlotOnReboot], true);
    214 
    215   install_plan_.run_post_install = true;
    216   // Optionally skip post install if and only if:
    217   // a) we're resuming
    218   // b) post install has already succeeded before
    219   // c) RUN_POST_INSTALL is set to 0.
    220   if (install_plan_.is_resume && prefs_->Exists(kPrefsPostInstallSucceeded)) {
    221     bool post_install_succeeded = false;
    222     prefs_->GetBoolean(kPrefsPostInstallSucceeded, &post_install_succeeded);
    223     if (post_install_succeeded) {
    224       install_plan_.run_post_install =
    225           GetHeaderAsBool(headers[kPayloadPropertyRunPostInstall], true);
    226     }
    227   }
    228 
    229   NetworkId network_id = kDefaultNetworkId;
    230   if (!headers[kPayloadPropertyNetworkId].empty()) {
    231     if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
    232                               &network_id)) {
    233       return LogAndSetError(
    234           error,
    235           FROM_HERE,
    236           "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
    237     }
    238     if (!network_selector_->SetProcessNetwork(network_id)) {
    239       return LogAndSetError(
    240           error,
    241           FROM_HERE,
    242           "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]);
    243     }
    244   }
    245 
    246   LOG(INFO) << "Using this install plan:";
    247   install_plan_.Dump();
    248 
    249   BuildUpdateActions(payload_url);
    250   // Setup extra headers.
    251   HttpFetcher* fetcher = download_action_->http_fetcher();
    252   if (!headers[kPayloadPropertyAuthorization].empty())
    253     fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]);
    254   if (!headers[kPayloadPropertyUserAgent].empty())
    255     fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]);
    256 
    257   SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
    258   ongoing_update_ = true;
    259 
    260   // Just in case we didn't update boot flags yet, make sure they're updated
    261   // before any update processing starts. This will start the update process.
    262   UpdateBootFlags();
    263 
    264   UpdatePrefsOnUpdateStart(install_plan_.is_resume);
    265   // TODO(xunchang) report the metrics for unresumable updates
    266 
    267   return true;
    268 }
    269 
    270 bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
    271   if (!ongoing_update_)
    272     return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
    273   processor_->SuspendProcessing();
    274   return true;
    275 }
    276 
    277 bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
    278   if (!ongoing_update_)
    279     return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
    280   processor_->ResumeProcessing();
    281   return true;
    282 }
    283 
    284 bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
    285   if (!ongoing_update_)
    286     return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
    287   processor_->StopProcessing();
    288   return true;
    289 }
    290 
    291 bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
    292   LOG(INFO) << "Attempting to reset state from "
    293             << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
    294 
    295   switch (status_) {
    296     case UpdateStatus::IDLE:
    297       return true;
    298 
    299     case UpdateStatus::UPDATED_NEED_REBOOT:  {
    300       // Remove the reboot marker so that if the machine is rebooted
    301       // after resetting to idle state, it doesn't go back to
    302       // UpdateStatus::UPDATED_NEED_REBOOT state.
    303       bool ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId);
    304       ClearMetricsPrefs();
    305 
    306       // Update the boot flags so the current slot has higher priority.
    307       if (!boot_control_->SetActiveBootSlot(boot_control_->GetCurrentSlot()))
    308         ret_value = false;
    309 
    310       // Mark the current slot as successful again, since marking it as active
    311       // may reset the successful bit. We ignore the result of whether marking
    312       // the current slot as successful worked.
    313       if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful){})))
    314         ret_value = false;
    315 
    316       if (!ret_value) {
    317         return LogAndSetError(
    318             error,
    319             FROM_HERE,
    320             "Failed to reset the status to ");
    321       }
    322 
    323       SetStatusAndNotify(UpdateStatus::IDLE);
    324       LOG(INFO) << "Reset status successful";
    325       return true;
    326     }
    327 
    328     default:
    329       return LogAndSetError(
    330           error,
    331           FROM_HERE,
    332           "Reset not allowed in this state. Cancel the ongoing update first");
    333   }
    334 }
    335 
    336 bool UpdateAttempterAndroid::VerifyPayloadApplicable(
    337     const std::string& metadata_filename, brillo::ErrorPtr* error) {
    338   FileDescriptorPtr fd(new EintrSafeFileDescriptor);
    339   if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) {
    340     return LogAndSetError(
    341         error, FROM_HERE, "Failed to open " + metadata_filename);
    342   }
    343   brillo::Blob metadata(kMaxPayloadHeaderSize);
    344   if (!fd->Read(metadata.data(), metadata.size())) {
    345     return LogAndSetError(
    346         error,
    347         FROM_HERE,
    348         "Failed to read payload header from " + metadata_filename);
    349   }
    350   ErrorCode errorcode;
    351   PayloadMetadata payload_metadata;
    352   if (payload_metadata.ParsePayloadHeader(
    353           metadata, kBrilloMajorPayloadVersion, &errorcode) !=
    354       MetadataParseResult::kSuccess) {
    355     return LogAndSetError(error,
    356                           FROM_HERE,
    357                           "Failed to parse payload header: " +
    358                               utils::ErrorCodeToString(errorcode));
    359   }
    360   metadata.resize(payload_metadata.GetMetadataSize() +
    361                   payload_metadata.GetMetadataSignatureSize());
    362   if (metadata.size() < kMaxPayloadHeaderSize) {
    363     return LogAndSetError(
    364         error,
    365         FROM_HERE,
    366         "Metadata size too small: " + std::to_string(metadata.size()));
    367   }
    368   if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize,
    369                 metadata.size() - kMaxPayloadHeaderSize)) {
    370     return LogAndSetError(
    371         error,
    372         FROM_HERE,
    373         "Failed to read metadata and signature from " + metadata_filename);
    374   }
    375   fd->Close();
    376   errorcode = payload_metadata.ValidateMetadataSignature(
    377       metadata, "", base::FilePath(constants::kUpdatePayloadPublicKeyPath));
    378   if (errorcode != ErrorCode::kSuccess) {
    379     return LogAndSetError(error,
    380                           FROM_HERE,
    381                           "Failed to validate metadata signature: " +
    382                               utils::ErrorCodeToString(errorcode));
    383   }
    384   DeltaArchiveManifest manifest;
    385   if (!payload_metadata.GetManifest(metadata, &manifest)) {
    386     return LogAndSetError(error, FROM_HERE, "Failed to parse manifest.");
    387   }
    388 
    389   BootControlInterface::Slot current_slot = boot_control_->GetCurrentSlot();
    390   for (const PartitionUpdate& partition : manifest.partitions()) {
    391     if (!partition.has_old_partition_info())
    392       continue;
    393     string partition_path;
    394     if (!boot_control_->GetPartitionDevice(
    395             partition.partition_name(), current_slot, &partition_path)) {
    396       return LogAndSetError(
    397           error,
    398           FROM_HERE,
    399           "Failed to get partition device for " + partition.partition_name());
    400     }
    401     if (!fd->Open(partition_path.c_str(), O_RDONLY)) {
    402       return LogAndSetError(
    403           error, FROM_HERE, "Failed to open " + partition_path);
    404     }
    405     for (const InstallOperation& operation : partition.operations()) {
    406       if (!operation.has_src_sha256_hash())
    407         continue;
    408       brillo::Blob source_hash;
    409       if (!fd_utils::ReadAndHashExtents(fd,
    410                                         operation.src_extents(),
    411                                         manifest.block_size(),
    412                                         &source_hash)) {
    413         return LogAndSetError(
    414             error, FROM_HERE, "Failed to hash " + partition_path);
    415       }
    416       if (!DeltaPerformer::ValidateSourceHash(
    417               source_hash, operation, fd, &errorcode)) {
    418         return false;
    419       }
    420     }
    421     fd->Close();
    422   }
    423   return true;
    424 }
    425 
    426 void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor,
    427                                             ErrorCode code) {
    428   LOG(INFO) << "Processing Done.";
    429 
    430   switch (code) {
    431     case ErrorCode::kSuccess:
    432       // Update succeeded.
    433       WriteUpdateCompletedMarker();
    434       prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
    435 
    436       LOG(INFO) << "Update successfully applied, waiting to reboot.";
    437       break;
    438 
    439     case ErrorCode::kFilesystemCopierError:
    440     case ErrorCode::kNewRootfsVerificationError:
    441     case ErrorCode::kNewKernelVerificationError:
    442     case ErrorCode::kFilesystemVerifierError:
    443     case ErrorCode::kDownloadStateInitializationError:
    444       // Reset the ongoing update for these errors so it starts from the
    445       // beginning next time.
    446       DeltaPerformer::ResetUpdateProgress(prefs_, false);
    447       LOG(INFO) << "Resetting update progress.";
    448       break;
    449 
    450     case ErrorCode::kPayloadTimestampError:
    451       // SafetyNet logging, b/36232423
    452       android_errorWriteLog(0x534e4554, "36232423");
    453       break;
    454 
    455     default:
    456       // Ignore all other error codes.
    457       break;
    458   }
    459 
    460   TerminateUpdateAndNotify(code);
    461 }
    462 
    463 void UpdateAttempterAndroid::ProcessingStopped(
    464     const ActionProcessor* processor) {
    465   TerminateUpdateAndNotify(ErrorCode::kUserCanceled);
    466 }
    467 
    468 void UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor,
    469                                              AbstractAction* action,
    470                                              ErrorCode code) {
    471   // Reset download progress regardless of whether or not the download
    472   // action succeeded.
    473   const string type = action->Type();
    474   if (type == DownloadAction::StaticType()) {
    475     download_progress_ = 0;
    476   }
    477   if (type == PostinstallRunnerAction::StaticType()) {
    478     bool succeeded =
    479         code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive;
    480     prefs_->SetBoolean(kPrefsPostInstallSucceeded, succeeded);
    481   }
    482   if (code != ErrorCode::kSuccess) {
    483     // If an action failed, the ActionProcessor will cancel the whole thing.
    484     return;
    485   }
    486   if (type == DownloadAction::StaticType()) {
    487     SetStatusAndNotify(UpdateStatus::FINALIZING);
    488   }
    489 }
    490 
    491 void UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed,
    492                                            uint64_t bytes_received,
    493                                            uint64_t total) {
    494   double progress = 0;
    495   if (total)
    496     progress = static_cast<double>(bytes_received) / static_cast<double>(total);
    497   if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) {
    498     download_progress_ = progress;
    499     SetStatusAndNotify(UpdateStatus::DOWNLOADING);
    500   } else {
    501     ProgressUpdate(progress);
    502   }
    503 
    504   // Update the bytes downloaded in prefs.
    505   int64_t current_bytes_downloaded =
    506       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
    507   int64_t total_bytes_downloaded =
    508       metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
    509   prefs_->SetInt64(kPrefsCurrentBytesDownloaded,
    510                    current_bytes_downloaded + bytes_progressed);
    511   prefs_->SetInt64(kPrefsTotalBytesDownloaded,
    512                    total_bytes_downloaded + bytes_progressed);
    513 }
    514 
    515 bool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) {
    516   // TODO(deymo): Notify the DownloadAction that it should cancel the update
    517   // download.
    518   return false;
    519 }
    520 
    521 void UpdateAttempterAndroid::DownloadComplete() {
    522   // Nothing needs to be done when the download completes.
    523 }
    524 
    525 void UpdateAttempterAndroid::ProgressUpdate(double progress) {
    526   // Self throttle based on progress. Also send notifications if progress is
    527   // too slow.
    528   if (progress == 1.0 ||
    529       progress - download_progress_ >= kBroadcastThresholdProgress ||
    530       TimeTicks::Now() - last_notify_time_ >=
    531           TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) {
    532     download_progress_ = progress;
    533     SetStatusAndNotify(status_);
    534   }
    535 }
    536 
    537 void UpdateAttempterAndroid::UpdateBootFlags() {
    538   if (updated_boot_flags_) {
    539     LOG(INFO) << "Already updated boot flags. Skipping.";
    540     CompleteUpdateBootFlags(true);
    541     return;
    542   }
    543   // This is purely best effort.
    544   LOG(INFO) << "Marking booted slot as good.";
    545   if (!boot_control_->MarkBootSuccessfulAsync(
    546           Bind(&UpdateAttempterAndroid::CompleteUpdateBootFlags,
    547                base::Unretained(this)))) {
    548     LOG(ERROR) << "Failed to mark current boot as successful.";
    549     CompleteUpdateBootFlags(false);
    550   }
    551 }
    552 
    553 void UpdateAttempterAndroid::CompleteUpdateBootFlags(bool successful) {
    554   updated_boot_flags_ = true;
    555   ScheduleProcessingStart();
    556 }
    557 
    558 void UpdateAttempterAndroid::ScheduleProcessingStart() {
    559   LOG(INFO) << "Scheduling an action processor start.";
    560   brillo::MessageLoop::current()->PostTask(
    561       FROM_HERE,
    562       Bind([](ActionProcessor* processor) { processor->StartProcessing(); },
    563            base::Unretained(processor_.get())));
    564 }
    565 
    566 void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) {
    567   if (status_ == UpdateStatus::IDLE) {
    568     LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called.";
    569     return;
    570   }
    571 
    572   download_progress_ = 0;
    573   actions_.clear();
    574   UpdateStatus new_status =
    575       (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT
    576                                          : UpdateStatus::IDLE);
    577   SetStatusAndNotify(new_status);
    578   ongoing_update_ = false;
    579 
    580   // The network id is only applicable to one download attempt and once it's
    581   // done the network id should not be re-used anymore.
    582   if (!network_selector_->SetProcessNetwork(kDefaultNetworkId)) {
    583     LOG(WARNING) << "Unable to unbind network.";
    584   }
    585 
    586   for (auto observer : daemon_state_->service_observers())
    587     observer->SendPayloadApplicationComplete(error_code);
    588 
    589   CollectAndReportUpdateMetricsOnUpdateFinished(error_code);
    590   ClearMetricsPrefs();
    591   if (error_code == ErrorCode::kSuccess) {
    592     metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_);
    593     // Clear the total bytes downloaded if and only if the update succeeds.
    594     prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0);
    595   }
    596 }
    597 
    598 void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) {
    599   status_ = status;
    600   size_t payload_size =
    601       install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
    602   UpdateEngineStatus status_to_send = {.status = status_,
    603                                        .progress = download_progress_,
    604                                        .new_size_bytes = payload_size};
    605 
    606   for (auto observer : daemon_state_->service_observers()) {
    607     observer->SendStatusUpdate(status_to_send);
    608   }
    609   last_notify_time_ = TimeTicks::Now();
    610 }
    611 
    612 void UpdateAttempterAndroid::BuildUpdateActions(const string& url) {
    613   CHECK(!processor_->IsRunning());
    614   processor_->set_delegate(this);
    615 
    616   // Actions:
    617   shared_ptr<InstallPlanAction> install_plan_action(
    618       new InstallPlanAction(install_plan_));
    619 
    620   HttpFetcher* download_fetcher = nullptr;
    621   if (FileFetcher::SupportedUrl(url)) {
    622     DLOG(INFO) << "Using FileFetcher for file URL.";
    623     download_fetcher = new FileFetcher();
    624   } else {
    625 #ifdef _UE_SIDELOAD
    626     LOG(FATAL) << "Unsupported sideload URI: " << url;
    627 #else
    628     LibcurlHttpFetcher* libcurl_fetcher =
    629         new LibcurlHttpFetcher(&proxy_resolver_, hardware_);
    630     libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload);
    631     download_fetcher = libcurl_fetcher;
    632 #endif  // _UE_SIDELOAD
    633   }
    634   shared_ptr<DownloadAction> download_action(
    635       new DownloadAction(prefs_,
    636                          boot_control_,
    637                          hardware_,
    638                          nullptr,           // system_state, not used.
    639                          download_fetcher,  // passes ownership
    640                          true /* is_interactive */));
    641   shared_ptr<FilesystemVerifierAction> filesystem_verifier_action(
    642       new FilesystemVerifierAction());
    643 
    644   shared_ptr<PostinstallRunnerAction> postinstall_runner_action(
    645       new PostinstallRunnerAction(boot_control_, hardware_));
    646 
    647   download_action->set_delegate(this);
    648   download_action->set_base_offset(base_offset_);
    649   download_action_ = download_action;
    650   postinstall_runner_action->set_delegate(this);
    651 
    652   actions_.push_back(shared_ptr<AbstractAction>(install_plan_action));
    653   actions_.push_back(shared_ptr<AbstractAction>(download_action));
    654   actions_.push_back(shared_ptr<AbstractAction>(filesystem_verifier_action));
    655   actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action));
    656 
    657   // Bond them together. We have to use the leaf-types when calling
    658   // BondActions().
    659   BondActions(install_plan_action.get(), download_action.get());
    660   BondActions(download_action.get(), filesystem_verifier_action.get());
    661   BondActions(filesystem_verifier_action.get(),
    662               postinstall_runner_action.get());
    663 
    664   // Enqueue the actions.
    665   for (const shared_ptr<AbstractAction>& action : actions_)
    666     processor_->EnqueueAction(action.get());
    667 }
    668 
    669 bool UpdateAttempterAndroid::WriteUpdateCompletedMarker() {
    670   string boot_id;
    671   TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
    672   prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id);
    673   return true;
    674 }
    675 
    676 bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() {
    677   // In case of an update_engine restart without a reboot, we stored the boot_id
    678   // when the update was completed by setting a pref, so we can check whether
    679   // the last update was on this boot or a previous one.
    680   string boot_id;
    681   TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
    682 
    683   string update_completed_on_boot_id;
    684   return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) &&
    685           prefs_->GetString(kPrefsUpdateCompletedOnBootId,
    686                             &update_completed_on_boot_id) &&
    687           update_completed_on_boot_id == boot_id);
    688 }
    689 
    690 // Collect and report the android metrics when we terminate the update.
    691 void UpdateAttempterAndroid::CollectAndReportUpdateMetricsOnUpdateFinished(
    692     ErrorCode error_code) {
    693   int64_t attempt_number =
    694       metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
    695   PayloadType payload_type = kPayloadTypeFull;
    696   int64_t payload_size = 0;
    697   for (const auto& p : install_plan_.payloads) {
    698     if (p.type == InstallPayloadType::kDelta)
    699       payload_type = kPayloadTypeDelta;
    700     payload_size += p.size;
    701   }
    702 
    703   metrics::AttemptResult attempt_result =
    704       metrics_utils::GetAttemptResult(error_code);
    705   Time attempt_start_time = Time::FromInternalValue(
    706       metrics_utils::GetPersistedValue(kPrefsUpdateTimestampStart, prefs_));
    707   TimeDelta duration = clock_->GetBootTime() - attempt_start_time;
    708   TimeDelta duration_uptime = clock_->GetMonotonicTime() - attempt_start_time;
    709 
    710   metrics_reporter_->ReportUpdateAttemptMetrics(
    711       nullptr,  // system_state
    712       static_cast<int>(attempt_number),
    713       payload_type,
    714       duration,
    715       duration_uptime,
    716       payload_size,
    717       attempt_result,
    718       error_code);
    719 
    720   int64_t current_bytes_downloaded =
    721       metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
    722   metrics_reporter_->ReportUpdateAttemptDownloadMetrics(
    723       current_bytes_downloaded,
    724       0,
    725       DownloadSource::kNumDownloadSources,
    726       metrics::DownloadErrorCode::kUnset,
    727       metrics::ConnectionType::kUnset);
    728 
    729   if (error_code == ErrorCode::kSuccess) {
    730     int64_t reboot_count =
    731         metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
    732     string build_version;
    733     prefs_->GetString(kPrefsPreviousVersion, &build_version);
    734 
    735     // For android metrics, we only care about the total bytes downloaded
    736     // for all sources; for now we assume the only download source is
    737     // HttpsServer.
    738     int64_t total_bytes_downloaded =
    739         metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
    740     int64_t num_bytes_downloaded[kNumDownloadSources] = {};
    741     num_bytes_downloaded[DownloadSource::kDownloadSourceHttpsServer] =
    742         total_bytes_downloaded;
    743 
    744     int download_overhead_percentage = 0;
    745     if (current_bytes_downloaded > 0) {
    746       download_overhead_percentage =
    747           (total_bytes_downloaded - current_bytes_downloaded) * 100ull /
    748           current_bytes_downloaded;
    749     }
    750     metrics_reporter_->ReportSuccessfulUpdateMetrics(
    751         static_cast<int>(attempt_number),
    752         0,  // update abandoned count
    753         payload_type,
    754         payload_size,
    755         num_bytes_downloaded,
    756         download_overhead_percentage,
    757         duration,
    758         static_cast<int>(reboot_count),
    759         0);  // url_switch_count
    760   }
    761 }
    762 
    763 void UpdateAttempterAndroid::UpdatePrefsAndReportUpdateMetricsOnReboot() {
    764   string current_boot_id;
    765   TEST_AND_RETURN(utils::GetBootId(&current_boot_id));
    766   // Example: [ro.build.version.incremental]: [4292972]
    767   string current_version =
    768       android::base::GetProperty("ro.build.version.incremental", "");
    769   TEST_AND_RETURN(!current_version.empty());
    770 
    771   // If there's no record of previous version (e.g. due to a data wipe), we
    772   // save the info of current boot and skip the metrics report.
    773   if (!prefs_->Exists(kPrefsPreviousVersion)) {
    774     prefs_->SetString(kPrefsBootId, current_boot_id);
    775     prefs_->SetString(kPrefsPreviousVersion, current_version);
    776     ClearMetricsPrefs();
    777     return;
    778   }
    779   string previous_version;
    780   // update_engine restarted under the same build.
    781   // TODO(xunchang) identify and report rollback by checking UpdateMarker.
    782   if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) &&
    783       previous_version == current_version) {
    784     string last_boot_id;
    785     bool is_reboot = prefs_->Exists(kPrefsBootId) &&
    786                      (prefs_->GetString(kPrefsBootId, &last_boot_id) &&
    787                       last_boot_id != current_boot_id);
    788     // Increment the reboot number if |kPrefsNumReboots| exists. That pref is
    789     // set when we start a new update.
    790     if (is_reboot && prefs_->Exists(kPrefsNumReboots)) {
    791       prefs_->SetString(kPrefsBootId, current_boot_id);
    792       int64_t reboot_count =
    793           metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
    794       metrics_utils::SetNumReboots(reboot_count + 1, prefs_);
    795     }
    796     return;
    797   }
    798 
    799   // Now that the build version changes, report the update metrics.
    800   // TODO(xunchang) check the build version is larger than the previous one.
    801   prefs_->SetString(kPrefsBootId, current_boot_id);
    802   prefs_->SetString(kPrefsPreviousVersion, current_version);
    803 
    804   bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber);
    805   // |kPrefsPayloadAttemptNumber| should be cleared upon successful update.
    806   if (previous_attempt_exists) {
    807     metrics_reporter_->ReportAbnormallyTerminatedUpdateAttemptMetrics();
    808   }
    809 
    810   metrics_utils::LoadAndReportTimeToReboot(
    811       metrics_reporter_.get(), prefs_, clock_.get());
    812   ClearMetricsPrefs();
    813 }
    814 
    815 // Save the update start time. Reset the reboot count and attempt number if the
    816 // update isn't a resume; otherwise increment the attempt number.
    817 void UpdateAttempterAndroid::UpdatePrefsOnUpdateStart(bool is_resume) {
    818   if (!is_resume) {
    819     metrics_utils::SetNumReboots(0, prefs_);
    820     metrics_utils::SetPayloadAttemptNumber(1, prefs_);
    821   } else {
    822     int64_t attempt_number =
    823         metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
    824     metrics_utils::SetPayloadAttemptNumber(attempt_number + 1, prefs_);
    825   }
    826   Time update_start_time = clock_->GetMonotonicTime();
    827   metrics_utils::SetUpdateTimestampStart(update_start_time, prefs_);
    828 }
    829 
    830 void UpdateAttempterAndroid::ClearMetricsPrefs() {
    831   CHECK(prefs_);
    832   prefs_->Delete(kPrefsCurrentBytesDownloaded);
    833   prefs_->Delete(kPrefsNumReboots);
    834   prefs_->Delete(kPrefsPayloadAttemptNumber);
    835   prefs_->Delete(kPrefsSystemUpdatedMarker);
    836   prefs_->Delete(kPrefsUpdateTimestampStart);
    837 }
    838 
    839 }  // namespace chromeos_update_engine
    840