15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_infobar_delegate.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_host.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_process_manager.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/infobars/infobar.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (observer_) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_->OnDelegateDeleted(); 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionInfoBarDelegate::Create(InfoBarService* infobar_service, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser, 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension* extension, 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int height) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ExtensionInfoBarDelegate(browser, infobar_service, extension, url, 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch infobar_service->web_contents(), height))); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionInfoBarDelegate::ExtensionInfoBarDelegate( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarService* infobar_service, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::WebContents* web_contents, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height) 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : InfoBarDelegate(infobar_service), 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(TOOLKIT_VIEWS) 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_(browser), 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_(NULL), 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch extension_(extension), 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closing_(false) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionProcessManager* manager = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionSystem::Get(browser->profile())->process_manager(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_host_.reset(manager->CreateInfobarHost(url, browser)); 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch extension_host_->SetAssociatedWebContents(web_contents); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(browser->profile())); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(browser->profile())); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK) || defined(OS_ANDROID) 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(dtrainor): On Android, this is not used. Might need to pull this from 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Android UI level in the future. Tracked via issue 115303. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int default_height = InfoBar::kDefaultBarTargetHeight; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkasting): Once Infobars have been ported to Mac, we can remove the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ifdefs and just use the Infobar constant below. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int default_height = 36; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height_ = std::max(0, height); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height_ = std::min(2 * default_height, height_); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (height_ == 0) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) height_ = default_height; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoBarDelegate* extension_delegate = 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->AsExtensionInfoBarDelegate(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When an extension crashes, an InfoBar is shown (for the crashed extension). 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // That will result in a call to this function (to see if this InfoBarDelegate 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is already showing the 'extension crashed InfoBar', which it never is), but 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if it is our extension that crashes, the extension delegate is NULL so 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we cannot check. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_delegate) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only allow one InfoBar at a time per extension. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_delegate->extension_host()->extension() == 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_host_->extension(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionInfoBarDelegate::InfoBarDismissed() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closing_ = true; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InfoBarDelegate::Type ExtensionInfoBarDelegate::GetInfoBarType() const { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PAGE_ACTION_TYPE; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionInfoBarDelegate* 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoBarDelegate::AsExtensionInfoBarDelegate() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionInfoBarDelegate::Observe( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_host_.get() == 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<extensions::ExtensionHost>(details).ptr()) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSelf(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED); 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (extension_ == content::Details<extensions::UnloadedExtensionInfo>( 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch details)->extension) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSelf(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 119