OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/component_updater/component_updater_service.h" | 5 #include "chrome/browser/component_updater/component_updater_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
| 19 #include "base/observer_list.h" |
19 #include "base/sequenced_task_runner.h" | 20 #include "base/sequenced_task_runner.h" |
20 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
21 #include "base/threading/sequenced_worker_pool.h" | 22 #include "base/threading/sequenced_worker_pool.h" |
22 #include "base/timer/timer.h" | 23 #include "base/timer/timer.h" |
23 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
24 #include "chrome/browser/component_updater/component_unpacker.h" | 25 #include "chrome/browser/component_updater/component_unpacker.h" |
25 #include "chrome/browser/component_updater/component_updater_ping_manager.h" | 26 #include "chrome/browser/component_updater/component_updater_ping_manager.h" |
26 #include "chrome/browser/component_updater/component_updater_utils.h" | 27 #include "chrome/browser/component_updater/component_updater_utils.h" |
27 #include "chrome/browser/component_updater/crx_downloader.h" | 28 #include "chrome/browser/component_updater/crx_downloader.h" |
28 #include "chrome/browser/component_updater/crx_update_item.h" | 29 #include "chrome/browser/component_updater/crx_update_item.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 diff_error_category(0), | 77 diff_error_category(0), |
77 diff_error_code(0), | 78 diff_error_code(0), |
78 diff_extra_code1(0) { | 79 diff_extra_code1(0) { |
79 } | 80 } |
80 | 81 |
81 CrxUpdateItem::~CrxUpdateItem() { | 82 CrxUpdateItem::~CrxUpdateItem() { |
82 } | 83 } |
83 | 84 |
84 CrxComponent::CrxComponent() | 85 CrxComponent::CrxComponent() |
85 : installer(NULL), | 86 : installer(NULL), |
86 observer(NULL), | |
87 allow_background_download(true) { | 87 allow_background_download(true) { |
88 } | 88 } |
89 | 89 |
90 CrxComponent::~CrxComponent() { | 90 CrxComponent::~CrxComponent() { |
91 } | 91 } |
92 | 92 |
93 CrxComponentInfo::CrxComponentInfo() { | 93 CrxComponentInfo::CrxComponentInfo() { |
94 } | 94 } |
95 | 95 |
96 CrxComponentInfo::~CrxComponentInfo() { | 96 CrxComponentInfo::~CrxComponentInfo() { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // There are no locks in this code, the main structure |work_items_| is mutated | 156 // There are no locks in this code, the main structure |work_items_| is mutated |
157 // only from the UI thread. The unpack and installation is done in a blocking | 157 // only from the UI thread. The unpack and installation is done in a blocking |
158 // pool thread. The network requests are done in the IO thread or in the file | 158 // pool thread. The network requests are done in the IO thread or in the file |
159 // thread. | 159 // thread. |
160 class CrxUpdateService : public ComponentUpdateService { | 160 class CrxUpdateService : public ComponentUpdateService { |
161 public: | 161 public: |
162 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 162 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
163 virtual ~CrxUpdateService(); | 163 virtual ~CrxUpdateService(); |
164 | 164 |
165 // Overrides for ComponentUpdateService. | 165 // Overrides for ComponentUpdateService. |
| 166 virtual void AddObserver(Observer* observer) OVERRIDE; |
| 167 virtual void RemoveObserver(Observer* observer) OVERRIDE; |
166 virtual Status Start() OVERRIDE; | 168 virtual Status Start() OVERRIDE; |
167 virtual Status Stop() OVERRIDE; | 169 virtual Status Stop() OVERRIDE; |
168 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 170 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
169 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | 171 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; |
170 virtual void GetComponents( | 172 virtual void GetComponents( |
171 std::vector<CrxComponentInfo>* components) OVERRIDE; | 173 std::vector<CrxComponentInfo>* components) OVERRIDE; |
172 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | 174 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( |
173 net::URLRequest* request, const std::string& crx_id) OVERRIDE; | 175 net::URLRequest* request, const std::string& crx_id) OVERRIDE; |
174 | 176 |
175 // Context for a crx download url request. | 177 // Context for a crx download url request. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 ComponentUnpacker::Error error, | 236 ComponentUnpacker::Error error, |
235 int extended_error); | 237 int extended_error); |
236 | 238 |
237 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); | 239 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); |
238 | 240 |
239 size_t ChangeItemStatus(CrxUpdateItem::Status from, | 241 size_t ChangeItemStatus(CrxUpdateItem::Status from, |
240 CrxUpdateItem::Status to); | 242 CrxUpdateItem::Status to); |
241 | 243 |
242 CrxUpdateItem* FindUpdateItemById(const std::string& id); | 244 CrxUpdateItem* FindUpdateItemById(const std::string& id); |
243 | 245 |
244 void NotifyComponentObservers(ComponentObserver::Events event, | 246 void NotifyObservers(Observer::Events event, const std::string& id); |
245 int extra) const; | |
246 | 247 |
247 bool HasOnDemandItems() const; | 248 bool HasOnDemandItems() const; |
248 | 249 |
249 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, | 250 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, |
250 const std::string& crx_id); | 251 const std::string& crx_id); |
251 | 252 |
252 scoped_ptr<ComponentUpdateService::Configurator> config_; | 253 scoped_ptr<ComponentUpdateService::Configurator> config_; |
253 | 254 |
254 scoped_ptr<UpdateChecker> update_checker_; | 255 scoped_ptr<UpdateChecker> update_checker_; |
255 | 256 |
256 scoped_ptr<PingManager> ping_manager_; | 257 scoped_ptr<PingManager> ping_manager_; |
257 | 258 |
258 scoped_refptr<ComponentUnpacker> unpacker_; | 259 scoped_refptr<ComponentUnpacker> unpacker_; |
259 | 260 |
260 scoped_ptr<CrxDownloader> crx_downloader_; | 261 scoped_ptr<CrxDownloader> crx_downloader_; |
261 | 262 |
262 // A collection of every work item. | 263 // A collection of every work item. |
263 typedef std::vector<CrxUpdateItem*> UpdateItems; | 264 typedef std::vector<CrxUpdateItem*> UpdateItems; |
264 UpdateItems work_items_; | 265 UpdateItems work_items_; |
265 | 266 |
266 base::OneShotTimer<CrxUpdateService> timer_; | 267 base::OneShotTimer<CrxUpdateService> timer_; |
267 | 268 |
268 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | 269 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
269 | 270 |
270 const Version chrome_version_; | 271 const Version chrome_version_; |
271 | 272 |
272 bool running_; | 273 bool running_; |
273 | 274 |
| 275 ObserverList<Observer> observer_list_; |
| 276 |
274 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); | 277 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); |
275 }; | 278 }; |
276 | 279 |
277 ////////////////////////////////////////////////////////////////////////////// | 280 ////////////////////////////////////////////////////////////////////////////// |
278 | 281 |
279 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) | 282 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) |
280 : config_(config), | 283 : config_(config), |
281 ping_manager_(new PingManager(config->PingUrl(), | 284 ping_manager_(new PingManager(config->PingUrl(), |
282 config->RequestContext())), | 285 config->RequestContext())), |
283 blocking_task_runner_(BrowserThread::GetBlockingPool()-> | 286 blocking_task_runner_(BrowserThread::GetBlockingPool()-> |
284 GetSequencedTaskRunnerWithShutdownBehavior( | 287 GetSequencedTaskRunnerWithShutdownBehavior( |
285 BrowserThread::GetBlockingPool()->GetSequenceToken(), | 288 BrowserThread::GetBlockingPool()->GetSequenceToken(), |
286 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 289 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
287 chrome_version_(chrome::VersionInfo().Version()), | 290 chrome_version_(chrome::VersionInfo().Version()), |
288 running_(false) { | 291 running_(false) { |
289 } | 292 } |
290 | 293 |
291 CrxUpdateService::~CrxUpdateService() { | 294 CrxUpdateService::~CrxUpdateService() { |
292 // Because we are a singleton, at this point only the UI thread should be | 295 // Because we are a singleton, at this point only the UI thread should be |
293 // alive, this simplifies the management of the work that could be in | 296 // alive, this simplifies the management of the work that could be in |
294 // flight in other threads. | 297 // flight in other threads. |
295 Stop(); | 298 Stop(); |
296 STLDeleteElements(&work_items_); | 299 STLDeleteElements(&work_items_); |
297 } | 300 } |
298 | 301 |
| 302 void CrxUpdateService::AddObserver(Observer* observer) { |
| 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 304 observer_list_.AddObserver(observer); |
| 305 } |
| 306 |
| 307 void CrxUpdateService::RemoveObserver(Observer* observer) { |
| 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 309 observer_list_.RemoveObserver(observer); |
| 310 } |
| 311 |
299 ComponentUpdateService::Status CrxUpdateService::Start() { | 312 ComponentUpdateService::Status CrxUpdateService::Start() { |
300 // Note that RegisterComponent will call Start() when the first | 313 // Note that RegisterComponent will call Start() when the first |
301 // component is registered, so it can be called twice. This way | 314 // component is registered, so it can be called twice. This way |
302 // we avoid scheduling the timer if there is no work to do. | 315 // we avoid scheduling the timer if there is no work to do. |
303 running_ = true; | 316 running_ = true; |
304 if (work_items_.empty()) | 317 if (work_items_.empty()) |
305 return kOk; | 318 return kOk; |
306 | 319 |
307 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_STARTED, 0); | 320 NotifyObservers(Observer::COMPONENT_UPDATER_STARTED, ""); |
308 | 321 |
309 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), | 322 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), |
310 this, &CrxUpdateService::ProcessPendingItems); | 323 this, &CrxUpdateService::ProcessPendingItems); |
311 return kOk; | 324 return kOk; |
312 } | 325 } |
313 | 326 |
314 // Stop the main check + update loop. In flight operations will be | 327 // Stop the main check + update loop. In flight operations will be |
315 // completed. | 328 // completed. |
316 ComponentUpdateService::Status CrxUpdateService::Stop() { | 329 ComponentUpdateService::Status CrxUpdateService::Stop() { |
317 running_ = false; | 330 running_ = false; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 break; | 375 break; |
363 case kStepDelayLong: | 376 case kStepDelayLong: |
364 delay_seconds = config_->NextCheckDelay(); | 377 delay_seconds = config_->NextCheckDelay(); |
365 break; | 378 break; |
366 } | 379 } |
367 } else { | 380 } else { |
368 delay_seconds = config_->StepDelay(); | 381 delay_seconds = config_->StepDelay(); |
369 } | 382 } |
370 | 383 |
371 if (step_delay != kStepDelayShort) { | 384 if (step_delay != kStepDelayShort) { |
372 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0); | 385 NotifyObservers(Observer::COMPONENT_UPDATER_SLEEPING, ""); |
373 | 386 |
374 // Zero is only used for unit tests. | 387 // Zero is only used for unit tests. |
375 if (0 == delay_seconds) | 388 if (0 == delay_seconds) |
376 return; | 389 return; |
377 } | 390 } |
378 | 391 |
379 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), | 392 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), |
380 this, &CrxUpdateService::ProcessPendingItems); | 393 this, &CrxUpdateService::ProcessPendingItems); |
381 } | 394 } |
382 | 395 |
(...skipping 15 matching lines...) Expand all Loading... |
398 CrxUpdateItem::Status to) { | 411 CrxUpdateItem::Status to) { |
399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
400 if (to == CrxUpdateItem::kNoUpdate || | 413 if (to == CrxUpdateItem::kNoUpdate || |
401 to == CrxUpdateItem::kUpdated || | 414 to == CrxUpdateItem::kUpdated || |
402 to == CrxUpdateItem::kUpToDate) { | 415 to == CrxUpdateItem::kUpToDate) { |
403 item->on_demand = false; | 416 item->on_demand = false; |
404 } | 417 } |
405 | 418 |
406 item->status = to; | 419 item->status = to; |
407 | 420 |
408 ComponentObserver* observer = item->component.observer; | 421 switch (to) { |
409 if (observer) { | 422 case CrxUpdateItem::kCanUpdate: |
410 switch (to) { | 423 NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); |
411 case CrxUpdateItem::kCanUpdate: | 424 break; |
412 observer->OnEvent(ComponentObserver::COMPONENT_UPDATE_FOUND, 0); | 425 case CrxUpdateItem::kUpdatingDiff: |
413 break; | 426 case CrxUpdateItem::kUpdating: |
414 case CrxUpdateItem::kUpdatingDiff: | 427 NotifyObservers(Observer::COMPONENT_UPDATE_READY, item->id); |
415 case CrxUpdateItem::kUpdating: | 428 break; |
416 observer->OnEvent(ComponentObserver::COMPONENT_UPDATE_READY, 0); | 429 case CrxUpdateItem::kUpdated: |
417 break; | 430 NotifyObservers(Observer::COMPONENT_UPDATED, item->id); |
418 case CrxUpdateItem::kUpdated: | 431 break; |
419 observer->OnEvent(ComponentObserver::COMPONENT_UPDATED, 0); | 432 case CrxUpdateItem::kUpToDate: |
420 break; | 433 case CrxUpdateItem::kNoUpdate: |
421 case CrxUpdateItem::kUpToDate: | 434 NotifyObservers(Observer::COMPONENT_NOT_UPDATED, item->id); |
422 case CrxUpdateItem::kNoUpdate: | 435 break; |
423 observer->OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0); | 436 case CrxUpdateItem::kNew: |
424 break; | 437 case CrxUpdateItem::kChecking: |
425 case CrxUpdateItem::kNew: | 438 case CrxUpdateItem::kDownloading: |
426 case CrxUpdateItem::kChecking: | 439 case CrxUpdateItem::kDownloadingDiff: |
427 case CrxUpdateItem::kDownloading: | 440 case CrxUpdateItem::kLastStatus: |
428 case CrxUpdateItem::kDownloadingDiff: | 441 // No notification for these states. |
429 case CrxUpdateItem::kLastStatus: | 442 break; |
430 // No notification for these states. | |
431 break; | |
432 } | |
433 } | 443 } |
434 | 444 |
435 // Free possible pending network requests. | 445 // Free possible pending network requests. |
436 if ((to == CrxUpdateItem::kUpdated) || | 446 if ((to == CrxUpdateItem::kUpdated) || |
437 (to == CrxUpdateItem::kUpToDate) || | 447 (to == CrxUpdateItem::kUpToDate) || |
438 (to == CrxUpdateItem::kNoUpdate)) { | 448 (to == CrxUpdateItem::kNoUpdate)) { |
439 UnblockandReapAllThrottles(&item->throttles); | 449 UnblockandReapAllThrottles(&item->throttles); |
440 } | 450 } |
441 } | 451 } |
442 | 452 |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 item->error_code = error; | 935 item->error_code = error; |
926 item->extra_code1 = extra_code; | 936 item->extra_code1 = extra_code; |
927 } | 937 } |
928 | 938 |
929 ping_manager_->OnUpdateComplete(item); | 939 ping_manager_->OnUpdateComplete(item); |
930 | 940 |
931 // Move on to the next update, if there is one available. | 941 // Move on to the next update, if there is one available. |
932 ScheduleNextRun(kStepDelayMedium); | 942 ScheduleNextRun(kStepDelayMedium); |
933 } | 943 } |
934 | 944 |
935 void CrxUpdateService::NotifyComponentObservers( | 945 void CrxUpdateService::NotifyObservers(Observer::Events event, |
936 ComponentObserver::Events event, int extra) const { | 946 const std::string& id) { |
937 for (UpdateItems::const_iterator it = work_items_.begin(); | 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
938 it != work_items_.end(); ++it) { | 948 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); |
939 ComponentObserver* observer = (*it)->component.observer; | |
940 if (observer) | |
941 observer->OnEvent(event, 0); | |
942 } | |
943 } | 949 } |
944 | 950 |
945 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( | 951 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( |
946 net::URLRequest* request, const std::string& crx_id) { | 952 net::URLRequest* request, const std::string& crx_id) { |
947 // We give the raw pointer to the caller, who will delete it at will | 953 // We give the raw pointer to the caller, who will delete it at will |
948 // and we keep for ourselves a weak pointer to it so we can post tasks | 954 // and we keep for ourselves a weak pointer to it so we can post tasks |
949 // from the UI thread without having to track lifetime directly. | 955 // from the UI thread without having to track lifetime directly. |
950 CUResourceThrottle* rt = new CUResourceThrottle(request); | 956 CUResourceThrottle* rt = new CUResourceThrottle(request); |
951 BrowserThread::PostTask( | 957 BrowserThread::PostTask( |
952 BrowserThread::UI, | 958 BrowserThread::UI, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 // The component update factory. Using the component updater as a singleton | 1015 // The component update factory. Using the component updater as a singleton |
1010 // is the job of the browser process. | 1016 // is the job of the browser process. |
1011 ComponentUpdateService* ComponentUpdateServiceFactory( | 1017 ComponentUpdateService* ComponentUpdateServiceFactory( |
1012 ComponentUpdateService::Configurator* config) { | 1018 ComponentUpdateService::Configurator* config) { |
1013 DCHECK(config); | 1019 DCHECK(config); |
1014 return new CrxUpdateService(config); | 1020 return new CrxUpdateService(config); |
1015 } | 1021 } |
1016 | 1022 |
1017 } // namespace component_updater | 1023 } // namespace component_updater |
1018 | 1024 |
OLD | NEW |