summaryrefslogtreecommitdiffstats
path: root/extensions/renderer/guest_view/guest_view_container.cc
diff options
context:
space:
mode:
authorfsamuel <fsamuel@chromium.org>2014-09-18 09:16:15 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-18 16:16:35 +0000
commit212c6daa34e6a5fd1a2754b08973d18d6d09246b (patch)
tree2c04943cee6bca37651c3f10a259ab2ec6a9b0fd /extensions/renderer/guest_view/guest_view_container.cc
parent271b5ac015bc9eeaee9a6e14442dbb9e8ef3889d (diff)
downloadchromium_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.cc112
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