summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/crx_installer.cc143
-rw-r--r--chrome/browser/extensions/crx_installer.h13
2 files changed, 116 insertions, 40 deletions
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 6179662..2ccfc4a 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -110,7 +110,8 @@ CrxInstaller::CrxInstaller(
error_on_unsupported_requirements_(false),
requirements_checker_(new RequirementsChecker()),
has_requirement_errors_(false),
- install_wait_for_idle_(true) {
+ install_wait_for_idle_(true),
+ update_from_settings_page_(false) {
installer_task_runner_ = frontend_weak->GetFileTaskRunner();
if (!approval)
return;
@@ -430,6 +431,10 @@ void CrxInstaller::ConfirmInstall() {
if (!frontend_weak_.get() || frontend_weak_->browser_terminating())
return;
+ // Check whether this install is initiated from the settings page to
+ // update an existing extension or app.
+ CheckUpdateFromSettingsPage();
+
string16 error;
if (!ExtensionSystem::Get(profile_)->management_policy()->
UserMayLoad(extension_, &error)) {
@@ -454,8 +459,10 @@ void CrxInstaller::ConfirmInstall() {
current_version_ =
frontend_weak_->extension_prefs()->GetVersionString(extension_->id());
- if (client_ && (!allow_silent_install_ || !approved_)) {
- AddRef(); // Balanced in Proceed() and Abort().
+ if (client_ &&
+ (!allow_silent_install_ || !approved_) &&
+ !update_from_settings_page_) {
+ AddRef(); // Balanced in InstallUIProceed() and InstallUIAbort().
client_->ConfirmInstall(this, extension_.get(), show_dialog_callback_);
} else {
if (!installer_task_runner_->PostTask(
@@ -467,31 +474,51 @@ void CrxInstaller::ConfirmInstall() {
}
void CrxInstaller::InstallUIProceed() {
- if (!installer_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&CrxInstaller::CompleteInstall, this)))
- NOTREACHED();
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- Release(); // balanced in ConfirmInstall().
-}
+ if (!frontend_weak_.get() || frontend_weak_->browser_terminating())
+ return;
-void CrxInstaller::InstallUIAbort(bool user_initiated) {
- std::string histogram_name = user_initiated ?
- "Extensions.Permissions_InstallCancel" :
- "Extensions.Permissions_InstallAbort";
- ExtensionService::RecordPermissionMessagesHistogram(
- extension_, histogram_name.c_str());
+ // If update_from_settings_page_ boolean is true, this functions is
+ // getting called in response to ExtensionInstallPrompt::ConfirmReEnable()
+ // and if it is false, this function is called in response to
+ // ExtensionInstallPrompt::ConfirmInstall().
+ if (update_from_settings_page_) {
+ frontend_weak_->GrantPermissionsAndEnableExtension(
+ extension_.get(), client_->record_oauth2_grant());
+ } else {
+ if (!installer_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&CrxInstaller::CompleteInstall, this)))
+ NOTREACHED();
+ }
- // Kill the theme loading bubble.
- content::NotificationService* service =
- content::NotificationService::current();
- service->Notify(chrome::NOTIFICATION_NO_THEME_DETECTED,
- content::Source<CrxInstaller>(this),
- content::NotificationService::NoDetails());
+ Release(); // balanced in ConfirmInstall() or ConfirmReEnable().
+}
- NotifyCrxInstallComplete(false);
+void CrxInstaller::InstallUIAbort(bool user_initiated) {
+ // If update_from_settings_page_ boolean is true, this functions is
+ // getting called in response to ExtensionInstallPrompt::ConfirmReEnable()
+ // and if it is false, this function is called in response to
+ // ExtensionInstallPrompt::ConfirmInstall().
+ if (!update_from_settings_page_) {
+ std::string histogram_name = user_initiated ?
+ "Extensions.Permissions_InstallCancel" :
+ "Extensions.Permissions_InstallAbort";
+ ExtensionService::RecordPermissionMessagesHistogram(
+ extension_, histogram_name.c_str());
+
+ // Kill the theme loading bubble.
+ content::NotificationService* service =
+ content::NotificationService::current();
+ service->Notify(chrome::NOTIFICATION_NO_THEME_DETECTED,
+ content::Source<CrxInstaller>(this),
+ content::NotificationService::NoDetails());
+
+ NotifyCrxInstallComplete(false);
+ }
- Release(); // balanced in ConfirmInstall().
+ Release(); // balanced in ConfirmInstall() or ConfirmReEnable().
// We're done. Since we don't post any more tasks to ourself, our ref count
// should go to zero and we die. The destructor will clean up the temp dir.
@@ -613,20 +640,21 @@ void CrxInstaller::ReportSuccessFromUIThread() {
if (!frontend_weak_.get() || frontend_weak_->browser_terminating())
return;
- // If there is a client, tell the client about installation.
- if (client_) {
- client_->OnInstallSuccess(extension_.get(), install_icon_.get());
- }
+ if (!update_from_settings_page_) {
+ // If there is a client, tell the client about installation.
+ if (client_)
+ client_->OnInstallSuccess(extension_.get(), install_icon_.get());
- if (client_ && !approved_)
- record_oauth2_grant_ = client_->record_oauth2_grant();
+ if (client_ && !approved_)
+ record_oauth2_grant_ = client_->record_oauth2_grant();
- // We update the extension's granted permissions if the user already approved
- // the install (client_ is non NULL), or we are allowed to install this
- // silently.
- if (client_ || allow_silent_install_) {
- PermissionsUpdater perms_updater(profile());
- perms_updater.GrantActivePermissions(extension_, record_oauth2_grant_);
+ // We update the extension's granted permissions if the user already
+ // approved the install (client_ is non NULL), or we are allowed to install
+ // this silently.
+ if (client_ || allow_silent_install_) {
+ PermissionsUpdater perms_updater(profile());
+ perms_updater.GrantActivePermissions(extension_, record_oauth2_grant_);
+ }
}
// Install the extension if it's not blacklisted, but notify either way.
@@ -678,9 +706,9 @@ void CrxInstaller::NotifyCrxInstallComplete(bool success) {
content::Source<CrxInstaller>(this),
content::Details<const Extension>(success ? extension_.get() : NULL));
- // We're done. We don't post any more tasks to ourselves so we are deleted
- // soon.
- extension_ = NULL;
+ if (success)
+ ConfirmReEnable();
+
}
void CrxInstaller::CleanupTempFiles() {
@@ -705,4 +733,43 @@ void CrxInstaller::CleanupTempFiles() {
}
}
+void CrxInstaller::CheckUpdateFromSettingsPage() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!frontend_weak_.get() || frontend_weak_->browser_terminating())
+ return;
+
+ if (off_store_install_allow_reason_ != OffStoreInstallAllowedFromSettingsPage)
+ return;
+
+ const Extension* installed_extension =
+ frontend_weak_->GetInstalledExtension(extension_->id());
+ if (installed_extension) {
+ // Previous version of the extension exists.
+ update_from_settings_page_ = true;
+ expected_id_ = installed_extension->id();
+ install_source_ = installed_extension->location();
+ install_cause_ = extension_misc::INSTALL_CAUSE_UPDATE;
+ }
+}
+
+void CrxInstaller::ConfirmReEnable() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!frontend_weak_.get() || frontend_weak_->browser_terminating())
+ return;
+
+ if (!update_from_settings_page_)
+ return;
+
+ extensions::ExtensionPrefs* prefs = frontend_weak_->extension_prefs();
+ if (!prefs->DidExtensionEscalatePermissions(extension_->id()))
+ return;
+
+ if (client_) {
+ AddRef(); // Balanced in InstallUIProceed() and InstallUIAbort().
+ client_->ConfirmReEnable(this, extension_.get());
+ }
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 90ad001..0f49f3b 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -247,8 +247,13 @@ class CrxInstaller
// Deletes temporary directory and crx file if needed.
void CleanupTempFiles();
- // Creates sequenced task runner for extension install file I/O operations.
- scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunner();
+ // Checks whether the current installation is initiated by the user from
+ // the extension settings page to update an existing extension or app.
+ void CheckUpdateFromSettingsPage();
+
+ // Show re-enable prompt if the update is initiated from the settings page
+ // and needs additional permissions.
+ void ConfirmReEnable();
// The file we're installing.
base::FilePath source_file_;
@@ -393,6 +398,10 @@ class CrxInstaller
// Used to show the install dialog.
ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback_;
+ // Whether the update is initiated by the user from the extension settings
+ // page.
+ bool update_from_settings_page_;
+
DISALLOW_COPY_AND_ASSIGN(CrxInstaller);
};