// 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 "chrome/browser/extensions/extension_disabled_infobar_delegate.h" #include #include "app/l10n_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/browser_list.h" #include "chrome/common/extensions/extension_file_util.h" #include "chrome/common/extensions/extension_resource.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/notification_source.h" #include "grit/generated_resources.h" class ExtensionDisabledDialogDelegate : public ExtensionInstallUI::Delegate, public base::RefCountedThreadSafe { public: 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_->ConfirmInstall(this, extension_); } // Overridden from ExtensionInstallUI::Delegate: virtual void InstallUIProceed() { service_->GrantPermissionsAndEnableExtension(extension_); Release(); } virtual void InstallUIAbort() { // Do nothing. The extension will remain disabled. Release(); } private: friend class base::RefCountedThreadSafe; virtual ~ExtensionDisabledDialogDelegate() {} // The UI for showing the install dialog when enabling. scoped_ptr install_ui_; ExtensionService* service_; const Extension* extension_; }; class ExtensionDisabledInfobarDelegate : public ConfirmInfoBarDelegate, public NotificationObserver { public: ExtensionDisabledInfobarDelegate(TabContents* tab_contents, ExtensionService* service, const Extension* extension) : ConfirmInfoBarDelegate(tab_contents), tab_contents_(tab_contents), service_(service), extension_(extension) { // The user might re-enable the extension in other ways, so watch for that. registrar_.Add(this, NotificationType::EXTENSION_LOADED, Source(service->profile())); registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, Source(service->profile())); } virtual ~ExtensionDisabledInfobarDelegate() { } virtual string16 GetMessageText() const { return l10n_util::GetStringFUTF16(extension_->is_app() ? IDS_APP_DISABLED_INFOBAR_LABEL : IDS_EXTENSION_DISABLED_INFOBAR_LABEL, UTF8ToUTF16(extension_->name())); } virtual SkBitmap* GetIcon() const { return NULL; } virtual int GetButtons() const { return BUTTON_OK; } virtual string16 GetButtonLabel( ConfirmInfoBarDelegate::InfoBarButton button) const { return l10n_util::GetStringUTF16( IDS_EXTENSION_DISABLED_INFOBAR_ENABLE_BUTTON); } virtual bool Accept() { // This object manages its own lifetime. new ExtensionDisabledDialogDelegate(tab_contents_->profile(), service_, extension_); return true; } virtual void InfoBarClosed() { delete this; } virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { // TODO(mpcomplete): RemoveInfoBar doesn't seem to always result in us // getting deleted. const Extension* extension = NULL; switch (type.value) { case NotificationType::EXTENSION_LOADED: extension = Details(details).ptr(); break; case NotificationType::EXTENSION_UNLOADED: { UnloadedExtensionInfo* info = Details(details).ptr(); if (info->reason == UnloadedExtensionInfo::DISABLE) extension = info->extension; break; } default: NOTREACHED(); return; } if (extension == extension_) tab_contents_->RemoveInfoBar(this); } private: NotificationRegistrar registrar_; TabContents* tab_contents_; ExtensionService* service_; const Extension* extension_; }; void ShowExtensionDisabledUI(ExtensionService* service, Profile* profile, const Extension* extension) { Browser* browser = BrowserList::GetLastActiveWithProfile(profile); if (!browser) return; TabContents* tab_contents = browser->GetSelectedTabContents(); if (!tab_contents) return; tab_contents->AddInfoBar(new ExtensionDisabledInfobarDelegate( tab_contents, service, extension)); } void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile, const Extension* extension) { // This object manages its own lifetime. new ExtensionDisabledDialogDelegate(profile, service, extension); }