web_contents_view_guest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright (c) 2012 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 "content/browser/web_contents/web_contents_view_guest.h" 6 7#include "build/build_config.h" 8#include "content/browser/browser_plugin/browser_plugin_embedder.h" 9#include "content/browser/browser_plugin/browser_plugin_guest.h" 10#include "content/browser/frame_host/interstitial_page_impl.h" 11#include "content/browser/frame_host/render_widget_host_view_guest.h" 12#include "content/browser/renderer_host/render_view_host_factory.h" 13#include "content/browser/renderer_host/render_view_host_impl.h" 14#include "content/browser/web_contents/web_contents_impl.h" 15#include "content/common/drag_messages.h" 16#include "content/public/browser/user_metrics.h" 17#include "content/public/browser/web_contents_delegate.h" 18#include "content/public/common/context_menu_params.h" 19#include "content/public/common/drop_data.h" 20#include "ui/gfx/image/image_skia.h" 21#include "ui/gfx/point.h" 22#include "ui/gfx/rect.h" 23#include "ui/gfx/size.h" 24 25#if defined(USE_AURA) 26#include "ui/aura/window.h" 27#endif 28 29using blink::WebDragOperation; 30using blink::WebDragOperationsMask; 31 32namespace content { 33 34WebContentsViewGuest::WebContentsViewGuest( 35 WebContentsImpl* web_contents, 36 BrowserPluginGuest* guest, 37 scoped_ptr<WebContentsViewPort> platform_view, 38 RenderViewHostDelegateView* platform_view_delegate_view) 39 : web_contents_(web_contents), 40 guest_(guest), 41 platform_view_(platform_view.Pass()), 42 platform_view_delegate_view_(platform_view_delegate_view) { 43} 44 45WebContentsViewGuest::~WebContentsViewGuest() { 46} 47 48gfx::NativeView WebContentsViewGuest::GetNativeView() const { 49 return platform_view_->GetNativeView(); 50} 51 52gfx::NativeView WebContentsViewGuest::GetContentNativeView() const { 53 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 54 if (!rwhv) 55 return NULL; 56 return rwhv->GetNativeView(); 57} 58 59gfx::NativeWindow WebContentsViewGuest::GetTopLevelNativeWindow() const { 60 return guest_->embedder_web_contents()->GetView()->GetTopLevelNativeWindow(); 61} 62 63void WebContentsViewGuest::OnGuestInitialized(WebContentsView* parent_view) { 64#if defined(USE_AURA) || defined(OS_WIN) 65 // In aura and windows, ScreenPositionClient doesn't work properly if we do 66 // not have the native view associated with this WebContentsViewGuest in the 67 // view hierarchy. We add this view as embedder's child here. 68 // This would go in WebContentsViewGuest::CreateView, but that is too early to 69 // access embedder_web_contents(). Therefore, we do it here. 70#if defined(USE_AURA) 71 // This can be win aura or chromeos. 72 parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView()); 73#elif defined(OS_WIN) 74 SetParent(platform_view_->GetNativeView(), parent_view->GetNativeView()); 75#endif 76#endif // defined(USE_AURA) || defined(OS_WIN) 77} 78 79void WebContentsViewGuest::GetContainerBounds(gfx::Rect* out) const { 80 // We need embedder container's bounds to calculate our bounds. 81 guest_->embedder_web_contents()->GetView()->GetContainerBounds(out); 82 gfx::Point guest_coordinates = guest_->GetScreenCoordinates(gfx::Point()); 83 out->Offset(guest_coordinates.x(), guest_coordinates.y()); 84 out->set_size(size_); 85} 86 87void WebContentsViewGuest::SizeContents(const gfx::Size& size) { 88 size_ = size; 89 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 90 if (rwhv) 91 rwhv->SetSize(size); 92} 93 94void WebContentsViewGuest::SetInitialFocus() { 95 platform_view_->SetInitialFocus(); 96} 97 98gfx::Rect WebContentsViewGuest::GetViewBounds() const { 99 return gfx::Rect(size_); 100} 101 102#if defined(OS_MACOSX) 103void WebContentsViewGuest::SetAllowOverlappingViews(bool overlapping) { 104 platform_view_->SetAllowOverlappingViews(overlapping); 105} 106 107bool WebContentsViewGuest::GetAllowOverlappingViews() const { 108 return platform_view_->GetAllowOverlappingViews(); 109} 110 111void WebContentsViewGuest::SetOverlayView( 112 WebContentsView* overlay, const gfx::Point& offset) { 113 platform_view_->SetOverlayView(overlay, offset); 114} 115 116void WebContentsViewGuest::RemoveOverlayView() { 117 platform_view_->RemoveOverlayView(); 118} 119#endif 120 121void WebContentsViewGuest::CreateView(const gfx::Size& initial_size, 122 gfx::NativeView context) { 123 platform_view_->CreateView(initial_size, context); 124 size_ = initial_size; 125} 126 127RenderWidgetHostView* WebContentsViewGuest::CreateViewForWidget( 128 RenderWidgetHost* render_widget_host) { 129 if (render_widget_host->GetView()) { 130 // During testing, the view will already be set up in most cases to the 131 // test view, so we don't want to clobber it with a real one. To verify that 132 // this actually is happening (and somebody isn't accidentally creating the 133 // view twice), we check for the RVH Factory, which will be set when we're 134 // making special ones (which go along with the special views). 135 DCHECK(RenderViewHostFactory::has_factory()); 136 return render_widget_host->GetView(); 137 } 138 139 RenderWidgetHostView* platform_widget = NULL; 140 platform_widget = platform_view_->CreateViewForWidget(render_widget_host); 141 142 RenderWidgetHostView* view = new RenderWidgetHostViewGuest( 143 render_widget_host, 144 guest_, 145 platform_widget); 146 147 return view; 148} 149 150RenderWidgetHostView* WebContentsViewGuest::CreateViewForPopupWidget( 151 RenderWidgetHost* render_widget_host) { 152 return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host); 153} 154 155void WebContentsViewGuest::SetPageTitle(const base::string16& title) { 156} 157 158void WebContentsViewGuest::RenderViewCreated(RenderViewHost* host) { 159 platform_view_->RenderViewCreated(host); 160} 161 162void WebContentsViewGuest::RenderViewSwappedIn(RenderViewHost* host) { 163 platform_view_->RenderViewSwappedIn(host); 164} 165 166void WebContentsViewGuest::SetOverscrollControllerEnabled(bool enabled) { 167 // This should never override the setting of the embedder view. 168} 169 170#if defined(OS_MACOSX) 171bool WebContentsViewGuest::IsEventTracking() const { 172 return false; 173} 174 175void WebContentsViewGuest::CloseTabAfterEventTracking() { 176} 177#endif 178 179WebContents* WebContentsViewGuest::web_contents() { 180 return web_contents_; 181} 182 183void WebContentsViewGuest::RestoreFocus() { 184 platform_view_->RestoreFocus(); 185} 186 187void WebContentsViewGuest::OnTabCrashed(base::TerminationStatus status, 188 int error_code) { 189} 190 191void WebContentsViewGuest::Focus() { 192 platform_view_->Focus(); 193} 194 195void WebContentsViewGuest::StoreFocus() { 196 platform_view_->StoreFocus(); 197} 198 199DropData* WebContentsViewGuest::GetDropData() const { 200 NOTIMPLEMENTED(); 201 return NULL; 202} 203 204void WebContentsViewGuest::UpdateDragCursor(WebDragOperation operation) { 205 RenderViewHostImpl* embedder_render_view_host = 206 static_cast<RenderViewHostImpl*>( 207 guest_->embedder_web_contents()->GetRenderViewHost()); 208 CHECK(embedder_render_view_host); 209 RenderViewHostDelegateView* view = 210 embedder_render_view_host->GetDelegate()->GetDelegateView(); 211 if (view) 212 view->UpdateDragCursor(operation); 213} 214 215void WebContentsViewGuest::GotFocus() { 216} 217 218void WebContentsViewGuest::TakeFocus(bool reverse) { 219} 220 221void WebContentsViewGuest::ShowContextMenu(RenderFrameHost* render_frame_host, 222 const ContextMenuParams& params) { 223#if defined(USE_AURA) || defined(OS_WIN) 224 // Context menu uses ScreenPositionClient::ConvertPointToScreen() in aura and 225 // windows to calculate popup position. Guest's native view 226 // (platform_view_->GetNativeView()) is part of the embedder's view hierarchy, 227 // but is placed at (0, 0) w.r.t. the embedder's position. Therefore, |offset| 228 // is added to |params|. 229 gfx::Rect embedder_bounds; 230 guest_->embedder_web_contents()->GetView()->GetContainerBounds( 231 &embedder_bounds); 232 gfx::Rect guest_bounds; 233 GetContainerBounds(&guest_bounds); 234 235 gfx::Vector2d offset = guest_bounds.origin() - embedder_bounds.origin(); 236 ContextMenuParams params_in_embedder = params; 237 params_in_embedder.x += offset.x(); 238 params_in_embedder.y += offset.y(); 239 platform_view_delegate_view_->ShowContextMenu( 240 render_frame_host, params_in_embedder); 241#else 242 platform_view_delegate_view_->ShowContextMenu(render_frame_host, params); 243#endif // defined(USE_AURA) || defined(OS_WIN) 244} 245 246void WebContentsViewGuest::StartDragging( 247 const DropData& drop_data, 248 WebDragOperationsMask ops, 249 const gfx::ImageSkia& image, 250 const gfx::Vector2d& image_offset, 251 const DragEventSourceInfo& event_info) { 252 WebContentsImpl* embedder_web_contents = guest_->embedder_web_contents(); 253 embedder_web_contents->GetBrowserPluginEmbedder()->StartDrag(guest_); 254 RenderViewHostImpl* embedder_render_view_host = 255 static_cast<RenderViewHostImpl*>( 256 embedder_web_contents->GetRenderViewHost()); 257 CHECK(embedder_render_view_host); 258 RenderViewHostDelegateView* view = 259 embedder_render_view_host->GetDelegate()->GetDelegateView(); 260 if (view) { 261 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.StartDrag")); 262 view->StartDragging(drop_data, ops, image, image_offset, event_info); 263 } else { 264 embedder_web_contents->SystemDragEnded(); 265 } 266} 267 268} // namespace content 269