1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/extension_infobar_delegate.h" 6 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/extensions/extension_view_host.h" 9 #include "chrome/browser/extensions/extension_view_host_factory.h" 10 #include "chrome/browser/infobars/infobar_service.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/ui/browser.h" 13 #include "components/infobars/core/infobar.h" 14 #include "content/public/browser/notification_details.h" 15 #include "content/public/browser/notification_source.h" 16 #include "extensions/browser/extension_registry.h" 17 #include "extensions/common/extension.h" 18 19 ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() { 20 } 21 22 // static 23 void ExtensionInfoBarDelegate::Create(content::WebContents* web_contents, 24 Browser* browser, 25 const extensions::Extension* extension, 26 const GURL& url, 27 int height) { 28 InfoBarService::FromWebContents(web_contents)->AddInfoBar( 29 ExtensionInfoBarDelegate::CreateInfoBar( 30 scoped_ptr<ExtensionInfoBarDelegate>(new ExtensionInfoBarDelegate( 31 browser, extension, url, web_contents, height)))); 32 } 33 34 ExtensionInfoBarDelegate::ExtensionInfoBarDelegate( 35 Browser* browser, 36 const extensions::Extension* extension, 37 const GURL& url, 38 content::WebContents* web_contents, 39 int height) 40 : infobars::InfoBarDelegate(), 41 #if defined(TOOLKIT_VIEWS) 42 browser_(browser), 43 #endif 44 extension_(extension), 45 extension_registry_observer_(this), 46 closing_(false) { 47 extension_view_host_.reset( 48 extensions::ExtensionViewHostFactory::CreateInfobarHost(url, browser)); 49 extension_view_host_->SetAssociatedWebContents(web_contents); 50 51 extension_registry_observer_.Add( 52 extensions::ExtensionRegistry::Get(browser->profile())); 53 registrar_.Add(this, 54 extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 55 content::Source<Profile>(browser->profile())); 56 57 height_ = std::max(0, height); 58 height_ = std::min(2 * infobars::InfoBar::kDefaultBarTargetHeight, height_); 59 if (height_ == 0) 60 height_ = infobars::InfoBar::kDefaultBarTargetHeight; 61 } 62 63 content::WebContents* ExtensionInfoBarDelegate::GetWebContents() { 64 return InfoBarService::WebContentsFromInfoBar(infobar()); 65 } 66 67 // ExtensionInfoBarDelegate::CreateInfoBar() is implemented in platform-specific 68 // files. 69 70 bool ExtensionInfoBarDelegate::EqualsDelegate( 71 infobars::InfoBarDelegate* delegate) const { 72 ExtensionInfoBarDelegate* extension_delegate = 73 delegate->AsExtensionInfoBarDelegate(); 74 // When an extension crashes, an InfoBar is shown (for the crashed extension). 75 // That will result in a call to this function (to see if this InfoBarDelegate 76 // is already showing the 'extension crashed InfoBar', which it never is), but 77 // if it is our extension that crashes, the extension delegate is NULL so 78 // we cannot check. 79 if (!extension_delegate) 80 return false; 81 82 // Only allow one InfoBar at a time per extension. 83 return extension_delegate->extension_view_host()->extension() == 84 extension_view_host_->extension(); 85 } 86 87 void ExtensionInfoBarDelegate::InfoBarDismissed() { 88 closing_ = true; 89 } 90 91 infobars::InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() 92 const { 93 return PAGE_ACTION_TYPE; 94 } 95 96 ExtensionInfoBarDelegate* 97 ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() { 98 return this; 99 } 100 101 void ExtensionInfoBarDelegate::OnExtensionUnloaded( 102 content::BrowserContext* browser_context, 103 const extensions::Extension* extension, 104 extensions::UnloadedExtensionInfo::Reason reason) { 105 if (extension_ == extension) 106 infobar()->RemoveSelf(); 107 } 108 109 void ExtensionInfoBarDelegate::Observe( 110 int type, 111 const content::NotificationSource& source, 112 const content::NotificationDetails& details) { 113 DCHECK_EQ(type, extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE); 114 if (extension_view_host_.get() == 115 content::Details<extensions::ExtensionHost>(details).ptr()) 116 infobar()->RemoveSelf(); 117 } 118