diff options
-rw-r--r-- | chrome/app/generated_resources.grd | 42 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.cc | 102 | ||||
-rwxr-xr-x[-rw-r--r--] | chrome/browser/extensions/extension_install_ui.h | 10 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_install_prompt2.cc | 309 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 1 |
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', |