Index: chrome/browser/extensions/crx_installer.cc |
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc |
index f997fc6fb78ab8869ba650c64851d3f9ff73df52..9ea03e9d7b26ab1406f22631c2c62d9149db199e 100644 |
--- a/chrome/browser/extensions/crx_installer.cc |
+++ b/chrome/browser/extensions/crx_installer.cc |
@@ -108,7 +108,8 @@ CrxInstaller::CrxInstaller( |
error_on_unsupported_requirements_(false), |
requirements_checker_(new extensions::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; |
@@ -428,6 +429,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)) { |
@@ -452,8 +457,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( |
@@ -465,31 +472,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. |
@@ -611,20 +638,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. |
@@ -674,9 +702,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() { |
@@ -701,4 +729,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 |