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