balloon_host.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 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/notifications/balloon_host.h" 6 7#include "chrome/browser/browser_list.h" 8#include "chrome/browser/extensions/extension_process_manager.h" 9#include "chrome/browser/notifications/balloon.h" 10#include "chrome/browser/profile.h" 11#include "chrome/browser/renderer_host/render_view_host.h" 12#include "chrome/browser/renderer_host/site_instance.h" 13#include "chrome/browser/renderer_preferences_util.h" 14#include "chrome/common/bindings_policy.h" 15#include "chrome/common/notification_service.h" 16#include "chrome/common/notification_type.h" 17#include "chrome/common/render_messages.h" 18#include "chrome/common/renderer_preferences.h" 19#include "chrome/common/url_constants.h" 20 21BalloonHost::BalloonHost(Balloon* balloon) 22 : render_view_host_(NULL), 23 balloon_(balloon), 24 initialized_(false), 25 should_notify_on_disconnect_(false), 26 enable_dom_ui_(false) { 27 DCHECK(balloon_); 28 29 // If the notification is for an extension URL, make sure to use the extension 30 // process to render it, so that it can communicate with other views in the 31 // extension. 32 const GURL& balloon_url = balloon_->notification().content_url(); 33 if (balloon_url.SchemeIs(chrome::kExtensionScheme)) { 34 site_instance_ = 35 balloon_->profile()->GetExtensionProcessManager()->GetSiteInstanceForURL( 36 balloon_url); 37 } else { 38 site_instance_ = SiteInstance::CreateSiteInstance(balloon_->profile()); 39 } 40} 41 42void BalloonHost::Shutdown() { 43 if (render_view_host_) { 44 render_view_host_->Shutdown(); 45 render_view_host_ = NULL; 46 } 47} 48 49Browser* BalloonHost::GetBrowser() const { 50 // Notifications aren't associated with a particular browser. 51 return NULL; 52} 53 54gfx::NativeView BalloonHost::GetNativeViewOfHost() { 55 // TODO(aa): Should this return the native view of the BalloonView*? 56 return NULL; 57} 58 59TabContents* BalloonHost::associated_tab_contents() const { return NULL; } 60 61WebPreferences BalloonHost::GetWebkitPrefs() { 62 WebPreferences prefs; 63 prefs.allow_scripts_to_close_windows = true; 64 return prefs; 65} 66 67SiteInstance* BalloonHost::GetSiteInstance() const { 68 return site_instance_.get(); 69} 70 71Profile* BalloonHost::GetProfile() const { 72 return balloon_->profile(); 73} 74 75const GURL& BalloonHost::GetURL() const { 76 return balloon_->notification().content_url(); 77} 78 79void BalloonHost::Close(RenderViewHost* render_view_host) { 80 balloon_->CloseByScript(); 81 NotifyDisconnect(); 82} 83 84void BalloonHost::RenderViewCreated(RenderViewHost* render_view_host) { 85 render_view_host->Send(new ViewMsg_DisableScrollbarsForSmallWindows( 86 render_view_host->routing_id(), balloon_->min_scrollbar_size())); 87 render_view_host->WasResized(); 88 render_view_host->EnablePreferredSizeChangedMode( 89 kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow); 90} 91 92void BalloonHost::RenderViewReady(RenderViewHost* render_view_host) { 93 should_notify_on_disconnect_ = true; 94 NotificationService::current()->Notify( 95 NotificationType::NOTIFY_BALLOON_CONNECTED, 96 Source<BalloonHost>(this), NotificationService::NoDetails()); 97} 98 99void BalloonHost::RenderViewGone(RenderViewHost* render_view_host) { 100 Close(render_view_host); 101} 102 103int BalloonHost::GetBrowserWindowID() const { 104 return extension_misc::kUnknownWindowId; 105} 106 107ViewType::Type BalloonHost::GetRenderViewType() const { 108 return ViewType::NOTIFICATION; 109} 110 111RenderViewHostDelegate::View* BalloonHost::GetViewDelegate() { 112 return this; 113} 114 115void BalloonHost::ProcessDOMUIMessage( 116 const ViewHostMsg_DomMessage_Params& params) { 117 if (extension_function_dispatcher_.get()) { 118 extension_function_dispatcher_->HandleRequest(params); 119 } 120} 121 122// RenderViewHostDelegate::View methods implemented to allow links to 123// open pages in new tabs. 124void BalloonHost::CreateNewWindow( 125 int route_id, 126 WindowContainerType window_container_type, 127 const string16& frame_name) { 128 delegate_view_helper_.CreateNewWindow( 129 route_id, 130 balloon_->profile(), 131 site_instance_.get(), 132 DOMUIFactory::GetDOMUIType(balloon_->profile(), 133 balloon_->notification().content_url()), 134 this, 135 window_container_type, 136 frame_name); 137} 138 139void BalloonHost::ShowCreatedWindow(int route_id, 140 WindowOpenDisposition disposition, 141 const gfx::Rect& initial_pos, 142 bool user_gesture) { 143 // Don't allow pop-ups from notifications. 144 if (disposition == NEW_POPUP) 145 return; 146 147 TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id); 148 if (!contents) 149 return; 150 Browser* browser = BrowserList::GetLastActiveWithProfile(balloon_->profile()); 151 if (!browser) 152 return; 153 154 browser->AddTabContents(contents, disposition, initial_pos, user_gesture); 155} 156 157void BalloonHost::UpdatePreferredSize(const gfx::Size& new_size) { 158 balloon_->SetContentPreferredSize(new_size); 159} 160 161void BalloonHost::HandleMouseDown() { 162 balloon_->OnClick(); 163} 164 165RendererPreferences BalloonHost::GetRendererPrefs(Profile* profile) const { 166 RendererPreferences preferences; 167 renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); 168 return preferences; 169} 170 171void BalloonHost::Init() { 172 DCHECK(!render_view_host_) << "BalloonViewHost already initialized."; 173 RenderViewHost* rvh = new RenderViewHost( 174 site_instance_.get(), this, MSG_ROUTING_NONE, NULL); 175 if (GetProfile()->GetExtensionsService()) { 176 extension_function_dispatcher_.reset( 177 ExtensionFunctionDispatcher::Create( 178 rvh, this, balloon_->notification().content_url())); 179 } 180 if (extension_function_dispatcher_.get()) { 181 rvh->AllowBindings(BindingsPolicy::EXTENSION); 182 rvh->set_is_extension_process(true); 183 } else if (enable_dom_ui_) { 184 rvh->AllowBindings(BindingsPolicy::DOM_UI); 185 } 186 187 // Do platform-specific initialization. 188 render_view_host_ = rvh; 189 InitRenderWidgetHostView(); 190 DCHECK(render_widget_host_view()); 191 192 rvh->set_view(render_widget_host_view()); 193 rvh->CreateRenderView(string16()); 194 rvh->NavigateToURL(balloon_->notification().content_url()); 195 196 initialized_ = true; 197} 198 199void BalloonHost::EnableDOMUI() { 200 DCHECK(render_view_host_ == NULL) << 201 "EnableDOMUI has to be called before a renderer is created."; 202 enable_dom_ui_ = true; 203} 204 205void BalloonHost::UpdateInspectorSetting(const std::string& key, 206 const std::string& value) { 207 RenderViewHostDelegateHelper::UpdateInspectorSetting( 208 GetProfile(), key, value); 209} 210 211void BalloonHost::ClearInspectorSettings() { 212 RenderViewHostDelegateHelper::ClearInspectorSettings(GetProfile()); 213} 214 215BalloonHost::~BalloonHost() {} 216 217void BalloonHost::NotifyDisconnect() { 218 if (!should_notify_on_disconnect_) 219 return; 220 221 should_notify_on_disconnect_ = false; 222 NotificationService::current()->Notify( 223 NotificationType::NOTIFY_BALLOON_DISCONNECTED, 224 Source<BalloonHost>(this), NotificationService::NoDetails()); 225} 226