Commit 7c40973a authored by mark@chromium.org's avatar mark@chromium.org

o Cleans up canonical extension_install_ui.cc to avoid #ifdefs when feasible.

o Adds Cocoa implementation of the extension installation prompt.
o Added new cross-platform implementations of the extension install error prompt.
o Got rid of unused extension install strings from early implementations.
o Added a string to display as the header of the error dialog, since it was inline English.

Patch by Andrew Bonventre <andybons@gmail.com>

BUG=19654
TEST=Install an extension on any platform, observe consistent visual behavior and messaging.
Review URL: http://codereview.chromium.org/333015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30091 0039d316-1c4b-4281-b951-d872f2087c98
parent c64d852e
......@@ -2639,19 +2639,8 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_EXTENSION_PACK_DIALOG_FAILURE_TITLE" desc="Message shown on titlebar of window after unsucessful packing of an extension.">
Extension Packaging Failure
</message>
<!-- TODO(aa): Remove these old warning messages when all the platforms are switched to the new ones, above. -->
<message name="IDS_EXTENSION_PROMPT_WARNING_1" desc="Humorous warning displayed in the extension install prompt that tells users that extensions have access to their computer and private data.">
Extensions have access to your computer and private data. This means they could forward all your email to your spouse.
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_2" desc="Humorous warning displayed in the extension install prompt that tells users that extensions have access to their computer and private data.">
Extensions have access to your computer and private data. They could send tweets or email on your behalf.
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_3" desc="Humorous warning displayed in the extension install prompt that tells users that extensions have access to their computer and private data.">
Extensions can access your computer and private data. They could post unflattering pictures to your Wall.
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_SEVERE" desc="A bolded warning below the humorous warning that reiterates that users should only install extensions they trust">
Only install extensions you trust.
<message name="IDS_EXTENSION_INSTALL_FAILURE_TITLE" desc="Message shown in titlebar/header of the dialog informing the user that an extension failed to install.">
Extension Install Failure
</message>
<message name="IDS_EXTENSION_PROMPT_INSTALL_BUTTON" desc="Text for the install button on the extension install prompt">
......
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include <string>
#include "app/l10n_util_mac.h"
#include "app/resource_bundle.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/common/extensions/extension.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "skia/ext/skia_utils_mac.h"
class Profile;
void ExtensionInstallUI::ShowExtensionInstallPrompt(
Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
const std::wstring& warning_text) {
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:l10n_util::GetNSString(
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()))];
[alert setInformativeText:base::SysWideToNSString(warning_text)];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setIcon:gfx::SkBitmapToNSImage(*icon)];
if ([alert runModal] == NSAlertFirstButtonReturn) {
delegate->ContinueInstall();
} else {
delegate->AbortInstall();
}
}
void ExtensionInstallUI::ShowExtensionInstallError(const std::string& error) {
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:l10n_util::GetNSString(IDS_OK)];
[alert setMessageText:l10n_util::GetNSString(
IDS_EXTENSION_INSTALL_FAILURE_TITLE)];
[alert setInformativeText:base::SysUTF8ToNSString(error)];
[alert setAlertStyle:NSWarningAlertStyle];
[alert runModal];
}
......@@ -10,6 +10,7 @@
#include "app/resource_bundle.h"
#include "base/file_util.h"
#include "base/rand_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
......@@ -20,21 +21,13 @@
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#if defined(OS_WIN)
#include "app/win_util.h"
#elif defined(OS_MACOSX)
#include "base/scoped_cftyperef.h"
#include "base/sys_string_conversions.h"
#include <CoreFoundation/CFUserNotification.h>
#elif defined(TOOLKIT_GTK)
#if defined(TOOLKIT_GTK)
#include "chrome/browser/extensions/gtk_theme_installed_infobar_delegate.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#endif
namespace {
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
static std::wstring GetInstallWarning(Extension* extension) {
// If the extension has a plugin, it's easy: the plugin has the most severe
// warning.
......@@ -80,8 +73,6 @@ static std::wstring GetInstallWarning(Extension* extension) {
return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_NEW_BROWSER);
}
#endif
} // namespace
ExtensionInstallUI::ExtensionInstallUI(Profile* profile)
......@@ -89,8 +80,7 @@ ExtensionInstallUI::ExtensionInstallUI(Profile* profile)
#if defined(TOOLKIT_GTK)
,previous_use_gtk_theme_(false)
#endif
{
}
{}
void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
Extension* extension,
......@@ -117,7 +107,6 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
return;
}
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
if (!install_icon) {
install_icon = ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_DEFAULT_EXTENSION_ICON_128);
......@@ -126,54 +115,6 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
ShowExtensionInstallPrompt(profile_, delegate, extension, install_icon,
GetInstallWarning(extension));
#elif defined(OS_MACOSX)
// TODO(port): Implement nicer UI.
// Using CoreFoundation to do this dialog is unimaginably lame but will do
// until the UI is redone.
scoped_cftyperef<CFStringRef> confirm_title(base::SysWideToCFStringRef(
l10n_util::GetString(IDS_EXTENSION_PROMPT_TITLE)));
// Build the confirmation prompt, including a heading, a random humorous
// warning, and a severe warning.
const string16& confirm_format(ASCIIToUTF16("$1\n\n$2\n\n$3"));
std::vector<string16> subst;
subst.push_back(l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_HEADING,
UTF8ToUTF16(extension->name())));
string16 warnings[] = {
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_1),
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_2),
l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_3)
};
subst.push_back(warnings[base::RandInt(0, arraysize(warnings) - 1)]);
subst.push_back(l10n_util::GetStringUTF16(
IDS_EXTENSION_PROMPT_WARNING_SEVERE));
scoped_cftyperef<CFStringRef> confirm_prompt(base::SysUTF16ToCFStringRef(
ReplaceStringPlaceholders(confirm_format, subst, NULL)));
scoped_cftyperef<CFStringRef> confirm_cancel(base::SysWideToCFStringRef(
l10n_util::GetString(IDS_EXTENSION_PROMPT_CANCEL_BUTTON)));
CFOptionFlags response;
CFUserNotificationDisplayAlert(
0, kCFUserNotificationCautionAlertLevel,
NULL, // TODO(port): show the install_icon instead of a default.
NULL, NULL, // Sound URL, localization URL.
confirm_title,
confirm_prompt,
NULL, // Default button.
confirm_cancel,
NULL, // Other button.
&response);
if (response == kCFUserNotificationAlternateResponse) {
delegate->AbortInstall();
} else {
delegate->ContinueInstall();
}
#else
// TODO(port): Implement some UI.
NOTREACHED();
delegate->ContinueInstall();
#endif // OS_*
}
void ExtensionInstallUI::OnInstallSuccess(Extension* extension) {
......@@ -183,24 +124,7 @@ void ExtensionInstallUI::OnInstallSuccess(Extension* extension) {
void ExtensionInstallUI::OnInstallFailure(const std::string& error) {
DCHECK(ui_loop_ == MessageLoop::current());
#if defined(OS_WIN)
win_util::MessageBox(NULL, UTF8ToWide(error), L"Extension Install Error",
MB_OK | MB_SETFOREGROUND);
#elif defined(OS_MACOSX)
// There must be a better way to do this, for all platforms.
scoped_cftyperef<CFStringRef> message_cf(
base::SysUTF8ToCFStringRef(error));
CFOptionFlags response;
CFUserNotificationDisplayAlert(
0, kCFUserNotificationNoteAlertLevel, NULL, NULL, NULL,
CFSTR("Extension Install Error"), message_cf,
NULL, NULL, NULL, &response);
#else
GtkWidget* dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", error.c_str());
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_widget_show_all(dialog);
#endif
ShowExtensionInstallError(error);
}
void ExtensionInstallUI::OnOverinstallAttempted(Extension* extension) {
......@@ -230,18 +154,22 @@ void ExtensionInstallUI::ShowThemeInfoBar(Extension* new_theme) {
}
// Then either replace that old one or add a new one.
InfoBarDelegate* new_delegate =
#if defined(TOOLKIT_GTK)
new GtkThemeInstalledInfoBarDelegate(
tab_contents,
new_theme->name(), previous_theme_id_, previous_use_gtk_theme_);
#else
new ThemeInstalledInfoBarDelegate(tab_contents,
new_theme->name(), previous_theme_id_);
#endif
InfoBarDelegate* new_delegate = GetNewInfoBarDelegate(new_theme,
tab_contents);
if (old_delegate)
tab_contents->ReplaceInfoBar(old_delegate, new_delegate);
else
tab_contents->AddInfoBar(new_delegate);
}
InfoBarDelegate* ExtensionInstallUI::GetNewInfoBarDelegate(
Extension* new_theme, TabContents* tab_contents) {
#if defined(TOOLKIT_GTK)
return new GtkThemeInstalledInfoBarDelegate(tab_contents, new_theme->name(),
previous_theme_id_, previous_use_gtk_theme_);
#else
return new ThemeInstalledInfoBarDelegate(tab_contents, new_theme->name(),
previous_theme_id_);
#endif
}
......@@ -15,8 +15,10 @@ class Extension;
class ExtensionsService;
class MessageLoop;
class Profile;
class InfoBarDelegate;
class SandboxedExtensionUnpacker;
class SkBitmap;
class TabContents;
// Displays all the UI around extension installation.
class ExtensionInstallUI {
......@@ -32,12 +34,13 @@ class ExtensionInstallUI {
virtual void AbortInstall() = 0;
};
// NOTE: The implementation of this is platform-specific.
// 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 ShowExtensionInstallError(const std::string& error);
ExtensionInstallUI(Profile* profile);
......@@ -60,8 +63,15 @@ class ExtensionInstallUI {
void OnOverinstallAttempted(Extension* extension);
private:
// When a Theme is downloaded it is applied and an info bar is shown to give
// the user a choice to keep it or undo the installation.
void ShowThemeInfoBar(Extension* new_theme);
// Returns the delegate to control the browser's info bar. This is within its
// own function due to its platform-specific nature.
InfoBarDelegate* GetNewInfoBarDelegate(Extension* new_theme,
TabContents* tab_contents);
Profile* profile_;
MessageLoop* ui_loop_;
std::string previous_theme_id_; // Used to undo theme installation.
......
......@@ -122,3 +122,12 @@ void ExtensionInstallUI::ShowExtensionInstallPrompt(
ShowInstallPromptDialog(browser_window->window(), icon, extension, delegate,
warning_ascii);
}
void ExtensionInstallUI::ShowExtensionInstallError(const std::string& error) {
GtkWidget* dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", error.c_str());
gtk_window_set_title(GTK_WINDOW(dialog),
l10n_util::GetStringUTF8(IDS_EXTENSION_INSTALL_FAILURE_TITLE).c_str());
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_widget_show_all(dialog);
}
......@@ -19,6 +19,10 @@
#include "views/window/dialog_delegate.h"
#include "views/window/window.h"
#if defined(OS_WIN)
#include "app/win_util.h"
#endif
class Profile;
namespace {
......@@ -134,7 +138,7 @@ class InstallDialogContent : public views::View, public views::DialogDelegate {
DISALLOW_COPY_AND_ASSIGN(InstallDialogContent);
};
} // namespace
} // namespace
void ExtensionInstallUI::ShowExtensionInstallPrompt(
Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
......@@ -155,3 +159,14 @@ void ExtensionInstallUI::ShowExtensionInstallPrompt(
new InstallDialogContent(delegate, extension, icon,
warning_text))->Show();
}
void ExtensionInstallUI::ShowExtensionInstallError(const std::string& error) {
#if defined(OS_WIN)
win_util::MessageBox(NULL, UTF8ToWide(error),
l10n_util::GetString(IDS_EXTENSION_INSTALL_FAILURE_TITLE),
MB_OK | MB_SETFOREGROUND);
#else
// TODO(port): Port this over to OS_*
NOTREACHED();
#endif
}
......@@ -1105,6 +1105,7 @@
'browser/cocoa/encoding_menu_controller_delegate_mac.mm',
'browser/cocoa/event_utils.h',
'browser/cocoa/event_utils.mm',
'browser/cocoa/extension_install_prompt.mm',
'browser/cocoa/extension_shelf_controller.h',
'browser/cocoa/extension_shelf_controller.mm',
'browser/cocoa/extension_view_mac.h',
......@@ -2732,6 +2733,7 @@
['include', '^browser/views/dragged_tab_controller.h'],
['include', '^browser/views/event_utils.cc'],
['include', '^browser/views/event_utils.h'],
['include', '^browser/views/extensions/extension_install_prompt.cc'],
['include', '^browser/views/extensions/extension_popup.cc'],
['include', '^browser/views/extensions/extension_popup.h'],
['include', '^browser/views/extensions/extension_shelf.cc'],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment