balloon_host.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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/in_process_webkit/webkit_context.h" 9#include "chrome/browser/extensions/extension_process_manager.h" 10#include "chrome/browser/notifications/balloon.h" 11#include "chrome/browser/profile.h" 12#include "chrome/browser/renderer_host/render_view_host.h" 13#include "chrome/browser/renderer_host/site_instance.h" 14#include "chrome/browser/renderer_preferences_util.h" 15#include "chrome/common/bindings_policy.h" 16#include "chrome/common/notification_service.h" 17#include "chrome/common/notification_type.h" 18#include "chrome/common/render_messages.h" 19#include "chrome/common/renderer_preferences.h" 20#include "chrome/common/url_constants.h" 21 22BalloonHost::BalloonHost(Balloon* balloon) 23 : render_view_host_(NULL), 24 balloon_(balloon), 25 initialized_(false), 26 should_notify_on_disconnect_(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 49WebPreferences BalloonHost::GetWebkitPrefs() { 50 WebPreferences prefs; 51 prefs.allow_scripts_to_close_windows = true; 52 return prefs; 53} 54 55void BalloonHost::Close(RenderViewHost* render_view_host) { 56 balloon_->CloseByScript(); 57 NotifyDisconnect(); 58} 59 60void BalloonHost::RenderViewCreated(RenderViewHost* render_view_host) { 61 render_view_host->Send(new ViewMsg_DisableScrollbarsForSmallWindows( 62 render_view_host->routing_id(), balloon_->min_scrollbar_size())); 63 render_view_host->WasResized(); 64 render_view_host->EnablePreferredSizeChangedMode( 65 kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow); 66} 67 68void BalloonHost::RenderViewReady(RenderViewHost* render_view_host) { 69 should_notify_on_disconnect_ = true; 70 NotificationService::current()->Notify( 71 NotificationType::NOTIFY_BALLOON_CONNECTED, 72 Source<BalloonHost>(this), NotificationService::NoDetails()); 73} 74 75void BalloonHost::RenderViewGone(RenderViewHost* render_view_host) { 76 Close(render_view_host); 77} 78 79void BalloonHost::ProcessDOMUIMessage(const std::string& message, 80 const ListValue* content, 81 const GURL& source_url, 82 int request_id, 83 bool has_callback) { 84 if (extension_function_dispatcher_.get()) { 85 extension_function_dispatcher_->HandleRequest( 86 message, content, source_url, request_id, has_callback); 87 } 88} 89 90// RenderViewHostDelegate::View methods implemented to allow links to 91// open pages in new tabs. 92void BalloonHost::CreateNewWindow( 93 int route_id, 94 WindowContainerType window_container_type, 95 const string16& frame_name) { 96 delegate_view_helper_.CreateNewWindow( 97 route_id, 98 balloon_->profile(), 99 site_instance_.get(), 100 DOMUIFactory::GetDOMUIType(balloon_->notification().content_url()), 101 this, 102 window_container_type, 103 frame_name); 104} 105 106void BalloonHost::ShowCreatedWindow(int route_id, 107 WindowOpenDisposition disposition, 108 const gfx::Rect& initial_pos, 109 bool user_gesture) { 110 // Don't allow pop-ups from notifications. 111 if (disposition == NEW_POPUP) 112 return; 113 114 TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id); 115 if (!contents) 116 return; 117 Browser* browser = BrowserList::GetLastActiveWithProfile(balloon_->profile()); 118 if (!browser) 119 return; 120 121 browser->AddTabContents(contents, disposition, initial_pos, user_gesture); 122} 123 124void BalloonHost::UpdatePreferredSize(const gfx::Size& new_size) { 125 balloon_->SetContentPreferredSize(new_size); 126} 127 128RendererPreferences BalloonHost::GetRendererPrefs(Profile* profile) const { 129 RendererPreferences preferences; 130 renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); 131 return preferences; 132} 133 134void BalloonHost::Init() { 135 DCHECK(!render_view_host_) << "BalloonViewHost already initialized."; 136 int64 session_storage_namespace_id = balloon_->profile()->GetWebKitContext()-> 137 dom_storage_context()->AllocateSessionStorageNamespaceId(); 138 RenderViewHost* rvh = new RenderViewHost(site_instance_.get(), 139 this, MSG_ROUTING_NONE, 140 session_storage_namespace_id); 141 if (GetProfile()->GetExtensionsService()) { 142 extension_function_dispatcher_.reset( 143 ExtensionFunctionDispatcher::Create( 144 rvh, this, balloon_->notification().content_url())); 145 } 146 if (extension_function_dispatcher_.get()) { 147 rvh->AllowBindings(BindingsPolicy::EXTENSION); 148 rvh->set_is_extension_process(true); 149 } 150 151 // Do platform-specific initialization. 152 render_view_host_ = rvh; 153 InitRenderWidgetHostView(); 154 DCHECK(render_widget_host_view()); 155 156 rvh->set_view(render_widget_host_view()); 157 rvh->CreateRenderView(GetProfile()->GetRequestContext(), string16()); 158 rvh->NavigateToURL(balloon_->notification().content_url()); 159 160 initialized_ = true; 161} 162 163void BalloonHost::NotifyDisconnect() { 164 if (!should_notify_on_disconnect_) 165 return; 166 167 should_notify_on_disconnect_ = false; 168 NotificationService::current()->Notify( 169 NotificationType::NOTIFY_BALLOON_DISCONNECTED, 170 Source<BalloonHost>(this), NotificationService::NoDetails()); 171} 172