1// Copyright (c) 2011 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/extensions/extension_host.h" 8#include "chrome/browser/extensions/extension_process_manager.h" 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/browser/ui/browser.h" 11#include "chrome/common/extensions/extension.h" 12#include "content/browser/tab_contents/tab_contents.h" 13#include "content/common/notification_details.h" 14#include "content/common/notification_source.h" 15#include "content/common/notification_type.h" 16 17ExtensionInfoBarDelegate::ExtensionInfoBarDelegate(Browser* browser, 18 TabContents* tab_contents, 19 const Extension* extension, 20 const GURL& url) 21 : InfoBarDelegate(tab_contents), 22 observer_(NULL), 23 extension_(extension), 24 tab_contents_(tab_contents), 25 closing_(false) { 26 ExtensionProcessManager* manager = 27 browser->profile()->GetExtensionProcessManager(); 28 extension_host_.reset(manager->CreateInfobar(url, browser)); 29 extension_host_->set_associated_tab_contents(tab_contents); 30 31 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 32 Source<Profile>(browser->profile())); 33 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 34 Source<Profile>(browser->profile())); 35} 36 37ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() { 38 if (observer_) 39 observer_->OnDelegateDeleted(); 40} 41 42bool ExtensionInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const { 43 ExtensionInfoBarDelegate* extension_delegate = 44 delegate->AsExtensionInfoBarDelegate(); 45 // When an extension crashes, an InfoBar is shown (for the crashed extension). 46 // That will result in a call to this function (to see if this InfoBarDelegate 47 // is already showing the 'extension crashed InfoBar', which it never is), but 48 // if it is our extension that crashes, the extension delegate is NULL so 49 // we cannot check. 50 if (!extension_delegate) 51 return false; 52 53 // Only allow one InfoBar at a time per extension. 54 return extension_delegate->extension_host()->extension() == 55 extension_host_->extension(); 56} 57 58void ExtensionInfoBarDelegate::InfoBarDismissed() { 59 closing_ = true; 60} 61 62void ExtensionInfoBarDelegate::InfoBarClosed() { 63 delete this; 64} 65 66InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() const { 67 return PAGE_ACTION_TYPE; 68} 69 70ExtensionInfoBarDelegate* 71 ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() { 72 return this; 73} 74 75void ExtensionInfoBarDelegate::Observe(NotificationType type, 76 const NotificationSource& source, 77 const NotificationDetails& details) { 78 switch (type.value) { 79 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: { 80 const ExtensionHost* result = Details<ExtensionHost>(details).ptr(); 81 if (extension_host_.get() == result) 82 tab_contents_->RemoveInfoBar(this); 83 break; 84 } 85 case NotificationType::EXTENSION_UNLOADED: { 86 const Extension* extension = 87 Details<UnloadedExtensionInfo>(details)->extension; 88 if (extension_ == extension) 89 tab_contents_->RemoveInfoBar(this); 90 break; 91 } 92 default: { 93 NOTREACHED() << "Unknown message"; 94 break; 95 } 96 } 97} 98