Index: chrome/browser/chromeos/login/update_screen.cc |
diff --git a/chrome/browser/chromeos/login/update_screen.cc b/chrome/browser/chromeos/login/update_screen.cc |
index 4f3d7b4afc0babbdd2c6bd7cdc8b1d65ec794fd5..32f20d38defdbce55b36255a34bad93df475657b 100644 |
--- a/chrome/browser/chromeos/login/update_screen.cc |
+++ b/chrome/browser/chromeos/login/update_screen.cc |
@@ -4,6 +4,7 @@ |
#include "chrome/browser/chromeos/login/update_screen.h" |
+#include <algorithm> |
#include "base/bind.h" |
#include "base/file_util.h" |
#include "base/logging.h" |
@@ -39,6 +40,17 @@ const int kUpdateScreenHeight = 305; |
const char kUpdateDeadlineFile[] = "/tmp/update-check-response-deadline"; |
+// Minimum timestep between two consecutive measurements for the |
+// download rate. |
+const base::TimeDelta kMinTimeStep = base::TimeDelta::FromMilliseconds(10); |
Nikita (slow)
2012/05/10 16:04:31
Perhaps set it to at least 1s so that rate is not
ygorshenin1
2012/05/11 12:42:50
Done.
|
+// Minimum allowed progress between two consecutive ETAs. |
Nikita (slow)
2012/05/10 16:04:31
nit: Insert extra line before each comment.
ygorshenin1
2012/05/11 12:42:50
Done.
|
+const double kMinProgressStep = 1e-3; |
+// Smooth factor that is used for the average downloading speed |
+// estimation. |
+const double kDownloadSpeedSmoothFactor = 0.01; |
+// Minumum allowed value for the average downloading speed. |
+const double kDownloadAverageSpeedDropBound = 1e-8; |
+ |
// Invoked from call to RequestUpdateCheck upon completion of the DBus call. |
void StartUpdateCallback(UpdateScreen* screen, |
UpdateEngineClient::UpdateCheckResult result) { |
@@ -99,6 +111,16 @@ void UpdateScreen::UpdateStatusChanged( |
ignore_idle_status_ = false; |
} |
+ if (status.status == UpdateEngineClient::UPDATE_STATUS_DOWNLOADING) { |
+ // |is_downloading_update_| is set below, so if it's value is |
+ // false, then this is the first notification from the downloading |
+ // stage. |
+ if (!is_downloading_update_) |
+ actor_->ShowUpdateDownloadingStats(true); |
Nikita (slow)
2012/05/10 16:04:31
What would it show if we call ExitUpdate(REASON_UP
ygorshenin1
2012/05/11 12:42:50
Nothing. These stats will be shown iff curtain is
|
+ } else if (is_downloading_update_) { |
+ actor_->ShowUpdateDownloadingStats(false); |
+ } |
+ |
switch (status.status) { |
case UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE: |
// Do nothing in these cases, we don't want to notify the user of the |
@@ -125,6 +147,11 @@ void UpdateScreen::UpdateStatusChanged( |
// Because update engine doesn't send UPDATE_STATUS_UPDATE_AVAILABLE |
// we need to is update critical on first downloading notification. |
is_downloading_update_ = true; |
+ download_start_time_ = download_last_time_ = base::Time::Now(); |
+ download_start_progress_ = status.download_progress; |
+ download_last_progress_ = status.download_progress; |
+ is_download_average_speed_computed_ = false; |
+ download_average_speed_ = 0.0; |
if (!HasCriticalUpdate()) { |
LOG(INFO) << "Non-critical update available: " |
<< status.new_version; |
@@ -136,6 +163,44 @@ void UpdateScreen::UpdateStatusChanged( |
actor_->ShowCurtain(false); |
} |
} |
+ |
+ base::Time download_current_time = base::Time::Now(); |
Nikita (slow)
2012/05/10 16:04:31
Extract to a separate function.
ygorshenin1
2012/05/11 12:42:50
Done.
|
+ if (download_current_time >= download_last_time_ + kMinTimeStep && |
+ status.download_progress >= |
+ download_last_progress_ + kMinProgressStep) { |
+ // Estimate downloading rate. |
+ double progress_delta = |
+ std::max(status.download_progress - download_last_progress_, 0.0); |
+ double time_delta = |
+ (download_current_time - download_last_time_).InSecondsF(); |
+ double download_rate = status.new_size * progress_delta / time_delta; |
+ actor_->SetDownloadingRate(download_rate); |
Nikita (slow)
2012/05/10 16:04:31
Move this call below to group with SetEstimatedTim
ygorshenin1
2012/05/11 12:42:50
Done.
|
+ download_last_time_ = download_current_time; |
+ download_last_progress_ = status.download_progress; |
+ |
+ // Estimate time left. |
+ double progress_left = std::max(1.0 - status.download_progress, 0.0); |
+ if (!is_download_average_speed_computed_) { |
+ download_average_speed_ = download_rate; |
+ is_download_average_speed_computed_ = true; |
+ } |
+ download_average_speed_ = |
+ kDownloadSpeedSmoothFactor * download_rate + |
+ (1.0 - kDownloadSpeedSmoothFactor) * download_average_speed_; |
+ if (download_average_speed_ < kDownloadAverageSpeedDropBound) { |
+ time_delta = |
+ (download_current_time - download_start_time_).InSecondsF(); |
+ download_average_speed_ = |
+ status.new_size * |
+ (status.download_progress - download_start_progress_) / |
+ time_delta; |
+ } |
+ double work_left = progress_left * status.new_size; |
+ double time_left = work_left / download_average_speed_; |
+ actor_->SetEstimatedTimeLeft( |
+ base::TimeDelta::FromSeconds(static_cast<int64>(time_left))); |
+ } |
+ |
int download_progress = static_cast<int>( |
status.download_progress * kDownloadProgressIncrement); |
actor_->SetProgress(kBeforeDownloadProgress + download_progress); |
@@ -277,24 +342,28 @@ void UpdateScreen::SetIgnoreIdleStatus(bool ignore_idle_status) { |
} |
bool UpdateScreen::HasCriticalUpdate() { |
Nikita (slow)
2012/05/10 16:04:31
Remove test code.
ygorshenin1
2012/05/11 12:42:50
Done.
|
- if (is_ignore_update_deadlines_) |
- return true; |
- |
- std::string deadline; |
- // Checking for update flag file causes us to do blocking IO on UI thread. |
- // Temporarily allow it until we fix http://crosbug.com/11106 |
- base::ThreadRestrictions::ScopedAllowIO allow_io; |
- FilePath update_deadline_file_path(kUpdateDeadlineFile); |
- if (!file_util::ReadFileToString(update_deadline_file_path, &deadline) || |
- deadline.empty()) { |
- return false; |
- } |
- |
- // TODO(dpolukhin): Analyze file content. Now we can just assume that |
- // if the file exists and not empty, there is critical update. |
return true; |
} |
+// bool UpdateScreen::HasCriticalUpdate() { |
+// if (is_ignore_update_deadlines_) |
+// return true; |
+ |
+// std::string deadline; |
+// // Checking for update flag file causes us to do blocking IO on UI thread. |
+// // Temporarily allow it until we fix http://crosbug.com/11106 |
+// base::ThreadRestrictions::ScopedAllowIO allow_io; |
+// FilePath update_deadline_file_path(kUpdateDeadlineFile); |
+// if (!file_util::ReadFileToString(update_deadline_file_path, &deadline) || |
+// deadline.empty()) { |
+// return false; |
+// } |
+ |
+// // TODO(dpolukhin): Analyze file content. Now we can just assume that |
+// // if the file exists and not empty, there is critical update. |
+// return true; |
+// } |
+ |
void UpdateScreen::OnActorDestroyed(UpdateScreenActor* actor) { |
if (actor_ == actor) |
actor_ = NULL; |