diff options
author | lazyboy <lazyboy@chromium.org> | 2015-06-29 08:18:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-29 15:18:59 +0000 |
commit | 6ec48b2a6529b753f28340fd6741908086224bee (patch) | |
tree | 1b0f3da2a92b39f4b7e7599e30a18a4a2327775c /extensions/renderer/guest_view | |
parent | 7086e3e8d2f35569f1a579af1353f28d52245468 (diff) | |
download | chromium_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')
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); |