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 17 ExtensionInfoBarDelegate::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 37 ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() { 38 if (observer_) 39 observer_->OnDelegateDeleted(); 40 } 41 42 bool 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 58 void ExtensionInfoBarDelegate::InfoBarDismissed() { 59 closing_ = true; 60 } 61 62 void ExtensionInfoBarDelegate::InfoBarClosed() { 63 delete this; 64 } 65 66 InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() const { 67 return PAGE_ACTION_TYPE; 68 } 69 70 ExtensionInfoBarDelegate* 71 ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() { 72 return this; 73 } 74 75 void 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