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/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 <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/at_exit.h" | 10 #include "base/at_exit.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 kChecking, | 189 kChecking, |
190 kCanUpdate, | 190 kCanUpdate, |
191 kDownloading, | 191 kDownloading, |
192 kUpdating, | 192 kUpdating, |
193 kUpdated, | 193 kUpdated, |
194 kUpToDate, | 194 kUpToDate, |
195 kNoUpdate, | 195 kNoUpdate, |
196 kLastStatus | 196 kLastStatus |
197 }; | 197 }; |
198 | 198 |
199 // A value that summarizes the result of a previously scheduled step. | |
200 // Essentially, these are the labels on the edges in the above diagram. | |
201 enum PrevStepStatus { | |
202 kPrevUnknown, | |
203 kPrevInProgress, | |
204 kPrevNoUpdate, | |
205 kPrevError, | |
206 kPrevSuccess | |
207 }; | |
208 | |
199 Status status; | 209 Status status; |
200 GURL crx_url; | 210 GURL crx_url; |
201 std::string id; | 211 std::string id; |
202 base::Time last_check; | 212 base::Time last_check; |
203 CrxComponent component; | 213 CrxComponent component; |
204 Version next_version; | 214 Version next_version; |
205 | 215 |
206 CrxUpdateItem() : status(kNew) {} | 216 CrxUpdateItem() : status(kNew) {} |
207 | 217 |
208 // Function object used to find a specific component. | 218 // Function object used to find a specific component. |
209 class FindById { | 219 class FindById { |
210 public: | 220 public: |
211 explicit FindById(const std::string& id) : id_(id) {} | 221 explicit FindById(const std::string& id) : id_(id) {} |
212 | 222 |
213 bool operator() (CrxUpdateItem* item) const { | 223 bool operator() (CrxUpdateItem* item) const { |
214 return (item->id == id_); | 224 return (item->id == id_); |
215 } | 225 } |
216 private: | 226 private: |
217 const std::string& id_; | 227 const std::string& id_; |
218 }; | 228 }; |
219 }; | 229 }; |
220 | 230 |
231 // This represents a CrxUpdateItem which a client asked to be checked ASAP. | |
232 // | |
233 // The item is initially in the "queued" state until ScheduleNextRun() | |
234 // is called again. During the next ScheduleNextRun(), it will transition to | |
235 // the "checking" state, and the service will check for an update only | |
236 // for the particular RequestedCrxUpdateItem. This interrupts the update | |
237 // cycle of other work items. | |
238 // | |
239 // When a full cycle of ScheduleNextRun()s completes successfully | |
240 // or with an error, we delete the RequestedCrxUpdateItem and resume | |
241 // the cycle of ScheduleNextRun()s for the interrupted work items. | |
242 // To accurately determine the amount of delay for resuming the interrupted | |
243 // task, we record the kind of step that was interrupted. | |
244 struct RequestedCrxUpdateItem { | |
245 enum Status { | |
246 kQueued, | |
247 kChecking | |
248 }; | |
249 | |
250 Status status; | |
251 CrxUpdateItem* item; | |
252 CrxUpdateItem::PrevStepStatus interrupted_step_status; | |
253 }; | |
254 | |
221 } // namespace. | 255 } // namespace. |
222 | 256 |
223 typedef ComponentUpdateService::Configurator Config; | 257 typedef ComponentUpdateService::Configurator Config; |
224 | 258 |
225 CrxComponent::CrxComponent() | 259 CrxComponent::CrxComponent() |
226 : installer(NULL), | 260 : installer(NULL), |
227 source(BANDAID) { | 261 source(BANDAID) { |
228 } | 262 } |
229 | 263 |
230 CrxComponent::~CrxComponent() { | 264 CrxComponent::~CrxComponent() { |
(...skipping 15 matching lines...) Expand all Loading... | |
246 class CrxUpdateService : public ComponentUpdateService { | 280 class CrxUpdateService : public ComponentUpdateService { |
247 public: | 281 public: |
248 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 282 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
249 | 283 |
250 virtual ~CrxUpdateService(); | 284 virtual ~CrxUpdateService(); |
251 | 285 |
252 // Overrides for ComponentUpdateService. | 286 // Overrides for ComponentUpdateService. |
253 virtual Status Start() OVERRIDE; | 287 virtual Status Start() OVERRIDE; |
254 virtual Status Stop() OVERRIDE; | 288 virtual Status Stop() OVERRIDE; |
255 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 289 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
290 virtual Status CheckForUpdateSoon(const CrxComponent& component) OVERRIDE; | |
256 | 291 |
257 // The only purpose of this class is to forward the | 292 // The only purpose of this class is to forward the |
258 // UtilityProcessHostClient callbacks so CrxUpdateService does | 293 // UtilityProcessHostClient callbacks so CrxUpdateService does |
259 // not have to derive from it because that is refcounted. | 294 // not have to derive from it because that is refcounted. |
260 class ManifestParserBridge : public UtilityProcessHostClient { | 295 class ManifestParserBridge : public UtilityProcessHostClient { |
261 public: | 296 public: |
262 explicit ManifestParserBridge(CrxUpdateService* service) | 297 explicit ManifestParserBridge(CrxUpdateService* service) |
263 : service_(service) {} | 298 : service_(service) {} |
264 | 299 |
265 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 300 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 const UpdateManifest::Results& results); | 351 const UpdateManifest::Results& results); |
317 | 352 |
318 // See ManifestParserBridge. | 353 // See ManifestParserBridge. |
319 void OnParseUpdateManifestFailed( | 354 void OnParseUpdateManifestFailed( |
320 const std::string& error_message); | 355 const std::string& error_message); |
321 | 356 |
322 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); | 357 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); |
323 | 358 |
324 void ProcessPendingItems(); | 359 void ProcessPendingItems(); |
325 | 360 |
326 void ScheduleNextRun(bool step_delay); | 361 void ProcessRequestedItem(); |
362 | |
363 typedef std::vector<CrxUpdateItem*> UpdateItems; | |
364 void ProcessWorkItems(const UpdateItems& work_items); | |
365 | |
366 void ScheduleNextRun(CrxUpdateItem::PrevStepStatus prev_status); | |
327 | 367 |
328 void ParseManifest(const std::string& xml); | 368 void ParseManifest(const std::string& xml); |
329 | 369 |
330 void Install(const CRXContext* context, const FilePath& crx_path); | 370 void Install(const CRXContext* context, const FilePath& crx_path); |
331 | 371 |
332 void DoneInstalling(const std::string& component_id, | 372 void DoneInstalling(const std::string& component_id, |
333 ComponentUnpacker::Error error); | 373 ComponentUnpacker::Error error); |
334 | 374 |
335 size_t ChangeItemStatus(CrxUpdateItem::Status from, | 375 size_t ChangeItemStatus(CrxUpdateItem::Status from, |
336 CrxUpdateItem::Status to); | 376 CrxUpdateItem::Status to); |
337 | 377 |
338 CrxUpdateItem* FindUpdateItemById(const std::string& id); | 378 CrxUpdateItem* FindUpdateItemById(const std::string& id); |
339 | 379 |
340 scoped_ptr<Config> config_; | 380 scoped_ptr<Config> config_; |
341 | 381 |
342 scoped_ptr<net::URLFetcher> url_fetcher_; | 382 scoped_ptr<net::URLFetcher> url_fetcher_; |
343 | 383 |
344 typedef std::vector<CrxUpdateItem*> UpdateItems; | 384 // A collection of every work item. |
345 UpdateItems work_items_; | 385 UpdateItems work_items_; |
346 | 386 |
387 // A particular work item from work_items_, which should be checked ASAP. | |
388 scoped_ptr<RequestedCrxUpdateItem> requested_work_item_; | |
389 | |
347 base::OneShotTimer<CrxUpdateService> timer_; | 390 base::OneShotTimer<CrxUpdateService> timer_; |
348 | 391 |
349 Version chrome_version_; | 392 Version chrome_version_; |
350 | 393 |
351 bool running_; | 394 bool running_; |
352 | 395 |
353 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); | 396 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); |
354 }; | 397 }; |
355 | 398 |
356 ////////////////////////////////////////////////////////////////////////////// | 399 ////////////////////////////////////////////////////////////////////////////// |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 } | 432 } |
390 | 433 |
391 // Stop the main check + update loop. In flight operations will be | 434 // Stop the main check + update loop. In flight operations will be |
392 // completed. | 435 // completed. |
393 ComponentUpdateService::Status CrxUpdateService::Stop() { | 436 ComponentUpdateService::Status CrxUpdateService::Stop() { |
394 running_ = false; | 437 running_ = false; |
395 timer_.Stop(); | 438 timer_.Stop(); |
396 return kOk; | 439 return kOk; |
397 } | 440 } |
398 | 441 |
399 // This function sets the timer which will call ProcessPendingItems() there | 442 // This function sets the timer which will call ProcessPendingItems() or |
400 // are two kind of waits, the short one (with step_delay = true) and the | 443 // ProcessRequestedItem() if there is an important requested item. There |
401 // long one. | 444 // are two kinds of waits: a short step_delay (when step_status is |
402 void CrxUpdateService::ScheduleNextRun(bool step_delay) { | 445 // kPrevInProgress) and a long one when a full check/update cycle |
446 // has completed either successfully or with an error. | |
447 void CrxUpdateService::ScheduleNextRun( | |
448 CrxUpdateItem::PrevStepStatus step_status) { | |
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
404 DCHECK(url_fetcher_.get() == NULL); | 450 DCHECK(url_fetcher_.get() == NULL); |
405 CHECK(!timer_.IsRunning()); | 451 CHECK(!timer_.IsRunning()); |
406 // It could be the case that Stop() had been called while a url request | 452 // It could be the case that Stop() had been called while a url request |
407 // or unpacking was in flight, if so we arrive here but |running_| is | 453 // or unpacking was in flight, if so we arrive here but |running_| is |
408 // false. In that case do not loop again. | 454 // false. In that case do not loop again. |
409 if (!running_) | 455 if (!running_) |
410 return; | 456 return; |
411 | 457 |
412 int64 delay = step_delay ? config_->StepDelay() : config_->NextCheckDelay(); | 458 // If there is a requested_work_item_, process just that one item |
459 // (not the others). | |
cpu_(ooo_6.6-7.5)
2013/02/05 00:04:47
this again in terms of fairness.
| |
460 if (requested_work_item_) { | |
461 switch (requested_work_item_->status) { | |
462 case RequestedCrxUpdateItem::kQueued: | |
463 requested_work_item_->interrupted_step_status = step_status; | |
464 requested_work_item_->status = RequestedCrxUpdateItem::kChecking; | |
465 timer_.Start(FROM_HERE, | |
466 base::TimeDelta::FromSeconds(config_->StepDelay()), | |
467 this, &CrxUpdateService::ProcessRequestedItem); | |
468 return; | |
469 case RequestedCrxUpdateItem::kChecking: | |
470 if (step_status == CrxUpdateItem::kPrevInProgress) { | |
471 // Keep hammering on this particular item. | |
472 timer_.Start(FROM_HERE, | |
473 base::TimeDelta::FromSeconds(config_->StepDelay()), | |
474 this, &CrxUpdateService::ProcessRequestedItem); | |
475 return; | |
476 } else { | |
477 // This particular item either finished successfully or hit an error. | |
478 switch (step_status) { | |
479 case CrxUpdateItem::kPrevSuccess: | |
480 content::NotificationService::current()->Notify( | |
481 chrome::NOTIFICATION_COMPONENT_UPDATE_COMPLETE, | |
cpu_(ooo_6.6-7.5)
2013/02/05 00:04:47
not sure we need this one, I mean the installer go
jvoung (off chromium)
2013/02/05 00:17:56
I imagine that it is the "thing" that called Check
cpu_(ooo_6.6-7.5)
2013/02/06 22:25:32
That would be ideal, that way you don't have to ha
jvoung (off chromium)
2013/02/11 21:04:26
Alright, removed the use of notification service.
| |
482 content::Source<std::string>(&requested_work_item_->item->id), | |
483 content::NotificationService::NoDetails()); | |
484 break; | |
485 case CrxUpdateItem::kPrevNoUpdate: | |
486 content::NotificationService::current()->Notify( | |
487 chrome::NOTIFICATION_COMPONENT_UPDATE_NOT_UPDATED, | |
488 content::Source<std::string>(&requested_work_item_->item->id), | |
489 content::NotificationService::NoDetails()); | |
490 break; | |
491 case CrxUpdateItem::kPrevError: | |
492 content::NotificationService::current()->Notify( | |
493 chrome::NOTIFICATION_COMPONENT_UPDATE_FAILED, | |
494 content::Source<std::string>(&requested_work_item_->item->id), | |
495 content::NotificationService::NoDetails()); | |
496 break; | |
497 default: | |
498 NOTREACHED() << "Unexpected step status: " << step_status; | |
499 } | |
500 // Delete the requested item and proceed. | |
501 step_status = requested_work_item_->interrupted_step_status; | |
502 DCHECK(step_status != CrxUpdateItem::kPrevUnknown); | |
503 requested_work_item_.reset(NULL); | |
504 // fall through | |
505 } | |
506 } | |
507 } | |
413 | 508 |
414 if (!step_delay) { | 509 int64 delay = (step_status == CrxUpdateItem::kPrevInProgress) |
510 ? config_->StepDelay() : config_->NextCheckDelay(); | |
511 | |
512 if (step_status != CrxUpdateItem::kPrevInProgress) { | |
415 content::NotificationService::current()->Notify( | 513 content::NotificationService::current()->Notify( |
416 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, | 514 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, |
417 content::Source<ComponentUpdateService>(this), | 515 content::Source<ComponentUpdateService>(this), |
418 content::NotificationService::NoDetails()); | 516 content::NotificationService::NoDetails()); |
419 // Zero is only used for unit tests. | 517 // Zero is only used for unit tests. |
420 if (0 == delay) | 518 if (0 == delay) |
421 return; | 519 return; |
422 } | 520 } |
423 | 521 |
424 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay), | 522 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 std::string* query) { | 594 std::string* query) { |
497 if (!AddQueryString(item->id, | 595 if (!AddQueryString(item->id, |
498 item->component.version.GetString(), | 596 item->component.version.GetString(), |
499 config_->UrlSizeLimit(), query)) | 597 config_->UrlSizeLimit(), query)) |
500 return false; | 598 return false; |
501 item->status = CrxUpdateItem::kChecking; | 599 item->status = CrxUpdateItem::kChecking; |
502 item->last_check = base::Time::Now(); | 600 item->last_check = base::Time::Now(); |
503 return true; | 601 return true; |
504 } | 602 } |
505 | 603 |
506 // Here is where the work gets scheduled. Given that our |work_items_| list | 604 // Here is where the work gets scheduled. |
605 void CrxUpdateService::ProcessPendingItems() { | |
606 ProcessWorkItems(work_items_); | |
607 } | |
608 | |
609 void CrxUpdateService::ProcessRequestedItem() { | |
610 UpdateItems one_item; | |
611 one_item.push_back(requested_work_item_->item); | |
612 ProcessWorkItems(one_item); | |
613 } | |
614 | |
615 // Start the process of checking for an update, for a particular component | |
616 // that was previously registered. If the component does not exist return | |
617 // kError, otherwise kOk. | |
618 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon( | |
619 const CrxComponent& component) { | |
620 if (component.pk_hash.empty() || | |
621 !component.version.IsValid() || | |
622 !component.installer) | |
623 return kError; | |
624 | |
625 std::string id = | |
626 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], | |
627 component.pk_hash.size()/2))); | |
628 | |
629 CrxUpdateItem* uit; | |
630 uit = FindUpdateItemById(id); | |
631 if (!uit) | |
632 return kError; | |
633 | |
634 // There is already a request submitted. | |
635 if (requested_work_item_) { | |
636 return kInProgress; | |
637 } | |
cpu_(ooo_6.6-7.5)
2013/02/05 00:04:47
hmm, we are trying to be fair here with all the co
jvoung (off chromium)
2013/02/05 00:17:56
Should the effect of the CL not be to "cut in line
cpu_(ooo_6.6-7.5)
2013/02/06 22:25:32
Yeah, until the component changes from kNew
jvoung (off chromium)
2013/02/11 21:04:26
Done.
| |
638 | |
639 requested_work_item_.reset(new RequestedCrxUpdateItem()); | |
640 requested_work_item_->status = RequestedCrxUpdateItem::kQueued; | |
641 requested_work_item_->item = uit; | |
642 requested_work_item_->interrupted_step_status = CrxUpdateItem::kPrevUnknown; | |
643 | |
644 // If the delay is long, try to set the timer to a shorter value | |
645 // to get the ball rolling. | |
646 if (timer_.IsRunning()) { | |
647 base::TimeDelta remaining_delay = | |
648 timer_.desired_run_time() - base::TimeTicks::Now(); | |
649 base::TimeDelta step_delay = | |
650 base::TimeDelta::FromSeconds(config_->StepDelay()); | |
651 if (remaining_delay > step_delay) { | |
652 timer_.Stop(); | |
653 // The only task it could have interrupted was a call to | |
654 // ProcessPendingItems, not ProcessRequestedItem. | |
cpu_(ooo_6.6-7.5)
2013/02/05 00:04:47
assuming that the config_ object returns constant
jvoung (off chromium)
2013/02/05 00:17:56
The step_delay that is saved to the variable is th
cpu_(ooo_6.6-7.5)
2013/02/06 22:25:32
Yes, that would be best.
jvoung (off chromium)
2013/02/11 21:04:26
Done.
| |
655 timer_.Start(FROM_HERE, step_delay, | |
656 this, &CrxUpdateService::ProcessPendingItems); | |
657 } | |
658 } | |
659 | |
660 return kOk; | |
661 } | |
662 | |
663 // Here is where the work gets scheduled. Given that our |work_items| list | |
507 // is expected to be ten or less items, we simply loop several times. | 664 // is expected to be ten or less items, we simply loop several times. |
508 void CrxUpdateService::ProcessPendingItems() { | 665 void CrxUpdateService::ProcessWorkItems(const UpdateItems& work_items) { |
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
510 // First check for ready upgrades and do one. The first | 667 // First check for ready upgrades and do one. The first |
511 // step is to fetch the crx package. | 668 // step is to fetch the crx package. |
512 for (UpdateItems::const_iterator it = work_items_.begin(); | 669 for (UpdateItems::const_iterator it = work_items.begin(); |
513 it != work_items_.end(); ++it) { | 670 it != work_items.end(); ++it) { |
514 CrxUpdateItem* item = *it; | 671 CrxUpdateItem* item = *it; |
515 if (item->status != CrxUpdateItem::kCanUpdate) | 672 if (item->status != CrxUpdateItem::kCanUpdate) |
516 continue; | 673 continue; |
517 // Found component to update, start the process. | 674 // Found component to update, start the process. |
518 item->status = CrxUpdateItem::kDownloading; | 675 item->status = CrxUpdateItem::kDownloading; |
519 CRXContext* context = new CRXContext; | 676 CRXContext* context = new CRXContext; |
520 context->pk_hash = item->component.pk_hash; | 677 context->pk_hash = item->component.pk_hash; |
521 context->id = item->id; | 678 context->id = item->id; |
522 context->installer = item->component.installer; | 679 context->installer = item->component.installer; |
523 url_fetcher_.reset(net::URLFetcher::Create( | 680 url_fetcher_.reset(net::URLFetcher::Create( |
524 0, item->crx_url, net::URLFetcher::GET, | 681 0, item->crx_url, net::URLFetcher::GET, |
525 MakeContextDelegate(this, context))); | 682 MakeContextDelegate(this, context))); |
526 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); | 683 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); |
527 return; | 684 return; |
528 } | 685 } |
529 | 686 |
530 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { | 687 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { |
531 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; | 688 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; |
532 | 689 |
533 std::string query; | 690 std::string query; |
534 // If no pending upgrades, we check if there are new components we have not | 691 // If no pending upgrades, we check if there are new components we have not |
535 // checked against the server. We can batch some in a single url request. | 692 // checked against the server. We can batch some in a single url request. |
536 for (UpdateItems::const_iterator it = work_items_.begin(); | 693 for (UpdateItems::const_iterator it = work_items.begin(); |
537 it != work_items_.end(); ++it) { | 694 it != work_items.end(); ++it) { |
538 CrxUpdateItem* item = *it; | 695 CrxUpdateItem* item = *it; |
539 if (item->status != CrxUpdateItem::kNew) | 696 if (item->status != CrxUpdateItem::kNew) |
540 continue; | 697 continue; |
541 if (item->component.source != manifest_source) | 698 if (item->component.source != manifest_source) |
542 continue; | 699 continue; |
543 if (!AddItemToUpdateCheck(item, &query)) | 700 if (!AddItemToUpdateCheck(item, &query)) |
544 break; | 701 break; |
545 } | 702 } |
546 | 703 |
547 // Next we can go back to components we already checked, here | 704 // Next we can go back to components we already checked, here |
548 // we can also batch them in a single url request, as long as | 705 // we can also batch them in a single url request, as long as |
549 // we have not checked them recently. | 706 // we have not checked them recently. |
550 const base::TimeDelta min_delta_time = | 707 const base::TimeDelta min_delta_time = |
551 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); | 708 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); |
552 | 709 |
553 for (UpdateItems::const_iterator it = work_items_.begin(); | 710 for (UpdateItems::const_iterator it = work_items.begin(); |
554 it != work_items_.end(); ++it) { | 711 it != work_items.end(); ++it) { |
555 CrxUpdateItem* item = *it; | 712 CrxUpdateItem* item = *it; |
556 if ((item->status != CrxUpdateItem::kNoUpdate) && | 713 if ((item->status != CrxUpdateItem::kNoUpdate) && |
557 (item->status != CrxUpdateItem::kUpToDate)) | 714 (item->status != CrxUpdateItem::kUpToDate)) |
558 continue; | 715 continue; |
559 if (item->component.source != manifest_source) | 716 if (item->component.source != manifest_source) |
560 continue; | 717 continue; |
561 base::TimeDelta delta = base::Time::Now() - item->last_check; | 718 base::TimeDelta delta = base::Time::Now() - item->last_check; |
562 if (delta < min_delta_time) | 719 if (delta < min_delta_time) |
563 continue; | 720 continue; |
564 if (!AddItemToUpdateCheck(item, &query)) | 721 if (!AddItemToUpdateCheck(item, &query)) |
565 break; | 722 break; |
566 } | 723 } |
567 | 724 |
568 // Finally, we check components that we already updated as long as | 725 // Finally, we check components that we already updated as long as |
569 // we have not checked them recently. | 726 // we have not checked them recently. |
570 for (UpdateItems::const_iterator it = work_items_.begin(); | 727 for (UpdateItems::const_iterator it = work_items.begin(); |
571 it != work_items_.end(); ++it) { | 728 it != work_items.end(); ++it) { |
572 CrxUpdateItem* item = *it; | 729 CrxUpdateItem* item = *it; |
573 if (item->status != CrxUpdateItem::kUpdated) | 730 if (item->status != CrxUpdateItem::kUpdated) |
574 continue; | 731 continue; |
575 if (item->component.source != manifest_source) | 732 if (item->component.source != manifest_source) |
576 continue; | 733 continue; |
577 base::TimeDelta delta = base::Time::Now() - item->last_check; | 734 base::TimeDelta delta = base::Time::Now() - item->last_check; |
578 if (delta < min_delta_time) | 735 if (delta < min_delta_time) |
579 continue; | 736 continue; |
580 if (!AddItemToUpdateCheck(item, &query)) | 737 if (!AddItemToUpdateCheck(item, &query)) |
581 break; | 738 break; |
(...skipping 10 matching lines...) Expand all Loading... | |
592 config_->ExtraRequestParams()); | 749 config_->ExtraRequestParams()); |
593 | 750 |
594 url_fetcher_.reset(net::URLFetcher::Create( | 751 url_fetcher_.reset(net::URLFetcher::Create( |
595 0, GURL(full_query), net::URLFetcher::GET, | 752 0, GURL(full_query), net::URLFetcher::GET, |
596 MakeContextDelegate(this, new UpdateContext()))); | 753 MakeContextDelegate(this, new UpdateContext()))); |
597 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); | 754 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); |
598 return; | 755 return; |
599 } | 756 } |
600 | 757 |
601 // No components to update. Next check after the long sleep. | 758 // No components to update. Next check after the long sleep. |
602 ScheduleNextRun(false); | 759 ScheduleNextRun(CrxUpdateItem::kPrevNoUpdate); |
603 } | 760 } |
604 | 761 |
605 // Caled when we got a response from the update server. It consists of an xml | 762 // Called when we got a response from the update server. It consists of an xml |
606 // document following the omaha update scheme. | 763 // document following the omaha update scheme. |
607 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, | 764 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, |
608 UpdateContext* context) { | 765 UpdateContext* context) { |
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 766 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
610 if (FetchSuccess(*source)) { | 767 if (FetchSuccess(*source)) { |
611 std::string xml; | 768 std::string xml; |
612 source->GetResponseAsString(&xml); | 769 source->GetResponseAsString(&xml); |
613 url_fetcher_.reset(); | 770 url_fetcher_.reset(); |
614 ParseManifest(xml); | 771 ParseManifest(xml); |
615 } else { | 772 } else { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, | 844 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, |
688 content::Source<std::string>(&crx->id), | 845 content::Source<std::string>(&crx->id), |
689 content::NotificationService::NoDetails()); | 846 content::NotificationService::NoDetails()); |
690 } | 847 } |
691 | 848 |
692 // All the components that are not mentioned in the manifest we | 849 // All the components that are not mentioned in the manifest we |
693 // consider them up to date. | 850 // consider them up to date. |
694 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); | 851 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); |
695 | 852 |
696 // If there are updates pending we do a short wait. | 853 // If there are updates pending we do a short wait. |
697 ScheduleNextRun(update_pending > 0); | 854 ScheduleNextRun(update_pending > 0 |
855 ? CrxUpdateItem::kPrevInProgress | |
856 : CrxUpdateItem::kPrevNoUpdate); | |
698 } | 857 } |
699 | 858 |
700 void CrxUpdateService::OnParseUpdateManifestFailed( | 859 void CrxUpdateService::OnParseUpdateManifestFailed( |
701 const std::string& error_message) { | 860 const std::string& error_message) { |
702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 861 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
703 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, | 862 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, |
704 CrxUpdateItem::kNoUpdate); | 863 CrxUpdateItem::kNoUpdate); |
705 config_->OnEvent(Configurator::kManifestError, static_cast<int>(count)); | 864 config_->OnEvent(Configurator::kManifestError, static_cast<int>(count)); |
706 DCHECK_GT(count, 0ul); | 865 DCHECK_GT(count, 0ul); |
707 ScheduleNextRun(false); | 866 ScheduleNextRun(CrxUpdateItem::kPrevError); |
708 } | 867 } |
709 | 868 |
710 // Called when the CRX package has been downloaded to a temporary location. | 869 // Called when the CRX package has been downloaded to a temporary location. |
711 // Here we fire the notifications and schedule the component-specific installer | 870 // Here we fire the notifications and schedule the component-specific installer |
712 // to be called in the file thread. | 871 // to be called in the file thread. |
713 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, | 872 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, |
714 CRXContext* context) { | 873 CRXContext* context) { |
715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 874 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
716 base::PlatformFileError error_code; | 875 base::PlatformFileError error_code; |
717 | 876 |
718 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { | 877 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { |
719 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, | 878 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, |
720 CrxUpdateItem::kNoUpdate); | 879 CrxUpdateItem::kNoUpdate); |
721 DCHECK_EQ(count, 1ul); | 880 DCHECK_EQ(count, 1ul); |
722 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id)); | 881 config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id)); |
723 url_fetcher_.reset(); | 882 url_fetcher_.reset(); |
724 ScheduleNextRun(false); | 883 ScheduleNextRun(CrxUpdateItem::kPrevError); |
725 } else { | 884 } else { |
726 FilePath temp_crx_path; | 885 FilePath temp_crx_path; |
727 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); | 886 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); |
728 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, | 887 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, |
729 CrxUpdateItem::kUpdating); | 888 CrxUpdateItem::kUpdating); |
730 DCHECK_EQ(count, 1ul); | 889 DCHECK_EQ(count, 1ul); |
731 url_fetcher_.reset(); | 890 url_fetcher_.reset(); |
732 | 891 |
733 content::NotificationService::current()->Notify( | 892 content::NotificationService::current()->Notify( |
734 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, | 893 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
789 break; | 948 break; |
790 case ComponentUnpacker::kInstallerError: | 949 case ComponentUnpacker::kInstallerError: |
791 event = Configurator::kInstallerError; | 950 event = Configurator::kInstallerError; |
792 break; | 951 break; |
793 default: | 952 default: |
794 event = Configurator::kUnpackError; | 953 event = Configurator::kUnpackError; |
795 break; | 954 break; |
796 } | 955 } |
797 | 956 |
798 config_->OnEvent(event, CrxIdtoUMAId(component_id)); | 957 config_->OnEvent(event, CrxIdtoUMAId(component_id)); |
799 ScheduleNextRun(false); | 958 ScheduleNextRun(error == ComponentUnpacker::kNone |
959 ? CrxUpdateItem::kPrevSuccess | |
960 : CrxUpdateItem::kPrevError); | |
800 } | 961 } |
801 | 962 |
802 // The component update factory. Using the component updater as a singleton | 963 // The component update factory. Using the component updater as a singleton |
803 // is the job of the browser process. | 964 // is the job of the browser process. |
804 ComponentUpdateService* ComponentUpdateServiceFactory( | 965 ComponentUpdateService* ComponentUpdateServiceFactory( |
805 ComponentUpdateService::Configurator* config) { | 966 ComponentUpdateService::Configurator* config) { |
806 DCHECK(config); | 967 DCHECK(config); |
807 return new CrxUpdateService(config); | 968 return new CrxUpdateService(config); |
808 } | 969 } |
OLD | NEW |