From 7e259aa9f2b26bb45f6e0b7a858918ad62dc7ee9 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Mon, 24 Jun 2013 16:40:40 +0000 Subject: [PATCH] Force flash and silverlight plugins to windowless mode when using off-screen rendering (issue #518). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1285 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/renderer/browser_impl.cc | 4 +- libcef/renderer/browser_impl.h | 7 +- libcef/renderer/content_renderer_client.cc | 86 +++++++++++++++++++++- libcef/renderer/content_renderer_client.h | 5 ++ 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index 6a71a32f7..e3aad0ee0 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -260,10 +260,12 @@ bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process, CefBrowserImpl::CefBrowserImpl(content::RenderView* render_view, int browser_id, - bool is_popup) + bool is_popup, + bool is_window_rendering_disabled) : content::RenderViewObserver(render_view), browser_id_(browser_id), is_popup_(is_popup), + is_window_rendering_disabled_(is_window_rendering_disabled), last_focused_frame_id_(kInvalidFrameId) { response_manager_.reset(new CefResponseManager); } diff --git a/libcef/renderer/browser_impl.h b/libcef/renderer/browser_impl.h index 485abc16c..bda3685c4 100644 --- a/libcef/renderer/browser_impl.h +++ b/libcef/renderer/browser_impl.h @@ -79,7 +79,8 @@ class CefBrowserImpl : public CefBrowser, CefBrowserImpl(content::RenderView* render_view, int browser_id, - bool is_popup); + bool is_popup, + bool is_window_rendering_disabled); virtual ~CefBrowserImpl(); void LoadRequest(const CefMsg_LoadRequest_Params& params); @@ -99,6 +100,9 @@ class CefBrowserImpl : public CefBrowser, int browser_id() const { return browser_id_; } bool is_popup() const { return is_popup_; } + bool is_window_rendering_disabled() const { + return is_window_rendering_disabled_; + } content::RenderView* render_view() { return content::RenderViewObserver::render_view(); } @@ -124,6 +128,7 @@ class CefBrowserImpl : public CefBrowser, // same browser ID. int browser_id_; bool is_popup_; + bool is_window_rendering_disabled_; // Id of the last frame that had focus. int64 last_focused_frame_id_; diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index dc0106d33..ffd68ea13 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -34,15 +34,19 @@ MSVC_POP_WARNING(); #include "content/child/child_thread.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" +#include "content/public/common/content_constants.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" +#include "content/renderer/render_view_impl.h" #include "ipc/ipc_sync_channel.h" #include "media/base/media.h" #include "third_party/WebKit/public/platform/WebPrerenderingSupport.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/platform/WebWorkerRunLoop.h" +#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebPluginParams.h" #include "third_party/WebKit/public/web/WebPrerendererClient.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" @@ -432,7 +436,8 @@ void CefContentRendererClient::RenderViewCreated( #endif CefRefPtr browser = - new CefBrowserImpl(render_view, params.browser_id, params.is_popup); + new CefBrowserImpl(render_view, params.browser_id, params.is_popup, + params.is_window_rendering_disabled); browsers_.insert(std::make_pair(render_view, browser)); new CefPrerendererClient(render_view); @@ -447,6 +452,85 @@ void CefContentRendererClient::RenderViewCreated( } } +bool CefContentRendererClient::OverrideCreatePlugin( + content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params, + WebKit::WebPlugin** plugin) { + CefRefPtr browser = + CefBrowserImpl::GetBrowserForMainFrame(frame->top()); + if (!browser || !browser->is_window_rendering_disabled()) + return false; + +#if defined(ENABLE_PLUGINS) + if (UTF16ToASCII(params.mimeType) == content::kBrowserPluginMimeType) + return false; + + content::RenderViewImpl* render_view_impl = + static_cast(render_view); + + webkit::WebPluginInfo info; + std::string mime_type; + bool found = render_view_impl->GetPluginInfo(params.url, + frame->top()->document().url(), + params.mimeType.utf8(), + &info, + &mime_type); + if (!found) + return false; + + bool flash = LowerCaseEqualsASCII(mime_type, + "application/x-shockwave-flash"); + bool silverlight = StartsWithASCII(mime_type, + "application/x-silverlight", false); + + if (flash) { + // "wmode" values of "opaque" or "transparent" are allowed. + size_t size = params.attributeNames.size(); + for (size_t i = 0; i < size; ++i) { + std::string name = params.attributeNames[i].utf8(); + if (name == "wmode") { + std::string value = params.attributeValues[i].utf8(); + if (value == "opaque" || value == "transparent") + flash = false; + break; + } + } + } + + if (flash || silverlight) { + // Force Flash and Silverlight plugins to use windowless mode. + WebKit::WebPluginParams params_to_use = params; + params_to_use.mimeType = WebKit::WebString::fromUTF8(mime_type); + + size_t size = params.attributeNames.size(); + WebKit::WebVector new_names(size+1), + new_values(size+1); + + for (size_t i = 0; i < size; ++i) { + new_names[i] = params.attributeNames[i]; + new_values[i] = params.attributeValues[i]; + } + + if (flash) { + new_names[size] = "wmode"; + new_values[size] = "opaque"; + } else if (silverlight) { + new_names[size] = "windowless"; + new_values[size] = "true"; + } + + params_to_use.attributeNames.swap(new_names); + params_to_use.attributeValues.swap(new_values); + + *plugin = render_view_impl->CreatePlugin(frame, info, params_to_use); + return true; + } +#endif // defined(ENABLE_PLUGINS) + + return false; +} + bool CefContentRendererClient::HandleNavigation( WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, diff --git a/libcef/renderer/content_renderer_client.h b/libcef/renderer/content_renderer_client.h index 12e104486..4508ae64a 100644 --- a/libcef/renderer/content_renderer_client.h +++ b/libcef/renderer/content_renderer_client.h @@ -76,6 +76,11 @@ class CefContentRendererClient : public content::ContentRendererClient, // ContentRendererClient implementation. virtual void RenderThreadStarted() OVERRIDE; virtual void RenderViewCreated(content::RenderView* render_view) OVERRIDE; + virtual bool OverrideCreatePlugin( + content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params, + WebKit::WebPlugin** plugin) OVERRIDE; virtual bool HandleNavigation(WebKit::WebFrame* frame, const WebKit::WebURLRequest& request, WebKit::WebNavigationType type,