Index: content/renderer/npapi/webplugin_delegate_proxy.cc |
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc |
deleted file mode 100644 |
index 05a021fe92bbae32917be81d44e3c3bc39c0d5ba..0000000000000000000000000000000000000000 |
--- a/content/renderer/npapi/webplugin_delegate_proxy.cc |
+++ /dev/null |
@@ -1,768 +0,0 @@ |
-// 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/renderer/npapi/webplugin_delegate_proxy.h" |
- |
-#include <stddef.h> |
- |
-#include <algorithm> |
-#include <utility> |
- |
-#include "base/auto_reset.h" |
-#include "base/command_line.h" |
-#include "base/files/file_util.h" |
-#include "base/logging.h" |
-#include "base/macros.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/process/process.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/version.h" |
-#include "build/build_config.h" |
-#include "cc/resources/shared_bitmap.h" |
-#include "content/child/child_process.h" |
-#include "content/child/child_shared_bitmap_manager.h" |
-#include "content/child/npapi/webplugin_resource_client.h" |
-#include "content/child/plugin_messages.h" |
-#include "content/common/content_constants_internal.h" |
-#include "content/common/cursors/webcursor.h" |
-#include "content/common/frame_messages.h" |
-#include "content/common/view_messages.h" |
-#include "content/public/renderer/content_renderer_client.h" |
-#include "content/renderer/npapi/plugin_channel_host.h" |
-#include "content/renderer/npapi/webplugin_impl.h" |
-#include "content/renderer/render_thread_impl.h" |
-#include "content/renderer/render_view_impl.h" |
-#include "content/renderer/sad_plugin.h" |
-#include "ipc/ipc_channel_handle.h" |
-#include "net/base/mime_util.h" |
-#include "skia/ext/platform_canvas.h" |
-#include "third_party/WebKit/public/platform/WebDragData.h" |
-#include "third_party/WebKit/public/platform/WebString.h" |
-#include "third_party/WebKit/public/web/WebDocument.h" |
-#include "third_party/WebKit/public/web/WebFrame.h" |
-#include "third_party/WebKit/public/web/WebView.h" |
-#include "ui/gfx/blit.h" |
-#include "ui/gfx/canvas.h" |
-#include "ui/gfx/geometry/size.h" |
-#include "ui/gfx/native_widget_types.h" |
-#include "ui/gfx/skia_util.h" |
- |
-#if defined(OS_POSIX) |
-#include "ipc/ipc_channel_posix.h" |
-#endif |
- |
-#if defined(OS_WIN) |
-#include "base/win/scoped_handle.h" |
-#include "content/public/common/sandbox_init.h" |
-#endif |
- |
-using blink::WebCursorInfo; |
-using blink::WebDragData; |
-using blink::WebInputEvent; |
-using blink::WebString; |
-using blink::WebView; |
- |
-namespace content { |
- |
-namespace { |
- |
-class ScopedLogLevel { |
- public: |
- explicit ScopedLogLevel(int level); |
- ~ScopedLogLevel(); |
- |
- private: |
- int old_level_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ScopedLogLevel); |
-}; |
- |
-ScopedLogLevel::ScopedLogLevel(int level) |
- : old_level_(logging::GetMinLogLevel()) { |
- logging::SetMinLogLevel(level); |
-} |
- |
-ScopedLogLevel::~ScopedLogLevel() { |
- logging::SetMinLogLevel(old_level_); |
-} |
- |
-} // namespace |
- |
-WebPluginDelegateProxy::WebPluginDelegateProxy( |
- WebPluginImpl* plugin, |
- const std::string& mime_type, |
- const base::WeakPtr<RenderViewImpl>& render_view, |
- RenderFrameImpl* render_frame) |
- : render_view_(render_view), |
- render_frame_(render_frame), |
- plugin_(plugin), |
- uses_shared_bitmaps_(true), |
-#if defined(OS_MACOSX) |
- uses_compositor_(false), |
-#endif |
- mime_type_(mime_type), |
- instance_id_(MSG_ROUTING_NONE), |
- sad_plugin_(NULL), |
- invalidate_pending_(false), |
- transparent_(false), |
- front_buffer_index_(0), |
- page_url_(render_view_->webview()->mainFrame()->document().url()) { |
-} |
- |
-WebPluginDelegateProxy::~WebPluginDelegateProxy() { |
-} |
- |
-WebPluginDelegateProxy::SharedBitmap::SharedBitmap() {} |
- |
-WebPluginDelegateProxy::SharedBitmap::~SharedBitmap() {} |
- |
-void WebPluginDelegateProxy::PluginDestroyed() { |
-#if defined(OS_MACOSX) |
- // Ensure that the renderer doesn't think the plugin still has focus. |
- if (render_view_) |
- render_view_->PluginFocusChanged(false, instance_id_); |
-#endif |
- |
- if (render_view_.get()) |
- render_view_->UnregisterPluginDelegate(this); |
- |
- if (channel_host_.get()) { |
- Send(new PluginMsg_DestroyInstance(instance_id_)); |
- |
- // Must remove the route after sending the destroy message, rather than |
- // before, since RemoveRoute can lead to all the outstanding NPObjects |
- // being told the channel went away if this was the last instance. |
- channel_host_->RemoveRoute(instance_id_); |
- |
- // Release the channel host now. If we are is the last reference to the |
- // channel, this avoids a race where this renderer asks a new connection to |
- // the same plugin between now and the time 'this' is actually deleted. |
- // Destroying the channel host is what releases the channel name -> FD |
- // association on POSIX, and if we ask for a new connection before it is |
- // released, the plugin will give us a new FD, and we'll assert when trying |
- // to associate it with the channel name. |
- channel_host_ = NULL; |
- } |
- |
- plugin_ = NULL; |
- |
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
-} |
- |
-bool WebPluginDelegateProxy::Initialize( |
- const GURL& url, |
- const std::vector<std::string>& arg_names, |
- const std::vector<std::string>& arg_values, |
- bool load_manually) { |
- // TODO(shess): Attempt to work around http://crbug.com/97285 and |
- // http://crbug.com/141055 by retrying the connection. Reports seem |
- // to indicate that the plugin hasn't crashed, and that the problem |
- // is not 100% persistent. |
- const size_t kAttempts = 2; |
- |
- bool result = false; |
- scoped_refptr<PluginChannelHost> channel_host; |
- int instance_id = 0; |
- |
- for (size_t attempt = 0; !result && attempt < kAttempts; attempt++) { |
-#if defined(OS_MACOSX) |
- // TODO(shess): Debugging for http://crbug.com/97285 . See comment |
- // in plugin_channel_host.cc. |
- scoped_ptr<base::AutoReset<bool> > track_nested_removes( |
- new base::AutoReset<bool>(PluginChannelHost::GetRemoveTrackingFlag(), |
- true)); |
-#endif |
- |
- IPC::ChannelHandle channel_handle; |
- if (!RenderThreadImpl::current()->Send(new FrameHostMsg_OpenChannelToPlugin( |
- render_frame_->GetRoutingID(), url, page_url_, mime_type_, |
- &channel_handle, &info_))) { |
- continue; |
- } |
- |
- if (channel_handle.name.empty()) { |
- // We got an invalid handle. Either the plugin couldn't be found (which |
- // shouldn't happen, since if we got here the plugin should exist) or the |
- // plugin crashed on initialization. |
- if (!info_.path.empty()) { |
- render_view_->GetMainRenderFrame()->PluginCrashed( |
- info_.path, base::kNullProcessId); |
- LOG(ERROR) << "Plugin crashed on start"; |
- |
- // Return true so that the plugin widget is created and we can paint the |
- // crashed plugin there. |
- return true; |
- } |
- LOG(ERROR) << "Plugin couldn't be found"; |
- return false; |
- } |
- |
- channel_host = PluginChannelHost::GetPluginChannelHost( |
- channel_handle, ChildProcess::current()->io_task_runner()); |
- if (!channel_host.get()) { |
- LOG(ERROR) << "Couldn't get PluginChannelHost"; |
- continue; |
- } |
-#if defined(OS_MACOSX) |
- track_nested_removes.reset(); |
-#endif |
- |
- { |
- // TODO(bauerb): Debugging for http://crbug.com/141055. |
- ScopedLogLevel log_level(-2); // Equivalent to --v=2 |
- result = channel_host->Send(new PluginMsg_CreateInstance( |
- mime_type_, &instance_id)); |
- if (!result) { |
- LOG(ERROR) << "Couldn't send PluginMsg_CreateInstance"; |
- continue; |
- } |
- } |
- } |
- |
- // Failed too often, give up. |
- if (!result) |
- return false; |
- |
- channel_host_ = channel_host; |
- instance_id_ = instance_id; |
- |
- channel_host_->AddRoute(instance_id_, this); |
- |
- // Now tell the PluginInstance in the plugin process to initialize. |
- PluginMsg_Init_Params params; |
- params.url = url; |
- params.page_url = page_url_; |
- params.arg_names = arg_names; |
- params.arg_values = arg_values; |
- params.host_render_view_routing_id = render_view_->GetRoutingID(); |
- params.load_manually = load_manually; |
- |
- result = false; |
- Send(new PluginMsg_Init(instance_id_, params, &transparent_, &result)); |
- |
- if (!result) |
- LOG(WARNING) << "PluginMsg_Init returned false"; |
- |
- render_view_->RegisterPluginDelegate(this); |
- |
- return result; |
-} |
- |
-bool WebPluginDelegateProxy::Send(IPC::Message* msg) { |
- if (!channel_host_.get()) { |
- DLOG(WARNING) << "dropping message because channel host is null"; |
- delete msg; |
- return false; |
- } |
- |
- return channel_host_->Send(msg); |
-} |
- |
-bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { |
- GetContentClient()->SetActiveURL(page_url_); |
- |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_ResolveProxy, OnResolveProxy) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_SetCookie, OnSetCookie) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading) |
-#if defined(OS_MACOSX) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_FocusChanged, |
- OnFocusChanged); |
- IPC_MESSAGE_HANDLER(PluginHostMsg_StartIme, |
- OnStartIme); |
- IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginEnabledRendering, |
- OnAcceleratedPluginEnabledRendering) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginAllocatedIOSurface, |
- OnAcceleratedPluginAllocatedIOSurface) |
- IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginSwappedIOSurface, |
- OnAcceleratedPluginSwappedIOSurface) |
-#endif |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
- DCHECK(handled); |
- return handled; |
-} |
- |
-void WebPluginDelegateProxy::OnChannelError() { |
- if (plugin_) { |
- plugin_->Invalidate(); |
- } |
- if (channel_host_.get() && !channel_host_->expecting_shutdown()) { |
- render_view_->GetMainRenderFrame()->PluginCrashed( |
- info_.path, channel_host_->peer_pid()); |
- } |
- |
-#if defined(OS_MACOSX) |
- // Ensure that the renderer doesn't think the plugin still has focus. |
- if (render_view_) |
- render_view_->PluginFocusChanged(false, instance_id_); |
-#endif |
-} |
- |
-static void CopySharedMemoryHandleForMessage( |
- const base::SharedMemoryHandle& handle_in, |
- base::SharedMemoryHandle* handle_out, |
- base::ProcessId peer_pid) { |
-#if defined(OS_POSIX) || defined(OS_WIN) |
- *handle_out = base::SharedMemory::DuplicateHandle(handle_in); |
-#else |
-#error Shared memory copy not implemented. |
-#endif |
-} |
- |
-void WebPluginDelegateProxy::SendUpdateGeometry( |
- bool bitmaps_changed) { |
- if (!channel_host_.get()) |
- return; |
- |
- PluginMsg_UpdateGeometry_Param param; |
- param.window_rect = plugin_rect_; |
- param.clip_rect = clip_rect_; |
- param.windowless_buffer0 = base::SharedMemory::NULLHandle(); |
- param.windowless_buffer1 = base::SharedMemory::NULLHandle(); |
- param.windowless_buffer_index = back_buffer_index(); |
- |
-#if defined(OS_POSIX) |
- // If we're using POSIX mmap'd TransportDIBs, sending the handle across |
- // IPC establishes a new mapping rather than just sending a window ID, |
- // so only do so if we've actually changed the shared memory bitmaps. |
- if (bitmaps_changed) |
-#endif |
- { |
- if (transport_stores_[0].bitmap) |
- CopySharedMemoryHandleForMessage( |
- transport_stores_[0].bitmap->shared_memory()->handle(), |
- ¶m.windowless_buffer0, channel_host_->peer_pid()); |
- |
- if (transport_stores_[1].bitmap) |
- CopySharedMemoryHandleForMessage( |
- transport_stores_[1].bitmap->shared_memory()->handle(), |
- ¶m.windowless_buffer1, channel_host_->peer_pid()); |
- } |
- |
- IPC::Message* msg; |
-#if defined(OS_WIN) |
- if (UseSynchronousGeometryUpdates()) { |
- msg = new PluginMsg_UpdateGeometrySync(instance_id_, param); |
- } else // NOLINT |
-#endif |
- { |
- msg = new PluginMsg_UpdateGeometry(instance_id_, param); |
- msg->set_unblock(true); |
- } |
- |
- Send(msg); |
-} |
- |
-void WebPluginDelegateProxy::UpdateGeometry(const gfx::Rect& window_rect, |
- const gfx::Rect& clip_rect) { |
- // window_rect becomes either a window in native windowing system |
- // coords, or a backing buffer. In either case things will go bad |
- // if the rectangle is very large. |
- if (window_rect.width() < 0 || window_rect.width() > kMaxPluginSideLength || |
- window_rect.height() < 0 || window_rect.height() > kMaxPluginSideLength || |
- // We know this won't overflow due to above checks. |
- static_cast<uint32_t>(window_rect.width()) * |
- static_cast<uint32_t>(window_rect.height()) > |
- kMaxPluginSize) { |
- return; |
- } |
- |
- plugin_rect_ = window_rect; |
- clip_rect_ = clip_rect; |
- |
- bool bitmaps_changed = false; |
- |
- if (uses_shared_bitmaps_) { |
- if (!front_buffer_canvas() || |
- (window_rect.width() != |
- front_buffer_canvas()->getBaseLayerSize().width() || |
- window_rect.height() != |
- front_buffer_canvas()->getBaseLayerSize().height())) |
- { |
- bitmaps_changed = true; |
- |
- // Create a shared memory section that the plugin paints into |
- // asynchronously. |
- ResetWindowlessBitmaps(); |
- if (!window_rect.IsEmpty()) { |
- if (!CreateSharedBitmap(&transport_stores_[0].bitmap, |
- &transport_stores_[0].canvas) || |
- !CreateSharedBitmap(&transport_stores_[1].bitmap, |
- &transport_stores_[1].canvas)) { |
- DCHECK(false); |
- ResetWindowlessBitmaps(); |
- return; |
- } |
- } |
- } |
- } |
- |
- SendUpdateGeometry(bitmaps_changed); |
-} |
- |
-void WebPluginDelegateProxy::ResetWindowlessBitmaps() { |
- transport_stores_[0].bitmap.reset(); |
- transport_stores_[1].bitmap.reset(); |
- |
- transport_stores_[0].canvas.clear(); |
- transport_stores_[1].canvas.clear(); |
- transport_store_painted_ = gfx::Rect(); |
- front_buffer_diff_ = gfx::Rect(); |
-} |
- |
-#if !defined(OS_WIN) |
-static size_t BitmapSizeForPluginRect(const gfx::Rect& plugin_rect) { |
- const size_t stride = |
- skia::PlatformCanvasStrideForWidth(plugin_rect.width()); |
- return stride * plugin_rect.height(); |
-} |
- |
-bool WebPluginDelegateProxy::CreateLocalBitmap( |
- std::vector<uint8_t>* memory, |
- skia::RefPtr<SkCanvas>* canvas) { |
- const size_t size = BitmapSizeForPluginRect(plugin_rect_); |
- memory->resize(size); |
- if (memory->size() != size) |
- return false; |
- *canvas = skia::AdoptRef(skia::CreatePlatformCanvas( |
- plugin_rect_.width(), plugin_rect_.height(), true, &((*memory)[0]), |
- skia::CRASH_ON_FAILURE)); |
- return true; |
-} |
-#endif |
- |
-bool WebPluginDelegateProxy::CreateSharedBitmap( |
- scoped_ptr<SharedMemoryBitmap>* memory, |
- skia::RefPtr<SkCanvas>* canvas) { |
- *memory = ChildThreadImpl::current() |
- ->shared_bitmap_manager() |
- ->AllocateSharedMemoryBitmap(plugin_rect_.size()); |
- if (!memory->get()) |
- return false; |
- DCHECK((*memory)->shared_memory()); |
-#if defined(OS_POSIX) |
- *canvas = skia::AdoptRef(skia::CreatePlatformCanvas( |
- plugin_rect_.width(), plugin_rect_.height(), true, (*memory)->pixels(), |
- skia::RETURN_NULL_ON_FAILURE)); |
-#else |
- *canvas = skia::AdoptRef(skia::CreatePlatformCanvas( |
- plugin_rect_.width(), plugin_rect_.height(), true, |
- (*memory)->shared_memory()->handle().GetHandle(), |
- skia::RETURN_NULL_ON_FAILURE)); |
-#endif |
- return !!canvas->get(); |
-} |
- |
-void WebPluginDelegateProxy::Paint(SkCanvas* canvas, |
- const gfx::Rect& damaged_rect) { |
- // Limit the damaged rectangle to whatever is contained inside the plugin |
- // rectangle, as that's the rectangle that we'll actually draw. |
- gfx::Rect rect = gfx::IntersectRects(damaged_rect, plugin_rect_); |
- |
- // If the plugin is no longer connected (channel crashed) draw a crashed |
- // plugin bitmap |
- if (!channel_host_.get() || !channel_host_->channel_valid()) { |
- // Lazily load the sad plugin image. |
- if (!sad_plugin_) |
- sad_plugin_ = GetContentClient()->renderer()->GetSadPluginBitmap(); |
- if (sad_plugin_) |
- PaintSadPlugin(canvas, plugin_rect_, *sad_plugin_); |
- return; |
- } |
- |
- if (!uses_shared_bitmaps_) |
- return; |
- |
- // We got a paint before the plugin's coordinates, so there's no buffer to |
- // copy from. |
- if (!front_buffer_canvas()) |
- return; |
- |
- gfx::Rect offset_rect = rect; |
- offset_rect.Offset(-plugin_rect_.x(), -plugin_rect_.y()); |
- |
- // transport_store_painted_ is really a bounding box, so in principle this |
- // check could falsely indicate that we don't need to paint offset_rect, but |
- // in practice it works fine. |
- if (!transport_store_painted_.Contains(offset_rect)) { |
- Send(new PluginMsg_Paint(instance_id_, offset_rect)); |
- // Since the plugin is not blocked on the renderer in this context, there is |
- // a chance that it will begin repainting the back-buffer before we complete |
- // capturing the data. Buffer flipping would increase that risk because |
- // geometry update is asynchronous, so we don't want to use buffer flipping |
- // here. |
- UpdateFrontBuffer(offset_rect, false); |
- } |
- |
- const SkBitmap bitmap = skia::ReadPixels(front_buffer_canvas()); |
- SkPaint paint; |
- paint.setXfermodeMode( |
- transparent_ ? SkXfermode::kSrcATop_Mode : SkXfermode::kSrc_Mode); |
- SkRect src_rect = gfx::RectToSkRect(offset_rect); |
- canvas->drawBitmapRect(bitmap, |
- src_rect, |
- gfx::RectToSkRect(rect), |
- &paint); |
- |
- if (invalidate_pending_) { |
- // Only send the PaintAck message if this paint is in response to an |
- // invalidate from the plugin, since this message acts as an access token |
- // to ensure only one process is using the shared bitmap at a time. |
- invalidate_pending_ = false; |
- Send(new PluginMsg_DidPaint(instance_id_)); |
- } |
-} |
- |
-void WebPluginDelegateProxy::SetFocus(bool focused) { |
- Send(new PluginMsg_SetFocus(instance_id_, focused)); |
-} |
- |
-bool WebPluginDelegateProxy::HandleInputEvent( |
- const WebInputEvent& event, |
- WebCursor::CursorInfo* cursor_info) { |
- bool handled = false; |
- WebCursor cursor; |
- Send(new PluginMsg_HandleInputEvent(instance_id_, &event, &handled, &cursor)); |
- return handled; |
-} |
- |
-int WebPluginDelegateProxy::GetProcessId() { |
- return channel_host_->peer_pid(); |
-} |
- |
-void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) { |
- IPC::Message* msg = new PluginMsg_SetContentAreaFocus(instance_id_, |
- has_focus); |
- // Make sure focus events are delivered in the right order relative to |
- // sync messages they might interact with (Paint, HandleEvent, etc.). |
- msg->set_unblock(true); |
- Send(msg); |
-} |
- |
-#if defined(OS_MACOSX) |
-void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) { |
- IPC::Message* msg = new PluginMsg_SetWindowFocus(instance_id_, |
- window_has_focus); |
- // Make sure focus events are delivered in the right order relative to |
- // sync messages they might interact with (Paint, HandleEvent, etc.). |
- msg->set_unblock(true); |
- Send(msg); |
-} |
- |
-void WebPluginDelegateProxy::SetContainerVisibility(bool is_visible) { |
- IPC::Message* msg; |
- if (is_visible) { |
- gfx::Rect window_frame = render_view_->GetWidget()->rootWindowRect(); |
- gfx::Rect view_frame = render_view_->GetWidget()->windowRect(); |
- blink::WebView* webview = render_view_->webview(); |
- msg = new PluginMsg_ContainerShown(instance_id_, window_frame, view_frame, |
- webview && webview->isActive()); |
- } else { |
- msg = new PluginMsg_ContainerHidden(instance_id_); |
- } |
- // Make sure visibility events are delivered in the right order relative to |
- // sync messages they might interact with (Paint, HandleEvent, etc.). |
- msg->set_unblock(true); |
- Send(msg); |
-} |
- |
-void WebPluginDelegateProxy::WindowFrameChanged(gfx::Rect window_frame, |
- gfx::Rect view_frame) { |
- IPC::Message* msg = new PluginMsg_WindowFrameChanged(instance_id_, |
- window_frame, |
- view_frame); |
- // Make sure frame events are delivered in the right order relative to |
- // sync messages they might interact with (e.g., HandleEvent). |
- msg->set_unblock(true); |
- Send(msg); |
-} |
-void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text, |
- int plugin_id) { |
- // If the message isn't intended for this plugin, there's nothing to do. |
- if (instance_id_ != plugin_id) |
- return; |
- |
- IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, |
- text); |
- // Order relative to other key events is important. |
- msg->set_unblock(true); |
- Send(msg); |
-} |
-#endif // OS_MACOSX |
- |
-void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) { |
- if (!plugin_) |
- return; |
- |
- // Clip the invalidation rect to the plugin bounds; the plugin may have been |
- // resized since the invalidate message was sent. |
- gfx::Rect clipped_rect = |
- gfx::IntersectRects(rect, gfx::Rect(plugin_rect_.size())); |
- |
- invalidate_pending_ = true; |
- // The plugin is blocked on the renderer because the invalidate message it has |
- // sent us is synchronous, so we can use buffer flipping here if the caller |
- // allows it. |
- UpdateFrontBuffer(clipped_rect, true); |
- plugin_->InvalidateRect(clipped_rect); |
-} |
- |
-void WebPluginDelegateProxy::OnResolveProxy(const GURL& url, |
- bool* result, |
- std::string* proxy_list) { |
- *result = RenderThreadImpl::current()->ResolveProxy(url, proxy_list); |
-} |
- |
-void WebPluginDelegateProxy::OnSetCookie(const GURL& url, |
- const GURL& first_party_for_cookies, |
- const std::string& cookie) { |
- if (plugin_) |
- plugin_->SetCookie(url, first_party_for_cookies, cookie); |
-} |
- |
-void WebPluginDelegateProxy::OnGetCookies(const GURL& url, |
- const GURL& first_party_for_cookies, |
- std::string* cookies) { |
- DCHECK(cookies); |
- if (plugin_) |
- *cookies = plugin_->GetCookies(url, first_party_for_cookies); |
-} |
- |
-void WebPluginDelegateProxy::CopyFromBackBufferToFrontBuffer( |
- const gfx::Rect& rect) { |
- // Blitting the bits directly is much faster than going through CG, and since |
- // the goal is just to move the raw pixels between two bitmaps with the same |
- // pixel format (no compositing, color correction, etc.), it's safe. |
- const size_t stride = |
- skia::PlatformCanvasStrideForWidth(plugin_rect_.width()); |
- const size_t chunk_size = 4 * rect.width(); |
- DCHECK(back_buffer_bitmap() != NULL); |
- uint8_t* source_data = |
- back_buffer_bitmap()->pixels() + rect.y() * stride + 4 * rect.x(); |
- DCHECK(front_buffer_bitmap() != NULL); |
- uint8_t* target_data = |
- front_buffer_bitmap()->pixels() + rect.y() * stride + 4 * rect.x(); |
- for (int row = 0; row < rect.height(); ++row) { |
- memcpy(target_data, source_data, chunk_size); |
- source_data += stride; |
- target_data += stride; |
- } |
-} |
- |
-void WebPluginDelegateProxy::UpdateFrontBuffer( |
- const gfx::Rect& rect, |
- bool allow_buffer_flipping) { |
- if (!front_buffer_canvas()) { |
- return; |
- } |
- |
-#if defined(OS_WIN) |
- // If SendUpdateGeometry() would block on the plugin process then we don't |
- // want to use buffer flipping at all since it would add extra locking. |
- // (Alternatively we could probably safely use async updates for buffer |
- // flipping all the time since the size is not changing.) |
- if (UseSynchronousGeometryUpdates()) { |
- allow_buffer_flipping = false; |
- } |
-#endif |
- |
- // Plugin has just painted "rect" into the back-buffer, so the front-buffer |
- // no longer holds the latest content for that rectangle. |
- front_buffer_diff_.Subtract(rect); |
- if (allow_buffer_flipping && front_buffer_diff_.IsEmpty()) { |
- // Back-buffer contains the latest content for all areas; simply flip |
- // the buffers. |
- front_buffer_index_ = back_buffer_index(); |
- SendUpdateGeometry(false); |
- // The front-buffer now holds newer content for this region than the |
- // back-buffer. |
- front_buffer_diff_ = rect; |
- } else { |
- // Back-buffer contains the latest content for "rect" but the front-buffer |
- // contains the latest content for some other areas (or buffer flipping not |
- // allowed); fall back to copying the data. |
- CopyFromBackBufferToFrontBuffer(rect); |
- } |
- transport_store_painted_.Union(rect); |
-} |
- |
-#if defined(OS_MACOSX) |
-void WebPluginDelegateProxy::OnFocusChanged(bool focused) { |
- if (render_view_) |
- render_view_->PluginFocusChanged(focused, instance_id_); |
-} |
- |
-void WebPluginDelegateProxy::OnStartIme() { |
- if (render_view_) |
- render_view_->StartPluginIme(); |
-} |
-#endif |
- |
-void WebPluginDelegateProxy::OnCancelDocumentLoad() { |
- plugin_->CancelDocumentLoad(); |
-} |
- |
-void WebPluginDelegateProxy::OnDidStartLoading() { |
- plugin_->DidStartLoading(); |
-} |
- |
-void WebPluginDelegateProxy::OnDidStopLoading() { |
- plugin_->DidStopLoading(); |
-} |
- |
-#if defined(OS_MACOSX) |
-void WebPluginDelegateProxy::OnAcceleratedPluginEnabledRendering() { |
- uses_compositor_ = true; |
- uses_shared_bitmaps_ = false; |
-} |
- |
-void WebPluginDelegateProxy::OnAcceleratedPluginAllocatedIOSurface( |
- int32_t width, |
- int32_t height, |
- uint32_t surface_id) { |
- if (plugin_) |
- plugin_->AcceleratedPluginAllocatedIOSurface(width, height, surface_id); |
-} |
- |
-void WebPluginDelegateProxy::OnAcceleratedPluginSwappedIOSurface() { |
- if (plugin_) |
- plugin_->AcceleratedPluginSwappedIOSurface(); |
-} |
-#endif |
- |
-#if defined(OS_WIN) |
-bool WebPluginDelegateProxy::UseSynchronousGeometryUpdates() { |
- // Need to update geometry synchronously with WMP, otherwise if a site |
- // scripts the plugin to start playing while it's in the middle of handling |
- // an update geometry message, videos don't play. See urls in bug 20260. |
- if (info_.name.find(base::ASCIIToUTF16("Windows Media Player")) != |
- base::string16::npos) |
- return true; |
- |
- // The move networks plugin needs to be informed of geometry updates |
- // synchronously. |
- std::vector<WebPluginMimeType>::iterator index; |
- for (index = info_.mime_types.begin(); index != info_.mime_types.end(); |
- index++) { |
- if (index->mime_type == "application/x-vnd.moveplayer.qm" || |
- index->mime_type == "application/x-vnd.moveplay2.qm" || |
- index->mime_type == "application/x-vnd.movenetworks.qm" || |
- index->mime_type == "application/x-vnd.mnplayer.qm") { |
- return true; |
- } |
- } |
- return false; |
-} |
-#endif |
- |
-} // namespace content |