diff options
Diffstat (limited to 'chrome/browser')
11 files changed, 206 insertions, 141 deletions
diff --git a/chrome/browser/extensions/bundle_installer.cc b/chrome/browser/extensions/bundle_installer.cc index db915d4..68a92bb 100644 --- a/chrome/browser/extensions/bundle_installer.cc +++ b/chrome/browser/extensions/bundle_installer.cc @@ -266,12 +266,8 @@ void BundleInstaller::ShowPrompt() { } else if (g_auto_approve_for_test == ABORT) { InstallUIAbort(true); } else { - ExtensionInstallUI::Prompt prompt( - ExtensionInstallUI::BUNDLE_INSTALL_PROMPT); - prompt.SetPermissions(permissions->GetWarningMessages()); - prompt.set_bundle(this); - - ShowExtensionInstallDialog(profile_, this, prompt); + install_ui_.reset(new ExtensionInstallUI(profile_)); + install_ui_->ConfirmBundleInstall(this, permissions); } } diff --git a/chrome/browser/extensions/bundle_installer.h b/chrome/browser/extensions/bundle_installer.h index 2a7cb0d..40034e7 100644 --- a/chrome/browser/extensions/bundle_installer.h +++ b/chrome/browser/extensions/bundle_installer.h @@ -10,6 +10,7 @@ #include <vector> #include "base/memory/linked_ptr.h" +#include "base/memory/scoped_ptr.h" #include "base/string16.h" #include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/webstore_installer.h" @@ -184,6 +185,9 @@ class BundleInstaller : public WebstoreInstallHelper::Delegate, // The profile that the bundle should be installed in. Profile* profile_; + // The UI that shows the confirmation prompt. + scoped_ptr<ExtensionInstallUI> install_ui_; + Delegate* delegate_; DISALLOW_COPY_AND_ASSIGN(BundleInstaller); diff --git a/chrome/browser/extensions/extension_install_dialog.cc b/chrome/browser/extensions/extension_install_dialog.cc index c1412d3..46c98cb 100644 --- a/chrome/browser/extensions/extension_install_dialog.cc +++ b/chrome/browser/extensions/extension_install_dialog.cc @@ -70,60 +70,3 @@ void ShowExtensionInstallDialog(Profile* profile, } ShowExtensionInstallDialogImpl(profile, delegate, prompt); } - -bool ShowExtensionInstallDialogForManifest( - Profile* profile, - ExtensionInstallUI::Delegate* delegate, - const DictionaryValue* manifest, - const std::string& id, - const std::string& localized_name, - const std::string& localized_description, - SkBitmap* icon, - const ExtensionInstallUI::Prompt& prompt, - scoped_refptr<Extension>* dummy_extension) { - scoped_ptr<DictionaryValue> localized_manifest; - if (!localized_name.empty() || !localized_description.empty()) { - localized_manifest.reset(manifest->DeepCopy()); - if (!localized_name.empty()) { - localized_manifest->SetString(extension_manifest_keys::kName, - localized_name); - } - if (!localized_description.empty()) { - localized_manifest->SetString(extension_manifest_keys::kDescription, - localized_description); - } - } - - std::string init_errors; - *dummy_extension = Extension::Create( - FilePath(), - Extension::INTERNAL, - localized_manifest.get() ? *localized_manifest.get() : *manifest, - Extension::NO_FLAGS, - id, - &init_errors); - if (!dummy_extension->get()) { - return false; - } - - if (icon->empty()) - icon = const_cast<SkBitmap*>(&Extension::GetDefaultIcon( - (*dummy_extension)->is_app())); - - // In tests, we may have setup to proceed or abort without putting up the real - // confirmation dialog. - AutoConfirmForTest auto_confirm = CheckAutoConfirmCommandLineSwitch(); - if (auto_confirm != DO_NOT_SKIP) { - DoAutoConfirm(auto_confirm, delegate); - return true; - } - - ExtensionInstallUI::Prompt filled_out_prompt = prompt; - filled_out_prompt.SetPermissions( - (*dummy_extension)->GetPermissionMessageStrings()); - filled_out_prompt.set_extension(*dummy_extension); - filled_out_prompt.set_icon(gfx::Image(new SkBitmap(*icon))); - - ShowExtensionInstallDialog(profile, delegate, filled_out_prompt); - return true; -} diff --git a/chrome/browser/extensions/extension_install_dialog.h b/chrome/browser/extensions/extension_install_dialog.h index 0728042..7ecdc27 100644 --- a/chrome/browser/extensions/extension_install_dialog.h +++ b/chrome/browser/extensions/extension_install_dialog.h @@ -29,25 +29,4 @@ void ShowExtensionInstallDialogImpl(Profile* profile, ExtensionInstallUI::Delegate* delegate, const ExtensionInstallUI::Prompt& prompt); -// Wrapper around ShowExtensionInstallDialog that shows the install dialog for -// a given manifest (that corresponds to an extension about to be installed with -// ID |id|). If the name or description in the manifest is a localized -// placeholder, it may be overidden with |localized_name| or -// |localized_description| (which may be empty). The Extension instance -// that's parsed is returned via |dummy_extension|. |prompt| should be fully -// populated except for the permissions field, which will be extracted from the -// extension. -// Returns true if |dummy_extension| is valid and delegate methods will be -// called. -bool ShowExtensionInstallDialogForManifest( - Profile *profile, - ExtensionInstallUI::Delegate* delegate, - const base::DictionaryValue* manifest, - const std::string& id, - const std::string& localized_name, - const std::string& localized_description, - SkBitmap* icon, - const ExtensionInstallUI::Prompt& prompt, - scoped_refptr<Extension>* dummy_extension); - #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_DIALOG_H_ diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc index 5a3f9f8..97364fa 100644 --- a/chrome/browser/extensions/extension_install_ui.cc +++ b/chrome/browser/extensions/extension_install_ui.cc @@ -33,6 +33,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_icon_set.h" +#include "chrome/common/extensions/extension_manifest_constants.h" #include "chrome/common/extensions/extension_resource.h" #include "chrome/common/extensions/url_pattern.h" #include "chrome/common/url_constants.h" @@ -211,13 +212,43 @@ string16 ExtensionInstallUI::Prompt::GetPermission(size_t index) const { IDS_EXTENSION_PERMISSION_LINE, permissions_[index]); } +// static +scoped_refptr<Extension> ExtensionInstallUI::GetLocalizedExtensionForDisplay( + const DictionaryValue* manifest, + const std::string& id, + const std::string& localized_name, + const std::string& localized_description, + std::string* error) { + scoped_ptr<DictionaryValue> localized_manifest; + if (!localized_name.empty() || !localized_description.empty()) { + localized_manifest.reset(manifest->DeepCopy()); + if (!localized_name.empty()) { + localized_manifest->SetString(extension_manifest_keys::kName, + localized_name); + } + if (!localized_description.empty()) { + localized_manifest->SetString(extension_manifest_keys::kDescription, + localized_description); + } + } + + return Extension::Create( + FilePath(), + Extension::INTERNAL, + localized_manifest.get() ? *localized_manifest.get() : *manifest, + Extension::NO_FLAGS, + id, + error); +} + ExtensionInstallUI::ExtensionInstallUI(Profile* profile) : profile_(profile), ui_loop_(MessageLoop::current()), previous_using_native_theme_(false), extension_(NULL), delegate_(NULL), - prompt_type_(NUM_PROMPT_TYPES), + prompt_(UNSET_PROMPT_TYPE), + prompt_type_(UNSET_PROMPT_TYPE), ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), use_app_installed_bubble_(false), skip_post_install_ui_(false) { @@ -235,12 +266,51 @@ ExtensionInstallUI::ExtensionInstallUI(Profile* profile) ExtensionInstallUI::~ExtensionInstallUI() { } +void ExtensionInstallUI::ConfirmBundleInstall( + extensions::BundleInstaller* bundle, + const ExtensionPermissionSet* permissions) { + DCHECK(ui_loop_ == MessageLoop::current()); + bundle_ = bundle; + permissions_ = permissions; + delegate_ = bundle; + prompt_type_ = BUNDLE_INSTALL_PROMPT; + + ShowConfirmation(); +} + +void ExtensionInstallUI::ConfirmInlineInstall( + Delegate* delegate, + const Extension* extension, + SkBitmap* icon, + ExtensionInstallUI::Prompt prompt) { + DCHECK(ui_loop_ == MessageLoop::current()); + extension_ = extension; + permissions_ = extension->GetActivePermissions(); + delegate_ = delegate; + prompt_ = prompt; + prompt_type_ = INLINE_INSTALL_PROMPT; + + SetIcon(icon); + ShowConfirmation(); +} + +void ExtensionInstallUI::ConfirmWebstoreInstall(Delegate* delegate, + const Extension* extension, + const SkBitmap* icon) { + // SetIcon requires |extension_| to be set. ConfirmInstall will setup the + // remaining fields. + extension_ = extension; + SetIcon(icon); + ConfirmInstall(delegate, extension); +} + void ExtensionInstallUI::ConfirmInstall(Delegate* delegate, const Extension* extension) { DCHECK(ui_loop_ == MessageLoop::current()); extension_ = extension; permissions_ = extension->GetActivePermissions(); delegate_ = delegate; + prompt_type_ = INSTALL_PROMPT; // We special-case themes to not show any confirm UI. Instead they are // immediately installed, and then we show an infobar (see OnInstallSuccess) @@ -250,7 +320,7 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate, return; } - ShowConfirmation(INSTALL_PROMPT); + LoadImageIfNeeded(); } void ExtensionInstallUI::ConfirmReEnable(Delegate* delegate, @@ -259,8 +329,9 @@ void ExtensionInstallUI::ConfirmReEnable(Delegate* delegate, extension_ = extension; permissions_ = extension->GetActivePermissions(); delegate_ = delegate; + prompt_type_ = RE_ENABLE_PROMPT; - ShowConfirmation(RE_ENABLE_PROMPT); + LoadImageIfNeeded(); } void ExtensionInstallUI::ConfirmPermissions( @@ -271,8 +342,9 @@ void ExtensionInstallUI::ConfirmPermissions( extension_ = extension; permissions_ = permissions; delegate_ = delegate; + prompt_type_ = PERMISSIONS_PROMPT; - ShowConfirmation(PERMISSIONS_PROMPT); + LoadImageIfNeeded(); } void ExtensionInstallUI::OnInstallSuccess(const Extension* extension, @@ -344,28 +416,7 @@ void ExtensionInstallUI::OnImageLoaded(const gfx::Image& image, const std::string& extension_id, int index) { SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap()); - - switch (prompt_type_) { - case PERMISSIONS_PROMPT: - case RE_ENABLE_PROMPT: - case INSTALL_PROMPT: { - content::NotificationService* service = - content::NotificationService::current(); - service->Notify(chrome::NOTIFICATION_EXTENSION_WILL_SHOW_CONFIRM_DIALOG, - content::Source<ExtensionInstallUI>(this), - content::NotificationService::NoDetails()); - - Prompt prompt(prompt_type_); - prompt.SetPermissions(permissions_->GetWarningMessages()); - prompt.set_extension(extension_); - prompt.set_icon(gfx::Image(new SkBitmap(icon_))); - ShowExtensionInstallDialog(profile_, delegate_, prompt); - break; - } - default: - NOTREACHED() << "Unknown message"; - break; - } + ShowConfirmation(); } // static @@ -444,9 +495,14 @@ void ExtensionInstallUI::ShowThemeInfoBar(const std::string& previous_theme_id, infobar_helper->AddInfoBar(new_delegate); } -void ExtensionInstallUI::ShowConfirmation(PromptType prompt_type) { +void ExtensionInstallUI::LoadImageIfNeeded() { + // Bundle install prompts do not have an icon. + if (!icon_.empty()) { + ShowConfirmation(); + return; + } + // Load the image asynchronously. For the response, check OnImageLoaded. - prompt_type_ = prompt_type; ExtensionResource image = extension_->GetIconResource(ExtensionIconSet::EXTENSION_ICON_LARGE, ExtensionIconSet::MATCH_BIGGER); @@ -455,6 +511,31 @@ void ExtensionInstallUI::ShowConfirmation(PromptType prompt_type) { ImageLoadingTracker::DONT_CACHE); } +void ExtensionInstallUI::ShowConfirmation() { + prompt_.set_type(prompt_type_); + prompt_.SetPermissions(permissions_->GetWarningMessages()); + + switch (prompt_type_) { + case PERMISSIONS_PROMPT: + case RE_ENABLE_PROMPT: + case INLINE_INSTALL_PROMPT: + case INSTALL_PROMPT: { + prompt_.set_extension(extension_); + prompt_.set_icon(gfx::Image(new SkBitmap(icon_))); + ShowExtensionInstallDialog(profile_, delegate_, prompt_); + break; + } + case BUNDLE_INSTALL_PROMPT: { + prompt_.set_bundle(bundle_); + ShowExtensionInstallDialog(profile_, delegate_, prompt_); + break; + } + default: + NOTREACHED() << "Unknown message"; + break; + } +} + InfoBarDelegate* ExtensionInstallUI::GetNewThemeInstalledInfoBarDelegate( TabContentsWrapper* tab_contents, const Extension* new_theme, diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h index 35e3fe0..e367091 100644 --- a/chrome/browser/extensions/extension_install_ui.h +++ b/chrome/browser/extensions/extension_install_ui.h @@ -25,6 +25,10 @@ class Profile; class InfoBarDelegate; class TabContentsWrapper; +namespace base { +class DictionaryValue; +} // namespace base + namespace extensions { class BundleInstaller; } // namespace extensions @@ -57,6 +61,7 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { int rating_count); PromptType type() const { return type_; } + void set_type(PromptType type) { type_ = type; } // Getters for UI element labels. string16 GetDialogTitle() const; @@ -131,6 +136,15 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { virtual ~Delegate() {} }; + // Creates a dummy extension from the |manifest|, replacing the name and + // description with the localizations if provided. + static scoped_refptr<Extension> GetLocalizedExtensionForDisplay( + const base::DictionaryValue* manifest, + const std::string& id, + const std::string& localized_name, + const std::string& localized_description, + std::string* error); + explicit ExtensionInstallUI(Profile* profile); virtual ~ExtensionInstallUI(); @@ -147,6 +161,30 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { skip_post_install_ui_ = skip_ui; } + // This is called by the bundle installer to verify whether the bundle + // should be installed. + // + // We *MUST* eventually call either Proceed() or Abort() on |delegate|. + virtual void ConfirmBundleInstall(extensions::BundleInstaller* bundle, + const ExtensionPermissionSet* permissions); + + // This is called by the inline installer to verify whether the inline + // install from the webstore should proceed. + // + // We *MUST* eventually call either Proceed() or Abort() on |delegate|. + virtual void ConfirmInlineInstall(Delegate* delegate, + const Extension* extension, + SkBitmap* icon, + Prompt prompt); + + // This is called by the installer to verify whether the installation from + // the webstore should proceed. + // + // We *MUST* eventually call either Proceed() or Abort() on |delegate|. + virtual void ConfirmWebstoreInstall(Delegate* delegate, + const Extension* extension, + const SkBitmap* icon); + // This is called by the installer to verify whether the installation should // proceed. This is declared virtual for testing. // @@ -182,7 +220,7 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { static void OpenAppInstalledUI(Browser* browser, const std::string& app_id); protected: - friend class ExtensionWebstorePrivateApiTest; + friend class ExtensionNoConfirmWebstorePrivateApiTest; friend class WebstoreInlineInstallUnpackFailureTest; // Disables showing UI (ErrorBox, etc.) for install failures. To be used only @@ -206,7 +244,10 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { // Starts the process of showing a confirmation UI, which is split into two. // 1) Set off a 'load icon' task. // 2) Handle the load icon response and show the UI (OnImageLoaded). - void ShowConfirmation(PromptType prompt_type); + void LoadImageIfNeeded(); + + // Shows the actual UI (the icon should already be loaded). + void ShowConfirmation(); // Returns the delegate to control the browser's info bar. This is // within its own function due to its platform-specific nature. @@ -229,12 +270,18 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer { // The extension we are showing the UI for. const Extension* extension_; + // The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT. + const extensions::BundleInstaller* bundle_; + // The permissions being prompted for. scoped_refptr<const ExtensionPermissionSet> permissions_; // The delegate we will call Proceed/Abort on after confirmation UI. Delegate* delegate_; + // A pre-filled prompt. + Prompt prompt_; + // The type of prompt we are going to show. PromptType prompt_type_; diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc index 02a88c47..b3efdd8 100644 --- a/chrome/browser/extensions/extension_webstore_private_api.cc +++ b/chrome/browser/extensions/extension_webstore_private_api.cc @@ -249,7 +249,7 @@ void InstallBundleFunction::OnBundleInstallCompleted() { } BeginInstallWithManifestFunction::BeginInstallWithManifestFunction() - : use_app_installed_bubble_(false) {} + : use_app_installed_bubble_(false) {} BeginInstallWithManifestFunction::~BeginInstallWithManifestFunction() {} @@ -356,23 +356,18 @@ void BeginInstallWithManifestFunction::OnWebstoreParseSuccess( icon_ = icon; parsed_manifest_.reset(parsed_manifest); - ExtensionInstallUI::Prompt prompt(ExtensionInstallUI::INSTALL_PROMPT); - - if (!ShowExtensionInstallDialogForManifest( - profile(), - this, - parsed_manifest, - id_, - localized_name_, - "", // no localized description - &icon_, - prompt, - &dummy_extension_)) { + std::string error; + dummy_extension_ = ExtensionInstallUI::GetLocalizedExtensionForDisplay( + parsed_manifest_.get(), id, localized_name_, "", &error); + + if (!dummy_extension_) { OnWebstoreParseFailure(id_, WebstoreInstallHelper::Delegate::MANIFEST_ERROR, kInvalidManifestError); return; } + install_ui_.reset(new ExtensionInstallUI(profile())); + install_ui_->ConfirmWebstoreInstall(this, dummy_extension_, &icon_); // Control flow finishes up in InstallUIProceed or InstallUIAbort. } diff --git a/chrome/browser/extensions/extension_webstore_private_api.h b/chrome/browser/extensions/extension_webstore_private_api.h index 193a186..a4ea8d0 100644 --- a/chrome/browser/extensions/extension_webstore_private_api.h +++ b/chrome/browser/extensions/extension_webstore_private_api.h @@ -140,6 +140,9 @@ class BeginInstallWithManifestFunction // ExtensionInstallUI to prompt for confirmation of the install. scoped_refptr<Extension> dummy_extension_; + // The class that displays the install prompt. + scoped_ptr<ExtensionInstallUI> install_ui_; + DECLARE_EXTENSION_FUNCTION_NAME("webstorePrivate.beginInstallWithManifest3"); }; diff --git a/chrome/browser/extensions/extension_webstore_private_apitest.cc b/chrome/browser/extensions/extension_webstore_private_apitest.cc index 75b5104..a3ba3f2 100644 --- a/chrome/browser/extensions/extension_webstore_private_apitest.cc +++ b/chrome/browser/extensions/extension_webstore_private_apitest.cc @@ -85,14 +85,12 @@ class WebstoreInstallListener : public WebstoreInstaller::Delegate { } // namespace // A base class for tests below. -class ExtensionWebstorePrivateApiTest : public ExtensionApiTest { +class ExtensionNoConfirmWebstorePrivateApiTest : public ExtensionApiTest { public: void SetUpCommandLine(CommandLine* command_line) OVERRIDE { ExtensionApiTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII( switches::kAppsGalleryURL, "http://www.example.com"); - command_line->AppendSwitchASCII( - switches::kAppsGalleryInstallAutoConfirmForTests, "accept"); } void SetUpInProcessBrowserTestFixture() OVERRIDE { @@ -135,6 +133,16 @@ class ExtensionWebstorePrivateApiTest : public ExtensionApiTest { } }; +class ExtensionWebstorePrivateApiTest : + public ExtensionNoConfirmWebstorePrivateApiTest { + public: + void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + ExtensionNoConfirmWebstorePrivateApiTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + switches::kAppsGalleryInstallAutoConfirmForTests, "accept"); + } +}; + class ExtensionWebstorePrivateBundleTest : public ExtensionWebstorePrivateApiTest { public: @@ -329,6 +337,17 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, BeginInstall) { EXPECT_EQ(browser()->profile(), approval->profile); } +// Tests that themes are installed without an install prompt. +IN_PROC_BROWSER_TEST_F(ExtensionNoConfirmWebstorePrivateApiTest, + InstallTheme) { + WebstoreInstallListener listener; + WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener); + ASSERT_TRUE(RunInstallTest("theme.html", "../../theme.crx")); + listener.Wait(); + ASSERT_TRUE(listener.received_success()); + ASSERT_EQ("iamefpfkojoapidjnbafmgkgncegbkad", listener.id()); +} + // Tests using silentlyInstall to install extensions. IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateBundleTest, SilentlyInstall) { WebstorePrivateApi::SetTrustTestIDsForTesting(true); diff --git a/chrome/browser/extensions/webstore_inline_installer.cc b/chrome/browser/extensions/webstore_inline_installer.cc index a11a194..eb76482 100644 --- a/chrome/browser/extensions/webstore_inline_installer.cc +++ b/chrome/browser/extensions/webstore_inline_installer.cc @@ -373,20 +373,17 @@ void WebstoreInlineInstaller::OnWebstoreParseSuccess( prompt.SetInlineInstallWebstoreData(localized_user_count_, average_rating_, rating_count_); - - if (!ShowExtensionInstallDialogForManifest(profile, - this, - manifest, - id_, - localized_name_, - localized_description_, - &icon_, - prompt, - &dummy_extension_)) { - CompleteInstall(kInvalidManifestError); + std::string error; + dummy_extension_ = ExtensionInstallUI::GetLocalizedExtensionForDisplay( + manifest, id_, localized_name_, localized_description_, &error); + if (!dummy_extension_) { + OnWebstoreParseFailure(id_, WebstoreInstallHelper::Delegate::MANIFEST_ERROR, + kInvalidManifestError); return; } + install_ui_.reset(new ExtensionInstallUI(profile)); + install_ui_->ConfirmInlineInstall(this, dummy_extension_, &icon_, prompt); // Control flow finishes up in InstallUIProceed or InstallUIAbort. } diff --git a/chrome/browser/extensions/webstore_inline_installer.h b/chrome/browser/extensions/webstore_inline_installer.h index 191267a..1d87c24 100644 --- a/chrome/browser/extensions/webstore_inline_installer.h +++ b/chrome/browser/extensions/webstore_inline_installer.h @@ -114,6 +114,7 @@ class WebstoreInlineInstaller std::string id_; GURL requestor_url_; Delegate* delegate_; + scoped_ptr<ExtensionInstallUI> install_ui_; // For fetching webstore JSON data. scoped_ptr<content::URLFetcher> webstore_data_url_fetcher_; |