Index: chrome/browser/extensions/crx_installer.cc |
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc |
index dcb1046cfc7d58fc4488769287b85110b2fe3f74..82658727e6db0eff74a226717deda9d85189c1c1 100644 |
--- a/chrome/browser/extensions/crx_installer.cc |
+++ b/chrome/browser/extensions/crx_installer.cc |
@@ -16,6 +16,7 @@ |
#include "base/scoped_temp_dir.h" |
#include "base/stl_util.h" |
#include "base/stringprintf.h" |
+#include "base/string_util.h" |
#include "base/threading/thread_restrictions.h" |
#include "base/time.h" |
#include "base/utf_string_conversions.h" |
@@ -29,6 +30,7 @@ |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/extensions/permissions_updater.h" |
+#include "chrome/browser/extensions/requirements_checker.h" |
#include "chrome/browser/extensions/webstore_installer.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/shell_integration.h" |
@@ -101,7 +103,9 @@ CrxInstaller::CrxInstaller( |
creation_flags_(Extension::NO_FLAGS), |
off_store_install_allow_reason_(OffStoreInstallDisallowed), |
did_handle_successfully_(true), |
- record_oauth2_grant_(false) { |
+ record_oauth2_grant_(false), |
+ error_on_unsupported_requirements_(false), |
+ requirements_checker_(new extensions::RequirementsChecker()) { |
if (!approval) |
return; |
@@ -204,7 +208,7 @@ void CrxInstaller::ConvertWebAppOnFileThread( |
OnUnpackSuccess(extension->path(), extension->path(), NULL, extension); |
} |
-CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) { |
+CrxInstallerError CrxInstaller::AllowInstall(Extension* extension) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
// Make sure the expected ID matches if one was supplied or if we want to |
@@ -349,7 +353,7 @@ void CrxInstaller::OnUnpackFailure(const string16& error_message) { |
void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, |
const FilePath& extension_dir, |
const DictionaryValue* original_manifest, |
- const Extension* extension) { |
+ Extension* extension) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", |
@@ -384,10 +388,30 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, |
&install_icon_); |
} |
- if (!BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&CrxInstaller::ConfirmInstall, this))) |
- NOTREACHED(); |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&CrxInstaller::CheckRequirements, this)); |
+} |
+ |
+void CrxInstaller::CheckRequirements() { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ requirements_checker_->Check(extension_, |
+ base::Bind(&CrxInstaller::RequirementsChecked, |
+ this)); |
+} |
+ |
+void CrxInstaller::RequirementsChecked(std::vector<std::string> errors) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ if (!errors.empty()) { |
+ if (error_on_unsupported_requirements_) { |
+ ReportFailureFromUIThread(CrxInstallerError( |
+ UTF8ToUTF16(JoinString(errors, ' ')))); |
+ return; |
+ } |
+ requirement_errors_.swap(errors); |
+ } |
+ |
+ ConfirmInstall(); |
} |
void CrxInstaller::ConfirmInstall() { |
@@ -520,6 +544,17 @@ void CrxInstaller::CompleteInstall() { |
&error); |
CHECK(error.empty()) << error; |
+ if (!requirement_errors_.empty()) { |
+ extensions::Extension::InstallWarningVector install_warnings; |
+ for (std::vector<std::string>::iterator it = requirement_errors_.begin(); |
+ it != requirement_errors_.end(); |
+ ++it) { |
+ install_warnings.push_back(Extension::InstallWarning( |
+ Extension::InstallWarning::FORMAT_TEXT, *it)); |
+ } |
+ extension_->AddInstallWarnings(install_warnings); |
+ } |
+ |
ReportSuccessFromFileThread(); |
} |
@@ -602,8 +637,10 @@ void CrxInstaller::ReportSuccessFromUIThread() { |
// Tell the frontend about the installation and hand off ownership of |
// extension_ to it. |
- frontend_weak_->OnExtensionInstalled(extension_, is_gallery_install(), |
- page_ordinal_); |
+ frontend_weak_->OnExtensionInstalled(extension_, |
+ is_gallery_install(), |
+ page_ordinal_, |
+ requirement_errors_); |
NotifyCrxInstallComplete(extension_.get()); |
@@ -613,7 +650,7 @@ void CrxInstaller::ReportSuccessFromUIThread() { |
// soon. |
} |
-void CrxInstaller::NotifyCrxInstallComplete(const Extension* extension) { |
+void CrxInstaller::NotifyCrxInstallComplete(Extension* extension) { |
// Some users (such as the download shelf) need to know when a |
// CRXInstaller is done. Listening for the EXTENSION_* events |
// is problematic because they don't know anything about the |