diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 18:42:09 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 18:42:09 +0000 |
commit | 4704fa5e6894a2ec42cdbcda9da18f8d203e634d (patch) | |
tree | a7bbfcbc6b1c017152048d05378c0c58951ff512 | |
parent | f7158b04f32b8cd19b922bb7b8fccc41a43c5dd4 (diff) | |
download | chromium_src-4704fa5e6894a2ec42cdbcda9da18f8d203e634d.zip chromium_src-4704fa5e6894a2ec42cdbcda9da18f8d203e634d.tar.gz chromium_src-4704fa5e6894a2ec42cdbcda9da18f8d203e634d.tar.bz2 |
Merge 142921 - Use an infobar instead of alert box for extension install
error.
Also, setup the 'learn more' link for off-store install
failure, but don't enable yet as we don't quite have anything
to link to.
BUG=55584
TBR=yoz@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10559056
TBR=aa@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10581043
git-svn-id: svn://svn.chromium.org/chrome/branches/1180/src@143213 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 2 | ||||
-rw-r--r-- | chrome/browser/download/download_browsertest.cc | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 105 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.h | 7 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer_browsertest.cc | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer_error.h | 41 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_browsertest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_prompt.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_prompt.h | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.h | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui_android.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui_android.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui_default.cc | 55 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui_default.h | 2 | ||||
-rw-r--r-- | chrome/chrome_browser_extensions.gypi | 1 |
15 files changed, 168 insertions, 68 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 603bbae..2497453 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4446,7 +4446,7 @@ Update checks have repeatedly failed for the extension "<ph name="EXTENSION_NAME Expected ID "<ph name="EXPECTED_ID">$1<ex>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</ex></ph>", but ID was "<ph name="NEW_ID">$2<ex>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</ex></ph>". </message> <message name="IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE" desc="Error displayed during installation of an extension when installation is not allowed from the current site."> - Extensions, apps, and user scripts cannot be installed from this web site. + Extensions, apps, and user scripts cannot be added from this web site. </message> <message name="IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION" desc="Error displayed during installation of a side-loaded app, extension, or theme when the version of the referenced extension does not match the version the developer declared during registration."> Expected version "<ph name="EXPECTED_VERSION">$1<ex>2.0</ex></ph>", but version was "<ph name="NEW_ID">$2<ex>1.0</ex></ph>". diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 94508eb2..a8fef34 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc @@ -163,7 +163,7 @@ class MockAbortExtensionInstallPrompt : public ExtensionInstallPrompt { } virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} - virtual void OnInstallFailure(const string16& error) {} + virtual void OnInstallFailure(const CrxInstallerError& error) {} }; // Mock that simulates a permissions dialog where the user allows @@ -179,7 +179,7 @@ class MockAutoConfirmExtensionInstallPrompt : public ExtensionInstallPrompt { } virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} - virtual void OnInstallFailure(const string16& error) {} + virtual void OnInstallFailure(const CrxInstallerError& error) {} }; static DownloadManager* DownloadManagerForBrowser(Browser* browser) { diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 27b6808..17b919b 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -172,7 +172,7 @@ void CrxInstaller::ConvertUserScriptOnFileThread() { scoped_refptr<Extension> extension = ConvertUserScriptToExtension(source_file_, download_url_, &error); if (!extension) { - ReportFailureFromFileThread(error); + ReportFailureFromFileThread(CrxInstallerError(error)); return; } @@ -202,36 +202,34 @@ void CrxInstaller::ConvertWebAppOnFileThread( OnUnpackSuccess(extension->path(), extension->path(), NULL, extension); } -bool CrxInstaller::AllowInstall(const Extension* extension, - string16* error) { +CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - DCHECK(error); // Make sure the expected ID matches if one was supplied or if we want to // bypass the prompt. if ((approved_ || !expected_id_.empty()) && expected_id_ != extension->id()) { - *error = l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALL_UNEXPECTED_ID, - ASCIIToUTF16(expected_id_), - ASCIIToUTF16(extension->id())); - return false; + return CrxInstallerError( + l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALL_UNEXPECTED_ID, + ASCIIToUTF16(expected_id_), + ASCIIToUTF16(extension->id()))); } if (expected_version_.get() && !expected_version_->Equals(*extension->version())) { - *error = l10n_util::GetStringFUTF16( - IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION, - ASCIIToUTF16(expected_version_->GetString()), - ASCIIToUTF16(extension->version()->GetString())); - return false; + return CrxInstallerError( + l10n_util::GetStringFUTF16( + IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION, + ASCIIToUTF16(expected_version_->GetString()), + ASCIIToUTF16(extension->version()->GetString()))); } // Make sure the manifests match if we want to bypass the prompt. if (approved_ && (!expected_manifest_.get() || !expected_manifest_->Equals(original_manifest_.get()))) { - *error = l10n_util::GetStringUTF16(IDS_EXTENSION_MANIFEST_INVALID); - return false; + return CrxInstallerError( + l10n_util::GetStringUTF16(IDS_EXTENSION_MANIFEST_INVALID)); } // The checks below are skipped for themes and external installs. @@ -239,11 +237,11 @@ bool CrxInstaller::AllowInstall(const Extension* extension, // and other uses of install_source_ that are no longer needed now that the // SandboxedExtensionUnpacker sets extension->location. if (extension->is_theme() || Extension::IsExternalLocation(install_source_)) - return true; + return CrxInstallerError(); if (!extensions_enabled_) { - *error = l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_NOT_ENABLED); - return false; + return CrxInstallerError( + l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_NOT_ENABLED)); } if (install_cause_ == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) { @@ -270,13 +268,15 @@ bool CrxInstaller::AllowInstall(const Extension* extension, } else { UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallDisallowed, NumOffStoreInstallDecision); - *error = l10n_util::GetStringUTF16( - IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE); // Don't delete source in this case so that the user can install // manually if they want. delete_source_ = false; did_handle_successfully_ = false; - return false; + + return CrxInstallerError( + CrxInstallerError::ERROR_OFF_STORE, + l10n_util::GetStringUTF16( + IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE)); } } } @@ -289,10 +289,10 @@ bool CrxInstaller::AllowInstall(const Extension* extension, if (!download_url_.SchemeIsFile() && apps_require_extension_mime_type_ && original_mime_type_ != Extension::kMimeType) { - *error = l10n_util::GetStringFUTF16( - IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE, - ASCIIToUTF16(Extension::kMimeType)); - return false; + return CrxInstallerError( + l10n_util::GetStringFUTF16( + IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE, + ASCIIToUTF16(Extension::kMimeType))); } // If the client_ is NULL, then the app is either being installed via @@ -303,10 +303,10 @@ bool CrxInstaller::AllowInstall(const Extension* extension, // from the gallery. // TODO(erikkay) Apply this rule for paid extensions and themes as well. if (extension->UpdatesFromGallery()) { - *error = l10n_util::GetStringFUTF16( - IDS_EXTENSION_DISALLOW_NON_DOWNLOADED_GALLERY_INSTALLS, - l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); - return false; + return CrxInstallerError( + l10n_util::GetStringFUTF16( + IDS_EXTENSION_DISALLOW_NON_DOWNLOADED_GALLERY_INSTALLS, + l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE))); } // For self-hosted apps, verify that the entire extent is on the same @@ -320,15 +320,15 @@ bool CrxInstaller::AllowInstall(const Extension* extension, for (URLPatternSet::const_iterator i = patterns.begin(); i != patterns.end(); ++i) { if (!pattern.MatchesHost(i->host())) { - *error = l10n_util::GetStringUTF16( - IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST); - return false; + return CrxInstallerError( + l10n_util::GetStringUTF16( + IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST)); } } } } - return true; + return CrxInstallerError(); } void CrxInstaller::OnUnpackFailure(const string16& error_message) { @@ -341,7 +341,7 @@ void CrxInstaller::OnUnpackFailure(const string16& error_message) { install_cause(), extension_misc::NUM_INSTALL_CAUSES); - ReportFailureFromFileThread(error_message); + ReportFailureFromFileThread(CrxInstallerError(error_message)); } void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, @@ -369,8 +369,8 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, // the temp dir. unpacked_extension_root_ = extension_dir; - string16 error; - if (!AllowInstall(extension, &error)) { + CrxInstallerError error = AllowInstall(extension); + if (error.type() != CrxInstallerError::ERROR_NONE) { ReportFailureFromFileThread(error); return; } @@ -398,14 +398,15 @@ void CrxInstaller::ConfirmInstall() { VLOG(1) << "This extension: " << extension_->id() << " is blacklisted. Install failed."; ReportFailureFromUIThread( - l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_INSTALL_BLACKLISTED)); + CrxInstallerError( + l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_INSTALL_BLACKLISTED))); return; } string16 error; if (!ExtensionSystem::Get(profile_)->management_policy()->UserMayLoad( extension_, &error)) { - ReportFailureFromUIThread(error); + ReportFailureFromUIThread(CrxInstallerError(error)); return; } @@ -415,9 +416,11 @@ void CrxInstaller::ConfirmInstall() { GetHostedAppByOverlappingWebExtent(extension_->web_extent()); if (overlapping_extension && overlapping_extension->id() != extension_->id()) { - ReportFailureFromUIThread(l10n_util::GetStringFUTF16( - IDS_EXTENSION_OVERLAPPING_WEB_EXTENT, - UTF8ToUTF16(overlapping_extension->name()))); + ReportFailureFromUIThread( + CrxInstallerError( + l10n_util::GetStringFUTF16( + IDS_EXTENSION_OVERLAPPING_WEB_EXTENT, + UTF8ToUTF16(overlapping_extension->name())))); return; } @@ -474,7 +477,8 @@ void CrxInstaller::CompleteInstall() { Version::GetVersionFromString(current_version_)); if (current_version->CompareTo(*(extension_->version())) > 0) { ReportFailureFromFileThread( - l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_DOWNGRADE_VERSION)); + CrxInstallerError( + l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_DOWNGRADE_VERSION))); return; } } @@ -493,8 +497,9 @@ void CrxInstaller::CompleteInstall() { install_directory_); if (version_dir.empty()) { ReportFailureFromFileThread( - l10n_util::GetStringUTF16( - IDS_EXTENSION_MOVE_DIRECTORY_TO_PROFILE_FAILED)); + CrxInstallerError( + l10n_util::GetStringUTF16( + IDS_EXTENSION_MOVE_DIRECTORY_TO_PROFILE_FAILED))); return; } @@ -516,29 +521,31 @@ void CrxInstaller::CompleteInstall() { ReportSuccessFromFileThread(); } -void CrxInstaller::ReportFailureFromFileThread(const string16& error) { +void CrxInstaller::ReportFailureFromFileThread(const CrxInstallerError& error) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); if (!BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&CrxInstaller::ReportFailureFromUIThread, this, error))) + base::Bind(&CrxInstaller::ReportFailureFromUIThread, this, error))) { NOTREACHED(); + } } -void CrxInstaller::ReportFailureFromUIThread(const string16& error) { +void CrxInstaller::ReportFailureFromUIThread(const CrxInstallerError& error) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); content::NotificationService* service = content::NotificationService::current(); service->Notify(chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, content::Source<CrxInstaller>(this), - content::Details<const string16>(&error)); + content::Details<const string16>(&error.message())); // This isn't really necessary, it is only used because unit tests expect to // see errors get reported via this interface. // // TODO(aa): Need to go through unit tests and clean them up too, probably get // rid of this line. - ExtensionErrorReporter::GetInstance()->ReportError(error, false); // quiet + ExtensionErrorReporter::GetInstance()->ReportError( + error.message(), false); // quiet if (client_) client_->OnInstallFailure(error); diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 4c6c70b..04c4c4a 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -13,6 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/version.h" +#include "chrome/browser/extensions/crx_installer_error.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/sandboxed_extension_unpacker.h" #include "chrome/browser/extensions/webstore_installer.h" @@ -186,7 +187,7 @@ class CrxInstaller // Called after OnUnpackSuccess as a last check to see whether the install // should complete. - bool AllowInstall(const extensions::Extension* extension, string16* error); + CrxInstallerError AllowInstall(const extensions::Extension* extension); // SandboxedExtensionUnpackerClient virtual void OnUnpackFailure(const string16& error_message) OVERRIDE; @@ -208,8 +209,8 @@ class CrxInstaller void CompleteInstall(); // Result reporting. - void ReportFailureFromFileThread(const string16& error); - void ReportFailureFromUIThread(const string16& error); + void ReportFailureFromFileThread(const CrxInstallerError& error); + void ReportFailureFromUIThread(const CrxInstallerError& error); void ReportSuccessFromFileThread(); void ReportSuccessFromUIThread(); void NotifyCrxInstallComplete(const extensions::Extension* extension); diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 6ecf682..a7ba2a5 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc @@ -47,8 +47,8 @@ class MockInstallPrompt : public ExtensionInstallPrompt { did_succeed_ = true; MessageLoopForUI::current()->Quit(); } - void OnInstallFailure(const string16& error) { - error_ = error; + void OnInstallFailure(const CrxInstallerError& error) { + error_ = error.message(); MessageLoopForUI::current()->Quit(); } diff --git a/chrome/browser/extensions/crx_installer_error.h b/chrome/browser/extensions/crx_installer_error.h new file mode 100644 index 0000000..f1e65f46 --- /dev/null +++ b/chrome/browser/extensions/crx_installer_error.h @@ -0,0 +1,41 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_ERROR_H_ +#define CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_ERROR_H_ +#pragma once + +#include "base/string16.h" + +// Simple error class for CrxInstaller. +class CrxInstallerError { + public: + // Typed errors that need to be handled specially by clients. + enum Type { + ERROR_NONE, + ERROR_OFF_STORE, + ERROR_OTHER + }; + + CrxInstallerError() : type_(ERROR_NONE) { + } + + explicit CrxInstallerError(const string16& message) + : type_(message.empty() ? ERROR_NONE : ERROR_OTHER), + message_(message) { + } + + CrxInstallerError(Type type, const string16& message) + : type_(type), message_(message) { + } + + Type type() const { return type_; } + const string16& message() const { return message_; } + + private: + Type type_; + string16 message_; +}; + +#endif // CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_ERROR_H_ diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index a2992fc..ccf9297 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc @@ -241,7 +241,7 @@ class MockAbortExtensionInstallPrompt : public ExtensionInstallPrompt { virtual void OnInstallSuccess(const Extension* extension, SkBitmap* icon) {} - virtual void OnInstallFailure(const string16& error) {} + virtual void OnInstallFailure(const CrxInstallerError& error) {} }; class MockAutoConfirmExtensionInstallPrompt : public ExtensionInstallPrompt { diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc index 14729f0..e738073 100644 --- a/chrome/browser/extensions/extension_install_prompt.cc +++ b/chrome/browser/extensions/extension_install_prompt.cc @@ -348,7 +348,7 @@ void ExtensionInstallPrompt::OnInstallSuccess(const Extension* extension, install_ui_->OnInstallSuccess(extension, &icon_); } -void ExtensionInstallPrompt::OnInstallFailure(const string16& error) { +void ExtensionInstallPrompt::OnInstallFailure(const CrxInstallerError& error) { install_ui_->OnInstallFailure(error); } diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h index bac327d..ce1f546 100644 --- a/chrome/browser/extensions/extension_install_prompt.h +++ b/chrome/browser/extensions/extension_install_prompt.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/string16.h" +#include "chrome/browser/extensions/crx_installer_error.h" #include "chrome/browser/extensions/image_loading_tracker.h" #include "chrome/common/extensions/url_pattern.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -205,7 +206,7 @@ class ExtensionInstallPrompt : public ImageLoadingTracker::Observer { SkBitmap* icon); // Installation failed. This is declared virtual for testing. - virtual void OnInstallFailure(const string16& error); + virtual void OnInstallFailure(const CrxInstallerError& error); // ImageLoadingTracker::Observer: virtual void OnImageLoaded(const gfx::Image& image, diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h index e5fabbe..fe83e18 100644 --- a/chrome/browser/extensions/extension_install_ui.h +++ b/chrome/browser/extensions/extension_install_ui.h @@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/string16.h" +#include "chrome/browser/extensions/crx_installer_error.h" class Browser; class SkBitmap; @@ -31,7 +32,7 @@ class ExtensionInstallUI { virtual void OnInstallSuccess(const extensions::Extension* extension, SkBitmap* icon) = 0; // Called when an extension failed to install. - virtual void OnInstallFailure(const string16& error) = 0; + virtual void OnInstallFailure(const CrxInstallerError& error) = 0; // Whether or not to show the default UI after completing the installation. virtual void SetSkipPostInstallUI(bool skip_ui) = 0; diff --git a/chrome/browser/extensions/extension_install_ui_android.cc b/chrome/browser/extensions/extension_install_ui_android.cc index 027ec93..c82cadd 100644 --- a/chrome/browser/extensions/extension_install_ui_android.cc +++ b/chrome/browser/extensions/extension_install_ui_android.cc @@ -11,7 +11,8 @@ void ExtensionInstallUIAndroid::OnInstallSuccess(const Extension* extension, NOTIMPLEMENTED(); } -void ExtensionInstallUIAndroid::OnInstallFailure(const string16& error) { +void ExtensionInstallUIAndroid::OnInstallFailure( + const CrxInstallerError& error) { NOTIMPLEMENTED(); } diff --git a/chrome/browser/extensions/extension_install_ui_android.h b/chrome/browser/extensions/extension_install_ui_android.h index 5d36f38..4e1d90f 100644 --- a/chrome/browser/extensions/extension_install_ui_android.h +++ b/chrome/browser/extensions/extension_install_ui_android.h @@ -16,7 +16,7 @@ class ExtensionInstallUIAndroid : public ExtensionInstallUI { // ExtensionInstallUI implementation: virtual void OnInstallSuccess(const extensions::Extension* extension, SkBitmap* icon); - virtual void OnInstallFailure(const string16& error); + virtual void OnInstallFailure(const CrxInstallerError& error); virtual void SetSkipPostInstallUI(bool skip_ui); private: diff --git a/chrome/browser/extensions/extension_install_ui_default.cc b/chrome/browser/extensions/extension_install_ui_default.cc index a3b0cda..06c3ed7 100644 --- a/chrome/browser/extensions/extension_install_ui_default.cc +++ b/chrome/browser/extensions/extension_install_ui_default.cc @@ -5,10 +5,12 @@ #include "chrome/browser/extensions/extension_install_ui_default.h" #include "base/command_line.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/theme_installed_infobar_delegate.h" #include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/tab_contents/confirm_infobar_delegate.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser.h" @@ -42,6 +44,47 @@ namespace { bool disable_failure_ui_for_tests = false; +// Helper class to put up an infobar when installation fails. +class ErrorInfobarDelegate : public ConfirmInfoBarDelegate { + public: + ErrorInfobarDelegate(InfoBarTabHelper* infobar_helper, + Browser* browser, + const CrxInstallerError& error) + : ConfirmInfoBarDelegate(infobar_helper), + browser_(browser), + error_(error) { + } + + private: + virtual string16 GetMessageText() const OVERRIDE { + return error_.message(); + } + + virtual int GetButtons() const OVERRIDE { + return BUTTON_OK; + } + + virtual string16 GetLinkText() const OVERRIDE { + // TODO(aa): Return the learn more link once we have the help article + // posted. + // return error_.type() == CrxInstallerError::ERROR_OFF_STORE ? + // l10n_util::GetStringUTF16(IDS_LEARN_MORE) : ASCIIToUTF16(""); + return ASCIIToUTF16(""); + } + + virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE { + browser::NavigateParams params(browser_, + GURL("http://www.google.com/"), + content::PAGE_TRANSITION_LINK); + params.disposition = NEW_FOREGROUND_TAB; + browser::Navigate(¶ms); + return false; + } + + Browser* browser_; + CrxInstallerError error_; +}; + } // namespace ExtensionInstallUIDefault::ExtensionInstallUIDefault(Browser* browser) @@ -100,15 +143,19 @@ void ExtensionInstallUIDefault::OnInstallSuccess(const Extension* extension, current_profile); } -void ExtensionInstallUIDefault::OnInstallFailure(const string16& error) { +void ExtensionInstallUIDefault::OnInstallFailure( + const CrxInstallerError& error) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (disable_failure_ui_for_tests || skip_post_install_ui_) return; Browser* browser = browser::FindLastActiveWithProfile(browser_->profile()); - browser::ShowMessageBox(browser ? browser->window()->GetNativeWindow() : NULL, - l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_FAILURE_TITLE), error, - browser::MESSAGE_BOX_TYPE_WARNING); + TabContents* tab_contents = browser->GetActiveTabContents(); + if (!tab_contents) + return; + InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper(); + infobar_helper->AddInfoBar( + new ErrorInfobarDelegate(infobar_helper, browser, error)); } void ExtensionInstallUIDefault::SetSkipPostInstallUI(bool skip_ui) { diff --git a/chrome/browser/extensions/extension_install_ui_default.h b/chrome/browser/extensions/extension_install_ui_default.h index 6c872be..74577d5 100644 --- a/chrome/browser/extensions/extension_install_ui_default.h +++ b/chrome/browser/extensions/extension_install_ui_default.h @@ -20,7 +20,7 @@ class ExtensionInstallUIDefault : public ExtensionInstallUI { // ExtensionInstallUI implementation: virtual void OnInstallSuccess(const extensions::Extension* extension, SkBitmap* icon) OVERRIDE; - virtual void OnInstallFailure(const string16& error) OVERRIDE; + virtual void OnInstallFailure(const CrxInstallerError& error) OVERRIDE; virtual void SetSkipPostInstallUI(bool skip_ui) OVERRIDE; virtual void SetUseAppInstalledBubble(bool use_bubble) OVERRIDE; diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 8718173..7fa79f3 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -245,6 +245,7 @@ 'browser/extensions/convert_web_app.h', 'browser/extensions/crx_installer.cc', 'browser/extensions/crx_installer.h', + 'browser/extensions/crx_installer_error.h', 'browser/extensions/default_apps.cc', 'browser/extensions/default_apps.h', 'browser/extensions/default_apps_trial.cc', |