update_attempter_android.cc 31 KB

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