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