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

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

Issue 624063002: <webview>: resizing with display:none set should resize on attachment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup Created 6 years, 2 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 "content/public/renderer/render_view.h"
10 #include "extensions/common/extension_messages.h" 10 #include "extensions/common/extension_messages.h"
11 #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" 12 #include "third_party/WebKit/public/web/WebLocalFrame.h"
13 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 13 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
14 #include "third_party/WebKit/public/web/WebView.h" 14 #include "third_party/WebKit/public/web/WebView.h"
15 15
16 namespace { 16 namespace {
17 typedef std::pair<int, int> GuestViewID; 17 typedef std::pair<int, int> GuestViewID;
18 typedef std::map<GuestViewID, extensions::GuestViewContainer*> 18 typedef std::map<GuestViewID, extensions::GuestViewContainer*>
19 GuestViewContainerMap; 19 GuestViewContainerMap;
20 static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map = 20 static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map =
21 LAZY_INSTANCE_INITIALIZER; 21 LAZY_INSTANCE_INITIALIZER;
22 } // namespace 22 } // namespace
23 23
24 namespace extensions { 24 namespace extensions {
25 25
26 GuestViewContainer::AttachRequest::AttachRequest(
27 int element_instance_id,
28 int guest_instance_id,
29 scoped_ptr<base::DictionaryValue> params,
30 v8::Handle<v8::Function> callback,
31 v8::Isolate* isolate)
32 : element_instance_id_(element_instance_id),
33 guest_instance_id_(guest_instance_id),
34 params_(params.Pass()),
35 callback_(callback),
36 isolate_(isolate) {
37 }
38
39 GuestViewContainer::AttachRequest::~AttachRequest() {
40 }
41
42 v8::Handle<v8::Function>
43 GuestViewContainer::AttachRequest::GetCallback() const {
44 return callback_.NewHandle(isolate_);
45 }
46
26 GuestViewContainer::GuestViewContainer( 47 GuestViewContainer::GuestViewContainer(
27 content::RenderFrame* render_frame, 48 content::RenderFrame* render_frame,
28 const std::string& mime_type) 49 const std::string& mime_type)
29 : content::BrowserPluginDelegate(render_frame, mime_type), 50 : content::BrowserPluginDelegate(render_frame, mime_type),
30 content::RenderFrameObserver(render_frame), 51 content::RenderFrameObserver(render_frame),
31 mime_type_(mime_type), 52 mime_type_(mime_type),
32 element_instance_id_(guestview::kInstanceIDNone), 53 element_instance_id_(guestview::kInstanceIDNone),
33 render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()), 54 render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()),
34 attached_(false), 55 attached_(false),
35 attach_pending_(false), 56 ready_(false) {
36 isolate_(NULL) {
37 } 57 }
38 58
39 GuestViewContainer::~GuestViewContainer() { 59 GuestViewContainer::~GuestViewContainer() {
40 if (element_instance_id_ != guestview::kInstanceIDNone) { 60 if (element_instance_id_ != guestview::kInstanceIDNone) {
41 g_guest_view_container_map.Get().erase( 61 g_guest_view_container_map.Get().erase(
42 GuestViewID(render_view_routing_id_, element_instance_id_)); 62 GuestViewID(render_view_routing_id_, element_instance_id_));
43 } 63 }
44 } 64 }
45 65
46 GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id, 66 GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id,
47 int element_instance_id) { 67 int element_instance_id) {
48 GuestViewContainerMap* guest_view_containers = 68 GuestViewContainerMap* guest_view_containers =
49 g_guest_view_container_map.Pointer(); 69 g_guest_view_container_map.Pointer();
50 GuestViewContainerMap::iterator it = guest_view_containers->find( 70 GuestViewContainerMap::iterator it = guest_view_containers->find(
51 GuestViewID(render_view_routing_id, element_instance_id)); 71 GuestViewID(render_view_routing_id, element_instance_id));
52 return it == guest_view_containers->end() ? NULL : it->second; 72 return it == guest_view_containers->end() ? NULL : it->second;
53 } 73 }
54 74
55 75 void GuestViewContainer::AttachGuest(linked_ptr<AttachRequest> request) {
56 void GuestViewContainer::AttachGuest(int element_instance_id, 76 if (!ready_ || !pending_requests_.empty() || pending_response_.get()) {
57 int guest_instance_id, 77 pending_requests_.push_back(request);
lazyboy 2014/10/03 20:30:05 Can you add a TODO here as we discussed: about que
Fady Samuel 2014/10/03 21:52:30 Done.
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; 78 return;
65 79 }
66 // Step 1, send the attach params to chrome/. 80 AttachGuestInternal(request);
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;
78 } 81 }
79 82
80 void GuestViewContainer::SetElementInstanceID(int element_instance_id) { 83 void GuestViewContainer::SetElementInstanceID(int element_instance_id) {
81 GuestViewID guest_view_id(render_view_routing_id_, element_instance_id); 84 GuestViewID guest_view_id(render_view_routing_id_, element_instance_id);
82 DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone); 85 DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone);
83 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) == 86 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) ==
84 g_guest_view_container_map.Get().end()); 87 g_guest_view_container_map.Get().end());
85 element_instance_id_ = element_instance_id; 88 element_instance_id_ = element_instance_id;
86 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this)); 89 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this));
87 } 90 }
88 91
89 void GuestViewContainer::DidFinishLoading() { 92 void GuestViewContainer::DidFinishLoading() {
90 if (mime_type_.empty()) 93 if (mime_type_.empty())
91 return; 94 return;
92 95
93 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 96 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
94 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest( 97 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest(
95 routing_id(), html_string_, mime_type_, element_instance_id_)); 98 routing_id(), html_string_, mime_type_, element_instance_id_));
96 } 99 }
97 100
98 void GuestViewContainer::DidReceiveData(const char* data, int data_length) { 101 void GuestViewContainer::DidReceiveData(const char* data, int data_length) {
99 std::string value(data, data_length); 102 std::string value(data, data_length);
100 html_string_ += value; 103 html_string_ += value;
101 } 104 }
102 105
106 void GuestViewContainer::Ready() {
107 ready_ = true;
108 CHECK(!pending_response_.get());
109 if (pending_requests_.empty())
110 return;
111
112 linked_ptr<AttachRequest> pending_request = pending_requests_.front();
113 pending_requests_.pop_front();
114 AttachGuestInternal(pending_request);
115 }
116
103 void GuestViewContainer::OnDestruct() { 117 void GuestViewContainer::OnDestruct() {
104 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let 118 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let
105 // RenderFrameObserver self-destruct here. 119 // RenderFrameObserver self-destruct here.
106 } 120 }
107 121
108 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) { 122 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) {
109 if (!ShouldHandleMessage(message)) 123 if (!ShouldHandleMessage(message))
110 return false; 124 return false;
111 125
112 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 126 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
(...skipping 17 matching lines...) Expand all
130 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK( 144 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK(
131 int element_instance_id) { 145 int element_instance_id) {
132 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 146 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
133 DCHECK_EQ(element_instance_id_, element_instance_id); 147 DCHECK_EQ(element_instance_id_, element_instance_id);
134 DCHECK(!mime_type_.empty()); 148 DCHECK(!mime_type_.empty());
135 render_frame()->AttachGuest(element_instance_id); 149 render_frame()->AttachGuest(element_instance_id);
136 } 150 }
137 151
138 void GuestViewContainer::OnGuestAttached(int element_instance_id, 152 void GuestViewContainer::OnGuestAttached(int element_instance_id,
139 int guest_routing_id) { 153 int guest_routing_id) {
154 CHECK(pending_response_.get());
155
140 attached_ = true; 156 attached_ = true;
141 attach_pending_ = false;
142 157
143 // If we don't have a callback then there's nothing more to do. 158 // If we don't have a callback then there's nothing more to do.
144 if (callback_.IsEmpty()) 159 if (!pending_response_->has_callback())
145 return; 160 return;
lazyboy 2014/10/03 20:30:05 Couldn't there be more stuff in the queue to be pr
Fady Samuel 2014/10/03 21:52:30 Good catch!
146 161
147 content::RenderView* guest_proxy_render_view = 162 content::RenderView* guest_proxy_render_view =
148 content::RenderView::FromRoutingID(guest_routing_id); 163 content::RenderView::FromRoutingID(guest_routing_id);
149 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing? 164 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
150 if (!guest_proxy_render_view) 165 if (!guest_proxy_render_view)
151 return; 166 return;
152 167
153 v8::HandleScope handle_scope(isolate_); 168 v8::HandleScope handle_scope(pending_response_->isolate());
154 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); 169 v8::Handle<v8::Function> callback = pending_response_->GetCallback();
155 v8::Handle<v8::Context> context = callback->CreationContext(); 170 v8::Handle<v8::Context> context = callback->CreationContext();
156 if (context.IsEmpty()) 171 if (context.IsEmpty())
157 return; 172 return;
158 173
159 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); 174 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
160 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); 175 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
161 176
162 const int argc = 1; 177 const int argc = 1;
163 v8::Handle<v8::Value> argv[argc] = { window }; 178 v8::Handle<v8::Value> argv[argc] = { window };
164 179
165 v8::Context::Scope context_scope(context); 180 v8::Context::Scope context_scope(context);
166 blink::WebScopedMicrotaskSuppression suppression; 181 blink::WebScopedMicrotaskSuppression suppression;
167 182
168 // Call the AttachGuest API's callback with the guest proxy as the first 183 // Call the AttachGuest API's callback with the guest proxy as the first
169 // parameter. 184 // parameter.
170 callback->Call(context->Global(), argc, argv); 185 callback->Call(context->Global(), argc, argv);
171 callback_.reset(); 186
187 pending_response_.reset();
188 if (!pending_requests_.empty()) {
189 linked_ptr<AttachRequest> pending_request = pending_requests_.front();
lazyboy 2014/10/03 20:30:05 Can this picking from queue and putting it to pend
Fady Samuel 2014/10/03 21:52:30 Done. I gave them slightly more descriptive names.
190 pending_requests_.pop_front();
191 AttachGuestInternal(pending_request);
192 }
193 }
194
195 void GuestViewContainer::AttachGuestInternal(
196 linked_ptr<AttachRequest> request) {
197 CHECK(!pending_response_.get());
198 // Step 1, send the attach params to chrome/.
199 render_frame()->Send(
200 new ExtensionHostMsg_AttachGuest(render_view_routing_id_,
201 request->element_instance_id(),
202 request->guest_instance_id(),
203 *request->attach_params()));
204
205 // Step 2, attach plugin through content/.
206 render_frame()->AttachGuest(request->element_instance_id());
207
208 pending_response_ = request;
172 } 209 }
173 210
174 // static 211 // static
175 bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) { 212 bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) {
176 switch (message.type()) { 213 switch (message.type()) {
177 case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID: 214 case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID:
178 case ExtensionMsg_GuestAttached::ID: 215 case ExtensionMsg_GuestAttached::ID:
179 return true; 216 return true;
180 default: 217 default:
181 break; 218 break;
182 } 219 }
183 return false; 220 return false;
184 } 221 }
185 222
186 } // namespace extensions 223 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698