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

Side by Side Diff: content/renderer/pepper/plugin_power_saver_helper.cc

Issue 904913003: Plugin Power Saver: Fix implicitly sized and below the fold plugins. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
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 "content/renderer/pepper/plugin_power_saver_helper.h" 5 #include "content/renderer/pepper/plugin_power_saver_helper.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "content/common/frame_messages.h" 9 #include "content/common/frame_messages.h"
10 #include "content/public/common/content_constants.h"
10 #include "content/public/renderer/document_state.h" 11 #include "content/public/renderer/document_state.h"
11 #include "content/public/renderer/navigation_state.h" 12 #include "content/public/renderer/navigation_state.h"
12 #include "content/public/renderer/render_frame.h" 13 #include "content/public/renderer/render_frame.h"
13 #include "third_party/WebKit/public/web/WebDocument.h" 14 #include "third_party/WebKit/public/web/WebDocument.h"
14 #include "third_party/WebKit/public/web/WebLocalFrame.h" 15 #include "third_party/WebKit/public/web/WebLocalFrame.h"
15 #include "third_party/WebKit/public/web/WebPluginParams.h" 16 #include "third_party/WebKit/public/web/WebPluginParams.h"
16 #include "third_party/WebKit/public/web/WebView.h" 17 #include "third_party/WebKit/public/web/WebView.h"
17 18
18 namespace content { 19 namespace content {
19 20
20 namespace { 21 namespace {
21 22
22 const char kPosterParamName[] = "poster";
23
24 // Initial decision of the peripheral content decision. 23 // Initial decision of the peripheral content decision.
25 // These numeric values are used in UMA logs; do not change them. 24 // These numeric values are used in UMA logs; do not change them.
26 enum PeripheralHeuristicDecision { 25 enum PeripheralHeuristicDecision {
27 HEURISTIC_DECISION_PERIPHERAL = 0, 26 HEURISTIC_DECISION_PERIPHERAL = 0,
28 HEURISTIC_DECISION_ESSENTIAL_SAME_ORIGIN = 1, 27 HEURISTIC_DECISION_ESSENTIAL_SAME_ORIGIN = 1,
29 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_BIG = 2, 28 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_BIG = 2,
30 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_WHITELISTED = 3, 29 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_WHITELISTED = 3,
31 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_TINY = 4, 30 HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_TINY = 4,
32 HEURISTIC_DECISION_NUM_ITEMS 31 HEURISTIC_DECISION_NUM_ITEMS
33 }; 32 };
34 33
35 const char kPeripheralHeuristicHistogram[] = 34 const char kPeripheralHeuristicHistogram[] =
36 "Plugin.PowerSaver.PeripheralHeuristic"; 35 "Plugin.PowerSaver.PeripheralHeuristic";
37 36
38 // Maximum dimensions plug-in content may have while still being considered 37 // Maximum dimensions plug-in content may have while still being considered
39 // peripheral content. These match the sizes used by Safari. 38 // peripheral content. These match the sizes used by Safari.
40 const int kPeripheralContentMaxWidth = 400; 39 const int kPeripheralContentMaxWidth = 400;
41 const int kPeripheralContentMaxHeight = 300; 40 const int kPeripheralContentMaxHeight = 300;
42 41
43 // Plug-in content below this size in height and width is considered "tiny". 42 // Plug-in content below this size in height and width is considered "tiny".
44 // Tiny content is never peripheral, as tiny plug-ins often serve a critical 43 // Tiny content is never peripheral, as tiny plug-ins often serve a critical
45 // purpose, and the user often cannot find and click to unthrottle it. 44 // purpose, and the user often cannot find and click to unthrottle it.
46 const int kPeripheralContentTinySize = 5; 45 const int kPeripheralContentTinySize = 5;
47 46
48 void RecordDecisionMetric(PeripheralHeuristicDecision decision) { 47 void RecordDecisionMetric(PeripheralHeuristicDecision decision) {
49 UMA_HISTOGRAM_ENUMERATION(kPeripheralHeuristicHistogram, decision, 48 UMA_HISTOGRAM_ENUMERATION(kPeripheralHeuristicHistogram, decision,
50 HEURISTIC_DECISION_NUM_ITEMS); 49 HEURISTIC_DECISION_NUM_ITEMS);
51 } 50 }
52 51
53 const char kWebPluginParamHeight[] = "height";
54 const char kWebPluginParamWidth[] = "width";
55
56 // Returns true if valid non-negative height and width extracted.
57 // When this returns false, |width| and |height| are set to undefined values.
58 bool ExtractDimensions(const blink::WebPluginParams& params,
59 int* width,
60 int* height) {
61 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
62 DCHECK(width);
63 DCHECK(height);
64 bool width_extracted = false;
65 bool height_extracted = false;
66 for (size_t i = 0; i < params.attributeNames.size(); ++i) {
67 if (params.attributeNames[i].utf8() == kWebPluginParamWidth) {
68 width_extracted =
69 base::StringToInt(params.attributeValues[i].utf8(), width);
70 } else if (params.attributeNames[i].utf8() == kWebPluginParamHeight) {
71 height_extracted =
72 base::StringToInt(params.attributeValues[i].utf8(), height);
73 }
74 }
75 return width_extracted && height_extracted && *width >= 0 && *height >= 0;
76 }
77
78 GURL GetPluginInstancePosterImage(const blink::WebPluginParams& params,
79 const GURL& page_base_url) {
80 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
81
82 for (size_t i = 0; i < params.attributeNames.size(); ++i) {
83 if (params.attributeNames[i] == kPosterParamName) {
84 std::string poster_value(params.attributeValues[i].utf8());
85 if (!poster_value.empty())
86 return page_base_url.Resolve(poster_value);
87 }
88 }
89 return GURL();
90 }
91
92 } // namespace 52 } // namespace
93 53
94 PluginPowerSaverHelper::PeripheralPlugin::PeripheralPlugin( 54 PluginPowerSaverHelper::PeripheralPlugin::PeripheralPlugin(
95 const GURL& content_origin, 55 const GURL& content_origin,
96 const base::Closure& unthrottle_callback) 56 const base::Closure& unthrottle_callback)
97 : content_origin(content_origin), unthrottle_callback(unthrottle_callback) { 57 : content_origin(content_origin), unthrottle_callback(unthrottle_callback) {
98 } 58 }
99 59
100 PluginPowerSaverHelper::PeripheralPlugin::~PeripheralPlugin() { 60 PluginPowerSaverHelper::PeripheralPlugin::~PeripheralPlugin() {
101 } 61 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 it = peripheral_plugins_.erase(it); 101 it = peripheral_plugins_.erase(it);
142 } else { 102 } else {
143 ++it; 103 ++it;
144 } 104 }
145 } 105 }
146 } 106 }
147 107
148 void PluginPowerSaverHelper::RegisterPeripheralPlugin( 108 void PluginPowerSaverHelper::RegisterPeripheralPlugin(
149 const GURL& content_origin, 109 const GURL& content_origin,
150 const base::Closure& unthrottle_callback) { 110 const base::Closure& unthrottle_callback) {
111 DCHECK_EQ(content_origin.GetOrigin(), content_origin);
151 peripheral_plugins_.push_back( 112 peripheral_plugins_.push_back(
152 PeripheralPlugin(content_origin, unthrottle_callback)); 113 PeripheralPlugin(content_origin, unthrottle_callback));
153 } 114 }
154 115
155 bool PluginPowerSaverHelper::ShouldThrottleContent( 116 bool PluginPowerSaverHelper::ShouldThrottleContent(
156 const blink::WebPluginParams& params, 117 const GURL& content_origin,
157 const GURL& plugin_frame_url, 118 const std::string& plugin_module_name,
158 GURL* poster_image, 119 int width,
120 int height,
159 bool* cross_origin_main_content) const { 121 bool* cross_origin_main_content) const {
160 if (poster_image) 122 DCHECK_EQ(content_origin.GetOrigin(), content_origin);
161 *poster_image = GURL();
162 if (cross_origin_main_content) 123 if (cross_origin_main_content)
163 *cross_origin_main_content = false; 124 *cross_origin_main_content = false;
164 125
165 GURL content_origin = GURL(params.url).GetOrigin(); 126 // This feature has only been tested throughly with Flash thus far.
127 if (plugin_module_name != content::kFlashPluginName)
128 return false;
166 129
167 int width = 0; 130 if (width <= 0 || height <= 0)
168 int height = 0;
169 if (!ExtractDimensions(params, &width, &height))
170 return false; 131 return false;
171 132
172 // TODO(alexmos): Update this to use the origin of the RemoteFrame when 426512 133 // TODO(alexmos): Update this to use the origin of the RemoteFrame when 426512
173 // is fixed. For now, case 3 in the class level comment doesn't work in 134 // is fixed. For now, case 3 in the class level comment doesn't work in
174 // --site-per-process mode. 135 // --site-per-process mode.
175 blink::WebFrame* main_frame = 136 blink::WebFrame* main_frame =
176 render_frame()->GetWebFrame()->view()->mainFrame(); 137 render_frame()->GetWebFrame()->view()->mainFrame();
177 if (main_frame->isWebRemoteFrame()) { 138 if (main_frame->isWebRemoteFrame()) {
178 RecordDecisionMetric(HEURISTIC_DECISION_PERIPHERAL); 139 RecordDecisionMetric(HEURISTIC_DECISION_PERIPHERAL);
179 if (poster_image)
180 *poster_image = GetPluginInstancePosterImage(params, plugin_frame_url);
181 return true; 140 return true;
182 } 141 }
183 142
184 // All same-origin plugin content is essential. 143 // All same-origin plugin content is essential.
185 GURL main_frame_origin = GURL(main_frame->document().url()).GetOrigin(); 144 GURL main_frame_origin = GURL(main_frame->document().url()).GetOrigin();
186 if (content_origin == main_frame_origin) { 145 if (content_origin == main_frame_origin) {
187 RecordDecisionMetric(HEURISTIC_DECISION_ESSENTIAL_SAME_ORIGIN); 146 RecordDecisionMetric(HEURISTIC_DECISION_ESSENTIAL_SAME_ORIGIN);
188 return false; 147 return false;
189 } 148 }
190 149
(...skipping 13 matching lines...) Expand all
204 // Plugin content large in both dimensions are the "main attraction". 163 // Plugin content large in both dimensions are the "main attraction".
205 if (width >= kPeripheralContentMaxWidth && 164 if (width >= kPeripheralContentMaxWidth &&
206 height >= kPeripheralContentMaxHeight) { 165 height >= kPeripheralContentMaxHeight) {
207 RecordDecisionMetric(HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_BIG); 166 RecordDecisionMetric(HEURISTIC_DECISION_ESSENTIAL_CROSS_ORIGIN_BIG);
208 if (cross_origin_main_content) 167 if (cross_origin_main_content)
209 *cross_origin_main_content = true; 168 *cross_origin_main_content = true;
210 return false; 169 return false;
211 } 170 }
212 171
213 RecordDecisionMetric(HEURISTIC_DECISION_PERIPHERAL); 172 RecordDecisionMetric(HEURISTIC_DECISION_PERIPHERAL);
214 if (poster_image)
215 *poster_image = GetPluginInstancePosterImage(params, plugin_frame_url);
216 return true; 173 return true;
217 } 174 }
218 175
219 void PluginPowerSaverHelper::WhitelistContentOrigin( 176 void PluginPowerSaverHelper::WhitelistContentOrigin(
220 const GURL& content_origin) { 177 const GURL& content_origin) {
221 DCHECK_EQ(content_origin.GetOrigin(), content_origin); 178 DCHECK_EQ(content_origin.GetOrigin(), content_origin);
222 if (origin_whitelist_.insert(content_origin).second) { 179 if (origin_whitelist_.insert(content_origin).second) {
223 Send(new FrameHostMsg_PluginContentOriginAllowed( 180 Send(new FrameHostMsg_PluginContentOriginAllowed(
224 render_frame()->GetRoutingID(), content_origin)); 181 render_frame()->GetRoutingID(), content_origin));
225 } 182 }
226 } 183 }
227 184
228 } // namespace content 185 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/pepper/plugin_power_saver_helper.h ('k') | content/renderer/pepper/plugin_power_saver_helper_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698