Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: extensions/renderer/guest_view/guest_view_container.cc

Issue 564973004: Move ContentWindow from BrowserPlugin To GuestView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments + fixed teardown bug Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/guest_view/guest_view_container.h" 5 #include "extensions/renderer/guest_view/guest_view_container.h"
6 6
7 #include "content/public/renderer/browser_plugin_delegate.h" 7 #include "content/public/renderer/browser_plugin_delegate.h"
8 #include "content/public/renderer/render_frame.h" 8 #include "content/public/renderer/render_frame.h"
9 #include "content/public/renderer/render_view.h"
9 #include "extensions/common/extension_messages.h" 10 #include "extensions/common/extension_messages.h"
10 #include "extensions/common/guest_view/guest_view_constants.h" 11 #include "extensions/common/guest_view/guest_view_constants.h"
12 #include "third_party/WebKit/public/web/WebLocalFrame.h"
13 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
14 #include "third_party/WebKit/public/web/WebView.h"
15
16 namespace {
17 typedef std::pair<int, int> GuestViewID;
18 typedef std::map<GuestViewID, extensions::GuestViewContainer*>
19 GuestViewContainerMap;
20 static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map =
21 LAZY_INSTANCE_INITIALIZER;
22 } // namespace
11 23
12 namespace extensions { 24 namespace extensions {
13 25
14 GuestViewContainer::GuestViewContainer( 26 GuestViewContainer::GuestViewContainer(
15 content::RenderFrame* render_frame, 27 content::RenderFrame* render_frame,
16 const std::string& mime_type) 28 const std::string& mime_type)
17 : content::BrowserPluginDelegate(render_frame, mime_type), 29 : content::BrowserPluginDelegate(render_frame, mime_type),
18 content::RenderFrameObserver(render_frame), 30 content::RenderFrameObserver(render_frame),
19 mime_type_(mime_type), 31 mime_type_(mime_type),
20 element_instance_id_(guestview::kInstanceIDNone) { 32 element_instance_id_(guestview::kInstanceIDNone),
33 render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()),
34 attached_(false),
35 attach_pending_(false),
36 isolate_(NULL) {
21 } 37 }
22 38
23 GuestViewContainer::~GuestViewContainer() { 39 GuestViewContainer::~GuestViewContainer() {
40 if (element_instance_id_ != guestview::kInstanceIDNone) {
41 g_guest_view_container_map.Get().erase(
42 GuestViewID(render_view_routing_id_, element_instance_id_));
43 }
44 }
45
46 GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id,
47 int element_instance_id) {
48 GuestViewContainerMap* guest_view_containers =
49 g_guest_view_container_map.Pointer();
50 GuestViewContainerMap::iterator it = guest_view_containers->find(
51 GuestViewID(render_view_routing_id, element_instance_id));
52 return it == guest_view_containers->end() ? NULL : it->second;
53 }
54
55
56 void GuestViewContainer::AttachGuest(int element_instance_id,
57 int guest_instance_id,
58 scoped_ptr<base::DictionaryValue> params,
59 v8::Handle<v8::Function> callback,
60 v8::Isolate* isolate) {
61 // GuestViewContainer supports reattachment (i.e. attached_ == true) but not
62 // while a current attach process is pending.
63 if (attach_pending_)
64 return;
65
66 // Step 1, send the attach params to chrome/.
67 render_frame()->Send(new ExtensionHostMsg_AttachGuest(render_view_routing_id_,
68 element_instance_id,
69 guest_instance_id,
70 *params));
71
72 // Step 2, attach plugin through content/.
73 render_frame()->AttachGuest(element_instance_id);
74
75 callback_.reset(callback);
76 isolate_ = isolate;
77 attach_pending_ = true;
24 } 78 }
25 79
26 void GuestViewContainer::SetElementInstanceID(int element_instance_id) { 80 void GuestViewContainer::SetElementInstanceID(int element_instance_id) {
81 GuestViewID guest_view_id(render_view_routing_id_, element_instance_id);
82 DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone);
83 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) ==
84 g_guest_view_container_map.Get().end());
27 element_instance_id_ = element_instance_id; 85 element_instance_id_ = element_instance_id;
86 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this));
28 } 87 }
29 88
30 void GuestViewContainer::DidFinishLoading() { 89 void GuestViewContainer::DidFinishLoading() {
31 if (mime_type_.empty()) 90 if (mime_type_.empty())
32 return; 91 return;
33 92
34 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 93 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
35 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest( 94 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest(
36 routing_id(), html_string_, mime_type_, element_instance_id_)); 95 routing_id(), html_string_, mime_type_, element_instance_id_));
37 } 96 }
38 97
39 void GuestViewContainer::DidReceiveData(const char* data, int data_length) { 98 void GuestViewContainer::DidReceiveData(const char* data, int data_length) {
40 std::string value(data, data_length); 99 std::string value(data, data_length);
41 html_string_ += value; 100 html_string_ += value;
42 } 101 }
43 102
44 void GuestViewContainer::OnDestruct() { 103 void GuestViewContainer::OnDestruct() {
45 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let 104 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let
46 // RenderFrameObserver self-destruct here. 105 // RenderFrameObserver self-destruct here.
47 } 106 }
48 107
49 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) { 108 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) {
50 if (message.type() != ExtensionMsg_CreateMimeHandlerViewGuestACK::ID) 109 if (!ShouldHandleMessage(message))
51 return false; 110 return false;
52 111
53 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 112 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
54 int element_instance_id = guestview::kInstanceIDNone; 113 int element_instance_id = guestview::kInstanceIDNone;
55 PickleIterator iter(message); 114 PickleIterator iter(message);
56 bool success = iter.ReadInt(&element_instance_id); 115 bool success = iter.ReadInt(&element_instance_id);
57 DCHECK(success); 116 DCHECK(success);
58 if (element_instance_id != element_instance_id_) 117 if (element_instance_id != element_instance_id_)
59 return false; 118 return false;
60 119
61 bool handled = true; 120 bool handled = true;
62 IPC_BEGIN_MESSAGE_MAP(GuestViewContainer, message) 121 IPC_BEGIN_MESSAGE_MAP(GuestViewContainer, message)
63 IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK, 122 IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK,
64 OnCreateMimeHandlerViewGuestACK) 123 OnCreateMimeHandlerViewGuestACK)
124 IPC_MESSAGE_HANDLER(ExtensionMsg_GuestAttached, OnGuestAttached)
65 IPC_MESSAGE_UNHANDLED(handled = false) 125 IPC_MESSAGE_UNHANDLED(handled = false)
66 IPC_END_MESSAGE_MAP() 126 IPC_END_MESSAGE_MAP()
67 return handled; 127 return handled;
68 } 128 }
69 129
70 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK( 130 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK(
71 int element_instance_id) { 131 int element_instance_id) {
72 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 132 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
73 DCHECK_EQ(element_instance_id_, element_instance_id); 133 DCHECK_EQ(element_instance_id_, element_instance_id);
74 DCHECK(!mime_type_.empty()); 134 DCHECK(!mime_type_.empty());
75 render_frame()->AttachGuest(element_instance_id); 135 render_frame()->AttachGuest(element_instance_id);
76 } 136 }
77 137
138 void GuestViewContainer::OnGuestAttached(int element_instance_id,
139 int guest_routing_id) {
140 attached_ = true;
141 attach_pending_ = false;
142
143 // If we don't have a callback then there's nothing more to do.
144 if (callback_.IsEmpty())
145 return;
146
147 content::RenderView* guest_proxy_render_view =
148 content::RenderView::FromRoutingID(guest_routing_id);
149 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
150 if (!guest_proxy_render_view)
151 return;
152
153 v8::HandleScope handle_scope(isolate_);
154 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_);
155 v8::Handle<v8::Context> context = callback->CreationContext();
156 if (context.IsEmpty())
157 return;
158
159 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
160 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
161
162 const int argc = 1;
163 v8::Handle<v8::Value> argv[argc] = { window };
164
165 v8::Context::Scope context_scope(context);
166 blink::WebScopedMicrotaskSuppression suppression;
167
168 // Call the AttachGuest API's callback with the guest proxy as the first
169 // parameter.
170 callback->Call(context->Global(), argc, argv);
171 callback_.reset();
172 }
173
174 // static
175 bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) {
176 switch (message.type()) {
177 case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID:
178 case ExtensionMsg_GuestAttached::ID:
179 return true;
180 default:
181 break;
182 }
183 return false;
184 }
185
78 } // namespace extensions 186 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698