summaryrefslogtreecommitdiffstats
path: root/extensions/renderer/guest_view
diff options
context:
space:
mode:
authorlazyboy <lazyboy@chromium.org>2015-06-29 08:18:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-29 15:18:59 +0000
commit6ec48b2a6529b753f28340fd6741908086224bee (patch)
tree1b0f3da2a92b39f4b7e7599e30a18a4a2327775c /extensions/renderer/guest_view
parent7086e3e8d2f35569f1a579af1353f28d52245468 (diff)
downloadchromium_src-6ec48b2a6529b753f28340fd6741908086224bee.zip
chromium_src-6ec48b2a6529b753f28340fd6741908086224bee.tar.gz
chromium_src-6ec48b2a6529b753f28340fd6741908086224bee.tar.bz2
Make <webview> use out-of-process iframe architecture.
This is behind --site-per-process flag. This is the first step to make <webview> --site-per-process compatible, only basic features work: rendering, input, navigation, executeScript and postMessage. This CL makes <webview> BrowserPlugin free, so <webview> is not a plugin to blink anymore, rather it's similar to iframe. Therefore, this CL makes <webview> work without BrowserPlugin or BrowserPluginGuest/BrowserPluginEmbedder. We still need to use the old browser/ counterparts (BPG and BPE) because we use it for 1) Guest related decision making in WebContents, so WebContentsImpl::browser_plugin_guest() is still used and useful, 2) Initializing and attaching logic inside content/, e.g. BPG::InitInternal(), BPG::OnWillAttachComplete. In subsequent CLs, these dependencies will be either removed if not required, or extracted to a separate class. TBR=jochen@chromium.org for testing/buildbot/chromium.fyi.json BUG=330264 Review URL: https://codereview.chromium.org/972313002 Cr-Commit-Position: refs/heads/master@{#336565}
Diffstat (limited to 'extensions/renderer/guest_view')
-rw-r--r--extensions/renderer/guest_view/extensions_guest_view_container.cc28
-rw-r--r--extensions/renderer/guest_view/extensions_guest_view_container.h5
-rw-r--r--extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc102
-rw-r--r--extensions/renderer/guest_view/guest_view_internal_custom_bindings.h7
4 files changed, 105 insertions, 37 deletions
diff --git a/extensions/renderer/guest_view/extensions_guest_view_container.cc b/extensions/renderer/guest_view/extensions_guest_view_container.cc
index 96650d8..3fa9882 100644
--- a/extensions/renderer/guest_view/extensions_guest_view_container.cc
+++ b/extensions/renderer/guest_view/extensions_guest_view_container.cc
@@ -13,7 +13,6 @@ namespace extensions {
ExtensionsGuestViewContainer::ExtensionsGuestViewContainer(
content::RenderFrame* render_frame)
: GuestViewContainer(render_frame),
- destruction_isolate_(nullptr),
element_resize_isolate_(nullptr),
weak_ptr_factory_(this) {
}
@@ -22,33 +21,6 @@ ExtensionsGuestViewContainer::~ExtensionsGuestViewContainer() {
}
void ExtensionsGuestViewContainer::OnDestroy(bool embedder_frame_destroyed) {
- // Do not attempt to run |destruction_callback_| if the embedder frame was
- // destroyed. Trying to invoke callback on RenderFrame destruction results in
- // assertion failure when calling WebScopedMicrotaskSuppression.
- if (embedder_frame_destroyed)
- return;
-
- // Call the destruction callback, if one is registered.
- if (!destruction_callback_.IsEmpty()) {
- v8::HandleScope handle_scope(destruction_isolate_);
- v8::Local<v8::Function> callback = v8::Local<v8::Function>::New(
- destruction_isolate_, destruction_callback_);
- v8::Local<v8::Context> context = callback->CreationContext();
- if (context.IsEmpty())
- return;
-
- v8::Context::Scope context_scope(context);
- blink::WebScopedMicrotaskSuppression suppression;
-
- callback->Call(context->Global(), 0 /* argc */, nullptr);
- }
-}
-
-void ExtensionsGuestViewContainer::RegisterDestructionCallback(
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate) {
- destruction_callback_.Reset(isolate, callback);
- destruction_isolate_ = isolate;
}
void ExtensionsGuestViewContainer::RegisterElementResizeCallback(
diff --git a/extensions/renderer/guest_view/extensions_guest_view_container.h b/extensions/renderer/guest_view/extensions_guest_view_container.h
index aabb47e..35f2211 100644
--- a/extensions/renderer/guest_view/extensions_guest_view_container.h
+++ b/extensions/renderer/guest_view/extensions_guest_view_container.h
@@ -20,8 +20,6 @@ class ExtensionsGuestViewContainer : public guest_view::GuestViewContainer {
public:
explicit ExtensionsGuestViewContainer(content::RenderFrame* render_frame);
- void RegisterDestructionCallback(v8::Local<v8::Function> callback,
- v8::Isolate* isolate);
void RegisterElementResizeCallback(v8::Local<v8::Function> callback,
v8::Isolate* isolate);
@@ -37,9 +35,6 @@ class ExtensionsGuestViewContainer : public guest_view::GuestViewContainer {
// GuestViewContainer implementation.
void OnDestroy(bool embedder_frame_destroyed) override;
- v8::Global<v8::Function> destruction_callback_;
- v8::Isolate* destruction_isolate_;
-
v8::Global<v8::Function> element_resize_callback_;
v8::Isolate* element_resize_isolate_;
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
index 82fbd27..3b5ce79 100644
--- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
+++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
@@ -11,14 +11,19 @@
#include "components/guest_view/common/guest_view_constants.h"
#include "components/guest_view/common/guest_view_messages.h"
#include "components/guest_view/renderer/guest_view_request.h"
+#include "components/guest_view/renderer/iframe_guest_view_container.h"
+#include "components/guest_view/renderer/iframe_guest_view_request.h"
#include "content/public/child/v8_value_converter.h"
+#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
+#include "extensions/common/guest_view/extensions_guest_view_messages.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
#include "extensions/renderer/script_context.h"
#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "v8/include/v8.h"
@@ -38,6 +43,21 @@ static base::LazyInstance<ViewMap> weak_view_map = LAZY_INSTANCE_INITIALIZER;
namespace extensions {
+namespace {
+
+content::RenderFrame* GetRenderFrame(v8::Handle<v8::Value> value) {
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Object>::Cast(value)->CreationContext();
+ if (context.IsEmpty())
+ return nullptr;
+ blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForContext(context);
+ if (!frame)
+ return nullptr;
+ return content::RenderFrame::FromWebFrame(frame);
+}
+
+} // namespace
+
GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
ScriptContext* context)
: ObjectBackedNativeHandler(context) {
@@ -47,6 +67,9 @@ GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
RouteFunction("DetachGuest",
base::Bind(&GuestViewInternalCustomBindings::DetachGuest,
base::Unretained(this)));
+ RouteFunction("AttachIframeGuest",
+ base::Bind(&GuestViewInternalCustomBindings::AttachIframeGuest,
+ base::Unretained(this)));
RouteFunction("DestroyContainer",
base::Bind(&GuestViewInternalCustomBindings::DestroyContainer,
base::Unretained(this)));
@@ -177,6 +200,77 @@ void GuestViewInternalCustomBindings::DetachGuest(
args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
}
+void GuestViewInternalCustomBindings::AttachIframeGuest(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ // Allow for an optional callback parameter.
+ const int num_required_params = 4;
+ CHECK(args.Length() >= num_required_params &&
+ args.Length() <= (num_required_params + 1));
+ // Element Instance ID.
+ CHECK(args[0]->IsInt32());
+ // Guest Instance ID.
+ CHECK(args[1]->IsInt32());
+ // Attach Parameters.
+ CHECK(args[2]->IsObject());
+ // <iframe>.contentWindow.
+ CHECK(args[3]->IsObject());
+ // Optional Callback Function.
+ CHECK(args.Length() <= num_required_params ||
+ args[num_required_params]->IsFunction());
+
+ int element_instance_id = args[0]->Int32Value();
+ int guest_instance_id = args[1]->Int32Value();
+
+ scoped_ptr<base::DictionaryValue> params;
+ {
+ scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+ scoped_ptr<base::Value> params_as_value(
+ converter->FromV8Value(args[2], context()->v8_context()));
+ CHECK(params_as_value->IsType(base::Value::TYPE_DICTIONARY));
+ params.reset(
+ static_cast<base::DictionaryValue*>(params_as_value.release()));
+ }
+
+ // Add flag to |params| to indicate that the element size is specified in
+ // logical units.
+ params->SetBoolean(guest_view::kElementSizeIsLogical, true);
+
+ content::RenderFrame* render_frame = GetRenderFrame(args[3]);
+ blink::WebLocalFrame* frame = render_frame->GetWebFrame();
+
+ // Parent must exist.
+ blink::WebFrame* parent_frame = frame->parent();
+ DCHECK(parent_frame);
+ DCHECK(parent_frame->isWebLocalFrame());
+
+ content::RenderFrame* embedder_parent_frame =
+ content::RenderFrame::FromWebFrame(parent_frame);
+
+ // Create a GuestViewContainer if it does not exist.
+ // An element instance ID uniquely identifies an IframeGuestViewContainer
+ // within a RenderView.
+ auto* guest_view_container =
+ static_cast<guest_view::IframeGuestViewContainer*>(
+ guest_view::GuestViewContainer::FromID(element_instance_id));
+ // This is the first time we hear about the |element_instance_id|.
+ DCHECK(!guest_view_container);
+ // The <webview> element's GC takes ownership of |guest_view_container|.
+ guest_view_container =
+ new guest_view::IframeGuestViewContainer(embedder_parent_frame);
+ guest_view_container->SetElementInstanceID(element_instance_id);
+
+ linked_ptr<guest_view::GuestViewRequest> request(
+ new guest_view::GuestViewAttachIframeRequest(
+ guest_view_container, render_frame->GetRoutingID(), guest_instance_id,
+ params.Pass(), args.Length() == (num_required_params + 1)
+ ? args[num_required_params].As<v8::Function>()
+ : v8::Local<v8::Function>(),
+ args.GetIsolate()));
+ guest_view_container->IssueRequest(request);
+
+ args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
+}
+
void GuestViewInternalCustomBindings::DestroyContainer(
const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().SetNull();
@@ -256,10 +350,10 @@ void GuestViewInternalCustomBindings::RegisterDestructionCallback(
CHECK(args[1]->IsFunction());
int element_instance_id = args[0]->Int32Value();
- // An element instance ID uniquely identifies a ExtensionsGuestViewContainer
- // within a RenderView.
- auto guest_view_container = static_cast<ExtensionsGuestViewContainer*>(
- guest_view::GuestViewContainer::FromID(element_instance_id));
+ // An element instance ID uniquely identifies a GuestViewContainer within a
+ // RenderView.
+ auto* guest_view_container =
+ guest_view::GuestViewContainer::FromID(element_instance_id);
if (!guest_view_container)
return;
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.h b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.h
index 6a6d6c3..f18e15c 100644
--- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.h
+++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.h
@@ -47,6 +47,13 @@ class GuestViewInternalCustomBindings : public ObjectBackedNativeHandler {
// been detached.
void DetachGuest(const v8::FunctionCallbackInfo<v8::Value>& args);
+ // AttachIframeGuest is --site-per-process variant of AttachGuest().
+ //
+ // AttachIframeGuest takes a |contentWindow| parameter in addition to the
+ // parameters to AttachGuest. That parameter is used to identify the
+ // RenderFrame of the <iframe> container element.
+ void AttachIframeGuest(const v8::FunctionCallbackInfo<v8::Value>& args);
+
// GetContentWindow takes in a RenderView routing ID and returns the
// Window JavaScript object for that RenderView.
void GetContentWindow(const v8::FunctionCallbackInfo<v8::Value>& args);