| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/browser_plugin/browser_plugin_embedder_helper.h" |
| |
| #include "content/browser/browser_plugin/browser_plugin_embedder.h" |
| #include "content/browser/renderer_host/render_view_host_impl.h" |
| #include "content/common/browser_plugin_messages.h" |
| #include "content/common/view_messages.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/render_widget_host_view.h" |
| #include "ui/gfx/size.h" |
| |
| namespace content { |
| |
| BrowserPluginEmbedderHelper::BrowserPluginEmbedderHelper( |
| BrowserPluginEmbedder* embedder, |
| RenderViewHost* render_view_host) |
| : RenderViewHostObserver(render_view_host), |
| embedder_(embedder) { |
| } |
| |
| BrowserPluginEmbedderHelper::~BrowserPluginEmbedderHelper() { |
| } |
| |
| bool BrowserPluginEmbedderHelper::Send(IPC::Message* message) { |
| return RenderViewHostObserver::Send(message); |
| } |
| |
| bool BrowserPluginEmbedderHelper::OnMessageReceived( |
| const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(BrowserPluginEmbedderHelper, message) |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateGuest, |
| OnNavigateGuest); |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest) |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateRect_ACK, OnUpdateRectACK); |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetFocus, OnSetFocus); |
| IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_HandleInputEvent, |
| OnHandleInputEvent(*static_cast<const IPC::SyncMessage*>(&message), |
| &handled)) |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginDestroyed, |
| OnPluginDestroyed); |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Stop, OnStop) |
| IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Reload, OnReload) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void BrowserPluginEmbedderHelper::OnResizeGuest( |
| int instance_id, |
| const BrowserPluginHostMsg_ResizeGuest_Params& params) { |
| TransportDIB* damage_buffer = NULL; |
| #if defined(OS_WIN) |
| // On Windows we need to duplicate the handle from the remote process. |
| HANDLE section; |
| DuplicateHandle(render_view_host()->GetProcess()->GetHandle(), |
| params.damage_buffer_id.handle, |
| GetCurrentProcess(), |
| §ion, |
| STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, |
| FALSE, 0); |
| damage_buffer = TransportDIB::Map(section); |
| #elif defined(OS_MACOSX) |
| // On OSX, the browser allocates all DIBs and keeps a file descriptor around |
| // for each. |
| damage_buffer = render_view_host()->GetProcess()-> |
| GetTransportDIB(params.damage_buffer_id); |
| #elif defined(OS_ANDROID) |
| damage_buffer = TransportDIB::Map(params.damage_buffer_id); |
| #elif defined(OS_POSIX) |
| damage_buffer = TransportDIB::Map(params.damage_buffer_id.shmkey); |
| #endif // defined(OS_POSIX) |
| DCHECK(damage_buffer); |
| // TODO(fsamuel): Schedule this later so that we don't stall the embedder for |
| // too long. |
| embedder_->ResizeGuest(instance_id, |
| damage_buffer, |
| #if defined(OS_WIN) |
| params.damage_buffer_size, |
| #endif |
| params.width, |
| params.height, |
| params.resize_pending, |
| params.scale_factor); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnHandleInputEvent( |
| const IPC::SyncMessage& message, |
| bool* handled) { |
| *handled = true; |
| PickleIterator iter(message); |
| |
| // TODO(fsamuel): This appears to be a monotonically increasing value. |
| int instance_id = -1; |
| const char* guest_rect_data = NULL; |
| int guest_rect_data_length = -1; |
| const char* input_event_data = NULL; |
| int input_event_data_length = -1; |
| if (!iter.SkipBytes(4) || |
| !message.ReadInt(&iter, &instance_id) || |
| !message.ReadData(&iter, &guest_rect_data, &guest_rect_data_length) || |
| !message.ReadData(&iter, &input_event_data, &input_event_data_length)) { |
| *handled = false; |
| return; |
| } |
| const gfx::Rect* guest_rect = |
| reinterpret_cast<const gfx::Rect*>(guest_rect_data); |
| const WebKit::WebInputEvent* input_event = |
| reinterpret_cast<const WebKit::WebInputEvent*>(input_event_data); |
| RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( |
| render_view_host()); |
| |
| // Convert the window coordinates into screen coordinates. |
| gfx::Rect guest_screen_rect(*guest_rect); |
| if (rvh->GetView()) |
| guest_screen_rect.Offset(rvh->GetView()->GetViewBounds().origin()); |
| |
| IPC::Message* reply_message = |
| IPC::SyncMessage::GenerateReply(&message); |
| embedder_->HandleInputEvent(instance_id, |
| rvh, |
| guest_screen_rect, |
| *input_event, |
| reply_message); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnNavigateGuest(int instance_id, |
| int64 frame_id, |
| const std::string& src, |
| const gfx::Size& size) { |
| embedder_->NavigateGuest(render_view_host(), instance_id, frame_id, src, |
| size); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnUpdateRectACK(int instance_id, |
| int message_id, |
| const gfx::Size& size) { |
| embedder_->UpdateRectACK(instance_id, message_id, size); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnSetFocus(int instance_id, bool focused) { |
| embedder_->SetFocus(instance_id, focused); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnPluginDestroyed(int instance_id) { |
| embedder_->PluginDestroyed(instance_id); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnStop(int instance_id) { |
| embedder_->Stop(instance_id); |
| } |
| |
| void BrowserPluginEmbedderHelper::OnReload(int instance_id) { |
| embedder_->Reload(instance_id); |
| } |
| |
| } // namespace content |