forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Renderer-side changes for browser plugin
Major Classes: BrowserPluginChannelManager: Manages GuestToEmbedderChannels. It essentially wraps a map that is keyed on channel names. GuestToEmbedderChannel: Is a Dispatcher. Receives/Sends Ppapi messages. Keeps track of all RenderViews that have an associated PP_Instance in a map (RenderViews that are guests). brettw@ might want to have a look here? BrowserPluginRegistry: Wrapper around map that keeps track of Browser Plugin PluginModules keyed on the guest process id. This is similar to the PepperPluginRegistry but has a different key type. BrowserPluginVarSerializationRules: Temporary do nothing class as suggested by brettw@ BrowserPlugin: Towards becoming a wrapper around a WebPluginContainerImpl that swaps out WebPluginImpl/WebViewPlugin on navigation. We get a blank WebViewPlugin (is this a best thing to do to get a blank placeholder?) if we have an empty src attribute or while we're navigating for the first time. Otherwise, on cross-process navigations, we substitute one WebPluginImpl for another WebPluginImpl. TODO: BrowserPlugin should track the lifetime of WebPluginContainerImpl, but right now it lives forever which is bad. Will fix this in a subsequent patch. This requires some WebKit changes first. BUG=117897 TEST=manually Review URL: https://chromiumcodereview.appspot.com/9968097 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138416 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
fsamuel@chromium.org
committed
May 23, 2012
1 parent
28599f4
commit 468e490
Showing
21 changed files
with
1,248 additions
and
291 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// 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.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/browser_plugin_messages.h" | ||
#include "content/public/common/url_constants.h" | ||
#include "content/renderer/render_view_impl.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/ppapi/ppapi_plugin_instance.h" | ||
#include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" | ||
#include "webkit/plugins/webview_plugin.h" | ||
|
||
static int g_next_id = 0; | ||
|
||
// The global list of all Browser Plugin Placeholders within a process. | ||
base::LazyInstance<IDMap<BrowserPlugin> >::Leaky | ||
g_all_browser_plugins = LAZY_INSTANCE_INITIALIZER; | ||
|
||
using WebKit::WebPlugin; | ||
using WebKit::WebPluginContainer; | ||
using webkit::WebViewPlugin; | ||
|
||
void Register(int id, BrowserPlugin* browser_plugin) { | ||
g_all_browser_plugins.Get().AddWithID(browser_plugin, id); | ||
} | ||
|
||
void Unregister(int id) { | ||
if (g_all_browser_plugins.Get().Lookup(id)) | ||
g_all_browser_plugins.Get().Remove(id); | ||
} | ||
|
||
// static | ||
WebKit::WebPlugin* BrowserPlugin::Create( | ||
RenderViewImpl* render_view, | ||
WebKit::WebFrame* frame, | ||
const WebKit::WebPluginParams& params) { | ||
// TODO(fsamuel): Figure out what the lifetime is of this class. | ||
// It seems we need to blow away this object once a WebPluginContainer is | ||
// gone. How do we detect it's gone? A WebKit change perhaps? | ||
BrowserPlugin* browser_plugin = new BrowserPlugin( | ||
render_view, frame, params, ""); | ||
return browser_plugin->placeholder(); | ||
} | ||
|
||
// static | ||
BrowserPlugin* BrowserPlugin::FromID(int id) { | ||
return g_all_browser_plugins.Get().Lookup(id); | ||
} | ||
|
||
BrowserPlugin::BrowserPlugin( | ||
RenderViewImpl* render_view, | ||
WebKit::WebFrame* frame, | ||
const WebKit::WebPluginParams& params, | ||
const std::string& html_data) | ||
: render_view_(render_view), | ||
plugin_params_(params), | ||
placeholder_(webkit::WebViewPlugin::Create( | ||
NULL, | ||
render_view->GetWebkitPreferences(), | ||
html_data, | ||
GURL(chrome::kAboutBlankURL))), | ||
plugin_(NULL) { | ||
id_ = ++g_next_id; | ||
Register(id_, this); | ||
|
||
// By default we do not navigate and simply stay with an | ||
// about:blank placeholder. | ||
gfx::Size size; | ||
std::string src; | ||
ParsePluginParameters(0, 0, "", &size, &src); | ||
|
||
if (!src.empty()) { | ||
render_view->Send(new BrowserPluginHostMsg_NavigateFromEmbedder( | ||
render_view->GetRoutingID(), | ||
id_, | ||
frame->identifier(), | ||
src, | ||
size)); | ||
} | ||
} | ||
|
||
BrowserPlugin::~BrowserPlugin() { | ||
Unregister(id_); | ||
} | ||
|
||
void BrowserPlugin::ParsePluginParameters( | ||
int default_width, | ||
int default_height, | ||
const std::string& default_src, | ||
gfx::Size* size, | ||
std::string* 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 BrowserPlugin::LoadGuest( | ||
int guest_process_id, | ||
const IPC::ChannelHandle& channel_handle) { | ||
webkit::ppapi::WebPluginImpl* new_guest = | ||
render_view()->CreateBrowserPlugin(channel_handle, | ||
guest_process_id, | ||
plugin_params()); | ||
Replace(new_guest); | ||
} | ||
|
||
void BrowserPlugin::Replace( | ||
webkit::ppapi::WebPluginImpl* new_plugin) { | ||
WebKit::WebPlugin* current_plugin = | ||
plugin_ ? static_cast<WebKit::WebPlugin*>(plugin_) : placeholder_; | ||
WebKit::WebPluginContainer* container = current_plugin->container(); | ||
if (!new_plugin || !new_plugin->initialize(container)) | ||
return; | ||
|
||
// Clear the container's backing texture ID and the script objects. | ||
if (plugin_) | ||
plugin_->instance()->BindGraphics(plugin_->instance()->pp_instance(), 0); | ||
|
||
// Inform the browser process of the association between the browser plugin's | ||
// instance ID and the pepper channel's PP_Instance identifier. | ||
render_view()->Send(new BrowserPluginHostMsg_MapInstance( | ||
render_view()->GetRoutingID(), | ||
id_, | ||
new_plugin->instance()->pp_instance())); | ||
// TODO(fsamuel): We should delay the swapping out of the current plugin | ||
// until after the guest's WebGraphicsContext3D has been initialized. That | ||
// way, we immediately have something to render onto the screen. | ||
container->setPlugin(new_plugin); | ||
container->invalidate(); | ||
container->reportGeometry(); | ||
if (plugin_) | ||
plugin_->destroy(); | ||
plugin_ = new_plugin; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// 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_H_ | ||
#define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_H_ | ||
#pragma once | ||
|
||
#include "base/process.h" | ||
#include "content/renderer/render_view_impl.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-embedder 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 embedder RenderView and to avoid introducing the | ||
// potential for deadlock, BrowserPlugin attaches a placeholder that takes | ||
// place of the guest RenderView until the guest has established a connection | ||
// with its embedder RenderView. This permits asynchronously loading of the | ||
// guest while the embedder RenderView is permitted to continue to receive and | ||
// process events. | ||
// | ||
// Furthermore, certain navigations can swap to a new guest RenderView on an | ||
// different process. BrowserPlugin is the consistent facade that the embedder's | ||
// WebKit instance talks to regardless of which process it's communicating with. | ||
class BrowserPlugin { | ||
public: | ||
// Creates a new WebViewPlugin with a BrowserPlugin as a delegate. | ||
static WebKit::WebPlugin* Create( | ||
RenderViewImpl* render_view, | ||
WebKit::WebFrame* frame, | ||
const WebKit::WebPluginParams& params); | ||
|
||
static BrowserPlugin* FromID(int id); | ||
|
||
webkit::WebViewPlugin* placeholder() { return placeholder_; } | ||
|
||
webkit::ppapi::WebPluginImpl* plugin() { return plugin_; } | ||
|
||
const WebKit::WebPluginParams& plugin_params() const { | ||
return plugin_params_; | ||
} | ||
|
||
void LoadGuest(int guest_process_id, | ||
const IPC::ChannelHandle& channel_handle); | ||
|
||
RenderViewImpl* render_view() { return render_view_; } | ||
|
||
private: | ||
BrowserPlugin(RenderViewImpl* render_view, | ||
WebKit::WebFrame* frame, | ||
const WebKit::WebPluginParams& params, | ||
const std::string& html_data); | ||
virtual ~BrowserPlugin(); | ||
|
||
// Parses the width, height, and source URL of the browser plugin | ||
// from the element's attributes and outputs them. If not found, it outputs | ||
// the defaults specified here as parameters. | ||
void ParsePluginParameters(int default_width, int default_height, | ||
const std::string& default_src, | ||
gfx::Size* size, | ||
std::string* src); | ||
// Replace the current guest with a new guest. | ||
void Replace(webkit::ppapi::WebPluginImpl* new_plugin); | ||
|
||
RenderViewImpl* render_view_; | ||
WebKit::WebPluginParams plugin_params_; | ||
webkit::WebViewPlugin* placeholder_; | ||
webkit::ppapi::WebPluginImpl* plugin_; | ||
int id_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(BrowserPlugin); | ||
}; | ||
|
||
#endif // CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_H_ |
Oops, something went wrong.