Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1856)

Unified Diff: chrome/browser/extensions/extension_disabled_ui.cc

Issue 9718008: Replace extension disabled infobar with a global error. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 2 Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_disabled_ui.cc
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc
new file mode 100644
index 0000000000000000000000000000000000000000..86afcbb589ec67218064af7b843def2b5a3b8fdd
--- /dev/null
+++ b/chrome/browser/extensions/extension_disabled_ui.cc
@@ -0,0 +1,291 @@
+// 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.
+
+#include "chrome/browser/extensions/extension_disabled_ui.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/message_loop.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_uninstall_dialog.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error_service.h"
+#include "chrome/browser/ui/global_error_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_source.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace {
+
+static base::LazyInstance<
+ std::bitset<IDC_EXTENSION_DISABLED_LAST -
+ IDC_EXTENSION_DISABLED_FIRST + 1> >
+ menu_command_ids = LAZY_INSTANCE_INITIALIZER;
+
+// Get an available menu ID.
+int GetMenuCommandID() {
+ int id;
+ for (id = IDC_EXTENSION_DISABLED_FIRST;
+ id <= IDC_EXTENSION_DISABLED_LAST; ++id) {
+ if (!menu_command_ids.Get()[id - IDC_EXTENSION_DISABLED_FIRST]) {
+ menu_command_ids.Get().set(id - IDC_EXTENSION_DISABLED_FIRST);
+ return id;
+ }
+ }
+ // This should not happen.
+ DCHECK(id <= IDC_EXTENSION_DISABLED_LAST) <<
+ "No available menu command IDs for ExtensionDisabledGlobalError";
+ return IDC_EXTENSION_DISABLED_LAST;
+}
+
+// Make a menu ID available when it is no longer used.
+void ReleaseMenuCommandID(int id) {
+ menu_command_ids.Get().reset(id - IDC_EXTENSION_DISABLED_FIRST);
+}
+
+} // namespace
+
+// ExtensionDisabledDialogDelegate --------------------------------------------
+
+class ExtensionDisabledDialogDelegate
+ : public ExtensionInstallUI::Delegate,
+ public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> {
+ public:
+ ExtensionDisabledDialogDelegate(Profile* profile,
+ ExtensionService* service,
+ const Extension* extension);
+
+ private:
+ friend class base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate>;
+
+ virtual ~ExtensionDisabledDialogDelegate();
+
+ // ExtensionInstallUI::Delegate:
+ virtual void InstallUIProceed() OVERRIDE;
+ virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
+
+ // The UI for showing the install dialog when enabling.
+ scoped_ptr<ExtensionInstallUI> install_ui_;
+
+ ExtensionService* service_;
+ const Extension* extension_;
+};
+
+ExtensionDisabledDialogDelegate::ExtensionDisabledDialogDelegate(
+ Profile* profile,
+ ExtensionService* service,
+ const Extension* extension)
+ : service_(service), extension_(extension) {
+ AddRef(); // Balanced in Proceed or Abort.
+
+ install_ui_.reset(new ExtensionInstallUI(profile));
+ install_ui_->ConfirmReEnable(this, extension_);
+}
+
+ExtensionDisabledDialogDelegate::~ExtensionDisabledDialogDelegate() {
+}
+
+void ExtensionDisabledDialogDelegate::InstallUIProceed() {
+ service_->GrantPermissionsAndEnableExtension(extension_);
+ Release();
+}
+
+void ExtensionDisabledDialogDelegate::InstallUIAbort(bool user_initiated) {
+ std::string histogram_name = user_initiated ?
+ "Extensions.Permissions_ReEnableCancel" :
+ "Extensions.Permissions_ReEnableAbort";
+ ExtensionService::RecordPermissionMessagesHistogram(
+ extension_, histogram_name.c_str());
+
+ // Do nothing. The extension will remain disabled.
+ Release();
+}
+
+// ExtensionDisabledGlobalError -----------------------------------------------
+
+class ExtensionDisabledGlobalError : public GlobalError,
+ public content::NotificationObserver,
+ public ExtensionUninstallDialog::Delegate {
+ public:
+ ExtensionDisabledGlobalError(ExtensionService* service,
+ const Extension* extension);
+ virtual ~ExtensionDisabledGlobalError();
+
+ // GlobalError implementation.
+ virtual bool HasBadge() OVERRIDE;
+ virtual bool HasMenuItem() OVERRIDE;
+ virtual int MenuItemCommandID() OVERRIDE;
+ virtual string16 MenuItemLabel() OVERRIDE;
+ virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
+ virtual bool HasBubbleView() OVERRIDE;
+ virtual string16 GetBubbleViewTitle() OVERRIDE;
+ virtual string16 GetBubbleViewMessage() OVERRIDE;
+ virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
+ virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
+
+ // ExtensionUninstallDialog::Delegate implementation.
+ virtual void ExtensionUninstallAccepted() OVERRIDE;
+ virtual void ExtensionUninstallCanceled() OVERRIDE;
+
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ private:
+ ExtensionService* service_;
+ const Extension* extension_;
+
+ scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_;
+
+ // Menu command ID assigned for this extension's error.
+ int menu_command_id_;
+
+ content::NotificationRegistrar registrar_;
+};
+
+// TODO(yoz): create error at startup for disabled extensions.
+ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
+ ExtensionService* service,
+ const Extension* extension)
+ : service_(service),
+ extension_(extension),
+ menu_command_id_(GetMenuCommandID()) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
+ content::Source<Profile>(service->profile()));
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
+ content::Source<Profile>(service->profile()));
+}
+
+ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
+}
+
+bool ExtensionDisabledGlobalError::HasBadge() {
+ return true;
+}
+
+bool ExtensionDisabledGlobalError::HasMenuItem() {
+ return true;
+}
+
+int ExtensionDisabledGlobalError::MenuItemCommandID() {
+ return menu_command_id_;
+}
+
+string16 ExtensionDisabledGlobalError::MenuItemLabel() {
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
+ UTF8ToUTF16(extension_->name()));
+}
+
+void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) {
+ ShowBubbleView(browser);
+}
+
+bool ExtensionDisabledGlobalError::HasBubbleView() {
+ return true;
+}
+
+string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() {
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE,
+ UTF8ToUTF16(extension_->name()));
+}
+
+string16 ExtensionDisabledGlobalError::GetBubbleViewMessage() {
+ return l10n_util::GetStringFUTF16(extension_->is_app() ?
+ IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL,
+ UTF8ToUTF16(extension_->name()));
+}
+
+string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() {
+ return l10n_util::GetStringUTF16(
+ IDS_EXTENSION_DISABLED_ERROR_ENABLE_BUTTON);
+}
+
+string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() {
+ return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL);
+}
+
+void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) {
+}
+
+void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed(
+ Browser* browser) {
+ new ExtensionDisabledDialogDelegate(service_->profile(), service_,
+ extension_);
+}
+
+void ExtensionDisabledGlobalError::BubbleViewCancelButtonPressed(
+ Browser* browser) {
+ uninstall_dialog_.reset(
+ ExtensionUninstallDialog::Create(service_->profile(), this));
+ uninstall_dialog_->ConfirmUninstall(extension_);
+}
+
+void ExtensionDisabledGlobalError::ExtensionUninstallAccepted() {
+ service_->UninstallExtension(extension_->id(), false, NULL);
+}
+
+void ExtensionDisabledGlobalError::ExtensionUninstallCanceled() {
+ // Nothing happens, and the error is still there.
+}
+
+void ExtensionDisabledGlobalError::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ const Extension* extension = NULL;
+ // The error is invalidated if the extension has been reloaded
+ // or unloaded.
+ if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
+ extension = content::Details<const Extension>(details).ptr();
+ } else {
+ DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNLOADED, type);
+ UnloadedExtensionInfo* info =
+ content::Details<UnloadedExtensionInfo>(details).ptr();
+ extension = info->extension;
+ }
+ if (extension == extension_) {
+ GlobalErrorServiceFactory::GetForProfile(service_->profile())->
+ RemoveGlobalError(this);
+ ReleaseMenuCommandID(menu_command_id_);
+ delete this;
+ }
+}
+
+// Globals --------------------------------------------------------------------
+
+namespace extensions {
+
+void ShowExtensionDisabledUI(ExtensionService* service,
+ Profile* profile,
+ const Extension* extension) {
+ GlobalErrorServiceFactory::GetForProfile(service->profile())->
+ AddGlobalError(new ExtensionDisabledGlobalError(service, extension));
+}
+
+void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
+ const Extension* extension) {
+ // This object manages its own lifetime.
+ new ExtensionDisabledDialogDelegate(profile, service, extension);
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698