diff options
-rw-r--r-- | content/browser/renderer_host/render_process_host_impl.cc | 1 | ||||
-rw-r--r-- | content/content_renderer.gypi | 4 | ||||
-rw-r--r-- | content/public/common/content_switches.cc | 3 | ||||
-rw-r--r-- | content/public/common/content_switches.h | 1 | ||||
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin_constants.cc | 10 | ||||
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin_constants.h | 13 | ||||
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin_placeholder.cc | 143 | ||||
-rw-r--r-- | content/renderer/browser_plugin/browser_plugin_placeholder.h | 89 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 11 |
9 files changed, 275 insertions, 0 deletions
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index b4bd350..869bdf0 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -678,6 +678,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDisableWebSockets, switches::kDomAutomationController, switches::kEnableAccessibilityLogging, + switches::kEnableBrowserPlugin, switches::kEnableDCHECK, switches::kEnableFixedLayout, switches::kEnableGamepad, diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index ec87f80..ca7fc6c 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -143,6 +143,10 @@ 'renderer/pepper/pepper_proxy_channel_delegate_impl.h', 'renderer/plugin_channel_host.cc', 'renderer/plugin_channel_host.h', + 'renderer/browser_plugin/browser_plugin_constants.cc', + 'renderer/browser_plugin/browser_plugin_constants.h', + 'renderer/browser_plugin/browser_plugin_placeholder.cc', + 'renderer/browser_plugin/browser_plugin_placeholder.h', 'renderer/render_process.h', 'renderer/render_process_impl.cc', 'renderer/render_process_impl.h', diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 865f768..0c2ac2a 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -223,6 +223,9 @@ const char kEnableAccessibility[] = "enable-accessibility"; // Turns on extremely verbose logging of accessibility events. const char kEnableAccessibilityLogging[] = "enable-accessibility-logging"; +// Turns on the browser plugin. +const char kEnableBrowserPlugin[] = "enable-browser-plugin"; + // Enables the creation of compositing layers for fixed position elements. const char kEnableCompositingForFixedPosition[] = "enable-fixed-position-compositing"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 97dbeb3..668a326 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -78,6 +78,7 @@ CONTENT_EXPORT extern const char kEnableAcceleratedPainting[]; CONTENT_EXPORT extern const char kEnableAcceleratedFilters[]; extern const char kEnableAccessibility[]; extern const char kEnableAccessibilityLogging[]; +extern const char kEnableBrowserPlugin[]; CONTENT_EXPORT extern const char kEnableCompositingForFixedPosition[]; extern const char kEnableCssRegions[]; CONTENT_EXPORT extern const char kEnableDeferred2dCanvas[]; diff --git a/content/renderer/browser_plugin/browser_plugin_constants.cc b/content/renderer/browser_plugin/browser_plugin_constants.cc new file mode 100644 index 0000000..9e62b9e --- /dev/null +++ b/content/renderer/browser_plugin/browser_plugin_constants.cc @@ -0,0 +1,10 @@ +// 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/browser_plugin/browser_plugin_constants.h" + +const char kBrowserPluginName[] = "Browser Plugin"; +const char kBrowserPluginMimeType[] = "application/browser-plugin"; +const char kBrowserPluginPath[] = "internal/browser-plugin"; +const char kBrowserPluginDescription[] = "Out-of-Process Browser Plugin"; diff --git a/content/renderer/browser_plugin/browser_plugin_constants.h b/content/renderer/browser_plugin/browser_plugin_constants.h new file mode 100644 index 0000000..446bd0c --- /dev/null +++ b/content/renderer/browser_plugin/browser_plugin_constants.h @@ -0,0 +1,13 @@ +// 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. + +#ifndef CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_CONSTANTS_H_ +#define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_CONSTANTS_H_ + +extern const char kBrowserPluginName[]; +extern const char kBrowserPluginMimeType[]; +extern const char kBrowserPluginPath[]; +extern const char kBrowserPluginDescription[]; + +#endif // CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_CONSTANTS_H_ diff --git a/content/renderer/browser_plugin/browser_plugin_placeholder.cc b/content/renderer/browser_plugin/browser_plugin_placeholder.cc new file mode 100644 index 0000000..21ac8ee --- /dev/null +++ b/content/renderer/browser_plugin/browser_plugin_placeholder.cc @@ -0,0 +1,143 @@ +// 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/browser_plugin/browser_plugin_placeholder.h" + +#include "base/atomic_sequence_num.h" +#include "base/id_map.h" +#include "base/lazy_instance.h" +#include "base/process.h" +#include "base/string_number_conversions.h" +#include "base/string_piece.h" +#include "base/string_util.h" +#include "base/values.h" +#include "content/common/view_messages.h" +#include "content/public/renderer/render_view.h" +#include "ipc/ipc_channel_handle.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" +#include "webkit/plugins/webview_plugin.h" + +static base::StaticAtomicSequenceNumber g_next_id; + +// The global list of all Browser Plugin Placeholders within a process. +base::LazyInstance<IDMap<BrowserPluginPlaceholder> >::Leaky + g_all_placeholders = LAZY_INSTANCE_INITIALIZER; + +using webkit::WebViewPlugin; +using WebKit::WebPlugin; +using WebKit::WebPluginContainer; + +const char* const kPluginPlaceholderDataURL = + "about:blank"; + +// static +webkit::WebViewPlugin* BrowserPluginPlaceholder::Create( + content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params) { + // TODO(fsamuel): Need a better loading screen at some point. Maybe this can + // be a part of the <browser> API? + // |browser_plugin| will destroy itself when its WebViewPlugin is going away. + BrowserPluginPlaceholder* browser_plugin = new BrowserPluginPlaceholder( + render_view, frame, params, ""); + return browser_plugin->plugin(); +} + +// static +BrowserPluginPlaceholder* BrowserPluginPlaceholder::FromID(int id) { + return g_all_placeholders.Get().Lookup(id); +} + +BrowserPluginPlaceholder::BrowserPluginPlaceholder( + content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params, + const std::string& html_data) + : render_view_(render_view), + plugin_params_(params), + plugin_(webkit::WebViewPlugin::Create( + this, render_view->GetWebkitPreferences(), html_data, + GURL(kPluginPlaceholderDataURL))) { + id_ = g_next_id.GetNext(); + RegisterPlaceholder(GetID(), this); + + // By default we navigate to google.com + GetPluginParameters(0, 0, "http://www.google.com/"); + + // TODO(fsamuel): Request a browser plugin instance from the + // browser process. +} + +BrowserPluginPlaceholder::~BrowserPluginPlaceholder() { + UnregisterPlaceholder(GetID()); +} + +void BrowserPluginPlaceholder::RegisterPlaceholder( + int id, + BrowserPluginPlaceholder* placeholder) { + g_all_placeholders.Get().AddWithID(placeholder, id); +} + +void BrowserPluginPlaceholder::UnregisterPlaceholder(int id) { + if (g_all_placeholders.Get().Lookup(id)) + g_all_placeholders.Get().Remove(id); +} + +const WebKit::WebPluginParams& BrowserPluginPlaceholder::plugin_params() const { + return plugin_params_; +} + +void BrowserPluginPlaceholder::GetPluginParameters( + int default_width, int default_height, + const std::string& default_src) { + int width = default_width; + int height = default_height; + + // Get the plugin parameters from the attributes vector + for (unsigned i = 0; i < plugin_params_.attributeNames.size(); ++i) { + std::string attributeName = plugin_params_.attributeNames[i].utf8(); + if (LowerCaseEqualsASCII(attributeName, "width")) { + std::string attributeValue = plugin_params_.attributeValues[i].utf8(); + CHECK(base::StringToInt(attributeValue, &width)); + } else if (LowerCaseEqualsASCII(attributeName, "height")) { + std::string attributeValue = plugin_params_.attributeValues[i].utf8(); + CHECK(base::StringToInt(attributeValue, &height)); + } else if (LowerCaseEqualsASCII(attributeName, "src")) { + src_ = plugin_params_.attributeValues[i].utf8(); + } + } + // If we didn't find the attributes set or they're not sensible, + // we reset our attributes to the default. + if (src_.empty()) + src_ = default_src; + + size_.SetSize(width, height); +} + +void BrowserPluginPlaceholder::GuestReady( + base::ProcessHandle process_handle, + const IPC::ChannelHandle& channel_handle) { + // TODO(fsamuel): Once the guest renderer is ready, + // it will inform the host renderer and the BrowserPluginPlaceholder + // can swap itself out with the guest. + NOTIMPLEMENTED(); +} + +void BrowserPluginPlaceholder::LoadGuest(WebKit::WebPlugin* new_plugin) { + WebKit::WebPluginContainer* container = plugin_->container(); + if (!new_plugin || !new_plugin->initialize(container)) + return; + plugin_->RestoreTitleText(); + container->setPlugin(new_plugin); + container->invalidate(); + container->reportGeometry(); + plugin_->ReplayReceivedData(new_plugin); + plugin_->destroy(); +} + +void BrowserPluginPlaceholder::WillDestroyPlugin() { + delete this; +} diff --git a/content/renderer/browser_plugin/browser_plugin_placeholder.h b/content/renderer/browser_plugin/browser_plugin_placeholder.h new file mode 100644 index 0000000..b7c229d --- /dev/null +++ b/content/renderer/browser_plugin/browser_plugin_placeholder.h @@ -0,0 +1,89 @@ +// 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. + +#ifndef CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_PLACEHOLDER_H_ +#define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_PLACEHOLDER_H_ +#pragma once + +#include "base/process.h" +#include "ipc/ipc_channel_handle.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" +#include "ui/gfx/size.h" +#include "webkit/plugins/webview_plugin.h" + +namespace content { +class RenderView; +} + +namespace WebKit { +class WebPlugin; +} + +// A browser plugin is a plugin container that hosts an out-of-process "guest" +// RenderView. Loading up a new process, creating a new RenderView, navigating +// to a given URL, and establishing a guest-to-host channel can take hundreds +// of milliseconds. Furthermore, a RenderView's associated browser-side +// WebContents, RenderViewHost, and SiteInstance must be created and accessed on +// the UI thread of the browser process. +// +// To avoid blocking the host RenderView and to avoid introducing the potential +// for deadlock, the BrowserPluginPlaceholder takes place of the guest +// RenderView until the guest has established a connection with its host +// RenderView. This permits loading the guest to happen asynchronously, while +// the host RenderView is permitted to continue to receive and process events. +class BrowserPluginPlaceholder: public webkit::WebViewPlugin::Delegate { + public: + // Creates a new WebViewPlugin with a BrowserPluginPlaceholder as a delegate. + static webkit::WebViewPlugin* Create( + content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params); + + static BrowserPluginPlaceholder* FromID(int id); + + void RegisterPlaceholder(int id, BrowserPluginPlaceholder* placeholder); + void UnregisterPlaceholder(int id); + + int GetID() { return id_; } + + webkit::WebViewPlugin* plugin() { return plugin_; } + + const WebKit::WebPluginParams& plugin_params() const; + + void GuestReady(base::ProcessHandle process_handle, + const IPC::ChannelHandle& channel_handle); + + content::RenderView* render_view() { return render_view_; } + + private: + BrowserPluginPlaceholder(content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params, + const std::string& html_data); + virtual ~BrowserPluginPlaceholder(); + + // Grabs the width, height, and source URL of the browser plugin + // from the element's attributes. If not found, it uses the defaults + // specified here as parameters. + void GetPluginParameters(int default_width, int default_height, + const std::string& default_src); + // Replace this placeholder with the real browser plugin. + void LoadGuest(WebKit::WebPlugin* new_plugin); + + virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE { } + virtual void WillDestroyPlugin() OVERRIDE; + virtual void ShowContextMenu(const WebKit::WebMouseEvent&) OVERRIDE { } + + content::RenderView* render_view_; + WebKit::WebPluginParams plugin_params_; + webkit::WebViewPlugin* plugin_; + int id_; + gfx::Size size_; + std::string src_; + + DISALLOW_COPY_AND_ASSIGN(BrowserPluginPlaceholder); +}; + +#endif // CONTNET_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_PLACEHOLDER_H_ diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index a1097c3..9db8271 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -73,6 +73,8 @@ #include "content/renderer/notification_provider.h" #include "content/renderer/p2p/socket_dispatcher.h" #include "content/renderer/plugin_channel_host.h" +#include "content/renderer/browser_plugin/browser_plugin_constants.h" +#include "content/renderer/browser_plugin/browser_plugin_placeholder.h" #include "content/renderer/render_process.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" @@ -2066,6 +2068,15 @@ bool RenderViewImpl::isPointerLocked() { WebPlugin* RenderViewImpl::createPlugin(WebFrame* frame, const WebPluginParams& params) { + // The browser plugin is a special kind of pepper plugin + // that loads asynchronously. We first create a placeholder here. + // When a guest is ready to be displayed, we swap out the placeholder + // with the guest. + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableBrowserPlugin) && + UTF16ToASCII(params.mimeType) == kBrowserPluginMimeType) + return BrowserPluginPlaceholder::Create(this, frame, params); + WebPlugin* plugin = NULL; if (content::GetContentClient()->renderer()->OverrideCreatePlugin( this, frame, params, &plugin)) { |