OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium 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 "chrome/browser/extensions/updater/extension_updater.h" | 5 #include "chrome/browser/extensions/updater/extension_updater.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "chrome/browser/extensions/extension_service.h" | 22 #include "chrome/browser/extensions/extension_service.h" |
23 #include "chrome/browser/extensions/updater/extension_downloader.h" | 23 #include "chrome/browser/extensions/updater/extension_downloader.h" |
24 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
25 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
26 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
27 #include "content/public/browser/notification_details.h" | 27 #include "content/public/browser/notification_details.h" |
28 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
29 #include "content/public/browser/notification_source.h" | 29 #include "content/public/browser/notification_source.h" |
30 #include "crypto/sha2.h" | 30 #include "crypto/sha2.h" |
31 #include "extensions/browser/pending_extension_manager.h" | 31 #include "extensions/browser/pending_extension_manager.h" |
| 32 #include "extensions/browser/pref_names.h" |
32 #include "extensions/common/constants.h" | 33 #include "extensions/common/constants.h" |
33 #include "extensions/common/extension.h" | 34 #include "extensions/common/extension.h" |
34 #include "extensions/common/extension_set.h" | 35 #include "extensions/common/extension_set.h" |
35 #include "extensions/common/manifest.h" | 36 #include "extensions/common/manifest.h" |
36 | 37 |
37 using base::RandDouble; | 38 using base::RandDouble; |
38 using base::RandInt; | 39 using base::RandInt; |
39 using base::Time; | 40 using base::Time; |
40 using base::TimeDelta; | 41 using base::TimeDelta; |
41 using content::BrowserThread; | 42 using content::BrowserThread; |
42 using prefs::kLastExtensionsUpdateCheck; | |
43 using prefs::kNextExtensionsUpdateCheck; | |
44 | 43 |
45 typedef extensions::ExtensionDownloaderDelegate::Error Error; | 44 typedef extensions::ExtensionDownloaderDelegate::Error Error; |
46 typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult; | 45 typedef extensions::ExtensionDownloaderDelegate::PingResult PingResult; |
47 | 46 |
48 namespace { | 47 namespace { |
49 | 48 |
50 // Wait at least 5 minutes after browser startup before we do any checks. If you | 49 // Wait at least 5 minutes after browser startup before we do any checks. If you |
51 // change this value, make sure to update comments where it is used. | 50 // change this value, make sure to update comments where it is used. |
52 const int kStartupWaitSeconds = 60 * 5; | 51 const int kStartupWaitSeconds = 60 * 5; |
53 | 52 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 | 157 |
159 // The overall goal here is to balance keeping clients up to date while | 158 // The overall goal here is to balance keeping clients up to date while |
160 // avoiding a thundering herd against update servers. | 159 // avoiding a thundering herd against update servers. |
161 TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { | 160 TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { |
162 DCHECK(alive_); | 161 DCHECK(alive_); |
163 // If someone's testing with a quick frequency, just allow it. | 162 // If someone's testing with a quick frequency, just allow it. |
164 if (frequency_seconds_ < kStartupWaitSeconds) | 163 if (frequency_seconds_ < kStartupWaitSeconds) |
165 return TimeDelta::FromSeconds(frequency_seconds_); | 164 return TimeDelta::FromSeconds(frequency_seconds_); |
166 | 165 |
167 // If we've never scheduled a check before, start at frequency_seconds_. | 166 // If we've never scheduled a check before, start at frequency_seconds_. |
168 if (!prefs_->HasPrefPath(kNextExtensionsUpdateCheck)) | 167 if (!prefs_->HasPrefPath(pref_names::kNextUpdateCheck)) |
169 return TimeDelta::FromSeconds(frequency_seconds_); | 168 return TimeDelta::FromSeconds(frequency_seconds_); |
170 | 169 |
171 // If it's been a long time since our last actual check, we want to do one | 170 // If it's been a long time since our last actual check, we want to do one |
172 // relatively soon. | 171 // relatively soon. |
173 Time now = Time::Now(); | 172 Time now = Time::Now(); |
174 Time last = Time::FromInternalValue(prefs_->GetInt64( | 173 Time last = Time::FromInternalValue(prefs_->GetInt64( |
175 kLastExtensionsUpdateCheck)); | 174 pref_names::kLastUpdateCheck)); |
176 int days = (now - last).InDays(); | 175 int days = (now - last).InDays(); |
177 if (days >= 30) { | 176 if (days >= 30) { |
178 // Wait 5-10 minutes. | 177 // Wait 5-10 minutes. |
179 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, | 178 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, |
180 kStartupWaitSeconds * 2)); | 179 kStartupWaitSeconds * 2)); |
181 } else if (days >= 14) { | 180 } else if (days >= 14) { |
182 // Wait 10-20 minutes. | 181 // Wait 10-20 minutes. |
183 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 2, | 182 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 2, |
184 kStartupWaitSeconds * 4)); | 183 kStartupWaitSeconds * 4)); |
185 } else if (days >= 3) { | 184 } else if (days >= 3) { |
186 // Wait 20-40 minutes. | 185 // Wait 20-40 minutes. |
187 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 4, | 186 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 4, |
188 kStartupWaitSeconds * 8)); | 187 kStartupWaitSeconds * 8)); |
189 } | 188 } |
190 | 189 |
191 // Read the persisted next check time, and use that if it isn't too soon. | 190 // Read the persisted next check time, and use that if it isn't too soon. |
192 // Otherwise pick something random. | 191 // Otherwise pick something random. |
193 Time saved_next = Time::FromInternalValue(prefs_->GetInt64( | 192 Time saved_next = Time::FromInternalValue(prefs_->GetInt64( |
194 kNextExtensionsUpdateCheck)); | 193 pref_names::kNextUpdateCheck)); |
195 Time earliest = now + TimeDelta::FromSeconds(kStartupWaitSeconds); | 194 Time earliest = now + TimeDelta::FromSeconds(kStartupWaitSeconds); |
196 if (saved_next >= earliest) { | 195 if (saved_next >= earliest) { |
197 return saved_next - now; | 196 return saved_next - now; |
198 } else { | 197 } else { |
199 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, | 198 return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, |
200 frequency_seconds_)); | 199 frequency_seconds_)); |
201 } | 200 } |
202 } | 201 } |
203 | 202 |
204 void ExtensionUpdater::Start() { | 203 void ExtensionUpdater::Start() { |
(...skipping 29 matching lines...) Expand all Loading... |
234 | 233 |
235 // Add +/- 10% random jitter. | 234 // Add +/- 10% random jitter. |
236 double delay_ms = target_delay.InMillisecondsF(); | 235 double delay_ms = target_delay.InMillisecondsF(); |
237 double jitter_factor = (RandDouble() * .2) - 0.1; | 236 double jitter_factor = (RandDouble() * .2) - 0.1; |
238 delay_ms += delay_ms * jitter_factor; | 237 delay_ms += delay_ms * jitter_factor; |
239 TimeDelta actual_delay = TimeDelta::FromMilliseconds( | 238 TimeDelta actual_delay = TimeDelta::FromMilliseconds( |
240 static_cast<int64>(delay_ms)); | 239 static_cast<int64>(delay_ms)); |
241 | 240 |
242 // Save the time of next check. | 241 // Save the time of next check. |
243 Time next = Time::Now() + actual_delay; | 242 Time next = Time::Now() + actual_delay; |
244 prefs_->SetInt64(kNextExtensionsUpdateCheck, next.ToInternalValue()); | 243 prefs_->SetInt64(pref_names::kNextUpdateCheck, next.ToInternalValue()); |
245 | 244 |
246 timer_.Start(FROM_HERE, actual_delay, this, &ExtensionUpdater::TimerFired); | 245 timer_.Start(FROM_HERE, actual_delay, this, &ExtensionUpdater::TimerFired); |
247 } | 246 } |
248 | 247 |
249 void ExtensionUpdater::TimerFired() { | 248 void ExtensionUpdater::TimerFired() { |
250 DCHECK(alive_); | 249 DCHECK(alive_); |
251 CheckNow(default_params_); | 250 CheckNow(default_params_); |
252 | 251 |
253 // If the user has overridden the update frequency, don't bother reporting | 252 // If the user has overridden the update frequency, don't bother reporting |
254 // this. | 253 // this. |
255 if (frequency_seconds_ == extensions::kDefaultUpdateFrequencySeconds) { | 254 if (frequency_seconds_ == extensions::kDefaultUpdateFrequencySeconds) { |
256 Time last = Time::FromInternalValue(prefs_->GetInt64( | 255 Time last = Time::FromInternalValue(prefs_->GetInt64( |
257 kLastExtensionsUpdateCheck)); | 256 pref_names::kLastUpdateCheck)); |
258 if (last.ToInternalValue() != 0) { | 257 if (last.ToInternalValue() != 0) { |
259 // Use counts rather than time so we can use minutes rather than millis. | 258 // Use counts rather than time so we can use minutes rather than millis. |
260 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.UpdateCheckGap", | 259 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.UpdateCheckGap", |
261 (Time::Now() - last).InMinutes(), | 260 (Time::Now() - last).InMinutes(), |
262 TimeDelta::FromSeconds(kStartupWaitSeconds).InMinutes(), | 261 TimeDelta::FromSeconds(kStartupWaitSeconds).InMinutes(), |
263 TimeDelta::FromDays(40).InMinutes(), | 262 TimeDelta::FromDays(40).InMinutes(), |
264 50); // 50 buckets seems to be the default. | 263 50); // 50 buckets seems to be the default. |
265 } | 264 } |
266 } | 265 } |
267 | 266 |
268 // Save the last check time, and schedule the next check. | 267 // Save the last check time, and schedule the next check. |
269 int64 now = Time::Now().ToInternalValue(); | 268 int64 now = Time::Now().ToInternalValue(); |
270 prefs_->SetInt64(kLastExtensionsUpdateCheck, now); | 269 prefs_->SetInt64(pref_names::kLastUpdateCheck, now); |
271 ScheduleNextCheck(TimeDelta::FromSeconds(frequency_seconds_)); | 270 ScheduleNextCheck(TimeDelta::FromSeconds(frequency_seconds_)); |
272 } | 271 } |
273 | 272 |
274 void ExtensionUpdater::CheckSoon() { | 273 void ExtensionUpdater::CheckSoon() { |
275 DCHECK(alive_); | 274 DCHECK(alive_); |
276 if (will_check_soon_) | 275 if (will_check_soon_) |
277 return; | 276 return; |
278 if (BrowserThread::PostTask( | 277 if (BrowserThread::PostTask( |
279 BrowserThread::UI, FROM_HERE, | 278 BrowserThread::UI, FROM_HERE, |
280 base::Bind(&ExtensionUpdater::DoCheckSoon, | 279 base::Bind(&ExtensionUpdater::DoCheckSoon, |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 const InProgressCheck& request = requests_in_progress_[request_id]; | 634 const InProgressCheck& request = requests_in_progress_[request_id]; |
636 if (request.in_progress_ids_.empty()) { | 635 if (request.in_progress_ids_.empty()) { |
637 VLOG(2) << "Finished update check " << request_id; | 636 VLOG(2) << "Finished update check " << request_id; |
638 if (!request.callback.is_null()) | 637 if (!request.callback.is_null()) |
639 request.callback.Run(); | 638 request.callback.Run(); |
640 requests_in_progress_.erase(request_id); | 639 requests_in_progress_.erase(request_id); |
641 } | 640 } |
642 } | 641 } |
643 | 642 |
644 } // namespace extensions | 643 } // namespace extensions |
OLD | NEW |