summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 18:42:09 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 18:42:09 +0000
commit4704fa5e6894a2ec42cdbcda9da18f8d203e634d (patch)
treea7bbfcbc6b1c017152048d05378c0c58951ff512
parentf7158b04f32b8cd19b922bb7b8fccc41a43c5dd4 (diff)
downloadchromium_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.grd2
-rw-r--r--chrome/browser/download/download_browsertest.cc4
-rw-r--r--chrome/browser/extensions/crx_installer.cc105
-rw-r--r--chrome/browser/extensions/crx_installer.h7
-rw-r--r--chrome/browser/extensions/crx_installer_browsertest.cc4
-rw-r--r--chrome/browser/extensions/crx_installer_error.h41
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc2
-rw-r--r--chrome/browser/extensions/extension_install_prompt.cc2
-rw-r--r--chrome/browser/extensions/extension_install_prompt.h3
-rw-r--r--chrome/browser/extensions/extension_install_ui.h3
-rw-r--r--chrome/browser/extensions/extension_install_ui_android.cc3
-rw-r--r--chrome/browser/extensions/extension_install_ui_android.h2
-rw-r--r--chrome/browser/extensions/extension_install_ui_default.cc55
-rw-r--r--chrome/browser/extensions/extension_install_ui_default.h2
-rw-r--r--chrome/chrome_browser_extensions.gypi1
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(&params);
+ 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',