diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-10 03:27:39 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-10 03:27:39 +0000 |
commit | a487176a89c3a2aff8226c8c1d9acc55ce70e483 (patch) | |
tree | cdbace8fd15777bad4a317328c5c7431d27f1d42 /chrome/browser | |
parent | b6a040a170be44d208a5ab379931c571232dd3e2 (diff) | |
download | chromium_src-a487176a89c3a2aff8226c8c1d9acc55ce70e483.zip chromium_src-a487176a89c3a2aff8226c8c1d9acc55ce70e483.tar.gz chromium_src-a487176a89c3a2aff8226c8c1d9acc55ce70e483.tar.bz2 |
Add confirmation on extension uninstallation.
Reuses the Install dialog (and makes it slightly more generic).
BUG=27162
TEST=None
Review URL: http://codereview.chromium.org/376030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31540 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/cocoa/extension_install_prompt.mm | 15 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.h | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_disabled_infobar_delegate.cc | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.cc | 33 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.h | 40 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.cc | 24 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.h | 12 | ||||
-rw-r--r-- | chrome/browser/gtk/extension_install_prompt_gtk.cc | 27 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_install_prompt.cc | 35 |
10 files changed, 152 insertions, 50 deletions
diff --git a/chrome/browser/cocoa/extension_install_prompt.mm b/chrome/browser/cocoa/extension_install_prompt.mm index 06bac7a..ce19119 100644 --- a/chrome/browser/cocoa/extension_install_prompt.mm +++ b/chrome/browser/cocoa/extension_install_prompt.mm @@ -18,24 +18,27 @@ class Profile; -void ExtensionInstallUI::ShowExtensionInstallPrompt( +void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, - const std::wstring& warning_text) { + const std::wstring& warning_text, bool is_uninstall) { NSAlert* alert = [[[NSAlert alloc] init] autorelease]; [alert addButtonWithTitle:l10n_util::GetNSString( - IDS_EXTENSION_PROMPT_INSTALL_BUTTON)]; + is_uninstall ? IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON : + IDS_EXTENSION_PROMPT_INSTALL_BUTTON)]; [alert addButtonWithTitle:l10n_util::GetNSString( IDS_EXTENSION_PROMPT_CANCEL_BUTTON)]; [alert setMessageText:l10n_util::GetNSStringF( - IDS_EXTENSION_PROMPT_HEADING, UTF8ToUTF16(extension->name()))]; + is_uninstall ? IDS_EXTENSION_UNINSTALL_PROMPT_HEADING : + IDS_EXTENSION_INSTALL_PROMPT_HEADING, + UTF8ToUTF16(extension->name()))]; [alert setInformativeText:base::SysWideToNSString(warning_text)]; [alert setAlertStyle:NSWarningAlertStyle]; [alert setIcon:gfx::SkBitmapToNSImage(*icon)]; if ([alert runModal] == NSAlertFirstButtonReturn) { - delegate->ContinueInstall(); + delegate->InstallUIProceed(); } else { - delegate->AbortInstall(); + delegate->InstallUIAbort(); } } diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index cb5b4e4..db84355 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -209,7 +209,7 @@ void CrxInstaller::ConfirmInstall() { frontend_->extension_prefs()->GetVersionString(extension_->id()); if (client_.get()) { - AddRef(); // balanced in ContinueInstall() and AbortInstall(). + AddRef(); // Balanced in Proceed() and Abort(). client_->ConfirmInstall(this, extension_.get(), install_icon_.get()); } else { ChromeThread::PostTask( @@ -219,7 +219,7 @@ void CrxInstaller::ConfirmInstall() { return; } -void CrxInstaller::ContinueInstall() { +void CrxInstaller::InstallUIProceed() { ChromeThread::PostTask( ChromeThread::FILE, FROM_HERE, NewRunnableMethod(this, &CrxInstaller::CompleteInstall)); @@ -227,7 +227,7 @@ void CrxInstaller::ContinueInstall() { Release(); // balanced in ConfirmInstall(). } -void CrxInstaller::AbortInstall() { +void CrxInstaller::InstallUIAbort() { // Kill the theme loading bubble. NotificationService* service = NotificationService::current(); service->Notify(NotificationType::NO_THEME_DETECTED, diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index bd78cf6..21de58d 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -77,8 +77,8 @@ class CrxInstaller : scoped_ptr<SkBitmap>* result); // ExtensionInstallUI::Delegate - virtual void ContinueInstall(); - virtual void AbortInstall(); + virtual void InstallUIProceed(); + virtual void InstallUIAbort(); private: CrxInstaller(const FilePath& source_file, diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc index 44f819f..54d2ed9 100644 --- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc +++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc @@ -26,7 +26,7 @@ class ExtensionDisabledDialogDelegate ExtensionsService* service, Extension* extension) : profile_(profile), service_(service), extension_(extension) { - AddRef(); // balanced in ContinueInstall or AbortInstall. + AddRef(); // Balanced in Proceed or Abort. // Do this now because we can't touch extension on the file loop. install_icon_resource_ = @@ -38,11 +38,11 @@ class ExtensionDisabledDialogDelegate } // ExtensionInstallUI::Delegate - virtual void ContinueInstall() { + virtual void InstallUIProceed() { service_->EnableExtension(extension_->id()); Release(); } - virtual void AbortInstall() { + virtual void InstallUIAbort() { // Do nothing. The extension will remain disabled. Release(); } diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc index ae13fc5..09a82c4 100644 --- a/chrome/browser/extensions/extension_install_ui.cc +++ b/chrome/browser/extensions/extension_install_ui.cc @@ -87,6 +87,22 @@ ExtensionInstallUI::ExtensionInstallUI(Profile* profile) #endif {} +// static +void ExtensionInstallUI::ShowExtensionInstallPrompt( + Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, + const std::wstring& warning_text) { + ShowExtensionInstallUIPromptImpl(profile, delegate, extension, icon, + warning_text, false); // uninstall == false. +} + +// static +void ExtensionInstallUI::ShowExtensionUninstallPrompt( + Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, + const std::wstring& warning_text) { + ShowExtensionInstallUIPromptImpl(profile, delegate, extension, icon, + warning_text, true); // uninstall == true. +} + void ExtensionInstallUI::ConfirmInstall(Delegate* delegate, Extension* extension, SkBitmap* install_icon) { @@ -108,7 +124,7 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate, GtkThemeProvider::GetFrom(profile_)->UseGtkTheme(); #endif - delegate->ContinueInstall(); + delegate->InstallUIProceed(); return; } @@ -127,6 +143,21 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate, GetInstallWarning(extension)); } +void ExtensionInstallUI::ConfirmUninstall(Delegate* delegate, + Extension* extension, + SkBitmap* icon) { + DCHECK(ui_loop_ == MessageLoop::current()); + + if (!icon) { + icon = ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_EXTENSIONS_SECTION); + } + + std::wstring message = + l10n_util::GetString(IDS_EXTENSION_UNINSTALL_CONFIRMATION); + ShowExtensionUninstallPrompt(profile_, delegate, extension, icon, message); +} + void ExtensionInstallUI::OnInstallSuccess(Extension* extension) { if (extension->IsTheme()) { ShowThemeInfoBar(extension); diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h index f2ddf8d..0267450 100644 --- a/chrome/browser/extensions/extension_install_ui.h +++ b/chrome/browser/extensions/extension_install_ui.h @@ -21,26 +21,32 @@ class InfoBarDelegate; class SandboxedExtensionUnpacker; class TabContents; -// Displays all the UI around extension installation. +// Displays all the UI around extension installation and uninstallation. class ExtensionInstallUI { public: class Delegate { public: - // We call this method after ConfirmInstall() to signal that the - // installation should continue. - virtual void ContinueInstall() = 0; + // We call this method after ConfirmInstall()/ConfirmUninstall() to signal + // that the installation/uninstallation should continue. + virtual void InstallUIProceed() = 0; - // We call this method after ConfirmInstall() to signal that the - // installation should stop. - virtual void AbortInstall() = 0; + // We call this method after ConfirmInstall()/ConfirmUninstall() to signal + // that the installation/uninstallation should stop. + virtual void InstallUIAbort() = 0; }; - // NOTE: The implementations of these functions are platform-specific. static void ShowExtensionInstallPrompt(Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* install_icon, const std::wstring& warning_text); + static void ShowExtensionUninstallPrompt(Profile* profile, + Delegate* delegate, + Extension* extension, + SkBitmap* install_icon, + const std::wstring& warning_text); + + // NOTE: The implementations of this function is platform-specific. static void ShowExtensionInstallError(const std::string& error); explicit ExtensionInstallUI(Profile* profile); @@ -48,15 +54,23 @@ class ExtensionInstallUI { // This is called by the installer to verify whether the installation should // proceed. // - // We *MUST* eventually call either ContinueInstall() or AbortInstall() + // We *MUST* eventually call either Proceed() or Abort() // on |delegate|. void ConfirmInstall(Delegate* delegate, Extension* extension, SkBitmap* icon); + // This is called by the extensions management page to verify whether the + // uninstallation should proceed. + // + // We *MUST* eventually call either Proceed() or Abort() + // on |delegate|. + void ConfirmUninstall(Delegate* delegate, Extension* extension, + SkBitmap* icon); + // Installation was successful. void OnInstallSuccess(Extension* extension); - // Intallation failed. + // Installation failed. void OnInstallFailure(const std::string& error); // The install was rejected because the same extension/version is already @@ -73,6 +87,12 @@ class ExtensionInstallUI { InfoBarDelegate* GetNewInfoBarDelegate(Extension* new_theme, TabContents* tab_contents); + // Implements the showing of the install/uninstall dialog prompt. + // NOTE: The implementations of this function is platform-specific. + static void ShowExtensionInstallUIPromptImpl( + Profile* profile, Delegate* delegate, Extension* extension, + SkBitmap* icon, const std::wstring& warning_text, bool is_uninstall); + Profile* profile_; MessageLoop* ui_loop_; std::string previous_theme_id_; // Used to undo theme installation. diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index c411444..f66ba3e 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -15,6 +15,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/debugger/devtools_manager.h" +#include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extensions_service.h" @@ -381,7 +382,28 @@ void ExtensionsDOMHandler::HandleUninstallMessage(const Value* value) { CHECK(list->GetSize() == 1); std::string extension_id; CHECK(list->GetString(0, &extension_id)); - extensions_service_->UninstallExtension(extension_id, false); + + Extension *extension = extensions_service_->GetExtensionById(extension_id); + if (!extension) + return; + + FilePath icon_path = + extension->GetIconPath(Extension::EXTENSION_ICON_LARGE).GetFilePath(); + scoped_ptr<SkBitmap> uninstall_icon; + CrxInstaller::DecodeInstallIcon(icon_path, &uninstall_icon); + + extension_id_uninstalling_ = extension_id; + ExtensionInstallUI client(dom_ui_->GetProfile()); + client.ConfirmUninstall(this, extension, uninstall_icon.get()); +} + +void ExtensionsDOMHandler::InstallUIProceed() { + extensions_service_->UninstallExtension(extension_id_uninstalling_, false); + extension_id_uninstalling_ = ""; +} + +void ExtensionsDOMHandler::InstallUIAbort() { + extension_id_uninstalling_ = ""; } void ExtensionsDOMHandler::HandleOptionsMessage(const Value* value) { diff --git a/chrome/browser/extensions/extensions_ui.h b/chrome/browser/extensions/extensions_ui.h index 352e42c..d2fe206 100644 --- a/chrome/browser/extensions/extensions_ui.h +++ b/chrome/browser/extensions/extensions_ui.h @@ -10,6 +10,7 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/dom_ui.h" +#include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/pack_extension_job.h" #include "chrome/browser/shell_dialogs.h" #include "chrome/common/extensions/extension_resource.h" @@ -58,7 +59,8 @@ class ExtensionsDOMHandler : public DOMMessageHandler, public NotificationObserver, public PackExtensionJob::Client, - public SelectFileDialog::Listener { + public SelectFileDialog::Listener, + public ExtensionInstallUI::Delegate { public: // Helper class that loads the icons for the extensions in the management UI. @@ -118,6 +120,11 @@ class ExtensionsDOMHandler virtual void OnPackFailure(const std::wstring& message); + // ExtensionInstallUI::Delegate implementation, used for receiving + // notification about uninstall confirmation dialog selections. + virtual void InstallUIProceed(); + virtual void InstallUIAbort(); + private: // Callback for "requestExtensionsData" message. void HandleRequestExtensionsData(const Value* value); @@ -203,6 +210,9 @@ class ExtensionsDOMHandler // necessary. NotificationRegistrar registrar_; + // The id of the extension we are about to un-install. + std::string extension_id_uninstalling_; + DISALLOW_COPY_AND_ASSIGN(ExtensionsDOMHandler); }; diff --git a/chrome/browser/gtk/extension_install_prompt_gtk.cc b/chrome/browser/gtk/extension_install_prompt_gtk.cc index 1335ceb..24aa07b 100644 --- a/chrome/browser/gtk/extension_install_prompt_gtk.cc +++ b/chrome/browser/gtk/extension_install_prompt_gtk.cc @@ -40,9 +40,9 @@ GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) { void OnDialogResponse(GtkDialog* dialog, int response_id, ExtensionInstallUI::Delegate* delegate) { if (response_id == GTK_RESPONSE_ACCEPT) { - delegate->ContinueInstall(); + delegate->InstallUIProceed(); } else { - delegate->AbortInstall(); + delegate->InstallUIAbort(); } gtk_widget_destroy(GTK_WIDGET(dialog)); @@ -51,10 +51,13 @@ void OnDialogResponse(GtkDialog* dialog, int response_id, void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon, Extension *extension, ExtensionInstallUI::Delegate *delegate, - const std::string& warning_text) { + const std::string& warning_text, + bool is_uninstall) { // Build the dialog. + int title_id = is_uninstall ? IDS_EXTENSION_UNINSTALL_PROMPT_TITLE : + IDS_EXTENSION_INSTALL_PROMPT_TITLE; GtkWidget* dialog = gtk_dialog_new_with_buttons( - l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_TITLE).c_str(), + l10n_util::GetStringUTF8(title_id).c_str(), parent, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, @@ -80,8 +83,10 @@ void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon, GtkWidget* right_column_area = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(icon_hbox), right_column_area, TRUE, TRUE, 0); + int heading_id = is_uninstall ? IDS_EXTENSION_UNINSTALL_PROMPT_HEADING : + IDS_EXTENSION_INSTALL_PROMPT_HEADING; std::string heading_text = WideToUTF8(l10n_util::GetStringF( - IDS_EXTENSION_PROMPT_HEADING, UTF8ToWide(extension->name()))); + heading_id, UTF8ToWide(extension->name()))); GtkWidget* heading_label = MakeMarkupLabel("<span weight=\"bold\">%s</span>", heading_text); gtk_misc_set_alignment(GTK_MISC(heading_label), 0.0, 0.5); @@ -102,25 +107,25 @@ void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon, } // namespace -void ExtensionInstallUI::ShowExtensionInstallPrompt( +void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, - const std::wstring& warning_text) { + const std::wstring& warning_text, bool is_uninstall) { Browser* browser = BrowserList::GetLastActiveWithProfile(profile); if (!browser) { - delegate->ContinueInstall(); + delegate->InstallUIProceed(); return; } BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>( browser->window()); if (!browser_window) { - delegate->AbortInstall(); + delegate->InstallUIAbort(); return; } std::string warning_ascii = WideToASCII(warning_text); - ShowInstallPromptDialog(browser_window->window(), icon, extension, delegate, - warning_ascii); + ShowInstallPromptDialog(browser_window->window(), icon, extension, + delegate, warning_ascii, is_uninstall); } void ExtensionInstallUI::ShowExtensionInstallError(const std::string& error) { diff --git a/chrome/browser/views/extensions/extension_install_prompt.cc b/chrome/browser/views/extensions/extension_install_prompt.cc index 58bdae1..c227040 100644 --- a/chrome/browser/views/extensions/extension_install_prompt.cc +++ b/chrome/browser/views/extensions/extension_install_prompt.cc @@ -34,8 +34,9 @@ const int kIconSize = 85; class InstallDialogContent : public views::View, public views::DialogDelegate { public: InstallDialogContent(ExtensionInstallUI::Delegate* delegate, - Extension* extension, SkBitmap* icon, const std::wstring& warning_text) - : delegate_(delegate), icon_(NULL) { + Extension* extension, SkBitmap* icon, const std::wstring& warning_text, + bool is_uninstall) + : delegate_(delegate), icon_(NULL), is_uninstall_(is_uninstall) { // Scale down to 85x85, but allow smaller icons (don't scale up). gfx::Size size(icon->width(), icon->height()); if (size.width() > kIconSize || size.height() > kIconSize) @@ -46,7 +47,9 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { AddChildView(icon_); heading_ = new views::Label( - l10n_util::GetStringF(IDS_EXTENSION_PROMPT_HEADING, + l10n_util::GetStringF(is_uninstall ? + IDS_EXTENSION_UNINSTALL_PROMPT_HEADING : + IDS_EXTENSION_INSTALL_PROMPT_HEADING, UTF8ToWide(extension->name()))); heading_->SetFont(heading_->GetFont().DeriveFont(1, gfx::Font::BOLD)); heading_->SetMultiLine(true); @@ -65,7 +68,10 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { MessageBoxFlags::DialogButton button) const { switch (button) { case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_EXTENSION_PROMPT_INSTALL_BUTTON); + if (is_uninstall_) + return l10n_util::GetString(IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON); + else + return l10n_util::GetString(IDS_EXTENSION_PROMPT_INSTALL_BUTTON); case MessageBoxFlags::DIALOGBUTTON_CANCEL: return l10n_util::GetString(IDS_EXTENSION_PROMPT_CANCEL_BUTTON); default: @@ -79,12 +85,12 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { } virtual bool Accept() { - delegate_->ContinueInstall(); + delegate_->InstallUIProceed(); return true; } virtual bool Cancel() { - delegate_->AbortInstall(); + delegate_->InstallUIAbort(); return true; } @@ -92,7 +98,10 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { // WindowDelegate virtual bool IsModal() const { return true; } virtual std::wstring GetWindowTitle() const { - return l10n_util::GetString(IDS_EXTENSION_PROMPT_TITLE); + if (is_uninstall_) + return l10n_util::GetString(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE); + else + return l10n_util::GetString(IDS_EXTENSION_INSTALL_PROMPT_TITLE); } virtual views::View* GetContentsView() { return this; } @@ -138,30 +147,32 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { views::ImageView* icon_; views::Label* heading_; views::Label* warning_; + bool is_uninstall_; DISALLOW_COPY_AND_ASSIGN(InstallDialogContent); }; } // namespace -void ExtensionInstallUI::ShowExtensionInstallPrompt( +// static +void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, - const std::wstring& warning_text) { + const std::wstring& warning_text, bool is_uninstall) { Browser* browser = BrowserList::GetLastActiveWithProfile(profile); if (!browser) { - delegate->ContinueInstall(); + delegate->InstallUIProceed(); return; } BrowserWindow* window = browser->window(); if (!window) { - delegate->AbortInstall(); + delegate->InstallUIAbort(); return; } views::Window::CreateChromeWindow(window->GetNativeHandle(), gfx::Rect(), new InstallDialogContent(delegate, extension, icon, - warning_text))->Show(); + warning_text, is_uninstall))->Show(); } void ExtensionInstallUI::ShowExtensionInstallError(const std::string& error) { |