Chromium Code Reviews| 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 |