| 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/crx_installer.h" | 5 #include "chrome/browser/extensions/crx_installer.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 16 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
| 19 #include "base/threading/sequenced_worker_pool.h" |
| 19 #include "base/threading/thread_restrictions.h" | 20 #include "base/threading/thread_restrictions.h" |
| 20 #include "base/time.h" | 21 #include "base/time.h" |
| 21 #include "base/threading/sequenced_worker_pool.h" | |
| 22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 23 #include "base/version.h" | 23 #include "base/version.h" |
| 24 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
| 25 #include "chrome/browser/extensions/convert_user_script.h" | 25 #include "chrome/browser/extensions/convert_user_script.h" |
| 26 #include "chrome/browser/extensions/convert_web_app.h" | 26 #include "chrome/browser/extensions/convert_web_app.h" |
| 27 #include "chrome/browser/extensions/extension_error_reporter.h" | 27 #include "chrome/browser/extensions/extension_error_reporter.h" |
| 28 #include "chrome/browser/extensions/extension_install_ui.h" | 28 #include "chrome/browser/extensions/extension_install_ui.h" |
| 29 #include "chrome/browser/extensions/extension_install_ui_default.h" |
| 29 #include "chrome/browser/extensions/extension_service.h" | 30 #include "chrome/browser/extensions/extension_service.h" |
| 30 #include "chrome/browser/extensions/extension_system.h" | 31 #include "chrome/browser/extensions/extension_system.h" |
| 31 #include "chrome/browser/extensions/management_policy.h" | 32 #include "chrome/browser/extensions/management_policy.h" |
| 32 #include "chrome/browser/extensions/permissions_updater.h" | 33 #include "chrome/browser/extensions/permissions_updater.h" |
| 33 #include "chrome/browser/extensions/requirements_checker.h" | 34 #include "chrome/browser/extensions/requirements_checker.h" |
| 34 #include "chrome/browser/extensions/webstore_installer.h" | 35 #include "chrome/browser/extensions/webstore_installer.h" |
| 35 #include "chrome/browser/profiles/profile.h" | 36 #include "chrome/browser/profiles/profile.h" |
| 36 #include "chrome/browser/shell_integration.h" | 37 #include "chrome/browser/shell_integration.h" |
| 37 #include "chrome/browser/web_applications/web_app.h" | 38 #include "chrome/browser/web_applications/web_app.h" |
| 38 #include "chrome/common/chrome_notification_types.h" | 39 #include "chrome/common/chrome_notification_types.h" |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 ExtensionService::RecordPermissionMessagesHistogram( | 479 ExtensionService::RecordPermissionMessagesHistogram( |
| 479 extension_, histogram_name.c_str()); | 480 extension_, histogram_name.c_str()); |
| 480 | 481 |
| 481 // Kill the theme loading bubble. | 482 // Kill the theme loading bubble. |
| 482 content::NotificationService* service = | 483 content::NotificationService* service = |
| 483 content::NotificationService::current(); | 484 content::NotificationService::current(); |
| 484 service->Notify(chrome::NOTIFICATION_NO_THEME_DETECTED, | 485 service->Notify(chrome::NOTIFICATION_NO_THEME_DETECTED, |
| 485 content::Source<CrxInstaller>(this), | 486 content::Source<CrxInstaller>(this), |
| 486 content::NotificationService::NoDetails()); | 487 content::NotificationService::NoDetails()); |
| 487 | 488 |
| 488 NotifyCrxInstallComplete(NULL); | 489 NotifyCrxInstallComplete(false); |
| 489 | 490 |
| 490 Release(); // balanced in ConfirmInstall(). | 491 Release(); // balanced in ConfirmInstall(). |
| 491 | 492 |
| 492 // We're done. Since we don't post any more tasks to ourself, our ref count | 493 // We're done. Since we don't post any more tasks to ourself, our ref count |
| 493 // should go to zero and we die. The destructor will clean up the temp dir. | 494 // should go to zero and we die. The destructor will clean up the temp dir. |
| 494 } | 495 } |
| 495 | 496 |
| 496 void CrxInstaller::CompleteInstall() { | 497 void CrxInstaller::CompleteInstall() { |
| 497 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); | 498 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); |
| 498 | 499 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 // see errors get reported via this interface. | 575 // see errors get reported via this interface. |
| 575 // | 576 // |
| 576 // TODO(aa): Need to go through unit tests and clean them up too, probably get | 577 // TODO(aa): Need to go through unit tests and clean them up too, probably get |
| 577 // rid of this line. | 578 // rid of this line. |
| 578 ExtensionErrorReporter::GetInstance()->ReportError( | 579 ExtensionErrorReporter::GetInstance()->ReportError( |
| 579 error.message(), false); // quiet | 580 error.message(), false); // quiet |
| 580 | 581 |
| 581 if (client_) | 582 if (client_) |
| 582 client_->OnInstallFailure(error); | 583 client_->OnInstallFailure(error); |
| 583 | 584 |
| 584 NotifyCrxInstallComplete(NULL); | 585 NotifyCrxInstallComplete(false); |
| 585 | 586 |
| 586 // Delete temporary files. | 587 // Delete temporary files. |
| 587 CleanupTempFiles(); | 588 CleanupTempFiles(); |
| 588 } | 589 } |
| 589 | 590 |
| 590 void CrxInstaller::ReportSuccessFromFileThread() { | 591 void CrxInstaller::ReportSuccessFromFileThread() { |
| 591 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); | 592 DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); |
| 592 | 593 |
| 593 // Tracking number of extensions installed by users | 594 // Tracking number of extensions installed by users |
| 594 if (install_cause() == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) | 595 if (install_cause() == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 618 record_oauth2_grant_ = client_->record_oauth2_grant(); | 619 record_oauth2_grant_ = client_->record_oauth2_grant(); |
| 619 | 620 |
| 620 // We update the extension's granted permissions if the user already approved | 621 // We update the extension's granted permissions if the user already approved |
| 621 // the install (client_ is non NULL), or we are allowed to install this | 622 // the install (client_ is non NULL), or we are allowed to install this |
| 622 // silently. | 623 // silently. |
| 623 if (client_ || allow_silent_install_) { | 624 if (client_ || allow_silent_install_) { |
| 624 PermissionsUpdater perms_updater(profile()); | 625 PermissionsUpdater perms_updater(profile()); |
| 625 perms_updater.GrantActivePermissions(extension_, record_oauth2_grant_); | 626 perms_updater.GrantActivePermissions(extension_, record_oauth2_grant_); |
| 626 } | 627 } |
| 627 | 628 |
| 628 // Tell the frontend about the installation and hand off ownership of | 629 // Install the extension if it's not blacklisted, but notify either way. |
| 629 // extension_ to it. | 630 ExtensionSystem::Get(profile_)->blacklist()->IsBlacklisted( |
| 630 frontend_weak_->OnExtensionInstalled(extension_, | 631 extension_->id(), |
| 631 page_ordinal_, | 632 base::Bind(&CrxInstaller::HandleIsBlacklistedResponse, |
| 632 has_requirement_errors_, | 633 this, |
| 633 install_wait_for_idle_); | 634 base::Bind(&ExtensionService::OnExtensionInstalled, |
| 634 | 635 frontend_weak_, |
| 635 NotifyCrxInstallComplete(extension_.get()); | 636 extension_, |
| 636 | 637 page_ordinal_, |
| 637 extension_ = NULL; | 638 has_requirement_errors_, |
| 638 | 639 install_wait_for_idle_))); |
| 639 // We're done. We don't post any more tasks to ourselves so we are deleted | |
| 640 // soon. | |
| 641 } | 640 } |
| 642 | 641 |
| 643 void CrxInstaller::NotifyCrxInstallComplete(const Extension* extension) { | 642 void CrxInstaller::HandleIsBlacklistedResponse( |
| 643 const base::Closure& on_success, |
| 644 bool is_blacklisted) { |
| 645 if (is_blacklisted) { |
| 646 ExtensionInstallUIDefault(profile()).OnInstallFailure( |
| 647 extensions::CrxInstallerError( |
| 648 l10n_util::GetStringFUTF16(IDS_EXTENSION_IS_BLACKLISTED, |
| 649 UTF8ToUTF16(extension_->name())))); |
| 650 } else { |
| 651 on_success.Run(); |
| 652 } |
| 653 NotifyCrxInstallComplete(!is_blacklisted); |
| 654 } |
| 655 |
| 656 void CrxInstaller::NotifyCrxInstallComplete(bool success) { |
| 644 // Some users (such as the download shelf) need to know when a | 657 // Some users (such as the download shelf) need to know when a |
| 645 // CRXInstaller is done. Listening for the EXTENSION_* events | 658 // CRXInstaller is done. Listening for the EXTENSION_* events |
| 646 // is problematic because they don't know anything about the | 659 // is problematic because they don't know anything about the |
| 647 // extension before it is unpacked, so they cannot filter based | 660 // extension before it is unpacked, so they cannot filter based |
| 648 // on the extension. | 661 // on the extension. |
| 649 content::NotificationService::current()->Notify( | 662 content::NotificationService::current()->Notify( |
| 650 chrome::NOTIFICATION_CRX_INSTALLER_DONE, | 663 chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
| 651 content::Source<CrxInstaller>(this), | 664 content::Source<CrxInstaller>(this), |
| 652 content::Details<const Extension>(extension)); | 665 content::Details<const Extension>(success ? extension_.get() : NULL)); |
| 666 |
| 667 // We're done. We don't post any more tasks to ourselves so we are deleted |
| 668 // soon. |
| 669 extension_ = NULL; |
| 653 } | 670 } |
| 654 | 671 |
| 655 void CrxInstaller::CleanupTempFiles() { | 672 void CrxInstaller::CleanupTempFiles() { |
| 656 if (!installer_task_runner_->RunsTasksOnCurrentThread()) { | 673 if (!installer_task_runner_->RunsTasksOnCurrentThread()) { |
| 657 if (!installer_task_runner_->PostTask( | 674 if (!installer_task_runner_->PostTask( |
| 658 FROM_HERE, | 675 FROM_HERE, |
| 659 base::Bind(&CrxInstaller::CleanupTempFiles, this))) { | 676 base::Bind(&CrxInstaller::CleanupTempFiles, this))) { |
| 660 NOTREACHED(); | 677 NOTREACHED(); |
| 661 } | 678 } |
| 662 return; | 679 return; |
| 663 } | 680 } |
| 664 | 681 |
| 665 // Delete the temp directory and crx file as necessary. | 682 // Delete the temp directory and crx file as necessary. |
| 666 if (!temp_dir_.value().empty()) { | 683 if (!temp_dir_.value().empty()) { |
| 667 extension_file_util::DeleteFile(temp_dir_, true); | 684 extension_file_util::DeleteFile(temp_dir_, true); |
| 668 temp_dir_ = FilePath(); | 685 temp_dir_ = FilePath(); |
| 669 } | 686 } |
| 670 | 687 |
| 671 if (delete_source_ && !source_file_.value().empty()) { | 688 if (delete_source_ && !source_file_.value().empty()) { |
| 672 extension_file_util::DeleteFile(source_file_, false); | 689 extension_file_util::DeleteFile(source_file_, false); |
| 673 source_file_ = FilePath(); | 690 source_file_ = FilePath(); |
| 674 } | 691 } |
| 675 } | 692 } |
| 676 | 693 |
| 677 } // namespace extensions | 694 } // namespace extensions |
| OLD | NEW |