update_attempter_android.cc revision 218397ff42cbef9f1b95fdfe30e8e82145ba9908
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> 215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <utility> 225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 235e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <base/bind.h> 245e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <base/logging.h> 25218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo#include <base/strings/string_number_conversions.h> 265e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <brillo/bind_lambda.h> 275e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include <brillo/message_loops/message_loop.h> 28218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo#include <brillo/strings/string_utils.h> 295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/constants.h" 315e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/libcurl_http_fetcher.h" 325e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/multi_range_http_fetcher.h" 335e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/common/utils.h" 345e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/daemon_state_android.h" 355e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/download_action.h" 365e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/filesystem_verifier_action.h" 375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo#include "update_engine/payload_consumer/postinstall_runner_action.h" 385e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::Bind; 405e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::TimeDelta; 415e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing base::TimeTicks; 425e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::shared_ptr; 435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::string; 445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymousing std::vector; 455e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymonamespace chromeos_update_engine { 475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymonamespace { 495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 505e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymoconst char* const kErrorDomain = "update_engine"; 515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// TODO(deymo): Convert the different errors to a numeric value to report them 525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// back on the service error. 535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymoconst char* const kGenericError = "generic_error"; 545e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo// Log and set the error on the passed ErrorPtr. 565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool LogAndSetError(brillo::ErrorPtr* error, 575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const tracked_objects::Location& location, 585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const string& reason) { 595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason); 605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(ERROR) << "Replying with failure: " << location.ToString() << ": " 615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo << reason; 625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return false; 635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} // namespace 665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 675e3ea278d9e771be3b51bd72985ad582678baddcAlex DeymoUpdateAttempterAndroid::UpdateAttempterAndroid( 685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo DaemonStateAndroid* daemon_state, 695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo PrefsInterface* prefs, 705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo BootControlInterface* boot_control, 715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo HardwareInterface* hardware) 725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo : daemon_state_(daemon_state), 735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_(prefs), 745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo boot_control_(boot_control), 755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo hardware_(hardware), 765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo processor_(new ActionProcessor()) { 775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 795e3ea278d9e771be3b51bd72985ad582678baddcAlex DeymoUpdateAttempterAndroid::~UpdateAttempterAndroid() { 805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Release ourselves as the ActionProcessor's delegate to prevent 815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // re-scheduling the updates due to the processing stopped. 825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo processor_->set_delegate(nullptr); 835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::Init() { 865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // In case of update_engine restart without a reboot we need to restore the 875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // reboot needed state. 885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (UpdateCompletedOnThisBoot()) 895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo status_ = UpdateStatus::UPDATED_NEED_REBOOT; 905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo else 915e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo status_ = UpdateStatus::IDLE; 925e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 935e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 945e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ApplyPayload( 955e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const string& payload_url, 965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo int64_t payload_offset, 975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo int64_t payload_size, 985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const vector<string>& key_value_pair_headers, 995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo brillo::ErrorPtr* error) { 1005e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) { 1015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError( 1025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo error, FROM_HERE, "An update already applied, waiting for reboot"); 1035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (ongoing_update_) { 1055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError( 1065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo error, FROM_HERE, "Already processing an update, cancel it first."); 1075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1085e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo DCHECK(status_ == UpdateStatus::IDLE); 1095e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 110218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo std::map<string, string> headers; 111218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo for (const string& key_value_pair : key_value_pair_headers) { 112218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo string key; 113218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo string value; 114218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo if (!brillo::string_utils::SplitAtFirst( 115218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo key_value_pair, "=", &key, &value, false)) { 116218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo return LogAndSetError( 117218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo error, FROM_HERE, "Passed invalid header: " + key_value_pair); 118218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo } 119218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo if (!headers.emplace(key, value).second) 120218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key); 121218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo } 122218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo 123218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo // Unique identifier for the payload. An empty string means that the payload 124218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo // can't be resumed. 125218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo string payload_id = (headers[kPayloadPropertyFileHash] + 126218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo headers[kPayloadPropertyMetadataHash]); 1275e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Setup the InstallPlan based on the request. 1295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_ = InstallPlan(); 1305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1315e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.download_url = payload_url; 1325e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.version = ""; 1330fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo base_offset_ = payload_offset; 134218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo install_plan_.payload_size = payload_size; 135218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo if (!install_plan_.payload_size) { 136218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo if (!base::StringToUint64(headers[kPayloadPropertyFileSize], 137218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo &install_plan_.payload_size)) { 138218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo install_plan_.payload_size = 0; 139218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo } 140218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo } 141218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo install_plan_.payload_hash = headers[kPayloadPropertyFileHash]; 142218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize], 143218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo &install_plan_.metadata_size)) { 144218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo install_plan_.metadata_size = 0; 145218397ff42cbef9f1b95fdfe30e8e82145ba9908Alex Deymo } 1465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.metadata_signature = ""; 1475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // The |public_key_rsa| key would override the public key stored on disk. 1485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.public_key_rsa = ""; 1495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1505e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild(); 1515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.is_resume = !payload_id.empty() && 1525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo DeltaPerformer::CanResumeUpdate(prefs_, payload_id); 1535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (!install_plan_.is_resume) { 1545e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) { 1555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(WARNING) << "Unable to reset the update progress."; 1565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) { 1585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(WARNING) << "Unable to save the update check response hash."; 1595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // The |is_full_update| is not used anymore since minor_version 3. 1625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.is_full_update = true; 1635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.source_slot = boot_control_->GetCurrentSlot(); 1655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0; 1665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.powerwash_required = false; 1675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Using this install plan:"; 1695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo install_plan_.Dump(); 1705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo BuildUpdateActions(); 1725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo SetupDownload(); 1735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo cpu_limiter_.StartLimiter(); 1745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE); 1755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Just in case we didn't update boot flags yet, make sure they're updated 1775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // before any update processing starts. This will start the update process. 1785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo UpdateBootFlags(); 1795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return true; 1805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 1815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) { 1835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // TODO(deymo): Implement suspend/resume. 1845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError(error, FROM_HERE, "Suspend/resume not implemented"); 1855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 1865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) { 1885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // TODO(deymo): Implement suspend/resume. 1895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError(error, FROM_HERE, "Suspend/resume not implemented"); 1905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 1915e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1925e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) { 1935e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (status_ == UpdateStatus::IDLE || 1945e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo status_ == UpdateStatus::UPDATED_NEED_REBOOT) { 1955e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel."); 1965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 1975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 1985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // TODO(deymo): Implement cancel. 1995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return LogAndSetError(error, FROM_HERE, "Cancel not implemented"); 2005e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor, 2035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo ErrorCode code) { 2045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Processing Done."; 2055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (code == ErrorCode::kSuccess) { 2075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Update succeeded. 2085e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo WriteUpdateCompletedMarker(); 2095e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); 2105e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo DeltaPerformer::ResetUpdateProgress(prefs_, false); 2115e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2125e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Update successfully applied, waiting to reboot."; 2135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo TerminateUpdateAndNotify(code); 2165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ProcessingStopped( 2195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const ActionProcessor* processor) { 2205e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo TerminateUpdateAndNotify(ErrorCode::kUserCanceled); 2215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2235e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor, 2245e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo AbstractAction* action, 2255e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo ErrorCode code) { 2265e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Reset download progress regardless of whether or not the download 2275e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // action succeeded. 2285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const string type = action->Type(); 2295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (type == DownloadAction::StaticType()) { 2305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_progress_ = 0.0; 2315e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2325e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (code != ErrorCode::kSuccess) { 2335e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // If an action failed, the ActionProcessor will cancel the whole thing. 2345e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return; 2355e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2365e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (type == DownloadAction::StaticType()) { 2375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo SetStatusAndNotify(UpdateStatus::FINALIZING); 2385e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2405e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2415e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed, 2425e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo uint64_t bytes_received, 2435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo uint64_t total) { 2445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo double progress = 0.; 2455e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (total) 2465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo progress = static_cast<double>(bytes_received) / static_cast<double>(total); 2475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Self throttle based on progress. Also send notifications if 2485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // progress is too slow. 2495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo const double kDeltaPercent = 0.01; // 1% 2505e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total || 2515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo progress - download_progress_ >= kDeltaPercent || 2525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo TimeTicks::Now() - last_notify_time_ >= TimeDelta::FromSeconds(10)) { 2535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_progress_ = progress; 2545e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo SetStatusAndNotify(UpdateStatus::DOWNLOADING); 2555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) { 2595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // TODO(deymo): Notify the DownloadAction that it should cancel the update 2605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // download. 2615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return false; 2625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::DownloadComplete() { 2655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Nothing needs to be done when the download completes. 2665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::UpdateBootFlags() { 2695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (updated_boot_flags_) { 2705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Already updated boot flags. Skipping."; 2715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo CompleteUpdateBootFlags(true); 2725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return; 2735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // This is purely best effort. 2755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Marking booted slot as good."; 2765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (!boot_control_->MarkBootSuccessfulAsync( 2775e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo Bind(&UpdateAttempterAndroid::CompleteUpdateBootFlags, 2785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo base::Unretained(this)))) { 2795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(ERROR) << "Failed to mark current boot as successful."; 2805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo CompleteUpdateBootFlags(false); 2815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 2825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2845e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::CompleteUpdateBootFlags(bool successful) { 2855e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo updated_boot_flags_ = true; 2865e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo ScheduleProcessingStart(); 2875e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2885e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::ScheduleProcessingStart() { 2905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(INFO) << "Scheduling an action processor start."; 2915e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo brillo::MessageLoop::current()->PostTask( 2925e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo FROM_HERE, Bind([this] { this->processor_->StartProcessing(); })); 2935e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 2945e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 2955e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) { 2965e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (status_ == UpdateStatus::IDLE) { 2975e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called."; 2985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return; 2995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 3005e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Reset cpu shares back to normal. 3025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo cpu_limiter_.StopLimiter(); 3035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_progress_ = 0.0; 3045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo actions_.clear(); 3055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo UpdateStatus new_status = 3065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT 3075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo : UpdateStatus::IDLE); 3085e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo SetStatusAndNotify(new_status); 3095e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo ongoing_update_ = false; 3105e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3115e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo for (auto observer : daemon_state_->service_observers()) 3125e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo observer->SendPayloadApplicationComplete(error_code); 3135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 3145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) { 3165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo status_ = status; 3175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo for (auto observer : daemon_state_->service_observers()) { 3185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo observer->SendStatusUpdate( 3195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 0, download_progress_, status_, "", install_plan_.payload_size); 3205e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 3215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo last_notify_time_ = TimeTicks::Now(); 3225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 3235e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3245e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::BuildUpdateActions() { 3255e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo CHECK(!processor_->IsRunning()); 3265e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo processor_->set_delegate(this); 3275e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3285e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Actions: 3295e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo shared_ptr<InstallPlanAction> install_plan_action( 3305e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo new InstallPlanAction(install_plan_)); 3315e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3325e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo LibcurlHttpFetcher* download_fetcher = 3335e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo new LibcurlHttpFetcher(&proxy_resolver_, hardware_); 3345e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_fetcher->set_server_to_check(ServerToCheck::kDownload); 3355e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo shared_ptr<DownloadAction> download_action(new DownloadAction( 3365e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_, 3375e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo boot_control_, 3385e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo hardware_, 3395e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo nullptr, // system_state, not used. 3405e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo new MultiRangeHttpFetcher(download_fetcher))); // passes ownership 3415e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo shared_ptr<FilesystemVerifierAction> dst_filesystem_verifier_action( 3425e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo new FilesystemVerifierAction(boot_control_, 3435e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo VerifierMode::kVerifyTargetHash)); 3445e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3455e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo shared_ptr<PostinstallRunnerAction> postinstall_runner_action( 3465e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo new PostinstallRunnerAction(boot_control_)); 3475e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3485e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_action->set_delegate(this); 3495e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo download_action_ = download_action; 3505e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3515e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo actions_.push_back(shared_ptr<AbstractAction>(install_plan_action)); 3525e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo actions_.push_back(shared_ptr<AbstractAction>(download_action)); 3535e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo actions_.push_back( 3545e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo shared_ptr<AbstractAction>(dst_filesystem_verifier_action)); 3555e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action)); 3565e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3575e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Bond them together. We have to use the leaf-types when calling 3585e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // BondActions(). 3595e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo BondActions(install_plan_action.get(), download_action.get()); 3605e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo BondActions(download_action.get(), dst_filesystem_verifier_action.get()); 3615e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo BondActions(dst_filesystem_verifier_action.get(), 3625e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo postinstall_runner_action.get()); 3635e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3645e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Enqueue the actions. 3655e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo for (const shared_ptr<AbstractAction>& action : actions_) 3665e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo processor_->EnqueueAction(action.get()); 3675e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 3685e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 3695e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymovoid UpdateAttempterAndroid::SetupDownload() { 3705e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo MultiRangeHttpFetcher* fetcher = 3715e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo static_cast<MultiRangeHttpFetcher*>(download_action_->http_fetcher()); 3725e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo fetcher->ClearRanges(); 3735e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo if (install_plan_.is_resume) { 3745e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // Resuming an update so fetch the update manifest metadata first. 3755e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo int64_t manifest_metadata_size = 0; 3765e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size); 3770fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo fetcher->AddRange(base_offset_, manifest_metadata_size); 3785e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // If there're remaining unprocessed data blobs, fetch them. Be careful not 3795e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // to request data beyond the end of the payload to avoid 416 HTTP response 3805e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // error codes. 3815e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo int64_t next_data_offset = 0; 3825e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset); 3835e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo uint64_t resume_offset = manifest_metadata_size + next_data_offset; 3840fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo if (!install_plan_.payload_size) { 3850fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo fetcher->AddRange(base_offset_ + resume_offset); 3860fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo } else if (resume_offset < install_plan_.payload_size) { 3870fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo fetcher->AddRange(base_offset_ + resume_offset, 3880fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo install_plan_.payload_size - resume_offset); 3895e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 3905e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } else { 3910fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo if (install_plan_.payload_size) { 3920fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo fetcher->AddRange(base_offset_, install_plan_.payload_size); 3930fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo } else { 3940fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo // If no payload size is passed we assume we read until the end of the 3950fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo // stream. 3960fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo fetcher->AddRange(base_offset_); 3970fd51ff8fd200aab7f9ab930b47736505a7b59c3Alex Deymo } 3985e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo } 3995e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 4005e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 4015e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::WriteUpdateCompletedMarker() { 4025e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo string boot_id; 4035e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 4045e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id); 4055e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return true; 4065e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 4075e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 4085e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymobool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() { 4095e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // In case of an update_engine restart without a reboot, we stored the boot_id 4105e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // when the update was completed by setting a pref, so we can check whether 4115e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo // the last update was on this boot or a previous one. 4125e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo string boot_id; 4135e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 4145e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 4155e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo string update_completed_on_boot_id; 4165e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) && 4175e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo prefs_->GetString(kPrefsUpdateCompletedOnBootId, 4185e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo &update_completed_on_boot_id) && 4195e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo update_completed_on_boot_id == boot_id); 4205e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} 4215e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo 4225e3ea278d9e771be3b51bd72985ad582678baddcAlex Deymo} // namespace chromeos_update_engine 423