summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd42
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc102
-rwxr-xr-x[-rw-r--r--]chrome/browser/extensions/extension_install_ui.h10
-rw-r--r--chrome/browser/views/extensions/extension_install_prompt2.cc309
-rwxr-xr-xchrome/chrome_browser.gypi1
5 files changed, 434 insertions, 30 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 92973a9..377d2d4 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3311,31 +3311,57 @@ each locale. -->
<message name="IDS_EXTENSION_PROMPT_WARNING_INCOGNITO" desc="The warning you get when you are about to enable an extension in incognito.">
Are you sure you want to allow this extension to run in incognito? <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> cannot prevent this extension from recording your browsing data.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to browser APIs.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to browser APIs.">
This extension will have access to your browsing history.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_SINGLE_HOST" desc="Warning displayed in body of extension dialog when the extension requires access to a single host.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_SINGLE_HOST" desc="Warning displayed in body of extension dialog when the extension requires access to a single host.">
This extension will have access to your private data on <ph name="HOST">$1<ex>maps.google.com</ex></ph>.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_SINGLE_HOST_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to a single host and browser APIs.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_SINGLE_HOST_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to a single host and browser APIs.">
This extension will have access to your browsing history and private data on <ph name="HOST">$1<ex>maps.google.com</ex></ph>.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_MULTIPLE_HOSTS" desc="Warning displayed in body of extension dialog when the extension requires access to multiple hosts, but not every host.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_MULTIPLE_HOSTS" desc="Warning displayed in body of extension dialog when the extension requires access to multiple hosts, but not every host.">
This extension will have access to your private data on multiple websites.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_MULTIPLE_HOSTS_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to multiple hosts, but not every host, and browser APIs.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_MULTIPLE_HOSTS_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to multiple hosts, but not every host, and browser APIs.">
This extension will have access to your browsing history and private data on multiple websites.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_ALL_HOSTS" desc="Warning displayed in body of extension dialog when the extension requires access to all hosts.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS" desc="Warning displayed in body of extension dialog when the extension requires access to all hosts.">
This extension will have access to your private data on all websites.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_ALL_HOSTS_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to all hosts and browser APIs.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS_AND_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to all hosts and browser APIs.">
This extension will have access to your browsing history and private data on all websites.
</message>
- <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_FULL_ACCESS" desc="Warning displayed in body of extension dialog when the extension requires access the local machine.">
+ <message name="IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS" desc="Warning displayed in body of extension dialog when the extension requires access the local machine.">
This extension will have full access to your computer and private data.
</message>
+ <!-- v2 extension install dialog strings -->
+ <message name="IDS_EXTENSION_PROMPT2_WILL_HAVE_ACCESS_TO" desc="Second line in the content area of the extension installation prompt.">
+ This extension needs access to:
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_FULL_ACCESS" desc="Permission string for full access to the computer and all web sites.">
+ All data on your computer and the web sites you visit.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_ALL_HOSTS" desc="Permission string for access to data on all web sites.">
+ Your data on all web sites.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_1_HOST" desc="Permission string for access to data on one web site.">
+ Your data on <ph name="WEBSITE_1">$1<ex>www.google.com</ex></ph>.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_2_HOSTS" desc="Permission string for access to data on two web sites.">
+ Your data on <ph name="WEBSITE_1">$1<ex>www.google.com</ex></ph> and <ph name="WEBSITE_2">$2<ex>www.reddit.com</ex></ph>.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_3_HOSTS" desc="Permission string for access to data on three web sites.">
+ Your data on <ph name="WEBSITE_1">$1<ex>www.google.com</ex></ph>, <ph name="WEBSITE_2">$2<ex>www.reddit.com</ex></ph>, and <ph name="WEBSITE_3">$3<ex>news.ycombinator.com</ex></ph>.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_4_OR_MORE_HOSTS" desc="Permission string for access to data on four or more web sites.">
+ Your data on <ph name="WEBSITE_1">$1<ex>www.google.com</ex></ph>, <ph name="WEBSITE_2">$2<ex>www.yahoo.com</ex></ph>, and <ph name="NUMBER_OF_OTHER_WEBSITES">$3<ex>3</ex></ph> other web sites.
+ </message>
+ <message name="IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY" desc="Permission string for access to browsing history.">
+ Your browsing history.
+ </message>
+
<!-- Extension error messages -->
<message name="IDS_EXTENSION_DIRECTORY_NO_EXISTS" desc="Warning displayed in pack dialog when the extension directory does not exist.">
Input directory must exist.
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc
index f36f02b..b95b957 100644
--- a/chrome/browser/extensions/extension_install_ui.cc
+++ b/chrome/browser/extensions/extension_install_ui.cc
@@ -10,6 +10,7 @@
#include "app/resource_bundle.h"
#include "base/file_util.h"
#include "base/rand_util.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
@@ -60,16 +61,11 @@ const int ExtensionInstallUI::kButtonIds[NUM_PROMPT_TYPES] = {
namespace {
-static std::wstring GetInstallWarning(Extension* extension) {
- // If the extension has a plugin, it's easy: the plugin has the most severe
- // warning.
- if (!extension->plugins().empty())
- return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_NEW_FULL_ACCESS);
-
- // We also show the severe warning if the extension has access to any file://
- // URLs. They aren't *quite* as dangerous as full access to the system via
- // NPAPI, but pretty dang close. Content scripts are currently the only way
- // that extension can get access to file:// URLs.
+// We also show the severe warning if the extension has access to any file://
+// URLs. They aren't *quite* as dangerous as full access to the system via
+// NPAPI, but pretty dang close. Content scripts are currently the only way
+// that extension can get access to file:// URLs.
+static bool ExtensionHasFileAccess(Extension* extension) {
for (UserScriptList::const_iterator script =
extension->content_scripts().begin();
script != extension->content_scripts().end();
@@ -78,42 +74,49 @@ static std::wstring GetInstallWarning(Extension* extension) {
script->url_patterns().begin();
pattern != script->url_patterns().end();
++pattern) {
- if (pattern->scheme() == chrome::kFileScheme) {
- return l10n_util::GetString(
- IDS_EXTENSION_PROMPT_WARNING_NEW_FULL_ACCESS);
- }
+ if (pattern->scheme() == chrome::kFileScheme)
+ return true;
}
}
+ return false;
+}
+
+static std::wstring GetInstallWarning(Extension* extension) {
+ // If the extension has a plugin, it's easy: the plugin has the most severe
+ // warning.
+ if (!extension->plugins().empty() || ExtensionHasFileAccess(extension))
+ return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS);
+
// Otherwise, we go in descending order of severity: all hosts, several hosts,
// a single host, no hosts. For each of these, we also have a variation of the
// message for when api permissions are also requested.
if (extension->HasAccessToAllHosts()) {
if (extension->api_permissions().empty())
- return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_NEW_ALL_HOSTS);
+ return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS);
else
return l10n_util::GetString(
- IDS_EXTENSION_PROMPT_WARNING_NEW_ALL_HOSTS_AND_BROWSER);
+ IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS_AND_BROWSER);
}
const std::set<std::string> hosts = extension->GetEffectiveHostPermissions();
if (hosts.size() > 1) {
if (extension->api_permissions().empty())
return l10n_util::GetString(
- IDS_EXTENSION_PROMPT_WARNING_NEW_MULTIPLE_HOSTS);
+ IDS_EXTENSION_PROMPT_WARNING_MULTIPLE_HOSTS);
else
return l10n_util::GetString(
- IDS_EXTENSION_PROMPT_WARNING_NEW_MULTIPLE_HOSTS_AND_BROWSER);
+ IDS_EXTENSION_PROMPT_WARNING_MULTIPLE_HOSTS_AND_BROWSER);
}
if (hosts.size() == 1) {
if (extension->api_permissions().empty())
return l10n_util::GetStringF(
- IDS_EXTENSION_PROMPT_WARNING_NEW_SINGLE_HOST,
+ IDS_EXTENSION_PROMPT_WARNING_SINGLE_HOST,
UTF8ToWide(*hosts.begin()));
else
return l10n_util::GetStringF(
- IDS_EXTENSION_PROMPT_WARNING_NEW_SINGLE_HOST_AND_BROWSER,
+ IDS_EXTENSION_PROMPT_WARNING_SINGLE_HOST_AND_BROWSER,
UTF8ToWide(*hosts.begin()));
}
@@ -121,8 +124,58 @@ static std::wstring GetInstallWarning(Extension* extension) {
if (extension->api_permissions().empty())
return L"";
else
- return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_NEW_BROWSER);
+ return l10n_util::GetString(IDS_EXTENSION_PROMPT_WARNING_BROWSER);
+}
+
+#if defined(OS_WIN)
+static void GetV2Warnings(Extension* extension,
+ std::vector<std::wstring>* warnings) {
+ if (!extension->plugins().empty() || ExtensionHasFileAccess(extension)) {
+ // TODO(aa): This one is a bit awkward. Should we have a separate
+ // presentation for this case?
+ warnings->push_back(
+ l10n_util::GetString(IDS_EXTENSION_PROMPT2_WARNING_FULL_ACCESS));
+ return;
+ }
+
+ if (extension->HasAccessToAllHosts()) {
+ warnings->push_back(
+ l10n_util::GetString(IDS_EXTENSION_PROMPT2_WARNING_ALL_HOSTS));
+ } else {
+ std::set<std::string> hosts = extension->GetEffectiveHostPermissions();
+ if (hosts.size() == 1) {
+ warnings->push_back(
+ l10n_util::GetStringF(IDS_EXTENSION_PROMPT2_WARNING_1_HOST,
+ UTF8ToWide(*hosts.begin())));
+ } else if (hosts.size() == 2) {
+ warnings->push_back(
+ l10n_util::GetStringF(IDS_EXTENSION_PROMPT2_WARNING_2_HOSTS,
+ UTF8ToWide(*hosts.begin()),
+ UTF8ToWide(*(++hosts.begin()))));
+ } else if (hosts.size() == 3) {
+ warnings->push_back(
+ l10n_util::GetStringF(IDS_EXTENSION_PROMPT2_WARNING_3_HOSTS,
+ UTF8ToWide(*hosts.begin()),
+ UTF8ToWide(*(++hosts.begin())),
+ UTF8ToWide(*(++++hosts.begin()))));
+ } else if (hosts.size() >= 4) {
+ warnings->push_back(
+ l10n_util::GetStringF(IDS_EXTENSION_PROMPT2_WARNING_4_OR_MORE_HOSTS,
+ UTF8ToWide(*hosts.begin()),
+ UTF8ToWide(*(++hosts.begin())),
+ IntToWString(hosts.size() - 2)));
+ }
+ }
+
+ if (extension->HasApiPermission(Extension::kTabPermission) ||
+ extension->HasApiPermission(Extension::kBookmarkPermission)) {
+ warnings->push_back(
+ l10n_util::GetString(IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY));
+ }
+
+ // TODO(aa): Geolocation, camera/mic, what else?
}
+#endif
} // namespace
@@ -254,9 +307,16 @@ void ExtensionInstallUI::OnImageLoaded(
Source<ExtensionInstallUI>(this),
NotificationService::NoDetails());
+#if defined(OS_WIN)
+ std::vector<std::wstring> warnings;
+ GetV2Warnings(extension_, &warnings);
+ ShowExtensionInstallUIPrompt2Impl(
+ profile_, delegate_, extension_, &icon_, warnings);
+#else
ShowExtensionInstallUIPromptImpl(
profile_, delegate_, extension_, &icon_,
WideToUTF16Hack(GetInstallWarning(extension_)), INSTALL_PROMPT);
+#endif
break;
}
case UNINSTALL_PROMPT: {
diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h
index 14c5f93..83c165e 100644..100755
--- a/chrome/browser/extensions/extension_install_ui.h
+++ b/chrome/browser/extensions/extension_install_ui.h
@@ -112,7 +112,15 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer {
// NOTE: The implementations of this function is platform-specific.
static void ShowExtensionInstallUIPromptImpl(
Profile* profile, Delegate* delegate, Extension* extension,
- SkBitmap* icon, const string16& warning_text, PromptType type);
+ SkBitmap* icon, const string16& warning, PromptType type);
+
+#if defined(OS_WIN)
+ // Implements the showing of the new install dialog. The implementations of
+ // this function are platform-specific.
+ static void ShowExtensionInstallUIPrompt2Impl(
+ Profile* profile, Delegate* delegate, Extension* extension,
+ SkBitmap* icon, const std::vector<std::wstring>& permissions);
+#endif
Profile* profile_;
MessageLoop* ui_loop_;
diff --git a/chrome/browser/views/extensions/extension_install_prompt2.cc b/chrome/browser/views/extensions/extension_install_prompt2.cc
new file mode 100644
index 0000000..56cb82d
--- /dev/null
+++ b/chrome/browser/views/extensions/extension_install_prompt2.cc
@@ -0,0 +1,309 @@
+// Copyright (c) 2010 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.
+
+#include "app/l10n_util.h"
+#include "base/string_util.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browser_window.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+#include "chrome/common/extensions/extension.h"
+#include "grit/generated_resources.h"
+#include "views/controls/image_view.h"
+#include "views/controls/label.h"
+#include "views/standard_layout.h"
+#include "views/view.h"
+#include "views/window/dialog_delegate.h"
+#include "views/window/window.h"
+
+class Profile;
+
+namespace {
+
+// Size of extension icon in top left of dialog.
+const int kIconSize = 69;
+
+// Width of the white permission box. This also is the max width of all
+// elements in the right column of the dialog in the case where the extension
+// requests permissions.
+const int kPermissionBoxWidth = 270;
+
+// Width of the right column of the dialog when the extension requests no
+// permissions.
+const int kNoPermissionsRightColumnWidth = 210;
+
+// Width of the gray border around the permission box.
+const int kPermissionBoxBorderWidth = 1;
+
+// Width of the horizontal padding inside the permission box border.
+const int kPermissionBoxHorizontalPadding = 10;
+
+// Width of the vertical padding inside the permission box border.
+const int kPermissionBoxVerticalPadding = 11;
+
+// The max width of the individual permission strings inside the permission
+// box.
+const int kPermissionLabelWidth =
+ kPermissionBoxWidth -
+ kPermissionBoxBorderWidth * 2 -
+ kPermissionBoxHorizontalPadding * 2;
+
+} // namespace
+
+
+// Implements the extension installation prompt for TOOLKIT_VIEWS.
+class InstallDialogContent2
+ : public views::View, public views::DialogDelegate {
+ public:
+ InstallDialogContent2(ExtensionInstallUI::Delegate* delegate,
+ Extension* extension,
+ SkBitmap* icon,
+ const std::vector<std::wstring>& permissions);
+
+ private:
+ // DialogDelegate overrides.
+ virtual std::wstring GetDialogButtonLabel(
+ MessageBoxFlags::DialogButton button) const;
+ virtual int GetDefaultDialogButton() const;
+ virtual bool Accept();
+ virtual bool Cancel();
+
+ // WindowDelegate overrides.
+ virtual bool IsModal() const;
+ virtual std::wstring GetWindowTitle() const;
+ virtual views::View* GetContentsView();
+
+ // View overrides.
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+
+ // The delegate that we will call back to when the user accepts or rejects
+ // the installation.
+ ExtensionInstallUI::Delegate* delegate_;
+
+ // Displays the extension's icon.
+ views::ImageView* icon_;
+
+ // Displays the main heading "Install FooBar?".
+ views::Label* heading_;
+
+ // Displays the permission box header "The extension will have access to:".
+ views::Label* will_have_access_to_;
+
+ // The white box containing the list of permissions the extension requires.
+ // This can be NULL if the extension requires no permissions.
+ views::View* permission_box_;
+
+ // The labels describing each of the permissions the extension requires.
+ std::vector<views::Label*> permissions_;
+
+ // The width of the right column of the dialog. Will be either
+ // kPermissionBoxWidth or kNoPermissionsRightColumnWidth, depending on
+ // whether the extension requires any permissions.
+ int right_column_width_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstallDialogContent2);
+};
+
+
+InstallDialogContent2::InstallDialogContent2(
+ ExtensionInstallUI::Delegate* delegate, Extension* extension,
+ SkBitmap* icon, const std::vector<std::wstring>& permissions)
+ : delegate_(delegate),
+ icon_(NULL),
+ heading_(NULL),
+ will_have_access_to_(NULL),
+ permission_box_(NULL),
+ right_column_width_(0) {
+ // Scale down to icon size, but allow smaller icons (don't scale up).
+ gfx::Size size(icon->width(), icon->height());
+ if (size.width() > kIconSize || size.height() > kIconSize)
+ size = gfx::Size(kIconSize, kIconSize);
+ icon_ = new views::ImageView();
+ icon_->SetImageSize(size);
+ icon_->SetImage(*icon);
+ icon_->SetHorizontalAlignment(views::ImageView::CENTER);
+ icon_->SetVerticalAlignment(views::ImageView::CENTER);
+ AddChildView(icon_);
+
+ heading_ = new views::Label(
+ l10n_util::GetStringF(IDS_EXTENSION_INSTALL_PROMPT_HEADING,
+ UTF8ToWide(extension->name())));
+ heading_->SetFont(heading_->GetFont().DeriveFont(1, gfx::Font::BOLD));
+ heading_->SetMultiLine(true);
+ heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(heading_);
+
+ if (permissions.size() == 0) {
+ right_column_width_ = kNoPermissionsRightColumnWidth;
+ } else {
+ right_column_width_ = kPermissionBoxWidth;
+
+ will_have_access_to_ = new views::Label(
+ l10n_util::GetString(IDS_EXTENSION_PROMPT2_WILL_HAVE_ACCESS_TO));
+ will_have_access_to_->SetMultiLine(true);
+ will_have_access_to_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(will_have_access_to_);
+
+ permission_box_ = new views::View();
+ permission_box_->set_background(
+ views::Background::CreateSolidBackground(SK_ColorWHITE));
+ permission_box_->set_border(
+ views::Border::CreateSolidBorder(kPermissionBoxBorderWidth,
+ SK_ColorLTGRAY));
+ AddChildView(permission_box_);
+ }
+
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ views::Label* label = new views::Label(permissions[i]);
+ label->SetMultiLine(true);
+ label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ permission_box_->AddChildView(label);
+ permissions_.push_back(label);
+ }
+}
+
+std::wstring InstallDialogContent2::GetDialogButtonLabel(
+ MessageBoxFlags::DialogButton button) const {
+ switch (button) {
+ case MessageBoxFlags::DIALOGBUTTON_OK:
+ return l10n_util::GetString(IDS_EXTENSION_PROMPT_INSTALL_BUTTON);
+ case MessageBoxFlags::DIALOGBUTTON_CANCEL:
+ return l10n_util::GetString(IDS_CANCEL);
+ default:
+ NOTREACHED();
+ return L"";
+ }
+}
+
+int InstallDialogContent2::GetDefaultDialogButton() const {
+ return MessageBoxFlags::DIALOGBUTTON_CANCEL;
+}
+
+bool InstallDialogContent2::Accept() {
+ delegate_->InstallUIProceed(false); // create shortcut
+ return true;
+}
+
+bool InstallDialogContent2::Cancel() {
+ delegate_->InstallUIAbort();
+ return true;
+}
+
+bool InstallDialogContent2::IsModal() const {
+ return true;
+}
+
+std::wstring InstallDialogContent2::GetWindowTitle() const {
+ return l10n_util::GetString(IDS_EXTENSION_INSTALL_PROMPT_TITLE);
+}
+
+views::View* InstallDialogContent2::GetContentsView() {
+ return this;
+}
+
+gfx::Size InstallDialogContent2::GetPreferredSize() {
+ int width = kPanelHorizMargin * 2;
+ width += kIconSize;
+ width += kPanelHorizMargin; // Gutter.
+ width += right_column_width_;
+
+ int height = kPanelVertMargin * 2;
+ height += heading_->GetHeightForWidth(right_column_width_);
+
+ if (permission_box_) {
+ height += kRelatedControlVerticalSpacing;
+ height += will_have_access_to_->GetHeightForWidth(right_column_width_);
+
+ height += kRelatedControlVerticalSpacing;
+ height += kPermissionBoxBorderWidth * 2;
+ height += kPermissionBoxVerticalPadding * 2;
+
+ for (size_t i = 0; i < permissions_.size(); ++i) {
+ if (i > 0)
+ height += kRelatedControlVerticalSpacing;
+ height += permissions_[0]->GetHeightForWidth(kPermissionLabelWidth);
+ }
+ }
+
+ return gfx::Size(width, std::max(height, kIconSize + kPanelVertMargin * 2));
+}
+
+void InstallDialogContent2::Layout() {
+ int x = kPanelHorizMargin;
+ int y = kPanelVertMargin;
+
+ icon_->SetBounds(x, y, kIconSize, kIconSize);
+ x += kIconSize;
+ x += kPanelHorizMargin;
+
+ heading_->SizeToFit(right_column_width_);
+ heading_->SetX(x);
+
+ // If there's no special permissions, we do a slightly different layout with
+ // the heading centered vertically wrt the icon.
+ if (!permission_box_) {
+ heading_->SetY((GetPreferredSize().height() - heading_->height()) / 2);
+ return;
+ }
+
+ // Otherwise, do the layout with the permission box.
+ heading_->SetY(y);
+ y += heading_->height();
+
+ y += kRelatedControlVerticalSpacing;
+ will_have_access_to_->SizeToFit(right_column_width_);
+ will_have_access_to_->SetX(x);
+ will_have_access_to_->SetY(y);
+ y += will_have_access_to_->height();
+
+ y += kRelatedControlVerticalSpacing;
+ permission_box_->SetX(x);
+ permission_box_->SetY(y);
+
+ // First we layout the labels inside the permission box, so that we know how
+ // big the box will have to be.
+ int label_x = kPermissionBoxBorderWidth + kPermissionBoxHorizontalPadding;
+ int label_y = kPermissionBoxBorderWidth + kPermissionBoxVerticalPadding;
+ int permission_box_height = kPermissionBoxBorderWidth * 2;
+ permission_box_height += kPermissionBoxVerticalPadding * 2;
+
+ for (size_t i = 0; i < permissions_.size(); ++i) {
+ if (i > 0) {
+ label_y += kRelatedControlVerticalSpacing;
+ permission_box_height += kPanelVertMargin;
+ }
+
+ permissions_[i]->SizeToFit(kPermissionLabelWidth);
+ permissions_[i]->SetX(label_x);
+ permissions_[i]->SetY(label_y);
+
+ label_y += permissions_[i]->height();
+ permission_box_height += permissions_[i]->height();
+ }
+
+ // Now finally we can size the permission box itself.
+ permission_box_->SetBounds(permission_box_->x(), permission_box_->y(),
+ right_column_width_, permission_box_height);
+}
+
+// static
+void ExtensionInstallUI::ShowExtensionInstallUIPrompt2Impl(
+ Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
+ const std::vector<std::wstring>& permissions) {
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
+ if (!browser) {
+ delegate->InstallUIAbort();
+ return;
+ }
+
+ BrowserWindow* window = browser->window();
+ if (!window) {
+ delegate->InstallUIAbort();
+ return;
+ }
+
+ views::Window::CreateChromeWindow(window->GetNativeHandle(), gfx::Rect(),
+ new InstallDialogContent2(delegate, extension, icon, permissions))
+ ->Show();
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index e544864..8da6e7d 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2150,6 +2150,7 @@
'browser/views/extensions/browser_action_overflow_menu_controller.cc',
'browser/views/extensions/browser_action_overflow_menu_controller.h',
'browser/views/extensions/extension_install_prompt.cc',
+ 'browser/views/extensions/extension_install_prompt2.cc',
'browser/views/extensions/extension_installed_bubble.cc',
'browser/views/extensions/extension_installed_bubble.h',
'browser/views/extensions/extension_popup.cc',