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

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: Addressed Istiaque's comments 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
lazyboy 2014/10/03 22:10:19 nit: remove empty line.
Fady Samuel 2014/10/03 22:23:59 Done.
43 bool GuestViewContainer::AttachRequest::HasCallback() const {
44 return !callback_.IsEmpty();
45 }
46
47 v8::Handle<v8::Function>
48 GuestViewContainer::AttachRequest::GetCallback() const {
49 return callback_.NewHandle(isolate_);
50 }
51
26 GuestViewContainer::GuestViewContainer( 52 GuestViewContainer::GuestViewContainer(
27 content::RenderFrame* render_frame, 53 content::RenderFrame* render_frame,
28 const std::string& mime_type) 54 const std::string& mime_type)
29 : content::BrowserPluginDelegate(render_frame, mime_type), 55 : content::BrowserPluginDelegate(render_frame, mime_type),
30 content::RenderFrameObserver(render_frame), 56 content::RenderFrameObserver(render_frame),
31 mime_type_(mime_type), 57 mime_type_(mime_type),
32 element_instance_id_(guestview::kInstanceIDNone), 58 element_instance_id_(guestview::kInstanceIDNone),
33 render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()), 59 render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()),
34 attached_(false), 60 attached_(false),
35 attach_pending_(false), 61 ready_(false) {
36 isolate_(NULL) {
37 } 62 }
38 63
39 GuestViewContainer::~GuestViewContainer() { 64 GuestViewContainer::~GuestViewContainer() {
40 if (element_instance_id_ != guestview::kInstanceIDNone) { 65 if (element_instance_id_ != guestview::kInstanceIDNone) {
41 g_guest_view_container_map.Get().erase( 66 g_guest_view_container_map.Get().erase(
42 GuestViewID(render_view_routing_id_, element_instance_id_)); 67 GuestViewID(render_view_routing_id_, element_instance_id_));
43 } 68 }
44 } 69 }
45 70
46 GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id, 71 GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id,
47 int element_instance_id) { 72 int element_instance_id) {
48 GuestViewContainerMap* guest_view_containers = 73 GuestViewContainerMap* guest_view_containers =
49 g_guest_view_container_map.Pointer(); 74 g_guest_view_container_map.Pointer();
50 GuestViewContainerMap::iterator it = guest_view_containers->find( 75 GuestViewContainerMap::iterator it = guest_view_containers->find(
51 GuestViewID(render_view_routing_id, element_instance_id)); 76 GuestViewID(render_view_routing_id, element_instance_id));
52 return it == guest_view_containers->end() ? NULL : it->second; 77 return it == guest_view_containers->end() ? NULL : it->second;
53 } 78 }
54 79
55 80 void GuestViewContainer::AttachGuest(linked_ptr<AttachRequest> request) {
56 void GuestViewContainer::AttachGuest(int element_instance_id, 81 EnqueueAttachRequest(request);
57 int guest_instance_id, 82 PerformPendingAttachRequest();
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;
78 } 83 }
79 84
80 void GuestViewContainer::SetElementInstanceID(int element_instance_id) { 85 void GuestViewContainer::SetElementInstanceID(int element_instance_id) {
81 GuestViewID guest_view_id(render_view_routing_id_, element_instance_id); 86 GuestViewID guest_view_id(render_view_routing_id_, element_instance_id);
82 DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone); 87 DCHECK_EQ(element_instance_id_, guestview::kInstanceIDNone);
83 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) == 88 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) ==
84 g_guest_view_container_map.Get().end()); 89 g_guest_view_container_map.Get().end());
85 element_instance_id_ = element_instance_id; 90 element_instance_id_ = element_instance_id;
86 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this)); 91 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this));
87 } 92 }
88 93
89 void GuestViewContainer::DidFinishLoading() { 94 void GuestViewContainer::DidFinishLoading() {
90 if (mime_type_.empty()) 95 if (mime_type_.empty())
91 return; 96 return;
92 97
93 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 98 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
94 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest( 99 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest(
95 routing_id(), html_string_, mime_type_, element_instance_id_)); 100 routing_id(), html_string_, mime_type_, element_instance_id_));
96 } 101 }
97 102
98 void GuestViewContainer::DidReceiveData(const char* data, int data_length) { 103 void GuestViewContainer::DidReceiveData(const char* data, int data_length) {
99 std::string value(data, data_length); 104 std::string value(data, data_length);
100 html_string_ += value; 105 html_string_ += value;
101 } 106 }
102 107
108 void GuestViewContainer::Ready() {
109 ready_ = true;
110 CHECK(!pending_response_.get());
111 PerformPendingAttachRequest();
112 }
113
103 void GuestViewContainer::OnDestruct() { 114 void GuestViewContainer::OnDestruct() {
104 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let 115 // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let
105 // RenderFrameObserver self-destruct here. 116 // RenderFrameObserver self-destruct here.
106 } 117 }
107 118
108 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) { 119 bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) {
109 if (!ShouldHandleMessage(message)) 120 if (!ShouldHandleMessage(message))
110 return false; 121 return false;
111 122
112 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 123 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
(...skipping 17 matching lines...) Expand all
130 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK( 141 void GuestViewContainer::OnCreateMimeHandlerViewGuestACK(
131 int element_instance_id) { 142 int element_instance_id) {
132 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone); 143 DCHECK_NE(element_instance_id_, guestview::kInstanceIDNone);
133 DCHECK_EQ(element_instance_id_, element_instance_id); 144 DCHECK_EQ(element_instance_id_, element_instance_id);
134 DCHECK(!mime_type_.empty()); 145 DCHECK(!mime_type_.empty());
135 render_frame()->AttachGuest(element_instance_id); 146 render_frame()->AttachGuest(element_instance_id);
136 } 147 }
137 148
138 void GuestViewContainer::OnGuestAttached(int element_instance_id, 149 void GuestViewContainer::OnGuestAttached(int element_instance_id,
139 int guest_routing_id) { 150 int guest_routing_id) {
151 CHECK(pending_response_.get());
152
140 attached_ = true; 153 attached_ = true;
141 attach_pending_ = false;
142 154
143 // If we don't have a callback then there's nothing more to do. 155 // If we don't have a callback then there's nothing more to do.
144 if (callback_.IsEmpty()) 156 if (!pending_response_->HasCallback()) {
157 pending_response_.reset();
158 PerformPendingAttachRequest();
145 return; 159 return;
160 }
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) {
166 pending_response_.reset();
167 PerformPendingAttachRequest();
151 return; 168 return;
169 }
152 170
153 v8::HandleScope handle_scope(isolate_); 171 v8::HandleScope handle_scope(pending_response_->isolate());
154 v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); 172 v8::Handle<v8::Function> callback = pending_response_->GetCallback();
155 v8::Handle<v8::Context> context = callback->CreationContext(); 173 v8::Handle<v8::Context> context = callback->CreationContext();
156 if (context.IsEmpty()) 174 if (context.IsEmpty()) {
175 pending_response_.reset();
176 PerformPendingAttachRequest();
157 return; 177 return;
178 }
158 179
159 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); 180 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
160 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); 181 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
161 182
162 const int argc = 1; 183 const int argc = 1;
163 v8::Handle<v8::Value> argv[argc] = { window }; 184 v8::Handle<v8::Value> argv[argc] = { window };
164 185
165 v8::Context::Scope context_scope(context); 186 v8::Context::Scope context_scope(context);
166 blink::WebScopedMicrotaskSuppression suppression; 187 blink::WebScopedMicrotaskSuppression suppression;
167 188
168 // Call the AttachGuest API's callback with the guest proxy as the first 189 // Call the AttachGuest API's callback with the guest proxy as the first
169 // parameter. 190 // parameter.
170 callback->Call(context->Global(), argc, argv); 191 callback->Call(context->Global(), argc, argv);
171 callback_.reset(); 192
193 pending_response_.reset();
lazyboy 2014/10/03 22:10:19 The repetitive pattern (4 times) suggests we would
Fady Samuel 2014/10/03 22:23:59 Done.
194 PerformPendingAttachRequest();
195 }
196
197 void GuestViewContainer::AttachGuestInternal(
198 linked_ptr<AttachRequest> request) {
199 CHECK(!pending_response_.get());
200 // Step 1, send the attach params to chrome/.
201 render_frame()->Send(
202 new ExtensionHostMsg_AttachGuest(render_view_routing_id_,
203 request->element_instance_id(),
204 request->guest_instance_id(),
205 *request->attach_params()));
206
207 // Step 2, attach plugin through content/.
208 render_frame()->AttachGuest(request->element_instance_id());
209
210 pending_response_ = request;
211 }
212
213 void GuestViewContainer::EnqueueAttachRequest(
214 linked_ptr<AttachRequest> request) {
215 pending_requests_.push_back(request);
216 }
217
218 void GuestViewContainer::PerformPendingAttachRequest() {
219 if (!ready_ || pending_requests_.empty() || pending_response_.get())
220 return;
221
222 linked_ptr<AttachRequest> pending_request = pending_requests_.front();
223 pending_requests_.pop_front();
224 AttachGuestInternal(pending_request);
172 } 225 }
173 226
174 // static 227 // static
175 bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) { 228 bool GuestViewContainer::ShouldHandleMessage(const IPC::Message& message) {
176 switch (message.type()) { 229 switch (message.type()) {
177 case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID: 230 case ExtensionMsg_CreateMimeHandlerViewGuestACK::ID:
178 case ExtensionMsg_GuestAttached::ID: 231 case ExtensionMsg_GuestAttached::ID:
179 return true; 232 return true;
180 default: 233 default:
181 break; 234 break;
182 } 235 }
183 return false; 236 return false;
184 } 237 }
185 238
186 } // namespace extensions 239 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698