Home | History | Annotate | Download | only in extensions
      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