172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string> 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_install_ui.h" 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_file_util.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_resource.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_details.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ExtensionDisabledDialogDelegate -------------------------------------------- 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionDisabledDialogDelegate 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : public ExtensionInstallUI::Delegate, 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionDisabledDialogDelegate(Profile* profile, 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionService* service, 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension* extension); 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate>; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual ~ExtensionDisabledDialogDelegate(); 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ExtensionInstallUI::Delegate: 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void InstallUIProceed(); 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void InstallUIAbort(); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The UI for showing the install dialog when enabling. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ExtensionInstallUI> install_ui_; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionService* service_; 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* extension_; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenExtensionDisabledDialogDelegate::ExtensionDisabledDialogDelegate( 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Profile* profile, 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ExtensionService* service, 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension* extension) 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : service_(service), extension_(extension) { 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AddRef(); // Balanced in Proceed or Abort. 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen install_ui_.reset(new ExtensionInstallUI(profile)); 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen install_ui_->ConfirmReEnable(this, extension_); 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenExtensionDisabledDialogDelegate::~ExtensionDisabledDialogDelegate() { 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionDisabledDialogDelegate::InstallUIProceed() { 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen service_->GrantPermissionsAndEnableExtension(extension_); 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Release(); 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionDisabledDialogDelegate::InstallUIAbort() { 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionService::RecordPermissionMessagesHistogram( 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension_, "Extensions.Permissions_ReEnableCancel"); 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Do nothing. The extension will remain disabled. 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Release(); 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ExtensionDisabledInfobarDelegate ------------------------------------------- 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass ExtensionDisabledInfobarDelegate : public ConfirmInfoBarDelegate, 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public NotificationObserver { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionDisabledInfobarDelegate(TabContents* tab_contents, 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionService* service, 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension* extension); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual ~ExtensionDisabledInfobarDelegate(); 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ConfirmInfoBarDelegate: 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void InfoBarClosed(); 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual string16 GetMessageText() const; 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int GetButtons() const; 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual string16 GetButtonLabel(InfoBarButton button) const; 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool Accept(); 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // NotificationObserver: 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Observe(NotificationType type, 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const NotificationDetails& details); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationRegistrar registrar_; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents_; 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionService* service_; 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* extension_; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenExtensionDisabledInfobarDelegate::ExtensionDisabledInfobarDelegate( 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TabContents* tab_contents, 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ExtensionService* service, 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension* extension) 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : ConfirmInfoBarDelegate(tab_contents), 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen tab_contents_(tab_contents), 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen service_(service), 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen extension_(extension) { 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The user might re-enable the extension in other ways, so watch for that. 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen registrar_.Add(this, NotificationType::EXTENSION_LOADED, 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Source<Profile>(service->profile())); 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Source<Profile>(service->profile())); 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenExtensionDisabledInfobarDelegate::~ExtensionDisabledInfobarDelegate() { 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionDisabledInfobarDelegate::InfoBarClosed() { 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delete this; 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 ExtensionDisabledInfobarDelegate::GetMessageText() const { 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return l10n_util::GetStringFUTF16(extension_->is_app() ? 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IDS_APP_DISABLED_INFOBAR_LABEL : IDS_EXTENSION_DISABLED_INFOBAR_LABEL, 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UTF8ToUTF16(extension_->name())); 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint ExtensionDisabledInfobarDelegate::GetButtons() const { 13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return BUTTON_OK; 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 ExtensionDisabledInfobarDelegate::GetButtonLabel( 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InfoBarButton button) const { 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK_EQ(BUTTON_OK, button); 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return l10n_util::GetStringUTF16( 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IDS_EXTENSION_DISABLED_INFOBAR_ENABLE_BUTTON); 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ExtensionDisabledInfobarDelegate::Accept() { 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This object manages its own lifetime. 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new ExtensionDisabledDialogDelegate(tab_contents_->profile(), service_, 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen extension_); 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionDisabledInfobarDelegate::Observe( 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotificationType type, 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const NotificationSource& source, 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const NotificationDetails& details) { 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(mpcomplete): RemoveInfoBar doesn't seem to always result in us getting 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // deleted. 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension* extension; 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (type.value == NotificationType::EXTENSION_LOADED) { 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen extension = Details<const Extension>(details).ptr(); 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK_EQ(NotificationType::EXTENSION_UNLOADED, type.value); 16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UnloadedExtensionInfo* info = Details<UnloadedExtensionInfo>(details).ptr(); 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen extension = (info->reason == UnloadedExtensionInfo::DISABLE) ? 16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen info->extension : NULL; 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (extension == extension_) 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen tab_contents_->RemoveInfoBar(this); 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Globals -------------------------------------------------------------------- 17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ShowExtensionDisabledUI(ExtensionService* service, Profile* profile, 176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* extension) { 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser = BrowserList::GetLastActiveWithProfile(profile); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser) 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = browser->GetSelectedTabContents(); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tab_contents) 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents->AddInfoBar(new ExtensionDisabledInfobarDelegate( 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tab_contents, service, extension)); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile, 190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* extension) { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This object manages its own lifetime. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new ExtensionDisabledDialogDelegate(profile, service, extension); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 194