web_contents_view_guest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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) 65 // In aura, 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 parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView()); 71#endif // defined(USE_AURA) 72} 73 74void WebContentsViewGuest::GetContainerBounds(gfx::Rect* out) const { 75 // We need embedder container's bounds to calculate our bounds. 76 guest_->embedder_web_contents()->GetView()->GetContainerBounds(out); 77 gfx::Point guest_coordinates = guest_->GetScreenCoordinates(gfx::Point()); 78 out->Offset(guest_coordinates.x(), guest_coordinates.y()); 79 out->set_size(size_); 80} 81 82void WebContentsViewGuest::SizeContents(const gfx::Size& size) { 83 size_ = size; 84 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 85 if (rwhv) 86 rwhv->SetSize(size); 87} 88 89void WebContentsViewGuest::SetInitialFocus() { 90 platform_view_->SetInitialFocus(); 91} 92 93gfx::Rect WebContentsViewGuest::GetViewBounds() const { 94 return gfx::Rect(size_); 95} 96 97#if defined(OS_MACOSX) 98void WebContentsViewGuest::SetAllowOverlappingViews(bool overlapping) { 99 platform_view_->SetAllowOverlappingViews(overlapping); 100} 101 102bool WebContentsViewGuest::GetAllowOverlappingViews() const { 103 return platform_view_->GetAllowOverlappingViews(); 104} 105 106void WebContentsViewGuest::SetOverlayView( 107 WebContentsView* overlay, const gfx::Point& offset) { 108 platform_view_->SetOverlayView(overlay, offset); 109} 110 111void WebContentsViewGuest::RemoveOverlayView() { 112 platform_view_->RemoveOverlayView(); 113} 114#endif 115 116void WebContentsViewGuest::CreateView(const gfx::Size& initial_size, 117 gfx::NativeView context) { 118 platform_view_->CreateView(initial_size, context); 119 size_ = initial_size; 120} 121 122RenderWidgetHostView* WebContentsViewGuest::CreateViewForWidget( 123 RenderWidgetHost* render_widget_host) { 124 if (render_widget_host->GetView()) { 125 // During testing, the view will already be set up in most cases to the 126 // test view, so we don't want to clobber it with a real one. To verify that 127 // this actually is happening (and somebody isn't accidentally creating the 128 // view twice), we check for the RVH Factory, which will be set when we're 129 // making special ones (which go along with the special views). 130 DCHECK(RenderViewHostFactory::has_factory()); 131 return render_widget_host->GetView(); 132 } 133 134 RenderWidgetHostView* platform_widget = NULL; 135 platform_widget = platform_view_->CreateViewForWidget(render_widget_host); 136 137 RenderWidgetHostView* view = new RenderWidgetHostViewGuest( 138 render_widget_host, 139 guest_, 140 platform_widget); 141 142 return view; 143} 144 145RenderWidgetHostView* WebContentsViewGuest::CreateViewForPopupWidget( 146 RenderWidgetHost* render_widget_host) { 147 return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host); 148} 149 150void WebContentsViewGuest::SetPageTitle(const base::string16& title) { 151} 152 153void WebContentsViewGuest::RenderViewCreated(RenderViewHost* host) { 154 platform_view_->RenderViewCreated(host); 155} 156 157void WebContentsViewGuest::RenderViewSwappedIn(RenderViewHost* host) { 158 platform_view_->RenderViewSwappedIn(host); 159} 160 161void WebContentsViewGuest::SetOverscrollControllerEnabled(bool enabled) { 162 // This should never override the setting of the embedder view. 163} 164 165#if defined(OS_MACOSX) 166bool WebContentsViewGuest::IsEventTracking() const { 167 return false; 168} 169 170void WebContentsViewGuest::CloseTabAfterEventTracking() { 171} 172#endif 173 174WebContents* WebContentsViewGuest::web_contents() { 175 return web_contents_; 176} 177 178void WebContentsViewGuest::RestoreFocus() { 179 platform_view_->RestoreFocus(); 180} 181 182void WebContentsViewGuest::OnTabCrashed(base::TerminationStatus status, 183 int error_code) { 184} 185 186void WebContentsViewGuest::Focus() { 187 platform_view_->Focus(); 188} 189 190void WebContentsViewGuest::StoreFocus() { 191 platform_view_->StoreFocus(); 192} 193 194DropData* WebContentsViewGuest::GetDropData() const { 195 NOTIMPLEMENTED(); 196 return NULL; 197} 198 199void WebContentsViewGuest::UpdateDragCursor(WebDragOperation operation) { 200 RenderViewHostImpl* embedder_render_view_host = 201 static_cast<RenderViewHostImpl*>( 202 guest_->embedder_web_contents()->GetRenderViewHost()); 203 CHECK(embedder_render_view_host); 204 RenderViewHostDelegateView* view = 205 embedder_render_view_host->GetDelegate()->GetDelegateView(); 206 if (view) 207 view->UpdateDragCursor(operation); 208} 209 210void WebContentsViewGuest::GotFocus() { 211} 212 213void WebContentsViewGuest::TakeFocus(bool reverse) { 214} 215 216void WebContentsViewGuest::ShowContextMenu(RenderFrameHost* render_frame_host, 217 const ContextMenuParams& params) { 218#if defined(USE_AURA) 219 // Context menu uses ScreenPositionClient::ConvertPointToScreen() in aura 220 // to calculate popup position. Guest's native view 221 // (platform_view_->GetNativeView()) is part of the embedder's view hierarchy, 222 // but is placed at (0, 0) w.r.t. the embedder's position. Therefore, |offset| 223 // is added to |params|. 224 gfx::Rect embedder_bounds; 225 guest_->embedder_web_contents()->GetView()->GetContainerBounds( 226 &embedder_bounds); 227 gfx::Rect guest_bounds; 228 GetContainerBounds(&guest_bounds); 229 230 gfx::Vector2d offset = guest_bounds.origin() - embedder_bounds.origin(); 231 ContextMenuParams params_in_embedder = params; 232 params_in_embedder.x += offset.x(); 233 params_in_embedder.y += offset.y(); 234 platform_view_delegate_view_->ShowContextMenu( 235 render_frame_host, params_in_embedder); 236#else 237 platform_view_delegate_view_->ShowContextMenu(render_frame_host, params); 238#endif // defined(USE_AURA) 239} 240 241void WebContentsViewGuest::StartDragging( 242 const DropData& drop_data, 243 WebDragOperationsMask ops, 244 const gfx::ImageSkia& image, 245 const gfx::Vector2d& image_offset, 246 const DragEventSourceInfo& event_info) { 247 WebContentsImpl* embedder_web_contents = guest_->embedder_web_contents(); 248 embedder_web_contents->GetBrowserPluginEmbedder()->StartDrag(guest_); 249 RenderViewHostImpl* embedder_render_view_host = 250 static_cast<RenderViewHostImpl*>( 251 embedder_web_contents->GetRenderViewHost()); 252 CHECK(embedder_render_view_host); 253 RenderViewHostDelegateView* view = 254 embedder_render_view_host->GetDelegate()->GetDelegateView(); 255 if (view) { 256 RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.StartDrag")); 257 view->StartDragging(drop_data, ops, image, image_offset, event_info); 258 } else { 259 embedder_web_contents->SystemDragEnded(); 260 } 261} 262 263} // namespace content 264