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

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

Issue 1732313003: Revert of Plugin Power Saver: Remove Size Recheck hack in plugin placeholders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@0047-pps-skip-poster-for-same-origin
Patch Set: Created 4 years, 10 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/loadable_plugin_placeholder.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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/loadable_plugin_placeholder.h" 5 #include "components/plugins/renderer/loadable_plugin_placeholder.h"
6 6
7 #include "base/auto_reset.h"
7 #include "base/bind.h" 8 #include "base/bind.h"
8 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
9 #include "base/json/string_escape.h" 10 #include "base/json/string_escape.h"
10 #include "base/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
11 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "content/public/child/v8_value_converter.h" 16 #include "content/public/child/v8_value_converter.h"
16 #include "content/public/renderer/render_frame.h" 17 #include "content/public/renderer/render_frame.h"
(...skipping 10 matching lines...) Expand all
27 #include "third_party/WebKit/public/web/WebView.h" 28 #include "third_party/WebKit/public/web/WebView.h"
28 #include "url/gurl.h" 29 #include "url/gurl.h"
29 #include "url/origin.h" 30 #include "url/origin.h"
30 31
31 using base::UserMetricsAction; 32 using base::UserMetricsAction;
32 using content::PluginInstanceThrottler; 33 using content::PluginInstanceThrottler;
33 using content::RenderThread; 34 using content::RenderThread;
34 35
35 namespace plugins { 36 namespace plugins {
36 37
38 // TODO(tommycli): After a size update, re-check the size after this delay, as
39 // Blink can report incorrect sizes to plugins while the compositing state is
40 // dirty. Chosen because it seems to work.
41 const int kSizeChangeRecheckDelayMilliseconds = 100;
42
37 void LoadablePluginPlaceholder::BlockForPowerSaverPoster() { 43 void LoadablePluginPlaceholder::BlockForPowerSaverPoster() {
38 DCHECK(!is_blocked_for_power_saver_poster_); 44 DCHECK(!is_blocked_for_power_saver_poster_);
39 is_blocked_for_power_saver_poster_ = true; 45 is_blocked_for_power_saver_poster_ = true;
40 46
41 render_frame()->RegisterPeripheralPlugin( 47 render_frame()->RegisterPeripheralPlugin(
42 url::Origin(GURL(GetPluginParams().url)), 48 url::Origin(GURL(GetPluginParams().url)),
43 base::Bind(&LoadablePluginPlaceholder::MarkPluginEssential, 49 base::Bind(&LoadablePluginPlaceholder::MarkPluginEssential,
44 weak_factory_.GetWeakPtr(), 50 weak_factory_.GetWeakPtr(),
45 PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_WHITELIST)); 51 PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_WHITELIST));
46 } 52 }
(...skipping 11 matching lines...) Expand all
58 const blink::WebPluginParams& params, 64 const blink::WebPluginParams& params,
59 const std::string& html_data) 65 const std::string& html_data)
60 : PluginPlaceholderBase(render_frame, frame, params, html_data), 66 : PluginPlaceholderBase(render_frame, frame, params, html_data),
61 is_blocked_for_background_tab_(false), 67 is_blocked_for_background_tab_(false),
62 is_blocked_for_prerendering_(false), 68 is_blocked_for_prerendering_(false),
63 is_blocked_for_power_saver_poster_(false), 69 is_blocked_for_power_saver_poster_(false),
64 power_saver_enabled_(false), 70 power_saver_enabled_(false),
65 premade_throttler_(nullptr), 71 premade_throttler_(nullptr),
66 allow_loading_(false), 72 allow_loading_(false),
67 finished_loading_(false), 73 finished_loading_(false),
74 in_size_recheck_(false),
68 heuristic_run_before_(premade_throttler_ != nullptr), 75 heuristic_run_before_(premade_throttler_ != nullptr),
69 weak_factory_(this) {} 76 weak_factory_(this) {}
70 77
71 LoadablePluginPlaceholder::~LoadablePluginPlaceholder() { 78 LoadablePluginPlaceholder::~LoadablePluginPlaceholder() {
72 } 79 }
73 80
74 void LoadablePluginPlaceholder::MarkPluginEssential( 81 void LoadablePluginPlaceholder::MarkPluginEssential(
75 PluginInstanceThrottler::PowerSaverUnthrottleMethod method) { 82 PluginInstanceThrottler::PowerSaverUnthrottleMethod method) {
76 if (!power_saver_enabled_) 83 if (!power_saver_enabled_)
77 return; 84 return;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 // Pass through JavaScript access to the underlying throttled plugin. 183 // Pass through JavaScript access to the underlying throttled plugin.
177 if (premade_throttler_ && premade_throttler_->GetWebPlugin()) { 184 if (premade_throttler_ && premade_throttler_->GetWebPlugin()) {
178 return premade_throttler_->GetWebPlugin()->v8ScriptableObject(isolate); 185 return premade_throttler_->GetWebPlugin()->v8ScriptableObject(isolate);
179 } 186 }
180 return v8::Local<v8::Object>(); 187 return v8::Local<v8::Object>();
181 } 188 }
182 189
183 void LoadablePluginPlaceholder::OnUnobscuredRectUpdate( 190 void LoadablePluginPlaceholder::OnUnobscuredRectUpdate(
184 const gfx::Rect& unobscured_rect) { 191 const gfx::Rect& unobscured_rect) {
185 DCHECK(content::RenderThread::Get()); 192 DCHECK(content::RenderThread::Get());
186 if (!plugin() || !power_saver_enabled_ || !finished_loading_) 193 if (!power_saver_enabled_ || !finished_loading_)
187 return; 194 return;
188 195
189 if (unobscured_rect_ == unobscured_rect) 196 // Only update the unobscured rect during the recheck phase. Also early exit
197 // to prevent reentrancy issues.
198 if (in_size_recheck_) {
199 unobscured_rect_ = unobscured_rect;
200 return;
201 }
202
203 if (!size_update_timer_.IsRunning()) {
204 // TODO(tommycli): We have to post a delayed task to recheck the size, as
205 // Blink can report wrong sizes for partially obscured plugins while the
206 // compositing state is dirty. https://crbug.com/343769
207 size_update_timer_.Start(
208 FROM_HERE,
209 base::TimeDelta::FromMilliseconds(kSizeChangeRecheckDelayMilliseconds),
210 base::Bind(&LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle,
211 weak_factory_.GetWeakPtr()));
212 }
213 }
214
215 void LoadablePluginPlaceholder::WasShown() {
216 if (is_blocked_for_background_tab_) {
217 is_blocked_for_background_tab_ = false;
218 if (!LoadingBlocked())
219 LoadPlugin();
220 }
221 }
222
223 void LoadablePluginPlaceholder::OnLoadBlockedPlugins(
224 const std::string& identifier) {
225 if (!identifier.empty() && identifier != identifier_)
190 return; 226 return;
191 227
192 unobscured_rect_ = unobscured_rect; 228 RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_UI"));
229 LoadPlugin();
230 }
231
232 void LoadablePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
233 // Prerendering can only be enabled prior to a RenderView's first navigation,
234 // so no BlockedPlugin should see the notification that enables prerendering.
235 DCHECK(!is_prerendering);
236 if (is_blocked_for_prerendering_) {
237 is_blocked_for_prerendering_ = false;
238 if (!LoadingBlocked())
239 LoadPlugin();
240 }
241 }
242
243 void LoadablePluginPlaceholder::LoadPlugin() {
244 // This is not strictly necessary but is an important defense in case the
245 // event propagation changes between "close" vs. "click-to-play".
246 if (hidden())
247 return;
248 if (!plugin())
249 return;
250 if (!allow_loading_) {
251 NOTREACHED();
252 return;
253 }
254
255 if (premade_throttler_) {
256 premade_throttler_->SetHiddenForPlaceholder(false /* hidden */);
257 ReplacePlugin(premade_throttler_->GetWebPlugin());
258 premade_throttler_ = nullptr;
259 } else {
260 ReplacePlugin(CreatePlugin());
261 }
262 }
263
264 void LoadablePluginPlaceholder::LoadCallback() {
265 RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Click"));
266 // If the user specifically clicks on the plugin content's placeholder,
267 // disable power saver throttling for this instance.
268 MarkPluginEssential(PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK);
269 LoadPlugin();
270 }
271
272 void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
273 finished_loading_ = true;
274 if (message_.length() > 0)
275 UpdateMessage();
276
277 // Wait for the placeholder to finish loading to hide the premade plugin.
278 // This is necessary to prevent a flicker.
279 if (premade_throttler_ && power_saver_enabled_)
280 premade_throttler_->SetHiddenForPlaceholder(true /* hidden */);
281
282 // In case our initial geometry was reported before the placeholder finished
283 // loading, request another one. Needed for correct large poster unthrottling.
284 if (plugin()) {
285 CHECK(plugin()->container());
286 plugin()->container()->reportGeometry();
287 }
288 }
289
290 void LoadablePluginPlaceholder::DidFinishIconRepositionForTestingCallback() {
291 // Set an attribute and post an event, so browser tests can wait for the
292 // placeholder to be ready to receive simulated user input.
293 blink::WebElement element = plugin()->container()->element();
294 element.setAttribute("placeholderReady", "true");
295
296 scoped_ptr<content::V8ValueConverter> converter(
297 content::V8ValueConverter::create());
298 base::StringValue value("placeholderReady");
299 blink::WebSerializedScriptValue message_data =
300 blink::WebSerializedScriptValue::serialize(converter->ToV8Value(
301 &value, element.document().frame()->mainWorldScriptContext()));
302 blink::WebDOMMessageEvent msg_event(message_data);
303
304 element.dispatchEvent(msg_event);
305 }
306
307 void LoadablePluginPlaceholder::SetPluginInfo(
308 const content::WebPluginInfo& plugin_info) {
309 plugin_info_ = plugin_info;
310 }
311
312 const content::WebPluginInfo& LoadablePluginPlaceholder::GetPluginInfo() const {
313 return plugin_info_;
314 }
315
316 void LoadablePluginPlaceholder::SetIdentifier(const std::string& identifier) {
317 identifier_ = identifier;
318 }
319
320 const std::string& LoadablePluginPlaceholder::GetIdentifier() const {
321 return identifier_;
322 }
323
324 bool LoadablePluginPlaceholder::LoadingBlocked() const {
325 DCHECK(allow_loading_);
326 return is_blocked_for_background_tab_ || is_blocked_for_power_saver_poster_ ||
327 is_blocked_for_prerendering_;
328 }
329
330 void LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle() {
331 DCHECK(content::RenderThread::Get());
332 DCHECK(!in_size_recheck_);
333 DCHECK(finished_loading_);
334
335 base::AutoReset<bool> recheck_scope(&in_size_recheck_, true);
336
337 if (!plugin())
338 return;
339
340 gfx::Rect old_rect = unobscured_rect_;
341
342 // Re-check the size in case the reported size was incorrect.
343 plugin()->container()->reportGeometry();
344
345 if (old_rect == unobscured_rect_)
346 return;
193 347
194 float zoom_factor = plugin()->container()->pageZoomFactor(); 348 float zoom_factor = plugin()->container()->pageZoomFactor();
195 int width = roundf(unobscured_rect_.width() / zoom_factor); 349 int width = roundf(unobscured_rect_.width() / zoom_factor);
196 int height = roundf(unobscured_rect_.height() / zoom_factor); 350 int height = roundf(unobscured_rect_.height() / zoom_factor);
197 351
198 if (is_blocked_for_power_saver_poster_) { 352 if (is_blocked_for_power_saver_poster_) {
199 // Adjust poster container padding and dimensions to center play button for 353 // Adjust poster container padding and dimensions to center play button for
200 // plugins and plugin posters that have their top or left portions obscured. 354 // plugins and plugin posters that have their top or left portions obscured.
201 int x = roundf(unobscured_rect_.x() / zoom_factor); 355 int x = roundf(unobscured_rect_.x() / zoom_factor);
202 int y = roundf(unobscured_rect_.y() / zoom_factor); 356 int y = roundf(unobscured_rect_.y() / zoom_factor);
(...skipping 18 matching lines...) Expand all
221 status == 375 status ==
222 content::RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_BIG) { 376 content::RenderFrame::CONTENT_STATUS_ESSENTIAL_CROSS_ORIGIN_BIG) {
223 render_frame()->WhitelistContentOrigin(content_origin); 377 render_frame()->WhitelistContentOrigin(content_origin);
224 } 378 }
225 } 379 }
226 380
227 heuristic_run_before_ = true; 381 heuristic_run_before_ = true;
228 } 382 }
229 } 383 }
230 384
231 void LoadablePluginPlaceholder::WasShown() {
232 if (is_blocked_for_background_tab_) {
233 is_blocked_for_background_tab_ = false;
234 if (!LoadingBlocked())
235 LoadPlugin();
236 }
237 }
238
239 void LoadablePluginPlaceholder::OnLoadBlockedPlugins(
240 const std::string& identifier) {
241 if (!identifier.empty() && identifier != identifier_)
242 return;
243
244 RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_UI"));
245 LoadPlugin();
246 }
247
248 void LoadablePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
249 // Prerendering can only be enabled prior to a RenderView's first navigation,
250 // so no BlockedPlugin should see the notification that enables prerendering.
251 DCHECK(!is_prerendering);
252 if (is_blocked_for_prerendering_) {
253 is_blocked_for_prerendering_ = false;
254 if (!LoadingBlocked())
255 LoadPlugin();
256 }
257 }
258
259 void LoadablePluginPlaceholder::LoadPlugin() {
260 // This is not strictly necessary but is an important defense in case the
261 // event propagation changes between "close" vs. "click-to-play".
262 if (hidden())
263 return;
264 if (!plugin())
265 return;
266 if (!allow_loading_) {
267 NOTREACHED();
268 return;
269 }
270
271 if (premade_throttler_) {
272 premade_throttler_->SetHiddenForPlaceholder(false /* hidden */);
273 ReplacePlugin(premade_throttler_->GetWebPlugin());
274 premade_throttler_ = nullptr;
275 } else {
276 ReplacePlugin(CreatePlugin());
277 }
278 }
279
280 void LoadablePluginPlaceholder::LoadCallback() {
281 RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Click"));
282 // If the user specifically clicks on the plugin content's placeholder,
283 // disable power saver throttling for this instance.
284 MarkPluginEssential(PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK);
285 LoadPlugin();
286 }
287
288 void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
289 finished_loading_ = true;
290 if (message_.length() > 0)
291 UpdateMessage();
292
293 // Wait for the placeholder to finish loading to hide the premade plugin.
294 // This is necessary to prevent a flicker.
295 if (premade_throttler_ && power_saver_enabled_)
296 premade_throttler_->SetHiddenForPlaceholder(true /* hidden */);
297
298 // In case our initial geometry was reported before the placeholder finished
299 // loading, request another one. Needed for correct large poster unthrottling.
300 if (plugin()) {
301 CHECK(plugin()->container());
302 plugin()->container()->reportGeometry();
303 }
304 }
305
306 void LoadablePluginPlaceholder::DidFinishIconRepositionForTestingCallback() {
307 // Set an attribute and post an event, so browser tests can wait for the
308 // placeholder to be ready to receive simulated user input.
309 blink::WebElement element = plugin()->container()->element();
310 element.setAttribute("placeholderReady", "true");
311
312 scoped_ptr<content::V8ValueConverter> converter(
313 content::V8ValueConverter::create());
314 base::StringValue value("placeholderReady");
315 blink::WebSerializedScriptValue message_data =
316 blink::WebSerializedScriptValue::serialize(converter->ToV8Value(
317 &value, element.document().frame()->mainWorldScriptContext()));
318 blink::WebDOMMessageEvent msg_event(message_data);
319
320 element.dispatchEvent(msg_event);
321 }
322
323 void LoadablePluginPlaceholder::SetPluginInfo(
324 const content::WebPluginInfo& plugin_info) {
325 plugin_info_ = plugin_info;
326 }
327
328 const content::WebPluginInfo& LoadablePluginPlaceholder::GetPluginInfo() const {
329 return plugin_info_;
330 }
331
332 void LoadablePluginPlaceholder::SetIdentifier(const std::string& identifier) {
333 identifier_ = identifier;
334 }
335
336 const std::string& LoadablePluginPlaceholder::GetIdentifier() const {
337 return identifier_;
338 }
339
340 bool LoadablePluginPlaceholder::LoadingBlocked() const {
341 DCHECK(allow_loading_);
342 return is_blocked_for_background_tab_ || is_blocked_for_power_saver_poster_ ||
343 is_blocked_for_prerendering_;
344 }
345
346 } // namespace plugins 385 } // namespace plugins
OLDNEW
« no previous file with comments | « components/plugins/renderer/loadable_plugin_placeholder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698