| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/browser_plugin/browser_plugin_guest.h" | 5 #include "content/browser/browser_plugin/browser_plugin_guest.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 int BrowserPluginGuest::GetGuestProxyRoutingID() { | 119 int BrowserPluginGuest::GetGuestProxyRoutingID() { |
| 120 if (GuestMode::IsCrossProcessFrameGuest(GetWebContents())) { | 120 if (GuestMode::IsCrossProcessFrameGuest(GetWebContents())) { |
| 121 // We don't use the proxy to send postMessage in --site-per-process, since | 121 // We don't use the proxy to send postMessage in --site-per-process, since |
| 122 // we use the contentWindow directly from the frame element instead. | 122 // we use the contentWindow directly from the frame element instead. |
| 123 return MSG_ROUTING_NONE; | 123 return MSG_ROUTING_NONE; |
| 124 } | 124 } |
| 125 | 125 |
| 126 if (guest_proxy_routing_id_ != MSG_ROUTING_NONE) | 126 if (guest_proxy_routing_id_ != MSG_ROUTING_NONE) |
| 127 return guest_proxy_routing_id_; | 127 return guest_proxy_routing_id_; |
| 128 | 128 |
| 129 // Create a RenderFrameProxyHost for the guest in the embedder renderer | 129 // In order to enable the embedder to post messages to the |
| 130 // process, so that the embedder can access the guest's window object. | 130 // guest, we need to create a RenderFrameProxyHost in root node of guest |
| 131 // On reattachment, we can reuse the same RenderFrameProxyHost because | 131 // WebContents' frame tree (i.e., create a RenderFrameProxy in the embedder |
| 132 // the embedder process will always be the same even if the embedder | 132 // process which can be used by the embedder to post messages to the guest). |
| 133 // WebContents changes. | 133 // The creation of RFPH for the reverse path, which enables the guest to post |
| 134 // messages to the embedder, will be postponed to when the embedder posts its |
| 135 // first message to the guest. |
| 134 // | 136 // |
| 135 // TODO(fsamuel): Make sure this works for transferring guests across | 137 // TODO(fsamuel): Make sure this works for transferring guests across |
| 136 // owners in different processes. We probably need to clear the | 138 // owners in different processes. We probably need to clear the |
| 137 // |guest_proxy_routing_id_| and perform any necessary cleanup on Detach | 139 // |guest_proxy_routing_id_| and perform any necessary cleanup on Detach |
| 138 // to enable this. | 140 // to enable this. |
| 139 SiteInstance* owner_site_instance = owner_web_contents_->GetSiteInstance(); | 141 // |
| 140 int proxy_routing_id = | 142 // TODO(ekaramad): If the guest is embedded inside a cross-process <iframe> |
| 141 GetWebContents()->GetFrameTree()->root()->render_manager()-> | 143 // (e.g., <embed>-ed PDF), the reverse proxy will not be created and the |
| 142 CreateRenderFrameProxy(owner_site_instance); | 144 // posted message's source attribute will be null which in turn breaks the |
| 145 // two-way messaging between the guest and the embedder. We should either |
| 146 // create a RenderFrameProxyHost for the reverse path, or implement |
| 147 // MimeHandlerViewGuest using OOPIF (https://crbug.com/659750). |
| 148 SiteInstance* owner_site_instance = delegate_->GetOwnerSiteInstance(); |
| 149 int proxy_routing_id = GetWebContents() |
| 150 ->GetFrameTree() |
| 151 ->root() |
| 152 ->render_manager() |
| 153 ->CreateRenderFrameProxy(owner_site_instance); |
| 143 guest_proxy_routing_id_ = RenderFrameProxyHost::FromID( | 154 guest_proxy_routing_id_ = RenderFrameProxyHost::FromID( |
| 144 owner_site_instance->GetProcess()->GetID(), proxy_routing_id) | 155 owner_site_instance->GetProcess()->GetID(), proxy_routing_id) |
| 145 ->GetRenderViewHost()->GetRoutingID(); | 156 ->GetRenderViewHost()->GetRoutingID(); |
| 146 | 157 |
| 147 return guest_proxy_routing_id_; | 158 return guest_proxy_routing_id_; |
| 148 } | 159 } |
| 149 | 160 |
| 150 int BrowserPluginGuest::LoadURLWithParams( | 161 int BrowserPluginGuest::LoadURLWithParams( |
| 151 const NavigationController::LoadURLParams& load_params) { | 162 const NavigationController::LoadURLParams& load_params) { |
| 152 GetWebContents()->GetController().LoadURLWithParams(load_params); | 163 GetWebContents()->GetController().LoadURLWithParams(load_params); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 163 void BrowserPluginGuest::SizeContents(const gfx::Size& new_size) { | 174 void BrowserPluginGuest::SizeContents(const gfx::Size& new_size) { |
| 164 GetWebContents()->GetView()->SizeContents(new_size); | 175 GetWebContents()->GetView()->SizeContents(new_size); |
| 165 } | 176 } |
| 166 | 177 |
| 167 void BrowserPluginGuest::WillDestroy() { | 178 void BrowserPluginGuest::WillDestroy() { |
| 168 is_in_destruction_ = true; | 179 is_in_destruction_ = true; |
| 169 owner_web_contents_ = nullptr; | 180 owner_web_contents_ = nullptr; |
| 170 attached_ = false; | 181 attached_ = false; |
| 171 } | 182 } |
| 172 | 183 |
| 184 RenderWidgetHostImpl* BrowserPluginGuest::GetOwnerRenderWidgetHost() const { |
| 185 return static_cast<RenderWidgetHostImpl*>( |
| 186 delegate_->GetOwnerRenderWidgetHost()); |
| 187 } |
| 188 |
| 173 void BrowserPluginGuest::Init() { | 189 void BrowserPluginGuest::Init() { |
| 174 if (initialized_) | 190 if (initialized_) |
| 175 return; | 191 return; |
| 176 initialized_ = true; | 192 initialized_ = true; |
| 177 | 193 |
| 178 // TODO(fsamuel): Initiailization prior to attachment should be behind a | 194 // TODO(fsamuel): Initiailization prior to attachment should be behind a |
| 179 // command line flag once we introduce experimental guest types that rely on | 195 // command line flag once we introduce experimental guest types that rely on |
| 180 // this functionality. | 196 // this functionality. |
| 181 if (!delegate_->CanRunInDetachedState()) | 197 if (!delegate_->CanRunInDetachedState()) |
| 182 return; | 198 return; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 WebContentsImpl* new_contents = | 250 WebContentsImpl* new_contents = |
| 235 static_cast<WebContentsImpl*>(delegate_->CreateNewGuestWindow(params)); | 251 static_cast<WebContentsImpl*>(delegate_->CreateNewGuestWindow(params)); |
| 236 DCHECK(new_contents); | 252 DCHECK(new_contents); |
| 237 return new_contents; | 253 return new_contents; |
| 238 } | 254 } |
| 239 | 255 |
| 240 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( | 256 bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( |
| 241 const IPC::Message& message) { | 257 const IPC::Message& message) { |
| 242 RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>( | 258 RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>( |
| 243 web_contents()->GetRenderWidgetHostView()); | 259 web_contents()->GetRenderWidgetHostView()); |
| 260 |
| 244 // Until the guest is attached, it should not be handling input events. | 261 // Until the guest is attached, it should not be handling input events. |
| 245 if (attached() && rwhv && | 262 if (attached() && rwhv && |
| 246 rwhv->OnMessageReceivedFromEmbedder( | 263 rwhv->OnMessageReceivedFromEmbedder(message, |
| 247 message, | 264 GetOwnerRenderWidgetHost())) { |
| 248 RenderWidgetHostImpl::From( | |
| 249 embedder_web_contents()->GetRenderViewHost()->GetWidget()))) { | |
| 250 return true; | 265 return true; |
| 251 } | 266 } |
| 252 | 267 |
| 253 bool handled = true; | 268 bool handled = true; |
| 254 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message) | 269 IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message) |
| 255 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Detach, OnDetach) | 270 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Detach, OnDetach) |
| 256 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate, | 271 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate, |
| 257 OnDragStatusUpdate) | 272 OnDragStatusUpdate) |
| 258 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand, | 273 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand, |
| 259 OnExecuteEditCommand) | 274 OnExecuteEditCommand) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 } | 382 } |
| 368 | 383 |
| 369 // static | 384 // static |
| 370 bool BrowserPluginGuest::IsGuest(RenderViewHostImpl* render_view_host) { | 385 bool BrowserPluginGuest::IsGuest(RenderViewHostImpl* render_view_host) { |
| 371 return render_view_host && IsGuest( | 386 return render_view_host && IsGuest( |
| 372 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost( | 387 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost( |
| 373 render_view_host))); | 388 render_view_host))); |
| 374 } | 389 } |
| 375 | 390 |
| 376 RenderWidgetHostView* BrowserPluginGuest::GetOwnerRenderWidgetHostView() { | 391 RenderWidgetHostView* BrowserPluginGuest::GetOwnerRenderWidgetHostView() { |
| 377 if (!owner_web_contents_) | 392 if (RenderWidgetHostImpl* owner = GetOwnerRenderWidgetHost()) |
| 378 return nullptr; | 393 return owner->GetView(); |
| 379 return owner_web_contents_->GetRenderWidgetHostView(); | 394 return nullptr; |
| 380 } | 395 } |
| 381 | 396 |
| 382 void BrowserPluginGuest::UpdateVisibility() { | 397 void BrowserPluginGuest::UpdateVisibility() { |
| 383 OnSetVisibility(browser_plugin_instance_id(), visible()); | 398 OnSetVisibility(browser_plugin_instance_id(), visible()); |
| 384 } | 399 } |
| 385 | 400 |
| 386 BrowserPluginGuestManager* | 401 BrowserPluginGuestManager* |
| 387 BrowserPluginGuest::GetBrowserPluginGuestManager() const { | 402 BrowserPluginGuest::GetBrowserPluginGuestManager() const { |
| 388 return GetWebContents()->GetBrowserContext()->GetGuestManager(); | 403 return GetWebContents()->GetBrowserContext()->GetGuestManager(); |
| 389 } | 404 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 bool BrowserPluginGuest::HandleStopFindingForEmbedder(StopFindAction action) { | 456 bool BrowserPluginGuest::HandleStopFindingForEmbedder(StopFindAction action) { |
| 442 return delegate_->HandleStopFindingForEmbedder(action); | 457 return delegate_->HandleStopFindingForEmbedder(action); |
| 443 } | 458 } |
| 444 | 459 |
| 445 void BrowserPluginGuest::ResendEventToEmbedder( | 460 void BrowserPluginGuest::ResendEventToEmbedder( |
| 446 const blink::WebInputEvent& event) { | 461 const blink::WebInputEvent& event) { |
| 447 if (!attached() || !owner_web_contents_) | 462 if (!attached() || !owner_web_contents_) |
| 448 return; | 463 return; |
| 449 | 464 |
| 450 DCHECK(browser_plugin_instance_id_); | 465 DCHECK(browser_plugin_instance_id_); |
| 451 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 466 RenderWidgetHostViewBase* view = |
| 452 embedder_web_contents()->GetMainFrame()->GetView()); | 467 static_cast<RenderWidgetHostViewBase*>(GetOwnerRenderWidgetHostView()); |
| 453 | 468 |
| 454 gfx::Vector2d offset_from_embedder = guest_window_rect_.OffsetFromOrigin(); | 469 gfx::Vector2d offset_from_embedder = guest_window_rect_.OffsetFromOrigin(); |
| 455 if (event.type == blink::WebInputEvent::GestureScrollUpdate) { | 470 if (event.type == blink::WebInputEvent::GestureScrollUpdate) { |
| 456 blink::WebGestureEvent resent_gesture_event; | 471 blink::WebGestureEvent resent_gesture_event; |
| 457 memcpy(&resent_gesture_event, &event, sizeof(blink::WebGestureEvent)); | 472 memcpy(&resent_gesture_event, &event, sizeof(blink::WebGestureEvent)); |
| 458 resent_gesture_event.x += offset_from_embedder.x(); | 473 resent_gesture_event.x += offset_from_embedder.x(); |
| 459 resent_gesture_event.y += offset_from_embedder.y(); | 474 resent_gesture_event.y += offset_from_embedder.y(); |
| 460 // Mark the resend source with the browser plugin's instance id, so the | 475 // Mark the resend source with the browser plugin's instance id, so the |
| 461 // correct browser_plugin will know to ignore the event. | 476 // correct browser_plugin will know to ignore the event. |
| 462 resent_gesture_event.resendingPluginId = browser_plugin_instance_id_; | 477 resent_gesture_event.resendingPluginId = browser_plugin_instance_id_; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 // in this case just queue any messages we receive. | 514 // in this case just queue any messages we receive. |
| 500 if (!attached() || !owner_web_contents_) { | 515 if (!attached() || !owner_web_contents_) { |
| 501 // Some pages such as data URLs, javascript URLs, and about:blank | 516 // Some pages such as data URLs, javascript URLs, and about:blank |
| 502 // do not load external resources and so they load prior to attachment. | 517 // do not load external resources and so they load prior to attachment. |
| 503 // As a result, we must save all these IPCs until attachment and then | 518 // As a result, we must save all these IPCs until attachment and then |
| 504 // forward them so that the embedder gets a chance to see and process | 519 // forward them so that the embedder gets a chance to see and process |
| 505 // the load events. | 520 // the load events. |
| 506 pending_messages_.push_back(std::move(msg)); | 521 pending_messages_.push_back(std::move(msg)); |
| 507 return; | 522 return; |
| 508 } | 523 } |
| 509 owner_web_contents_->Send(msg.release()); | 524 |
| 525 // If the guest is inside a cross-process frame, it is possible to get here |
| 526 // after the owner frame is detached. Then, the owner RenderWidgetHost will |
| 527 // be null and the message is dropped. |
| 528 if (auto* rwh = GetOwnerRenderWidgetHost()) |
| 529 rwh->Send(msg.release()); |
| 510 } | 530 } |
| 511 | 531 |
| 512 void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y, | 532 void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y, |
| 513 int screen_x, int screen_y, blink::WebDragOperation operation) { | 533 int screen_x, int screen_y, blink::WebDragOperation operation) { |
| 514 web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y, | 534 web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y, |
| 515 screen_x, screen_y, operation); | 535 screen_x, screen_y, operation); |
| 516 seen_embedder_drag_source_ended_at_ = true; | 536 seen_embedder_drag_source_ended_at_ = true; |
| 517 EndSystemDragIfApplicable(); | 537 EndSystemDragIfApplicable(); |
| 518 } | 538 } |
| 519 | 539 |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 range, character_bounds); | 1058 range, character_bounds); |
| 1039 } | 1059 } |
| 1040 #endif | 1060 #endif |
| 1041 | 1061 |
| 1042 void BrowserPluginGuest::SetContextMenuPosition(const gfx::Point& position) { | 1062 void BrowserPluginGuest::SetContextMenuPosition(const gfx::Point& position) { |
| 1043 if (delegate_) | 1063 if (delegate_) |
| 1044 delegate_->SetContextMenuPosition(position); | 1064 delegate_->SetContextMenuPosition(position); |
| 1045 } | 1065 } |
| 1046 | 1066 |
| 1047 } // namespace content | 1067 } // namespace content |
| OLD | NEW |