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_host.h"
      9 #include "chrome/browser/extensions/extension_process_manager.h"
     10 #include "chrome/browser/extensions/extension_system.h"
     11 #include "chrome/browser/infobars/infobar.h"
     12 #include "chrome/browser/infobars/infobar_service.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/ui/browser.h"
     15 #include "chrome/common/extensions/extension.h"
     16 #include "content/public/browser/notification_details.h"
     17 #include "content/public/browser/notification_source.h"
     18 
     19 
     20 ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() {
     21   if (observer_)
     22     observer_->OnDelegateDeleted();
     23 }
     24 
     25 // static
     26 void ExtensionInfoBarDelegate::Create(InfoBarService* infobar_service,
     27                                       Browser* browser,
     28                                       const extensions::Extension* extension,
     29                                       const GURL& url,
     30                                       int height) {
     31   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
     32       new ExtensionInfoBarDelegate(browser, infobar_service, extension, url,
     33                                    infobar_service->web_contents(), height)));
     34 }
     35 
     36 ExtensionInfoBarDelegate::ExtensionInfoBarDelegate(
     37     Browser* browser,
     38     InfoBarService* infobar_service,
     39     const extensions::Extension* extension,
     40     const GURL& url,
     41     content::WebContents* web_contents,
     42     int height)
     43     : InfoBarDelegate(infobar_service),
     44 #if defined(TOOLKIT_VIEWS)
     45       browser_(browser),
     46 #endif
     47       observer_(NULL),
     48       extension_(extension),
     49       closing_(false) {
     50   ExtensionProcessManager* manager =
     51       extensions::ExtensionSystem::Get(browser->profile())->process_manager();
     52   extension_host_.reset(manager->CreateInfobarHost(url, browser));
     53   extension_host_->SetAssociatedWebContents(web_contents);
     54 
     55   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
     56                  content::Source<Profile>(browser->profile()));
     57   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
     58                  content::Source<Profile>(browser->profile()));
     59 
     60 #if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK) || defined(OS_ANDROID)
     61   // TODO(dtrainor): On Android, this is not used.  Might need to pull this from
     62   // Android UI level in the future.  Tracked via issue 115303.
     63   int default_height = InfoBar::kDefaultBarTargetHeight;
     64 #elif defined(OS_MACOSX)
     65   // TODO(pkasting): Once Infobars have been ported to Mac, we can remove the
     66   // ifdefs and just use the Infobar constant below.
     67   int default_height = 36;
     68 #endif
     69   height_ = std::max(0, height);
     70   height_ = std::min(2 * default_height, height_);
     71   if (height_ == 0)
     72     height_ = default_height;
     73 }
     74 
     75 bool ExtensionInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
     76   ExtensionInfoBarDelegate* extension_delegate =
     77       delegate->AsExtensionInfoBarDelegate();
     78   // When an extension crashes, an InfoBar is shown (for the crashed extension).
     79   // That will result in a call to this function (to see if this InfoBarDelegate
     80   // is already showing the 'extension crashed InfoBar', which it never is), but
     81   // if it is our extension that crashes, the extension delegate is NULL so
     82   // we cannot check.
     83   if (!extension_delegate)
     84     return false;
     85 
     86   // Only allow one InfoBar at a time per extension.
     87   return extension_delegate->extension_host()->extension() ==
     88          extension_host_->extension();
     89 }
     90 
     91 void ExtensionInfoBarDelegate::InfoBarDismissed() {
     92   closing_ = true;
     93 }
     94 
     95 InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() const {
     96   return PAGE_ACTION_TYPE;
     97 }
     98 
     99 ExtensionInfoBarDelegate*
    100     ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() {
    101   return this;
    102 }
    103 
    104 void ExtensionInfoBarDelegate::Observe(
    105     int type,
    106     const content::NotificationSource& source,
    107     const content::NotificationDetails& details) {
    108   if (type == chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE) {
    109     if (extension_host_.get() ==
    110         content::Details<extensions::ExtensionHost>(details).ptr())
    111       RemoveSelf();
    112   } else {
    113     DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED);
    114     if (extension_ == content::Details<extensions::UnloadedExtensionInfo>(
    115         details)->extension)
    116       RemoveSelf();
    117   }
    118 }
    119