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 |