15e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//
25e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// Copyright (C) 2016 The Android Open Source Project
35e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//
45e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
55e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// you may not use this file except in compliance with the License.
65e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// You may obtain a copy of the License at
75e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//
85e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
95e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//
105e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// Unless required by applicable law or agreed to in writing, software
115e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
125e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// See the License for the specific language governing permissions and
145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// limitations under the License.
155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo//
165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/update_attempter_android.h"
185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <algorithm>
20218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo#include <map>
2190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu#include <memory>
225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <utility>
235e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu#include <android-base/properties.h>
255e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <base/bind.h>
265e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <base/logging.h>
27218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo#include <base/strings/string_number_conversions.h>
285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <brillo/bind_lambda.h>
292703ef4466066d64d8021904e233b120f38c0272Sen Jiang#include <brillo/data_encoding.h>
305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <brillo/message_loops/message_loop.h>
31218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo#include <brillo/strings/string_utils.h>
32acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang#include <log/log_safetynet.h>
335e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
345e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/constants.h"
358371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/common/error_code_utils.h"
362c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo#include "update_engine/common/file_fetcher.h"
375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/utils.h"
3803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/daemon_state_interface.h"
39d4c5debc65bb35ee61c2764bda059b7f307fd093Tianjie Xu#include "update_engine/metrics_reporter_interface.h"
401b66114d367d1b85b4397bb559e274dbd0ebcd31Tianjie Xu#include "update_engine/metrics_utils.h"
4187792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo#include "update_engine/network_selector.h"
428371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/payload_consumer/delta_performer.h"
435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/download_action.h"
448371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/payload_consumer/file_descriptor.h"
458371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/payload_consumer/file_descriptor_utils.h"
465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/filesystem_verifier_action.h"
478371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/payload_consumer/payload_constants.h"
488371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang#include "update_engine/payload_consumer/payload_metadata.h"
495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/postinstall_runner_action.h"
503b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo#include "update_engine/update_status_utils.h"
515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5214c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#ifndef _UE_SIDELOAD
5314c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo// Do not include support for external HTTP(s) urls when building
5414c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo// update_engine_sideload.
5514c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#include "update_engine/libcurl_http_fetcher.h"
5614c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#endif
5714c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo
585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::Bind;
5990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xuusing base::Time;
605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::TimeDelta;
615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::TimeTicks;
625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::shared_ptr;
635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::string;
645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::vector;
657f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Woodusing update_engine::UpdateEngineStatus;
665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymonamespace chromeos_update_engine {
685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymonamespace {
705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
710d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo// Minimum threshold to broadcast an status update in progress and time.
720d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymoconst double kBroadcastThresholdProgress = 0.01;  // 1%
730d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymoconst int kBroadcastThresholdSeconds = 10;
740d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo
755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymoconst char* const kErrorDomain = "update_engine";
765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// TODO(deymo): Convert the different errors to a numeric value to report them
775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// back on the service error.
785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymoconst char* const kGenericError = "generic_error";
795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// Log and set the error on the passed ErrorPtr.
815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool LogAndSetError(brillo::ErrorPtr* error,
825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                    const tracked_objects::Location& location,
835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                    const string& reason) {
845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason);
855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  LOG(ERROR) << "Replying with failure: " << location.ToString() << ": "
865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo             << reason;
875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  return false;
885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
90fe5228282571154b51d3907cad4744e228e66a22Sen Jiangbool GetHeaderAsBool(const string& header, bool default_value) {
91fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  int value = 0;
92fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  if (base::StringToInt(header, &value) && (value == 0 || value == 1))
93fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    return value == 1;
94fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  return default_value;
95fe5228282571154b51d3907cad4744e228e66a22Sen Jiang}
96fe5228282571154b51d3907cad4744e228e66a22Sen Jiang
975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}  // namespace
985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
995e3ea278d9e771be3b51bd72985ad582678baddcAlex DeymoUpdateAttempterAndroid::UpdateAttempterAndroid(
10003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo    DaemonStateInterface* daemon_state,
1015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    PrefsInterface* prefs,
1025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    BootControlInterface* boot_control,
1035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    HardwareInterface* hardware)
1045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    : daemon_state_(daemon_state),
1055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      prefs_(prefs),
1065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      boot_control_(boot_control),
1075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      hardware_(hardware),
1081b66114d367d1b85b4397bb559e274dbd0ebcd31Tianjie Xu      processor_(new ActionProcessor()),
109d4c5debc65bb35ee61c2764bda059b7f307fd093Tianjie Xu      clock_(new Clock()) {
110d4c5debc65bb35ee61c2764bda059b7f307fd093Tianjie Xu  metrics_reporter_ = metrics::CreateMetricsReporter();
11187792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo  network_selector_ = network::CreateNetworkSelector();
1125e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
1135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1145e3ea278d9e771be3b51bd72985ad582678baddcAlex DeymoUpdateAttempterAndroid::~UpdateAttempterAndroid() {
1155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Release ourselves as the ActionProcessor's delegate to prevent
1165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // re-scheduling the updates due to the processing stopped.
1175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  processor_->set_delegate(nullptr);
1185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
1195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1205e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::Init() {
1215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // In case of update_engine restart without a reboot we need to restore the
1225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // reboot needed state.
12390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (UpdateCompletedOnThisBoot()) {
1240e061aebc651e041b6d1d8a3a91834feb87e0d62Alex Deymo    SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
12590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  } else {
1260e061aebc651e041b6d1d8a3a91834feb87e0d62Alex Deymo    SetStatusAndNotify(UpdateStatus::IDLE);
12790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    UpdatePrefsAndReportUpdateMetricsOnReboot();
12890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
1295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
1305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1315e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ApplyPayload(
1325e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    const string& payload_url,
1335e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    int64_t payload_offset,
1345e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    int64_t payload_size,
1355e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    const vector<string>& key_value_pair_headers,
1365e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    brillo::ErrorPtr* error) {
1375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
1385e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return LogAndSetError(
1395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo        error, FROM_HERE, "An update already applied, waiting for reboot");
1405e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
1415e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (ongoing_update_) {
1425e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return LogAndSetError(
1435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo        error, FROM_HERE, "Already processing an update, cancel it first.");
1445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
1455e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  DCHECK(status_ == UpdateStatus::IDLE);
1465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
147218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  std::map<string, string> headers;
148218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  for (const string& key_value_pair : key_value_pair_headers) {
149218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    string key;
150218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    string value;
151218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    if (!brillo::string_utils::SplitAtFirst(
152218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo            key_value_pair, "=", &key, &value, false)) {
153218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo      return LogAndSetError(
154218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo          error, FROM_HERE, "Passed invalid header: " + key_value_pair);
155218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    }
156218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    if (!headers.emplace(key, value).second)
157218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo      return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key);
158218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  }
159218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo
160218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  // Unique identifier for the payload. An empty string means that the payload
161218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  // can't be resumed.
162218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  string payload_id = (headers[kPayloadPropertyFileHash] +
163218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo                       headers[kPayloadPropertyMetadataHash]);
1645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Setup the InstallPlan based on the request.
1665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_ = InstallPlan();
1675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.download_url = payload_url;
1695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.version = "";
1700fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo  base_offset_ = payload_offset;
1710affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang  InstallPlan::Payload payload;
1720affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang  payload.size = payload_size;
1730affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang  if (!payload.size) {
174218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    if (!base::StringToUint64(headers[kPayloadPropertyFileSize],
1750affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang                              &payload.size)) {
1760affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang      payload.size = 0;
177218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo    }
178218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  }
1792703ef4466066d64d8021904e233b120f38c0272Sen Jiang  if (!brillo::data_encoding::Base64Decode(headers[kPayloadPropertyFileHash],
1800affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang                                           &payload.hash)) {
1812703ef4466066d64d8021904e233b120f38c0272Sen Jiang    LOG(WARNING) << "Unable to decode base64 file hash: "
1822703ef4466066d64d8021904e233b120f38c0272Sen Jiang                 << headers[kPayloadPropertyFileHash];
1832703ef4466066d64d8021904e233b120f38c0272Sen Jiang  }
184218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize],
1850affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang                            &payload.metadata_size)) {
1860affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang    payload.metadata_size = 0;
187218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo  }
188cdd5206c6507fa5c70344c269053d30777f7d674Sen Jiang  // The |payload.type| is not used anymore since minor_version 3.
189cdd5206c6507fa5c70344c269053d30777f7d674Sen Jiang  payload.type = InstallPayloadType::kUnknown;
1900affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang  install_plan_.payloads.push_back(payload);
1910affc2c099fac47b999ba39f8f1bacb418e65a97Sen Jiang
1925e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // The |public_key_rsa| key would override the public key stored on disk.
1935e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.public_key_rsa = "";
1945e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
1955e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild();
1965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.is_resume = !payload_id.empty() &&
1975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                            DeltaPerformer::CanResumeUpdate(prefs_, payload_id);
1985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (!install_plan_.is_resume) {
1995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) {
2005e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      LOG(WARNING) << "Unable to reset the update progress.";
2015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    }
2025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) {
2035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      LOG(WARNING) << "Unable to save the update check response hash.";
2045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    }
2055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
2065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.source_slot = boot_control_->GetCurrentSlot();
2075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0;
208fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo
209fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo  install_plan_.powerwash_required =
210fe5228282571154b51d3907cad4744e228e66a22Sen Jiang      GetHeaderAsBool(headers[kPayloadPropertyPowerwash], false);
211fe5228282571154b51d3907cad4744e228e66a22Sen Jiang
212fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  install_plan_.switch_slot_on_reboot =
213fe5228282571154b51d3907cad4744e228e66a22Sen Jiang      GetHeaderAsBool(headers[kPayloadPropertySwitchSlotOnReboot], true);
214fe5228282571154b51d3907cad4744e228e66a22Sen Jiang
215fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  install_plan_.run_post_install = true;
216fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  // Optionally skip post install if and only if:
217fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  // a) we're resuming
218fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  // b) post install has already succeeded before
219fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  // c) RUN_POST_INSTALL is set to 0.
220fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  if (install_plan_.is_resume && prefs_->Exists(kPrefsPostInstallSucceeded)) {
221fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    bool post_install_succeeded = false;
222fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    prefs_->GetBoolean(kPrefsPostInstallSucceeded, &post_install_succeeded);
223fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    if (post_install_succeeded) {
224fe5228282571154b51d3907cad4744e228e66a22Sen Jiang      install_plan_.run_post_install =
225fe5228282571154b51d3907cad4744e228e66a22Sen Jiang          GetHeaderAsBool(headers[kPayloadPropertyRunPostInstall], true);
226fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    }
227fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  }
2285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
22987792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo  NetworkId network_id = kDefaultNetworkId;
23087792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo  if (!headers[kPayloadPropertyNetworkId].empty()) {
23187792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo    if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
23287792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo                              &network_id)) {
23387792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo      return LogAndSetError(
23487792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo          error,
23587792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo          FROM_HERE,
23687792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo          "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
23787792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo    }
23887792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo    if (!network_selector_->SetProcessNetwork(network_id)) {
239cbd37c68ca69ceec25a9609c0c36fa30ee707f6dSen Jiang      return LogAndSetError(
240cbd37c68ca69ceec25a9609c0c36fa30ee707f6dSen Jiang          error,
241cbd37c68ca69ceec25a9609c0c36fa30ee707f6dSen Jiang          FROM_HERE,
242cbd37c68ca69ceec25a9609c0c36fa30ee707f6dSen Jiang          "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]);
24387792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo    }
24487792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo  }
24587792ea818a63f2d246bbba2b7429b85ee8d669fAlex Deymo
2465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  LOG(INFO) << "Using this install plan:";
2475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  install_plan_.Dump();
2485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2492c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  BuildUpdateActions(payload_url);
250fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo  // Setup extra headers.
251fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo  HttpFetcher* fetcher = download_action_->http_fetcher();
252fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo  if (!headers[kPayloadPropertyAuthorization].empty())
253fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo    fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]);
254fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo  if (!headers[kPayloadPropertyUserAgent].empty())
255fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo    fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]);
256fdd6dec9c4be2fbd667cf874c4cc6f4ffecaeef9Alex Deymo
2575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
258f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  ongoing_update_ = true;
2595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Just in case we didn't update boot flags yet, make sure they're updated
2615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // before any update processing starts. This will start the update process.
2625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  UpdateBootFlags();
26390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
26490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  UpdatePrefsOnUpdateStart(install_plan_.is_resume);
26590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // TODO(xunchang) report the metrics for unresumable updates
26690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
2675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  return true;
2685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
2695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
271f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  if (!ongoing_update_)
272f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
273f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  processor_->SuspendProcessing();
274f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  return true;
2755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
2765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
278f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  if (!ongoing_update_)
279f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
280f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  processor_->ResumeProcessing();
281f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  return true;
2825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
2835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
285f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  if (!ongoing_update_)
2865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
287f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  processor_->StopProcessing();
288f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  return true;
2895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
2905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
2913b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymobool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
2923b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo  LOG(INFO) << "Attempting to reset state from "
2933b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo            << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
2943b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
2953b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo  switch (status_) {
2963b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo    case UpdateStatus::IDLE:
2973b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      return true;
2983b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
2993b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo    case UpdateStatus::UPDATED_NEED_REBOOT:  {
3003b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      // Remove the reboot marker so that if the machine is rebooted
3013b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      // after resetting to idle state, it doesn't go back to
3023b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      // UpdateStatus::UPDATED_NEED_REBOOT state.
3033b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      bool ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId);
30490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      ClearMetricsPrefs();
3053b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
3063b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      // Update the boot flags so the current slot has higher priority.
3073b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      if (!boot_control_->SetActiveBootSlot(boot_control_->GetCurrentSlot()))
3083b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo        ret_value = false;
3093b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
3105259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo      // Mark the current slot as successful again, since marking it as active
3115259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo      // may reset the successful bit. We ignore the result of whether marking
3125259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo      // the current slot as successful worked.
3135259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo      if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful){})))
3145259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo        ret_value = false;
3155259033d23938ce3ce20e4a9b599be0eec113610Alex Deymo
3163b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      if (!ret_value) {
3173b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo        return LogAndSetError(
3183b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo            error,
3193b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo            FROM_HERE,
3203b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo            "Failed to reset the status to ");
3213b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      }
3223b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
3233b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      SetStatusAndNotify(UpdateStatus::IDLE);
3243b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      LOG(INFO) << "Reset status successful";
3253b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      return true;
3263b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo    }
3273b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
3283b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo    default:
3293b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo      return LogAndSetError(
3303b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo          error,
3313b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo          FROM_HERE,
3323b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo          "Reset not allowed in this state. Cancel the ongoing update first");
3333b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo  }
3343b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo}
3353b678db2e7fd4baa38c6d6b8bb8334f7d88b8682Alex Deymo
3368371c1c852eae461043d8a3d911394a0ec0db909Sen Jiangbool UpdateAttempterAndroid::VerifyPayloadApplicable(
3378371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    const std::string& metadata_filename, brillo::ErrorPtr* error) {
3388371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  FileDescriptorPtr fd(new EintrSafeFileDescriptor);
3398371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) {
3408371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(
3418371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        error, FROM_HERE, "Failed to open " + metadata_filename);
3428371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3438371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  brillo::Blob metadata(kMaxPayloadHeaderSize);
3448371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (!fd->Read(metadata.data(), metadata.size())) {
3458371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(
3468371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        error,
3478371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        FROM_HERE,
3488371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        "Failed to read payload header from " + metadata_filename);
3498371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3508371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  ErrorCode errorcode;
3518371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  PayloadMetadata payload_metadata;
3528371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (payload_metadata.ParsePayloadHeader(
3538371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang          metadata, kBrilloMajorPayloadVersion, &errorcode) !=
3548371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      MetadataParseResult::kSuccess) {
3558371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(error,
3568371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                          FROM_HERE,
3578371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                          "Failed to parse payload header: " +
3588371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                              utils::ErrorCodeToString(errorcode));
3598371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3608371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  metadata.resize(payload_metadata.GetMetadataSize() +
3618371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                  payload_metadata.GetMetadataSignatureSize());
3628371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (metadata.size() < kMaxPayloadHeaderSize) {
3638371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(
3648371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        error,
3658371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        FROM_HERE,
3668371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        "Metadata size too small: " + std::to_string(metadata.size()));
3678371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3688371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize,
3698371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                metadata.size() - kMaxPayloadHeaderSize)) {
3708371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(
3718371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        error,
3728371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        FROM_HERE,
3738371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        "Failed to read metadata and signature from " + metadata_filename);
3748371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3758371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  fd->Close();
3768371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  errorcode = payload_metadata.ValidateMetadataSignature(
3778371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      metadata, "", base::FilePath(constants::kUpdatePayloadPublicKeyPath));
3788371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (errorcode != ErrorCode::kSuccess) {
3798371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(error,
3808371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                          FROM_HERE,
3818371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                          "Failed to validate metadata signature: " +
3828371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                              utils::ErrorCodeToString(errorcode));
3838371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3848371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  DeltaArchiveManifest manifest;
3858371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  if (!payload_metadata.GetManifest(metadata, &manifest)) {
3868371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    return LogAndSetError(error, FROM_HERE, "Failed to parse manifest.");
3878371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
3888371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang
3898371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  BootControlInterface::Slot current_slot = boot_control_->GetCurrentSlot();
3908371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  for (const PartitionUpdate& partition : manifest.partitions()) {
3918371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    if (!partition.has_old_partition_info())
3928371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      continue;
3938371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    string partition_path;
3948371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    if (!boot_control_->GetPartitionDevice(
3958371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang            partition.partition_name(), current_slot, &partition_path)) {
3968371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      return LogAndSetError(
3978371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang          error,
3988371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang          FROM_HERE,
3998371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang          "Failed to get partition device for " + partition.partition_name());
4008371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    }
4018371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    if (!fd->Open(partition_path.c_str(), O_RDONLY)) {
4028371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      return LogAndSetError(
4038371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang          error, FROM_HERE, "Failed to open " + partition_path);
4048371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    }
4058371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    for (const InstallOperation& operation : partition.operations()) {
4068371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      if (!operation.has_src_sha256_hash())
4078371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        continue;
4088371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      brillo::Blob source_hash;
4098371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      if (!fd_utils::ReadAndHashExtents(fd,
4108371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                                        operation.src_extents(),
4118371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                                        manifest.block_size(),
4128371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang                                        &source_hash)) {
4138371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        return LogAndSetError(
4148371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang            error, FROM_HERE, "Failed to hash " + partition_path);
4158371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      }
4168371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      if (!DeltaPerformer::ValidateSourceHash(
4178371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang              source_hash, operation, fd, &errorcode)) {
4188371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang        return false;
4198371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang      }
4208371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    }
4218371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang    fd->Close();
4228371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  }
4238371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang  return true;
4248371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang}
4258371c1c852eae461043d8a3d911394a0ec0db909Sen Jiang
4265e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor,
4275e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                            ErrorCode code) {
4285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  LOG(INFO) << "Processing Done.";
4295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
4305990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo  switch (code) {
4315990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kSuccess:
4325990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      // Update succeeded.
4335990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      WriteUpdateCompletedMarker();
4345990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
4355990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo
4365990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      LOG(INFO) << "Update successfully applied, waiting to reboot.";
4375990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      break;
4385990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo
4395990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kFilesystemCopierError:
4405990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kNewRootfsVerificationError:
4415990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kNewKernelVerificationError:
4425990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kFilesystemVerifierError:
4435990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    case ErrorCode::kDownloadStateInitializationError:
4445990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      // Reset the ongoing update for these errors so it starts from the
4455990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      // beginning next time.
4465990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      DeltaPerformer::ResetUpdateProgress(prefs_, false);
4475990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      LOG(INFO) << "Resetting update progress.";
4485990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      break;
4495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
450acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang    case ErrorCode::kPayloadTimestampError:
451acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang      // SafetyNet logging, b/36232423
452acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang      android_errorWriteLog(0x534e4554, "36232423");
453acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang      break;
454acbdd1cc442e80df4ca35ba27fdeed1c8b00f5c1Sen Jiang
4555990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo    default:
4565990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      // Ignore all other error codes.
4575990bf33b50beec0caf55a97f5ca87608ccbc694Alex Deymo      break;
45803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo  }
4595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
4605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  TerminateUpdateAndNotify(code);
4615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
4625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
4635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ProcessingStopped(
4645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    const ActionProcessor* processor) {
4655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  TerminateUpdateAndNotify(ErrorCode::kUserCanceled);
4665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
4675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
4685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor,
4695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                             AbstractAction* action,
4705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                             ErrorCode code) {
4715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Reset download progress regardless of whether or not the download
4725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // action succeeded.
4735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  const string type = action->Type();
4745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (type == DownloadAction::StaticType()) {
4750d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo    download_progress_ = 0;
4765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
477fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  if (type == PostinstallRunnerAction::StaticType()) {
478fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    bool succeeded =
479fe5228282571154b51d3907cad4744e228e66a22Sen Jiang        code == ErrorCode::kSuccess || code == ErrorCode::kUpdatedButNotActive;
480fe5228282571154b51d3907cad4744e228e66a22Sen Jiang    prefs_->SetBoolean(kPrefsPostInstallSucceeded, succeeded);
481fe5228282571154b51d3907cad4744e228e66a22Sen Jiang  }
4825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (code != ErrorCode::kSuccess) {
4835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    // If an action failed, the ActionProcessor will cancel the whole thing.
4845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return;
4855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
4865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (type == DownloadAction::StaticType()) {
4875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    SetStatusAndNotify(UpdateStatus::FINALIZING);
4885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
4895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
4905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
4915e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed,
4925e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                           uint64_t bytes_received,
4935e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                           uint64_t total) {
4940d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  double progress = 0;
4955e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (total)
4965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    progress = static_cast<double>(bytes_received) / static_cast<double>(total);
4970d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) {
4985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    download_progress_ = progress;
4995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    SetStatusAndNotify(UpdateStatus::DOWNLOADING);
5000d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  } else {
5010d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo    ProgressUpdate(progress);
5025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
503d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu
504d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  // Update the bytes downloaded in prefs.
505d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  int64_t current_bytes_downloaded =
506d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
507d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  int64_t total_bytes_downloaded =
508d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
509d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  prefs_->SetInt64(kPrefsCurrentBytesDownloaded,
510d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu                   current_bytes_downloaded + bytes_progressed);
511d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  prefs_->SetInt64(kPrefsTotalBytesDownloaded,
512d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu                   total_bytes_downloaded + bytes_progressed);
5135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) {
5165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // TODO(deymo): Notify the DownloadAction that it should cancel the update
5175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // download.
5185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  return false;
5195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5205e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::DownloadComplete() {
5225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Nothing needs to be done when the download completes.
5235e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5245e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5250d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymovoid UpdateAttempterAndroid::ProgressUpdate(double progress) {
5260d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  // Self throttle based on progress. Also send notifications if progress is
5270d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  // too slow.
5280d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  if (progress == 1.0 ||
5290d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo      progress - download_progress_ >= kBroadcastThresholdProgress ||
5300d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo      TimeTicks::Now() - last_notify_time_ >=
5310d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo          TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) {
5320d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo    download_progress_ = progress;
5330d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo    SetStatusAndNotify(status_);
5340d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  }
5350d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo}
5360d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo
5375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::UpdateBootFlags() {
5385e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (updated_boot_flags_) {
5395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    LOG(INFO) << "Already updated boot flags. Skipping.";
5405e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    CompleteUpdateBootFlags(true);
5415e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return;
5425e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
5435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // This is purely best effort.
5445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  LOG(INFO) << "Marking booted slot as good.";
5455e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (!boot_control_->MarkBootSuccessfulAsync(
5465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo          Bind(&UpdateAttempterAndroid::CompleteUpdateBootFlags,
5475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo               base::Unretained(this)))) {
5485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    LOG(ERROR) << "Failed to mark current boot as successful.";
5495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    CompleteUpdateBootFlags(false);
5505e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
5515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::CompleteUpdateBootFlags(bool successful) {
5545e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  updated_boot_flags_ = true;
5555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  ScheduleProcessingStart();
5565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ScheduleProcessingStart() {
5595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  LOG(INFO) << "Scheduling an action processor start.";
5605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  brillo::MessageLoop::current()->PostTask(
561f1cf34849efdc0158fb1987ba74a51f25016c5bdLuis Hector Chavez      FROM_HERE,
562f1cf34849efdc0158fb1987ba74a51f25016c5bdLuis Hector Chavez      Bind([](ActionProcessor* processor) { processor->StartProcessing(); },
563f1cf34849efdc0158fb1987ba74a51f25016c5bdLuis Hector Chavez           base::Unretained(processor_.get())));
5645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) {
5675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  if (status_ == UpdateStatus::IDLE) {
5685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called.";
5695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    return;
5705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
5715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5720d29854cf5bb05a22cf161b50052539aa420a36eAlex Deymo  download_progress_ = 0;
5735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  actions_.clear();
5745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  UpdateStatus new_status =
5755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT
5765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                                         : UpdateStatus::IDLE);
5775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  SetStatusAndNotify(new_status);
5785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  ongoing_update_ = false;
5795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
580b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang  // The network id is only applicable to one download attempt and once it's
581b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang  // done the network id should not be re-used anymore.
582b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang  if (!network_selector_->SetProcessNetwork(kDefaultNetworkId)) {
583b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang    LOG(WARNING) << "Unable to unbind network.";
584b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang  }
585b19c3ec7bda83b15c7fc659f65eb6f92ca84f9c4Sen Jiang
5865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  for (auto observer : daemon_state_->service_observers())
5875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    observer->SendPayloadApplicationComplete(error_code);
5881b66114d367d1b85b4397bb559e274dbd0ebcd31Tianjie Xu
58990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  CollectAndReportUpdateMetricsOnUpdateFinished(error_code);
59090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  ClearMetricsPrefs();
59190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (error_code == ErrorCode::kSuccess) {
59290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_utils::SetSystemUpdatedMarker(clock_.get(), prefs_);
593d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    // Clear the total bytes downloaded if and only if the update succeeds.
594d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    prefs_->SetInt64(kPrefsTotalBytesDownloaded, 0);
59590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
5965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
5975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
5985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) {
5995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  status_ = status;
6002d1c87bbd55878c5b4dd93e97a8cc28e715137ecSen Jiang  size_t payload_size =
6012d1c87bbd55878c5b4dd93e97a8cc28e715137ecSen Jiang      install_plan_.payloads.empty() ? 0 : install_plan_.payloads[0].size;
6027f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Wood  UpdateEngineStatus status_to_send = {.status = status_,
6037f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Wood                                       .progress = download_progress_,
6047f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Wood                                       .new_size_bytes = payload_size};
6057f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Wood
6065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  for (auto observer : daemon_state_->service_observers()) {
6077f92e2b7060cb35719acf96ef96a4e273e165bc5Aaron Wood    observer->SendStatusUpdate(status_to_send);
6085e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  }
6095e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  last_notify_time_ = TimeTicks::Now();
6105e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
6115e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6122c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymovoid UpdateAttempterAndroid::BuildUpdateActions(const string& url) {
6135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  CHECK(!processor_->IsRunning());
6145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  processor_->set_delegate(this);
6155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Actions:
6175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  shared_ptr<InstallPlanAction> install_plan_action(
6185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo      new InstallPlanAction(install_plan_));
6195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6202c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  HttpFetcher* download_fetcher = nullptr;
6212c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  if (FileFetcher::SupportedUrl(url)) {
6222c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo    DLOG(INFO) << "Using FileFetcher for file URL.";
6232c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo    download_fetcher = new FileFetcher();
6242c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  } else {
62514c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#ifdef _UE_SIDELOAD
62614c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo    LOG(FATAL) << "Unsupported sideload URI: " << url;
62714c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#else
6282c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo    LibcurlHttpFetcher* libcurl_fetcher =
6292c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo        new LibcurlHttpFetcher(&proxy_resolver_, hardware_);
6302c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo    libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload);
6312c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo    download_fetcher = libcurl_fetcher;
63214c0da88a93aa7b1aa71d5e7e923b537f0d419f3Alex Deymo#endif  // _UE_SIDELOAD
6332c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  }
6345ae865b431cc041feed82f1db28a38e99dbd631fSen Jiang  shared_ptr<DownloadAction> download_action(
6355ae865b431cc041feed82f1db28a38e99dbd631fSen Jiang      new DownloadAction(prefs_,
6365ae865b431cc041feed82f1db28a38e99dbd631fSen Jiang                         boot_control_,
6375ae865b431cc041feed82f1db28a38e99dbd631fSen Jiang                         hardware_,
63844906965d0809992052e47e11809ec730813d8b0Sen Jiang                         nullptr,           // system_state, not used.
63944906965d0809992052e47e11809ec730813d8b0Sen Jiang                         download_fetcher,  // passes ownership
6407ecda265a87236e83cf820364947a1618872b6beAmin Hassani                         true /* is_interactive */));
641fef85fd9ece49941db274559a938fe8b2c5157bfSen Jiang  shared_ptr<FilesystemVerifierAction> filesystem_verifier_action(
642e6e4bb929acd73e57b68a30d1e3a33d76607aec3Sen Jiang      new FilesystemVerifierAction());
6435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  shared_ptr<PostinstallRunnerAction> postinstall_runner_action(
645fb905d9b8d49f8fe41297c7aba2dd0942f1be311Alex Deymo      new PostinstallRunnerAction(boot_control_, hardware_));
6465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  download_action->set_delegate(this);
6485ae865b431cc041feed82f1db28a38e99dbd631fSen Jiang  download_action->set_base_offset(base_offset_);
6495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  download_action_ = download_action;
650b6eef73e20736b4b6a43611fa732d8bba72ff7ffAlex Deymo  postinstall_runner_action->set_delegate(this);
6515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  actions_.push_back(shared_ptr<AbstractAction>(install_plan_action));
6535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  actions_.push_back(shared_ptr<AbstractAction>(download_action));
654fef85fd9ece49941db274559a938fe8b2c5157bfSen Jiang  actions_.push_back(shared_ptr<AbstractAction>(filesystem_verifier_action));
6555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action));
6565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Bond them together. We have to use the leaf-types when calling
6585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // BondActions().
6595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  BondActions(install_plan_action.get(), download_action.get());
660fef85fd9ece49941db274559a938fe8b2c5157bfSen Jiang  BondActions(download_action.get(), filesystem_verifier_action.get());
661fef85fd9ece49941db274559a938fe8b2c5157bfSen Jiang  BondActions(filesystem_verifier_action.get(),
6625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo              postinstall_runner_action.get());
6635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // Enqueue the actions.
6655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  for (const shared_ptr<AbstractAction>& action : actions_)
6665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo    processor_->EnqueueAction(action.get());
6675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
6685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::WriteUpdateCompletedMarker() {
6705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  string boot_id;
6715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
6725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id);
6735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  return true;
6745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
6755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() {
6775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // In case of an update_engine restart without a reboot, we stored the boot_id
6785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // when the update was completed by setting a pref, so we can check whether
6795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  // the last update was on this boot or a previous one.
6805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  string boot_id;
6815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
6825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
6835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  string update_completed_on_boot_id;
6845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo  return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) &&
6855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo          prefs_->GetString(kPrefsUpdateCompletedOnBootId,
6865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo                            &update_completed_on_boot_id) &&
6875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo          update_completed_on_boot_id == boot_id);
6885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}
6895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo
69090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu// Collect and report the android metrics when we terminate the update.
69190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xuvoid UpdateAttempterAndroid::CollectAndReportUpdateMetricsOnUpdateFinished(
69290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    ErrorCode error_code) {
69390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  int64_t attempt_number =
69490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
69590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  PayloadType payload_type = kPayloadTypeFull;
69690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  int64_t payload_size = 0;
69790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  for (const auto& p : install_plan_.payloads) {
69890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    if (p.type == InstallPayloadType::kDelta)
69990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      payload_type = kPayloadTypeDelta;
70090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    payload_size += p.size;
70190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
70290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
70390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  metrics::AttemptResult attempt_result =
70490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      metrics_utils::GetAttemptResult(error_code);
70590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  Time attempt_start_time = Time::FromInternalValue(
70690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      metrics_utils::GetPersistedValue(kPrefsUpdateTimestampStart, prefs_));
70752c678cddc5dd7bda8a29e74ce6ef4d67e8d1487Tianjie Xu  TimeDelta duration = clock_->GetBootTime() - attempt_start_time;
70890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  TimeDelta duration_uptime = clock_->GetMonotonicTime() - attempt_start_time;
70990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
71090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  metrics_reporter_->ReportUpdateAttemptMetrics(
71190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      nullptr,  // system_state
71290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      static_cast<int>(attempt_number),
71390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      payload_type,
71452c678cddc5dd7bda8a29e74ce6ef4d67e8d1487Tianjie Xu      duration,
71590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      duration_uptime,
71690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      payload_size,
71790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      attempt_result,
71890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      error_code);
71990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
720d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  int64_t current_bytes_downloaded =
721d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, prefs_);
722d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  metrics_reporter_->ReportUpdateAttemptDownloadMetrics(
723d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      current_bytes_downloaded,
724d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      0,
725d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      DownloadSource::kNumDownloadSources,
726d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      metrics::DownloadErrorCode::kUnset,
727d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      metrics::ConnectionType::kUnset);
728d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu
72990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (error_code == ErrorCode::kSuccess) {
73090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    int64_t reboot_count =
73190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
73290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    string build_version;
73390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    prefs_->GetString(kPrefsPreviousVersion, &build_version);
734d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu
735d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    // For android metrics, we only care about the total bytes downloaded
736d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    // for all sources; for now we assume the only download source is
737d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    // HttpsServer.
738d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    int64_t total_bytes_downloaded =
739d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu        metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, prefs_);
740d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    int64_t num_bytes_downloaded[kNumDownloadSources] = {};
741d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    num_bytes_downloaded[DownloadSource::kDownloadSourceHttpsServer] =
742d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu        total_bytes_downloaded;
743d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu
744d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    int download_overhead_percentage = 0;
745d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    if (current_bytes_downloaded > 0) {
746d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu      download_overhead_percentage =
747d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu          (total_bytes_downloaded - current_bytes_downloaded) * 100ull /
748d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu          current_bytes_downloaded;
749d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu    }
75090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_reporter_->ReportSuccessfulUpdateMetrics(
75190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        static_cast<int>(attempt_number),
75290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        0,  // update abandoned count
75390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        payload_type,
75490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        payload_size,
755d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu        num_bytes_downloaded,
756d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu        download_overhead_percentage,
75752c678cddc5dd7bda8a29e74ce6ef4d67e8d1487Tianjie Xu        duration,
75890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        static_cast<int>(reboot_count),
75990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        0);  // url_switch_count
76090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
76190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu}
76290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
76390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xuvoid UpdateAttempterAndroid::UpdatePrefsAndReportUpdateMetricsOnReboot() {
76490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  string current_boot_id;
76590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  TEST_AND_RETURN(utils::GetBootId(&current_boot_id));
76690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // Example: [ro.build.version.incremental]: [4292972]
76790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  string current_version =
76890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      android::base::GetProperty("ro.build.version.incremental", "");
76990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  TEST_AND_RETURN(!current_version.empty());
77090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
77190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // If there's no record of previous version (e.g. due to a data wipe), we
77290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // save the info of current boot and skip the metrics report.
77390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (!prefs_->Exists(kPrefsPreviousVersion)) {
77490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    prefs_->SetString(kPrefsBootId, current_boot_id);
77590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    prefs_->SetString(kPrefsPreviousVersion, current_version);
77690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    ClearMetricsPrefs();
77790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    return;
77890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
77990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  string previous_version;
78090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // update_engine restarted under the same build.
78190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // TODO(xunchang) identify and report rollback by checking UpdateMarker.
78290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (prefs_->GetString(kPrefsPreviousVersion, &previous_version) &&
78390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      previous_version == current_version) {
78490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    string last_boot_id;
78590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    bool is_reboot = prefs_->Exists(kPrefsBootId) &&
78690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu                     (prefs_->GetString(kPrefsBootId, &last_boot_id) &&
78790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu                      last_boot_id != current_boot_id);
78890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    // Increment the reboot number if |kPrefsNumReboots| exists. That pref is
78990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    // set when we start a new update.
79090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    if (is_reboot && prefs_->Exists(kPrefsNumReboots)) {
79190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      prefs_->SetString(kPrefsBootId, current_boot_id);
79290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      int64_t reboot_count =
79390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu          metrics_utils::GetPersistedValue(kPrefsNumReboots, prefs_);
79490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      metrics_utils::SetNumReboots(reboot_count + 1, prefs_);
79590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    }
79690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    return;
79790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
79890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
79990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // Now that the build version changes, report the update metrics.
80090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // TODO(xunchang) check the build version is larger than the previous one.
80190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->SetString(kPrefsBootId, current_boot_id);
80290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->SetString(kPrefsPreviousVersion, current_version);
80390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
80490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  bool previous_attempt_exists = prefs_->Exists(kPrefsPayloadAttemptNumber);
80590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  // |kPrefsPayloadAttemptNumber| should be cleared upon successful update.
80690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (previous_attempt_exists) {
80790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_reporter_->ReportAbnormallyTerminatedUpdateAttemptMetrics();
80890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
80990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
81090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  metrics_utils::LoadAndReportTimeToReboot(
81190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu      metrics_reporter_.get(), prefs_, clock_.get());
81290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  ClearMetricsPrefs();
81390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu}
81490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
81590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu// Save the update start time. Reset the reboot count and attempt number if the
81690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu// update isn't a resume; otherwise increment the attempt number.
81790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xuvoid UpdateAttempterAndroid::UpdatePrefsOnUpdateStart(bool is_resume) {
81890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  if (!is_resume) {
81990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_utils::SetNumReboots(0, prefs_);
82090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_utils::SetPayloadAttemptNumber(1, prefs_);
82190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  } else {
82290aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    int64_t attempt_number =
82390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu        metrics_utils::GetPersistedValue(kPrefsPayloadAttemptNumber, prefs_);
82490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu    metrics_utils::SetPayloadAttemptNumber(attempt_number + 1, prefs_);
82590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  }
82690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  Time update_start_time = clock_->GetMonotonicTime();
82790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  metrics_utils::SetUpdateTimestampStart(update_start_time, prefs_);
82890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu}
82990aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
83090aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xuvoid UpdateAttempterAndroid::ClearMetricsPrefs() {
83190aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  CHECK(prefs_);
832d4777a148bc822ca11b8355a9df733a5798852c1Tianjie Xu  prefs_->Delete(kPrefsCurrentBytesDownloaded);
83390aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->Delete(kPrefsNumReboots);
83490aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->Delete(kPrefsPayloadAttemptNumber);
83590aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->Delete(kPrefsSystemUpdatedMarker);
83690aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu  prefs_->Delete(kPrefsUpdateTimestampStart);
83790aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu}
83890aaa109e38f147ec4bfc772439d9949f1b237c0Tianjie Xu
8395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo}  // namespace chromeos_update_engine
840