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

Side by Side Diff: components/plugins/renderer/webview_plugin.cc

Issue 2600253003: Fix plugin placeholders not loading (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « components/plugins/renderer/webview_plugin.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/plugins/renderer/webview_plugin.h" 5 #include "components/plugins/renderer/webview_plugin.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 using blink::WebVector; 46 using blink::WebVector;
47 using blink::WebView; 47 using blink::WebView;
48 using content::WebPreferences; 48 using content::WebPreferences;
49 49
50 WebViewPlugin::WebViewPlugin(content::RenderView* render_view, 50 WebViewPlugin::WebViewPlugin(content::RenderView* render_view,
51 WebViewPlugin::Delegate* delegate, 51 WebViewPlugin::Delegate* delegate,
52 const WebPreferences& preferences) 52 const WebPreferences& preferences)
53 : content::RenderViewObserver(render_view), 53 : content::RenderViewObserver(render_view),
54 delegate_(delegate), 54 delegate_(delegate),
55 container_(nullptr), 55 container_(nullptr),
56 web_view_(WebView::create(this, blink::WebPageVisibilityStateVisible)), 56 finished_loading_(false),
57 focused_(false), 57 focused_(false),
58 is_painting_(false), 58 is_painting_(false),
59 is_resizing_(false), 59 is_resizing_(false),
60 web_frame_client_(this), 60 web_view_helper_(this, preferences),
61 weak_factory_(this) { 61 weak_factory_(this) {
62 // ApplyWebPreferences before making a WebLocalFrame so that the frame sees a
63 // consistent view of our preferences.
64 content::RenderView::ApplyWebPreferences(preferences, web_view_);
65 WebLocalFrame* web_frame = WebLocalFrame::create(
66 blink::WebTreeScopeType::Document, &web_frame_client_);
67 web_view_->setMainFrame(web_frame);
68 // TODO(dcheng): The main frame widget currently has a special case.
69 // Eliminate this once WebView is no longer a WebWidget.
70 WebFrameWidget::create(this, web_view_, web_frame);
71 } 62 }
72 63
73 // static 64 // static
74 WebViewPlugin* WebViewPlugin::Create(content::RenderView* render_view, 65 WebViewPlugin* WebViewPlugin::Create(content::RenderView* render_view,
75 WebViewPlugin::Delegate* delegate, 66 WebViewPlugin::Delegate* delegate,
76 const WebPreferences& preferences, 67 const WebPreferences& preferences,
77 const std::string& html_data, 68 const std::string& html_data,
78 const GURL& url) { 69 const GURL& url) {
79 DCHECK(url.is_valid()) << "Blink requires the WebView to have a valid URL."; 70 DCHECK(url.is_valid()) << "Blink requires the WebView to have a valid URL.";
80 WebViewPlugin* plugin = new WebViewPlugin(render_view, delegate, preferences); 71 WebViewPlugin* plugin = new WebViewPlugin(render_view, delegate, preferences);
81 plugin->web_view()->mainFrame()->loadHTMLString(html_data, url); 72 plugin->web_view()->mainFrame()->loadHTMLString(html_data, url);
82 return plugin; 73 return plugin;
83 } 74 }
84 75
85 WebViewPlugin::~WebViewPlugin() { 76 WebViewPlugin::~WebViewPlugin() {
86 DCHECK(!weak_factory_.HasWeakPtrs()); 77 DCHECK(!weak_factory_.HasWeakPtrs());
87 web_view_->close(); 78 }
79
80 void WebViewPlugin::ReplayReceivedData(WebPlugin* plugin) {
81 if (!response_.isNull()) {
82 plugin->didReceiveResponse(response_);
83 size_t total_bytes = 0;
84 for (std::list<std::string>::iterator it = data_.begin(); it != data_.end();
85 ++it) {
86 plugin->didReceiveData(
87 it->c_str(), base::checked_cast<int>(it->length()));
88 total_bytes += it->length();
89 }
90 }
91 // We need to transfer the |focused_| to new plugin after it loaded.
92 if (focused_) {
Bernhard Bauer 2017/01/03 17:01:33 Nit: It looks like the style for single-line bodie
Nate Chapin 2017/01/03 20:04:26 Done. I had just reverted to what I had deleted, b
93 plugin->updateFocus(true, blink::WebFocusTypeNone);
94 }
95 if (finished_loading_) {
96 plugin->didFinishLoading();
97 }
98 if (error_) {
99 plugin->didFailLoading(*error_);
100 }
88 } 101 }
89 102
90 WebPluginContainer* WebViewPlugin::container() const { return container_; } 103 WebPluginContainer* WebViewPlugin::container() const { return container_; }
91 104
92 bool WebViewPlugin::initialize(WebPluginContainer* container) { 105 bool WebViewPlugin::initialize(WebPluginContainer* container) {
93 DCHECK(container); 106 DCHECK(container);
94 DCHECK_EQ(this, container->plugin()); 107 DCHECK_EQ(this, container->plugin());
95 container_ = container; 108 container_ = container;
96 109
97 // We must call layout again here to ensure that the container is laid 110 // We must call layout again here to ensure that the container is laid
98 // out before we next try to paint it, which is a requirement of the 111 // out before we next try to paint it, which is a requirement of the
99 // document life cycle in Blink. In most cases, needsLayout is set by 112 // document life cycle in Blink. In most cases, needsLayout is set by
100 // scheduleAnimation, but due to timers controlling widget update, 113 // scheduleAnimation, but due to timers controlling widget update,
101 // scheduleAnimation may be invoked before this initialize call (which 114 // scheduleAnimation may be invoked before this initialize call (which
102 // comes through the widget update process). It doesn't hurt to mark 115 // comes through the widget update process). It doesn't hurt to mark
103 // for animation again, and it does help us in the race-condition situation. 116 // for animation again, and it does help us in the race-condition situation.
104 container_->scheduleAnimation(); 117 container_->scheduleAnimation();
105 118
106 old_title_ = container_->element().getAttribute("title"); 119 old_title_ = container_->element().getAttribute("title");
107 120
108 // Propagate device scale and zoom level to inner webview. 121 // Propagate device scale and zoom level to inner webview.
109 web_view_->setDeviceScaleFactor(container_->deviceScaleFactor()); 122 web_view()->setDeviceScaleFactor(container_->deviceScaleFactor());
110 web_view_->setZoomLevel( 123 web_view()->setZoomLevel(
111 blink::WebView::zoomFactorToZoomLevel(container_->pageZoomFactor())); 124 blink::WebView::zoomFactorToZoomLevel(container_->pageZoomFactor()));
112 125
113 return true; 126 return true;
114 } 127 }
115 128
116 void WebViewPlugin::destroy() { 129 void WebViewPlugin::destroy() {
117 weak_factory_.InvalidateWeakPtrs(); 130 weak_factory_.InvalidateWeakPtrs();
118 131
119 if (delegate_) { 132 if (delegate_) {
120 delegate_->PluginDestroyed(); 133 delegate_->PluginDestroyed();
121 delegate_ = nullptr; 134 delegate_ = nullptr;
122 } 135 }
123 container_ = nullptr; 136 container_ = nullptr;
124 content::RenderViewObserver::Observe(nullptr); 137 content::RenderViewObserver::Observe(nullptr);
125 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); 138 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
126 } 139 }
127 140
128 v8::Local<v8::Object> WebViewPlugin::v8ScriptableObject(v8::Isolate* isolate) { 141 v8::Local<v8::Object> WebViewPlugin::v8ScriptableObject(v8::Isolate* isolate) {
129 if (!delegate_) 142 if (!delegate_)
130 return v8::Local<v8::Object>(); 143 return v8::Local<v8::Object>();
131 144
132 return delegate_->GetV8ScriptableObject(isolate); 145 return delegate_->GetV8ScriptableObject(isolate);
133 } 146 }
134 147
135 void WebViewPlugin::updateAllLifecyclePhases() { 148 void WebViewPlugin::updateAllLifecyclePhases() {
136 web_view_->updateAllLifecyclePhases(); 149 web_view()->updateAllLifecyclePhases();
137 } 150 }
138 151
139 void WebViewPlugin::paint(WebCanvas* canvas, const WebRect& rect) { 152 void WebViewPlugin::paint(WebCanvas* canvas, const WebRect& rect) {
140 gfx::Rect paint_rect = gfx::IntersectRects(rect_, rect); 153 gfx::Rect paint_rect = gfx::IntersectRects(rect_, rect);
141 if (paint_rect.IsEmpty()) 154 if (paint_rect.IsEmpty())
142 return; 155 return;
143 156
144 base::AutoReset<bool> is_painting( 157 base::AutoReset<bool> is_painting(
145 &is_painting_, true); 158 &is_painting_, true);
146 159
147 paint_rect.Offset(-rect_.x(), -rect_.y()); 160 paint_rect.Offset(-rect_.x(), -rect_.y());
148 161
149 canvas->save(); 162 canvas->save();
150 canvas->translate(SkIntToScalar(rect_.x()), SkIntToScalar(rect_.y())); 163 canvas->translate(SkIntToScalar(rect_.x()), SkIntToScalar(rect_.y()));
151 164
152 // Apply inverse device scale factor, as the outer webview has already 165 // Apply inverse device scale factor, as the outer webview has already
153 // applied it, and the inner webview will apply it again. 166 // applied it, and the inner webview will apply it again.
154 SkScalar inverse_scale = 167 SkScalar inverse_scale =
155 SkFloatToScalar(1.0 / container_->deviceScaleFactor()); 168 SkFloatToScalar(1.0 / container_->deviceScaleFactor());
156 canvas->scale(inverse_scale, inverse_scale); 169 canvas->scale(inverse_scale, inverse_scale);
157 170
158 web_view_->paint(canvas, paint_rect); 171 web_view()->paint(canvas, paint_rect);
159 172
160 canvas->restore(); 173 canvas->restore();
161 } 174 }
162 175
163 // Coordinates are relative to the containing window. 176 // Coordinates are relative to the containing window.
164 void WebViewPlugin::updateGeometry(const WebRect& window_rect, 177 void WebViewPlugin::updateGeometry(const WebRect& window_rect,
165 const WebRect& clip_rect, 178 const WebRect& clip_rect,
166 const WebRect& unobscured_rect, 179 const WebRect& unobscured_rect,
167 const WebVector<WebRect>& cut_outs_rects, 180 const WebVector<WebRect>& cut_outs_rects,
168 bool is_visible) { 181 bool is_visible) {
169 DCHECK(container_); 182 DCHECK(container_);
170 183
171 base::AutoReset<bool> is_resizing(&is_resizing_, true); 184 base::AutoReset<bool> is_resizing(&is_resizing_, true);
172 185
173 if (static_cast<gfx::Rect>(window_rect) != rect_) { 186 if (static_cast<gfx::Rect>(window_rect) != rect_) {
174 rect_ = window_rect; 187 rect_ = window_rect;
175 web_view_->resize(rect_.size()); 188 web_view()->resize(rect_.size());
176 } 189 }
177 190
178 // Plugin updates are forbidden during Blink layout. Therefore, 191 // Plugin updates are forbidden during Blink layout. Therefore,
179 // UpdatePluginForNewGeometry must be posted to a task to run asynchronously. 192 // UpdatePluginForNewGeometry must be posted to a task to run asynchronously.
180 base::ThreadTaskRunnerHandle::Get()->PostTask( 193 base::ThreadTaskRunnerHandle::Get()->PostTask(
181 FROM_HERE, 194 FROM_HERE,
182 base::Bind(&WebViewPlugin::UpdatePluginForNewGeometry, 195 base::Bind(&WebViewPlugin::UpdatePluginForNewGeometry,
183 weak_factory_.GetWeakPtr(), window_rect, unobscured_rect)); 196 weak_factory_.GetWeakPtr(), window_rect, unobscured_rect));
184 } 197 }
185 198
(...skipping 16 matching lines...) Expand all
202 215
203 if (event.type == WebInputEvent::ContextMenu) { 216 if (event.type == WebInputEvent::ContextMenu) {
204 if (delegate_) { 217 if (delegate_) {
205 const WebMouseEvent& mouse_event = 218 const WebMouseEvent& mouse_event =
206 reinterpret_cast<const WebMouseEvent&>(event); 219 reinterpret_cast<const WebMouseEvent&>(event);
207 delegate_->ShowContextMenu(mouse_event); 220 delegate_->ShowContextMenu(mouse_event);
208 } 221 }
209 return blink::WebInputEventResult::HandledSuppressed; 222 return blink::WebInputEventResult::HandledSuppressed;
210 } 223 }
211 current_cursor_ = cursor; 224 current_cursor_ = cursor;
212 blink::WebInputEventResult handled = web_view_->handleInputEvent(event); 225 blink::WebInputEventResult handled = web_view()->handleInputEvent(event);
213 cursor = current_cursor_; 226 cursor = current_cursor_;
214 227
215 return handled; 228 return handled;
216 } 229 }
217 230
218 void WebViewPlugin::didReceiveResponse(const WebURLResponse& response) { 231 void WebViewPlugin::didReceiveResponse(const WebURLResponse& response) {
219 NOTREACHED(); 232 DCHECK(response_.isNull());
233 response_ = response;
220 } 234 }
221 235
222 void WebViewPlugin::didReceiveData(const char* data, int data_length) { 236 void WebViewPlugin::didReceiveData(const char* data, int data_length) {
223 NOTREACHED(); 237 data_.push_back(std::string(data, data_length));
224 } 238 }
225 239
226 void WebViewPlugin::didFinishLoading() { 240 void WebViewPlugin::didFinishLoading() {
227 NOTREACHED(); 241 DCHECK(!finished_loading_);
242 finished_loading_ = true;
228 } 243 }
229 244
230 void WebViewPlugin::didFailLoading(const WebURLError& error) { 245 void WebViewPlugin::didFailLoading(const WebURLError& error) {
231 NOTREACHED(); 246 DCHECK(!error_.get());
247 error_.reset(new WebURLError(error));
232 } 248 }
233 249
234 bool WebViewPlugin::acceptsLoadDrops() { return false; } 250 WebViewPlugin::WebViewHelper::WebViewHelper(
235 251 WebViewPlugin* plugin,
236 void WebViewPlugin::setToolTipText(const WebString& text, 252 const WebPreferences& preferences) : plugin_(plugin) {
237 blink::WebTextDirection hint) { 253 // ApplyWebPreferences before making a WebLocalFrame so that the frame sees a
Bernhard Bauer 2017/01/03 17:01:33 Nit: Move this comment right before the call to Ap
Nate Chapin 2017/01/03 20:04:26 Done.
238 if (container_) 254 // consistent view of our preferences.
239 container_->element().setAttribute("title", text); 255 web_view_ =
256 WebView::create(this, blink::WebPageVisibilityStateVisible);
257 content::RenderView::ApplyWebPreferences(preferences, web_view_);
258 WebLocalFrame* web_frame = WebLocalFrame::create(
259 blink::WebTreeScopeType::Document, this);
260 web_view_->setMainFrame(web_frame);
261 // TODO(dcheng): The main frame widget currently has a special case.
262 // Eliminate this once WebView is no longer a WebWidget.
263 WebFrameWidget::create(this, web_view_, web_frame);
240 } 264 }
241 265
242 void WebViewPlugin::startDragging(blink::WebReferrerPolicy, 266 WebViewPlugin::WebViewHelper::~WebViewHelper() {
243 const WebDragData&, 267 web_view_->close();
244 WebDragOperationsMask, 268 }
245 const WebImage&, 269
246 const WebPoint&) { 270 bool WebViewPlugin::WebViewHelper::acceptsLoadDrops() { return false; }
271
272 void WebViewPlugin::WebViewHelper::setToolTipText(
273 const WebString& text,
274 blink::WebTextDirection hint) {
275 if (plugin_->container_)
276 plugin_->container_->element().setAttribute("title", text);
277 }
278
279 void WebViewPlugin::WebViewHelper::startDragging(blink::WebReferrerPolicy,
280 const WebDragData&,
281 WebDragOperationsMask,
282 const WebImage&,
283 const WebPoint&) {
247 // Immediately stop dragging. 284 // Immediately stop dragging.
248 DCHECK(web_view_->mainFrame()->isWebLocalFrame()); 285 DCHECK(web_view_->mainFrame()->isWebLocalFrame());
249 web_view_->mainFrame()->toWebLocalFrame()->frameWidget()-> 286 web_view_->mainFrame()->toWebLocalFrame()->frameWidget()->
250 dragSourceSystemDragEnded(); 287 dragSourceSystemDragEnded();
251 } 288 }
252 289
253 bool WebViewPlugin::allowsBrokenNullLayerTreeView() const { 290 bool WebViewPlugin::WebViewHelper::allowsBrokenNullLayerTreeView() const {
254 return true; 291 return true;
255 } 292 }
256 293
257 void WebViewPlugin::didInvalidateRect(const WebRect& rect) { 294 void WebViewPlugin::WebViewHelper::didInvalidateRect(const WebRect& rect) {
258 if (container_) 295 if (plugin_->container_)
259 container_->invalidateRect(rect); 296 plugin_->container_->invalidateRect(rect);
260 } 297 }
261 298
262 void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) { 299 void WebViewPlugin::WebViewHelper::didChangeCursor(
263 current_cursor_ = cursor; 300 const WebCursorInfo& cursor) {
301 plugin_->current_cursor_ = cursor;
264 } 302 }
265 303
266 void WebViewPlugin::scheduleAnimation() { 304 void WebViewPlugin::WebViewHelper::scheduleAnimation() {
267 // Resizes must be self-contained: any lifecycle updating must 305 // Resizes must be self-contained: any lifecycle updating must
268 // be triggerd from within the WebView or this WebViewPlugin. 306 // be triggerd from within the WebView or this WebViewPlugin.
269 // This is because this WebViewPlugin is contained in another 307 // This is because this WebViewPlugin is contained in another
270 // Web View which may be in the middle of updating its lifecycle, 308 // Web View which may be in the middle of updating its lifecycle,
271 // but after layout is done, and it is illegal to dirty earlier 309 // but after layout is done, and it is illegal to dirty earlier
272 // lifecycle stages during later ones. 310 // lifecycle stages during later ones.
273 if (is_resizing_) 311 if (plugin_->is_resizing_)
274 return; 312 return;
275 if (container_) { 313 if (plugin_->container_) {
276 // This should never happen; see also crbug.com/545039 for context. 314 // This should never happen; see also crbug.com/545039 for context.
Bernhard Bauer 2017/01/03 17:01:33 https://crbug.com/545039 has been marked fixed; ca
Nate Chapin 2017/01/03 20:04:26 Double-checked with chrishtr, who added the commen
277 CHECK(!is_painting_); 315 CHECK(!plugin_->is_painting_);
278 container_->scheduleAnimation(); 316 plugin_->container_->scheduleAnimation();
279 } 317 }
280 } 318 }
281 319
282 void WebViewPlugin::PluginWebFrameClient::didClearWindowObject( 320 void WebViewPlugin::WebViewHelper::didClearWindowObject(
283 WebLocalFrame* frame) { 321 WebLocalFrame* frame) {
284 if (!plugin_->delegate_) 322 if (!plugin_->delegate_)
285 return; 323 return;
286 324
287 v8::Isolate* isolate = blink::mainThreadIsolate(); 325 v8::Isolate* isolate = blink::mainThreadIsolate();
288 v8::HandleScope handle_scope(isolate); 326 v8::HandleScope handle_scope(isolate);
289 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); 327 v8::Local<v8::Context> context = frame->mainWorldScriptContext();
290 DCHECK(!context.IsEmpty()); 328 DCHECK(!context.IsEmpty());
291 329
292 v8::Context::Scope context_scope(context); 330 v8::Context::Scope context_scope(context);
293 v8::Local<v8::Object> global = context->Global(); 331 v8::Local<v8::Object> global = context->Global();
294 332
295 global->Set(gin::StringToV8(isolate, "plugin"), 333 global->Set(gin::StringToV8(isolate, "plugin"),
296 plugin_->delegate_->GetV8Handle(isolate)); 334 plugin_->delegate_->GetV8Handle(isolate));
297 } 335 }
298 336
299 void WebViewPlugin::OnDestruct() {}
300
301 void WebViewPlugin::OnZoomLevelChanged() { 337 void WebViewPlugin::OnZoomLevelChanged() {
302 if (container_) { 338 if (container_) {
303 web_view_->setZoomLevel( 339 web_view()->setZoomLevel(
304 blink::WebView::zoomFactorToZoomLevel(container_->pageZoomFactor())); 340 blink::WebView::zoomFactorToZoomLevel(container_->pageZoomFactor()));
305 } 341 }
306 } 342 }
307 343
308 void WebViewPlugin::UpdatePluginForNewGeometry( 344 void WebViewPlugin::UpdatePluginForNewGeometry(
309 const blink::WebRect& window_rect, 345 const blink::WebRect& window_rect,
310 const blink::WebRect& unobscured_rect) { 346 const blink::WebRect& unobscured_rect) {
311 DCHECK(container_); 347 DCHECK(container_);
312 if (!delegate_) 348 if (!delegate_)
313 return; 349 return;
314 350
315 // The delegate may instantiate a new plugin. 351 // The delegate may instantiate a new plugin.
316 delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); 352 delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect));
317 // The delegate may have dirtied style and layout of the WebView. 353 // The delegate may have dirtied style and layout of the WebView.
318 // See for example the resizePoster function in plugin_poster.html. 354 // See for example the resizePoster function in plugin_poster.html.
319 // Run the lifecycle now so that it is clean. 355 // Run the lifecycle now so that it is clean.
320 web_view_->updateAllLifecyclePhases(); 356 web_view()->updateAllLifecyclePhases();
321 } 357 }
OLDNEW
« no previous file with comments | « components/plugins/renderer/webview_plugin.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698