| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "update_engine/update_attempter.h" | 5 #include "update_engine/update_attempter.h" |
| 6 | 6 |
| 7 // From 'man clock_gettime': feature test macro: _POSIX_C_SOURCE >= 199309L | 7 // From 'man clock_gettime': feature test macro: _POSIX_C_SOURCE >= 199309L |
| 8 #ifndef _POSIX_C_SOURCE | 8 #ifndef _POSIX_C_SOURCE |
| 9 #define _POSIX_C_SOURCE 199309L | 9 #define _POSIX_C_SOURCE 199309L |
| 10 #endif // _POSIX_C_SOURCE | 10 #endif // _POSIX_C_SOURCE |
| 11 #include <time.h> | 11 #include <time.h> |
| 12 | 12 |
| 13 #include <tr1/memory> | 13 #include <tr1/memory> |
| 14 #include <string> | 14 #include <string> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include <glib.h> | 17 #include <glib.h> |
| 18 | 18 |
| 19 #include "metrics/metrics_library.h" | 19 #include "metrics/metrics_library.h" |
| 20 #include "update_engine/dbus_service.h" | 20 #include "update_engine/dbus_service.h" |
| 21 #include "update_engine/download_action.h" | 21 #include "update_engine/download_action.h" |
| 22 #include "update_engine/filesystem_copier_action.h" | 22 #include "update_engine/filesystem_copier_action.h" |
| 23 #include "update_engine/libcurl_http_fetcher.h" | 23 #include "update_engine/libcurl_http_fetcher.h" |
| 24 #include "update_engine/omaha_request_action.h" | 24 #include "update_engine/omaha_request_action.h" |
| 25 #include "update_engine/omaha_request_params.h" | 25 #include "update_engine/omaha_request_params.h" |
| 26 #include "update_engine/omaha_response_handler_action.h" | 26 #include "update_engine/omaha_response_handler_action.h" |
| 27 #include "update_engine/postinstall_runner_action.h" | 27 #include "update_engine/postinstall_runner_action.h" |
| 28 #include "update_engine/set_bootable_flag_action.h" | 28 #include "update_engine/set_bootable_flag_action.h" |
| 29 | 29 |
| 30 using base::TimeDelta; |
| 31 using base::TimeTicks; |
| 30 using std::tr1::shared_ptr; | 32 using std::tr1::shared_ptr; |
| 31 using std::string; | 33 using std::string; |
| 32 using std::vector; | 34 using std::vector; |
| 33 | 35 |
| 34 namespace chromeos_update_engine { | 36 namespace chromeos_update_engine { |
| 35 | 37 |
| 36 const char* kUpdateCompletedMarker = "/tmp/update_engine_autoupdate_completed"; | 38 const char* kUpdateCompletedMarker = "/tmp/update_engine_autoupdate_completed"; |
| 37 | 39 |
| 38 namespace { | |
| 39 // Returns true on success. | |
| 40 bool GetCPUClockTime(struct timespec* out) { | |
| 41 return clock_gettime(CLOCK_REALTIME, out) == 0; | |
| 42 } | |
| 43 // Returns stop - start. | |
| 44 struct timespec CPUClockTimeElapsed(const struct timespec& start, | |
| 45 const struct timespec& stop) { | |
| 46 CHECK(start.tv_sec >= 0); | |
| 47 CHECK(stop.tv_sec >= 0); | |
| 48 CHECK(start.tv_nsec >= 0); | |
| 49 CHECK(stop.tv_nsec >= 0); | |
| 50 | |
| 51 const int64_t kOneBillion = 1000000000L; | |
| 52 const int64_t start64 = start.tv_sec * kOneBillion + start.tv_nsec; | |
| 53 const int64_t stop64 = stop.tv_sec * kOneBillion + stop.tv_nsec; | |
| 54 | |
| 55 const int64_t result64 = stop64 - start64; | |
| 56 | |
| 57 struct timespec ret; | |
| 58 ret.tv_sec = result64 / kOneBillion; | |
| 59 ret.tv_nsec = result64 % kOneBillion; | |
| 60 | |
| 61 return ret; | |
| 62 } | |
| 63 bool CPUClockTimeGreaterThanHalfSecond(const struct timespec& spec) { | |
| 64 if (spec.tv_sec >= 1) | |
| 65 return true; | |
| 66 return (spec.tv_nsec > 500000000); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 const char* UpdateStatusToString(UpdateStatus status) { | 40 const char* UpdateStatusToString(UpdateStatus status) { |
| 71 switch (status) { | 41 switch (status) { |
| 72 case UPDATE_STATUS_IDLE: | 42 case UPDATE_STATUS_IDLE: |
| 73 return "UPDATE_STATUS_IDLE"; | 43 return "UPDATE_STATUS_IDLE"; |
| 74 case UPDATE_STATUS_CHECKING_FOR_UPDATE: | 44 case UPDATE_STATUS_CHECKING_FOR_UPDATE: |
| 75 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; | 45 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; |
| 76 case UPDATE_STATUS_UPDATE_AVAILABLE: | 46 case UPDATE_STATUS_UPDATE_AVAILABLE: |
| 77 return "UPDATE_STATUS_UPDATE_AVAILABLE"; | 47 return "UPDATE_STATUS_UPDATE_AVAILABLE"; |
| 78 case UPDATE_STATUS_DOWNLOADING: | 48 case UPDATE_STATUS_DOWNLOADING: |
| 79 return "UPDATE_STATUS_DOWNLOADING"; | 49 return "UPDATE_STATUS_DOWNLOADING"; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 prefs_(prefs), | 90 prefs_(prefs), |
| 121 metrics_lib_(metrics_lib), | 91 metrics_lib_(metrics_lib), |
| 122 priority_(utils::kProcessPriorityNormal), | 92 priority_(utils::kProcessPriorityNormal), |
| 123 manage_priority_source_(NULL), | 93 manage_priority_source_(NULL), |
| 124 download_active_(false), | 94 download_active_(false), |
| 125 status_(UPDATE_STATUS_IDLE), | 95 status_(UPDATE_STATUS_IDLE), |
| 126 download_progress_(0.0), | 96 download_progress_(0.0), |
| 127 last_checked_time_(0), | 97 last_checked_time_(0), |
| 128 new_version_("0.0.0.0"), | 98 new_version_("0.0.0.0"), |
| 129 new_size_(0) { | 99 new_size_(0) { |
| 130 last_notify_time_.tv_sec = 0; | |
| 131 last_notify_time_.tv_nsec = 0; | |
| 132 if (utils::FileExists(kUpdateCompletedMarker)) | 100 if (utils::FileExists(kUpdateCompletedMarker)) |
| 133 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; | 101 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; |
| 134 } | 102 } |
| 135 | 103 |
| 136 UpdateAttempter::~UpdateAttempter() { | 104 UpdateAttempter::~UpdateAttempter() { |
| 137 CleanupPriorityManagement(); | 105 CleanupPriorityManagement(); |
| 138 } | 106 } |
| 139 | 107 |
| 140 void UpdateAttempter::Update(const std::string& app_version, | 108 void UpdateAttempter::Update(const std::string& app_version, |
| 141 const std::string& omaha_url) { | 109 const std::string& omaha_url) { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 void UpdateAttempter::SetDownloadStatus(bool active) { | 323 void UpdateAttempter::SetDownloadStatus(bool active) { |
| 356 download_active_ = active; | 324 download_active_ = active; |
| 357 LOG(INFO) << "Download status: " << (active ? "active" : "inactive"); | 325 LOG(INFO) << "Download status: " << (active ? "active" : "inactive"); |
| 358 } | 326 } |
| 359 | 327 |
| 360 void UpdateAttempter::BytesReceived(uint64_t bytes_received, uint64_t total) { | 328 void UpdateAttempter::BytesReceived(uint64_t bytes_received, uint64_t total) { |
| 361 if (!download_active_) { | 329 if (!download_active_) { |
| 362 LOG(ERROR) << "BytesReceived called while not downloading."; | 330 LOG(ERROR) << "BytesReceived called while not downloading."; |
| 363 return; | 331 return; |
| 364 } | 332 } |
| 365 download_progress_ = static_cast<double>(bytes_received) / | 333 double progress = static_cast<double>(bytes_received) / |
| 366 static_cast<double>(total); | 334 static_cast<double>(total); |
| 367 // We self throttle here | 335 // Self throttle based on progress. Also send notifications if |
| 368 timespec now; | 336 // progress is too slow. |
| 369 now.tv_sec = 0; | 337 const double kDeltaPercent = 0.01; // 1% |
| 370 now.tv_nsec = 0; | 338 if (status_ != UPDATE_STATUS_DOWNLOADING || |
| 371 if (GetCPUClockTime(&now) && | 339 bytes_received == total || |
| 372 CPUClockTimeGreaterThanHalfSecond( | 340 progress - download_progress_ >= kDeltaPercent || |
| 373 CPUClockTimeElapsed(last_notify_time_, now))) { | 341 TimeTicks::Now() - last_notify_time_ >= TimeDelta::FromSeconds(10)) { |
| 342 download_progress_ = progress; |
| 374 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); | 343 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); |
| 375 } | 344 } |
| 376 } | 345 } |
| 377 | 346 |
| 378 bool UpdateAttempter::GetStatus(int64_t* last_checked_time, | 347 bool UpdateAttempter::GetStatus(int64_t* last_checked_time, |
| 379 double* progress, | 348 double* progress, |
| 380 std::string* current_operation, | 349 std::string* current_operation, |
| 381 std::string* new_version, | 350 std::string* new_version, |
| 382 int64_t* new_size) { | 351 int64_t* new_size) { |
| 383 *last_checked_time = last_checked_time_; | 352 *last_checked_time = last_checked_time_; |
| 384 *progress = download_progress_; | 353 *progress = download_progress_; |
| 385 *current_operation = UpdateStatusToString(status_); | 354 *current_operation = UpdateStatusToString(status_); |
| 386 *new_version = new_version_; | 355 *new_version = new_version_; |
| 387 *new_size = new_size_; | 356 *new_size = new_size_; |
| 388 return true; | 357 return true; |
| 389 } | 358 } |
| 390 | 359 |
| 391 void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) { | 360 void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) { |
| 392 status_ = status; | 361 status_ = status; |
| 393 if (!dbus_service_) | 362 if (!dbus_service_) |
| 394 return; | 363 return; |
| 395 GetCPUClockTime(&last_notify_time_); | 364 last_notify_time_ = TimeTicks::Now(); |
| 396 update_engine_service_emit_status_update( | 365 update_engine_service_emit_status_update( |
| 397 dbus_service_, | 366 dbus_service_, |
| 398 last_checked_time_, | 367 last_checked_time_, |
| 399 download_progress_, | 368 download_progress_, |
| 400 UpdateStatusToString(status_), | 369 UpdateStatusToString(status_), |
| 401 new_version_.c_str(), | 370 new_version_.c_str(), |
| 402 new_size_); | 371 new_size_); |
| 403 } | 372 } |
| 404 | 373 |
| 405 void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action, | 374 void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 SetPriority(utils::kProcessPriorityNormal); | 455 SetPriority(utils::kProcessPriorityNormal); |
| 487 return true; | 456 return true; |
| 488 } | 457 } |
| 489 // Set the priority to high and let GLib destroy the timeout source. | 458 // Set the priority to high and let GLib destroy the timeout source. |
| 490 SetPriority(utils::kProcessPriorityHigh); | 459 SetPriority(utils::kProcessPriorityHigh); |
| 491 manage_priority_source_ = NULL; | 460 manage_priority_source_ = NULL; |
| 492 return false; | 461 return false; |
| 493 } | 462 } |
| 494 | 463 |
| 495 } // namespace chromeos_update_engine | 464 } // namespace chromeos_update_engine |
| OLD | NEW |