diff options
author | fsamuel <fsamuel@chromium.org> | 2014-09-18 09:16:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-18 16:16:35 +0000 |
commit | 212c6daa34e6a5fd1a2754b08973d18d6d09246b (patch) | |
tree | 2c04943cee6bca37651c3f10a259ab2ec6a9b0fd /extensions/renderer/guest_view/guest_view_container.cc | |
parent | 271b5ac015bc9eeaee9a6e14442dbb9e8ef3889d (diff) | |
download | chromium_src-212c6daa34e6a5fd1a2754b08973d18d6d09246b.zip chromium_src-212c6daa34e6a5fd1a2754b08973d18d6d09246b.tar.gz chromium_src-212c6daa34e6a5fd1a2754b08973d18d6d09246b.tar.bz2 |
Move ContentWindow from BrowserPlugin To GuestView
This CL plumbs out the swapped out RenderView's routing ID out to the content embedder which then uses it to expose its contentWindow to an optional callback in the AttachGuest API Method.
This patch also makes it fairly trivial to support a contentWindow in other GuestViews.
BUG=330264
Review URL: https://codereview.chromium.org/564973004
Cr-Commit-Position: refs/heads/master@{#295477}
Diffstat (limited to 'extensions/renderer/guest_view/guest_view_container.cc')
-rw-r--r-- | extensions/renderer/guest_view/guest_view_container.cc | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/extensions/renderer/guest_view/guest_view_container.cc b/extensions/renderer/guest_view/guest_view_container.cc index 40051b1..8ef8054 100644 --- a/extensions/renderer/guest_view/guest_view_container.cc +++ b/extensions/renderer/guest_view/guest_view_container.cc @@ -6,8 +6,20 @@ #include "content/public/renderer/browser_plugin_delegate.h" #include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_view.h" #include "extensions/common/extension_messages.h" #include "extensions/common/guest_view/guest_view_constants.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" +#include "third_party/WebKit/public/web/WebView.h" + +namespace { +typedef std::pair<int, int> GuestViewID; +typedef std::map<GuestViewID, extensions::GuestViewContainer*> + GuestViewContainerMap; +static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map = + LAZY_INSTANCE_INITIALIZER; +} // namespace namespace extensions { @@ -17,14 +29,61 @@ GuestViewContainer::GuestViewContainer( : content::BrowserPluginDelegate(render_frame, mime_type), content::RenderFrameObserver(render_frame), mime_type_(mime_type), - element_instance_id_(guestview::kInstanceIDNone) { + element_instance_id_(guestview::kInstanceIDNone), + render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()), + attached_(false), + attach_pending_(false), + isolate_(NULL) { } GuestViewContainer::~GuestViewContainer() { + if (element_instance_id_ != guestview::kInstanceIDNone) { + g_guest_view_container_map.Get().erase( + GuestViewID(render_view_routing_id_, element_instance_id_)); + } +} + +GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id, + int element_instance_id) { + GuestViewContainerMap* guest_view_containers = + g_guest_view_container_map.Pointer(); + GuestViewContainerMap::iterator it = guest_view_containers->find( + GuestViewID(render_view_routing_id, element_instance_id)); + return it == guest_view_containers->end() ? NULL : it->second; +} + + +void GuestViewContainer::AttachGuest(int element_instance_id, + int guest_instance_id, + scoped_ptr<base::DictionaryValue> params, + v8::Handle<v8::Function> callback, + v8::Isolate* isolate) { + // GuestViewContainer supports reattachment (i.e. attached_ == true) but not + // while a current attach process is pending. + if (attach_pending_) + return; + + // Step 1, send the attach params to chrome/. + render_frame()->Send(new ExtensionHostMsg_AttachGuest(render_view_routing_id_, + element_instance_id, + guest_instance_id, + *params)); + + // Step 2, attach plugin through content/. + render_frame()->AttachGuest(element_instance_id); + + callback_.reset(callback); + isolate_ = isolate; + attach_pending_ = true; } void GuestViewContainer::SetElementInstanceID(int element_instance_id) { + GuestViewID guest_view_id(render_view_routing_id_, element_instance_id); + DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone); + DCHECK(g_guest_view_container_map.Get().find(guest_view_id) == + g_guest_view_container_map.Get().end()); element_instance_id_ = element_instance_id; + g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this)); } void GuestViewContainer::DidFinishLoading() { @@ -47,7 +106,7 @@ void GuestViewContainer::OnDestruct() { } bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) { - if (message.type() != ExtensionMsg_CreateMimeHandlerViewGuestACK::ID) + if (!ShouldHandleMessage(message)) return false; DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); @@ -62,6 +121,7 @@ bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(GuestViewContainer, message) IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK, OnCreateMimeHandlerViewGuestACK) + IPC_MESSAGE_HANDLER(ExtensionMsg_GuestAttached, OnGuestAttached) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -75,4 +135,52 @@ void GuestViewContainer::OnCreateMimeHandlerViewGuestACK( render_frame()->AttachGuest(element_instance_id); } +void GuestViewContainer::OnGuestAttached(int element_instance_id, + int guest_routing_id) { + attached_ = true; + attach_pending_ = false; + + // If we don't have a callback then there's nothing more to do. + if (callback_.IsEmpty()) + return; + + content::RenderView* guest_proxy_render_view = + content::RenderView::FromRoutingID(guest_routing_id); + // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing? + if (!guest_proxy_render_view) + return; + + v8::HandleScope handle_scope(isolate_); + v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); + v8::Handle<v8::Context> context = callback->CreationContext(); + if (context.IsEmpty()) + return; + + blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); + v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); + + const int argc = 1; + v8::Handle<v8::Value> argv[argc] = { window }; + + v8::Context::Scope context_scope(context); + blink::WebScopedMicrotaskSuppression suppression; + + // Call the AttachGuest API's callback with the guest proxy as the first + // parameter. + callback->Call(context->Global(), argc, argv); + callback_.reset(); +} + +// static +bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) { + switch (message.type()) { + case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID: + case ExtensionMsg_GuestAttached::ID: + return true; + default: + break; + } + return false; +} + } // namespace extensions |