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/webstore_installer.h" | 5 #include "chrome/browser/extensions/webstore_installer.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 } | 332 } |
333 | 333 |
334 void WebstoreInstaller::Observe(int type, | 334 void WebstoreInstaller::Observe(int type, |
335 const content::NotificationSource& source, | 335 const content::NotificationSource& source, |
336 const content::NotificationDetails& details) { | 336 const content::NotificationDetails& details) { |
337 switch (type) { | 337 switch (type) { |
338 case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { | 338 case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { |
339 const Extension* extension = | 339 const Extension* extension = |
340 content::Details<const Extension>(details).ptr(); | 340 content::Details<const Extension>(details).ptr(); |
341 CrxInstaller* installer = content::Source<CrxInstaller>(source).ptr(); | 341 CrxInstaller* installer = content::Source<CrxInstaller>(source).ptr(); |
342 if (extension == NULL && download_item_ != NULL && | 342 if (crx_installer_.get() == installer) { |
343 installer->download_url() == download_item_->GetURL() && | 343 crx_installer_ = NULL; |
344 installer->profile()->IsSameProfile(profile_)) { | 344 // ReportFailure releases a reference to this object so it must be the |
345 ReportFailure(kInstallCanceledError, FAILURE_REASON_CANCELLED); | 345 // last operation in this method. |
| 346 if (extension == NULL) |
| 347 ReportFailure(kInstallCanceledError, FAILURE_REASON_CANCELLED); |
346 } | 348 } |
347 break; | 349 break; |
348 } | 350 } |
349 | 351 |
350 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { | 352 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { |
351 CHECK(profile_->IsSameProfile(content::Source<Profile>(source).ptr())); | 353 CHECK(profile_->IsSameProfile(content::Source<Profile>(source).ptr())); |
352 const Extension* extension = | 354 const Extension* extension = |
353 content::Details<const InstalledExtensionInfo>(details)->extension; | 355 content::Details<const InstalledExtensionInfo>(details)->extension; |
354 if (pending_modules_.empty()) | 356 if (pending_modules_.empty()) |
355 return; | 357 return; |
(...skipping 21 matching lines...) Expand all Loading... |
377 } else { | 379 } else { |
378 DownloadNextPendingModule(); | 380 DownloadNextPendingModule(); |
379 } | 381 } |
380 } | 382 } |
381 break; | 383 break; |
382 } | 384 } |
383 | 385 |
384 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { | 386 case chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR: { |
385 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); | 387 CrxInstaller* crx_installer = content::Source<CrxInstaller>(source).ptr(); |
386 CHECK(crx_installer); | 388 CHECK(crx_installer); |
387 if (!profile_->IsSameProfile(crx_installer->profile())) | 389 if (crx_installer != crx_installer_.get()) |
388 return; | 390 return; |
389 | 391 |
390 // TODO(rdevlin.cronin): Continue removing std::string errors and | 392 // TODO(rdevlin.cronin): Continue removing std::string errors and |
391 // replacing with base::string16. See crbug.com/71980. | 393 // replacing with base::string16. See crbug.com/71980. |
392 const base::string16* error = | 394 const base::string16* error = |
393 content::Details<const base::string16>(details).ptr(); | 395 content::Details<const base::string16>(details).ptr(); |
394 const std::string utf8_error = base::UTF16ToUTF8(*error); | 396 const std::string utf8_error = base::UTF16ToUTF8(*error); |
395 if (download_url_ == crx_installer->original_download_url()) | 397 crx_installer_ = NULL; |
396 ReportFailure(utf8_error, FAILURE_REASON_OTHER); | 398 // ReportFailure releases a reference to this object so it must be the |
| 399 // last operation in this method. |
| 400 ReportFailure(utf8_error, FAILURE_REASON_OTHER); |
397 break; | 401 break; |
398 } | 402 } |
399 | 403 |
400 default: | 404 default: |
401 NOTREACHED(); | 405 NOTREACHED(); |
402 } | 406 } |
403 } | 407 } |
404 | 408 |
405 void WebstoreInstaller::InvalidateDelegate() { | 409 void WebstoreInstaller::InvalidateDelegate() { |
406 delegate_ = NULL; | 410 delegate_ = NULL; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 ReportFailure(kDownloadCanceledError, FAILURE_REASON_CANCELLED); | 470 ReportFailure(kDownloadCanceledError, FAILURE_REASON_CANCELLED); |
467 break; | 471 break; |
468 case DownloadItem::INTERRUPTED: | 472 case DownloadItem::INTERRUPTED: |
469 RecordInterrupt(download); | 473 RecordInterrupt(download); |
470 ReportFailure(kDownloadInterruptedError, FAILURE_REASON_OTHER); | 474 ReportFailure(kDownloadInterruptedError, FAILURE_REASON_OTHER); |
471 break; | 475 break; |
472 case DownloadItem::COMPLETE: | 476 case DownloadItem::COMPLETE: |
473 // Wait for other notifications if the download is really an extension. | 477 // Wait for other notifications if the download is really an extension. |
474 if (!download_crx_util::IsExtensionDownload(*download)) { | 478 if (!download_crx_util::IsExtensionDownload(*download)) { |
475 ReportFailure(kInvalidDownloadError, FAILURE_REASON_OTHER); | 479 ReportFailure(kInvalidDownloadError, FAILURE_REASON_OTHER); |
476 } else if (pending_modules_.empty()) { | 480 } else { |
477 // The download is the last module - the extension main module. | 481 if (crx_installer_.get()) |
478 if (delegate_) | 482 return; // DownloadItemImpl calls the observer twice, ignore it. |
479 delegate_->OnExtensionDownloadProgress(id_, download); | 483 StartCrxInstaller(*download); |
480 extensions::InstallTracker* tracker = | 484 |
481 extensions::InstallTrackerFactory::GetForProfile(profile_); | 485 if (pending_modules_.empty()) { |
482 tracker->OnDownloadProgress(id_, 100); | 486 // The download is the last module - the extension main module. |
| 487 if (delegate_) |
| 488 delegate_->OnExtensionDownloadProgress(id_, download); |
| 489 extensions::InstallTracker* tracker = |
| 490 extensions::InstallTrackerFactory::GetForProfile(profile_); |
| 491 tracker->OnDownloadProgress(id_, 100); |
| 492 } |
483 } | 493 } |
484 // Stop the progress timer if it's running. | 494 // Stop the progress timer if it's running. |
485 download_progress_timer_.Stop(); | 495 download_progress_timer_.Stop(); |
486 break; | 496 break; |
487 case DownloadItem::IN_PROGRESS: { | 497 case DownloadItem::IN_PROGRESS: { |
488 if (delegate_ && pending_modules_.size() == 1) { | 498 if (delegate_ && pending_modules_.size() == 1) { |
489 // Only report download progress for the main module to |delegrate_|. | 499 // Only report download progress for the main module to |delegrate_|. |
490 delegate_->OnExtensionDownloadProgress(id_, download); | 500 delegate_->OnExtensionDownloadProgress(id_, download); |
491 } | 501 } |
492 UpdateDownloadProgress(); | 502 UpdateDownloadProgress(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 download_progress_timer_.Start( | 655 download_progress_timer_.Start( |
646 FROM_HERE, | 656 FROM_HERE, |
647 base::TimeDelta::FromSeconds(kTimeRemainingMinutesThreshold), | 657 base::TimeDelta::FromSeconds(kTimeRemainingMinutesThreshold), |
648 this, | 658 this, |
649 &WebstoreInstaller::UpdateDownloadProgress); | 659 &WebstoreInstaller::UpdateDownloadProgress); |
650 } else { | 660 } else { |
651 download_progress_timer_.Stop(); | 661 download_progress_timer_.Stop(); |
652 } | 662 } |
653 } | 663 } |
654 | 664 |
| 665 void WebstoreInstaller::StartCrxInstaller(const DownloadItem& download) { |
| 666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 667 DCHECK(!crx_installer_.get()); |
| 668 |
| 669 ExtensionService* service = ExtensionSystem::Get(profile_)-> |
| 670 extension_service(); |
| 671 CHECK(service); |
| 672 |
| 673 const Approval* approval = GetAssociatedApproval(download); |
| 674 DCHECK(approval); |
| 675 |
| 676 crx_installer_ = download_crx_util::CreateCrxInstaller(profile_, download); |
| 677 |
| 678 crx_installer_->set_expected_id(approval->extension_id); |
| 679 crx_installer_->set_is_gallery_install(true); |
| 680 crx_installer_->set_allow_silent_install(true); |
| 681 |
| 682 crx_installer_->InstallCrx(download.GetFullPath()); |
| 683 } |
| 684 |
655 void WebstoreInstaller::ReportFailure(const std::string& error, | 685 void WebstoreInstaller::ReportFailure(const std::string& error, |
656 FailureReason reason) { | 686 FailureReason reason) { |
657 if (delegate_) { | 687 if (delegate_) { |
658 delegate_->OnExtensionInstallFailure(id_, error, reason); | 688 delegate_->OnExtensionInstallFailure(id_, error, reason); |
659 delegate_ = NULL; | 689 delegate_ = NULL; |
660 } | 690 } |
661 | 691 |
662 extensions::InstallTracker* tracker = | 692 extensions::InstallTracker* tracker = |
663 extensions::InstallTrackerFactory::GetForProfile(profile_); | 693 extensions::InstallTrackerFactory::GetForProfile(profile_); |
664 tracker->OnInstallFailure(id_); | 694 tracker->OnInstallFailure(id_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 1, | 726 1, |
697 kMaxSizeKb, | 727 kMaxSizeKb, |
698 kNumBuckets); | 728 kNumBuckets); |
699 } | 729 } |
700 UMA_HISTOGRAM_BOOLEAN( | 730 UMA_HISTOGRAM_BOOLEAN( |
701 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown", | 731 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown", |
702 total_bytes <= 0); | 732 total_bytes <= 0); |
703 } | 733 } |
704 | 734 |
705 } // namespace extensions | 735 } // namespace extensions |
OLD | NEW |