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

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

Issue 707113002: Plugin Power Saver: Refactor Plugin Instance Throttling code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@0190-plugin-power-saver-add-some-umas
Patch Set: Created 6 years, 1 month 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/pepper_plugin_instance_throttler.h" 5 #include "content/renderer/pepper/pepper_plugin_instance_throttler.h"
6 6
7 #include "base/command_line.h"
7 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h"
10 #include "base/metrics/sparse_histogram.h"
8 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "content/public/common/content_constants.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
15 #include "content/renderer/pepper/plugin_module.h"
16 #include "content/renderer/pepper/plugin_power_saver_helper.h"
17 #include "content/renderer/render_frame_impl.h"
18 #include "content/renderer/render_thread_impl.h"
19 #include "third_party/WebKit/public/platform/WebRect.h"
20 #include "third_party/WebKit/public/web/WebElement.h"
21 #include "third_party/WebKit/public/web/WebInputEvent.h"
22 #include "third_party/WebKit/public/web/WebPluginContainer.h"
9 23
10 namespace content { 24 namespace content {
11 25
12 namespace { 26 namespace {
13 27
28 static const int kInfiniteRatio = 99999;
29
30 #define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) \
31 UMA_HISTOGRAM_SPARSE_SLOWLY( \
32 name, (height) ? ((width)*100) / (height) : kInfiniteRatio);
33
34 // Histogram tracking prevalence of tiny Flash instances. Units in pixels.
35 enum PluginFlashTinyContentSize {
36 TINY_CONTENT_SIZE_1_1 = 0,
37 TINY_CONTENT_SIZE_5_5 = 1,
38 TINY_CONTENT_SIZE_10_10 = 2,
39 TINY_CONTENT_SIZE_LARGE = 3,
40 TINY_CONTENT_SIZE_NUM_ITEMS
41 };
42
43 // How the throttled power saver is unthrottled, if ever.
44 // These numeric values are used in UMA logs; do not change them.
45 enum PowerSaverUnthrottleMethod {
46 UNTHROTTLE_METHOD_NEVER = 0,
47 UNTHROTTLE_METHOD_BY_CLICK = 1,
48 UNTHROTTLE_METHOD_BY_WHITELIST = 2,
49 UNTHROTTLE_METHOD_NUM_ITEMS
50 };
51
14 // When we give up waiting for a suitable preview frame, and simply suspend 52 // When we give up waiting for a suitable preview frame, and simply suspend
15 // the plugin where it's at. In milliseconds. 53 // the plugin where it's at. In milliseconds.
16 const int kThrottleTimeout = 5000; 54 const int kThrottleTimeout = 5000;
55
56 const char kFlashClickSizeAspectRatioHistogram[] =
57 "Plugin.Flash.ClickSize.AspectRatio";
58 const char kFlashClickSizeHeightHistogram[] = "Plugin.Flash.ClickSize.Height";
59 const char kFlashClickSizeWidthHistogram[] = "Plugin.Flash.ClickSize.Width";
60 const char kFlashTinyContentSizeHistogram[] = "Plugin.Flash.TinyContentSize";
61 const char kPowerSaverUnthrottleHistogram[] = "Plugin.PowerSaver.Unthrottle";
62
63 // Record size metrics for all Flash instances.
64 void RecordFlashSizeMetric(int width, int height) {
65 PluginFlashTinyContentSize size = TINY_CONTENT_SIZE_LARGE;
66
67 if (width <= 1 && height <= 1)
68 size = TINY_CONTENT_SIZE_1_1;
69 else if (width <= 5 && height <= 5)
70 size = TINY_CONTENT_SIZE_5_5;
71 else if (width <= 10 && height <= 10)
72 size = TINY_CONTENT_SIZE_10_10;
73
74 UMA_HISTOGRAM_ENUMERATION(kFlashTinyContentSizeHistogram, size,
75 TINY_CONTENT_SIZE_NUM_ITEMS);
76 }
77
78 void RecordUnthrottleMethodMetric(PowerSaverUnthrottleMethod method) {
79 UMA_HISTOGRAM_ENUMERATION(kPowerSaverUnthrottleHistogram, method,
80 UNTHROTTLE_METHOD_NUM_ITEMS);
81 }
82
83 // Records size metrics for Flash instances that are clicked.
84 void RecordFlashClickSizeMetric(int width, int height) {
85 base::HistogramBase* width_histogram = base::LinearHistogram::FactoryGet(
86 kFlashClickSizeWidthHistogram,
87 0, // minimum width
88 500, // maximum width
89 100, // number of buckets.
90 base::HistogramBase::kUmaTargetedHistogramFlag);
91 width_histogram->Add(width);
92
93 base::HistogramBase* height_histogram = base::LinearHistogram::FactoryGet(
94 kFlashClickSizeHeightHistogram,
95 0, // minimum height
96 400, // maximum height
97 100, // number of buckets.
98 base::HistogramBase::kUmaTargetedHistogramFlag);
99 height_histogram->Add(height);
100
101 UMA_HISTOGRAM_ASPECT_RATIO(kFlashClickSizeAspectRatioHistogram, width,
102 height);
103 }
104
105 bool IsFlashPlugin(PluginModule* module) {
106 return module->name() == kFlashPluginName;
107 }
17 } 108 }
18 109
19 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler( 110 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler(
20 const base::Closure& throttle_closure) { 111 PepperPluginInstanceImpl* instance,
raymes 2014/11/12 06:38:20 It looks like if we pass in: -The PluginPowerSaver
tommycli 2014/11/12 21:18:14 Done.
21 DCHECK(!throttle_closure.is_null()); 112 const base::Closure& throttle_change_callback)
22 base::MessageLoop::current()->PostDelayedTask( 113 : instance_(instance),
23 FROM_HERE, throttle_closure, 114 throttle_change_callback_(throttle_change_callback),
24 base::TimeDelta::FromMilliseconds(kThrottleTimeout)); 115 has_been_clicked_(false),
116 power_saver_enabled_(false),
117 is_peripheral_content_(false),
118 plugin_throttled_(false),
119 weak_factory_(this) {
120 DCHECK(instance);
121
122 PluginPowerSaverHelper* power_saver_helper =
123 instance->render_frame()->plugin_power_saver_helper();
124 GURL content_origin = instance->GetPluginURL().GetOrigin();
125 blink::WebRect bounds =
126 instance->container()->element().boundsInViewportSpace();
127
128 if (IsFlashPlugin(instance->module())) {
129 RenderThread::Get()->RecordAction(
130 base::UserMetricsAction("Flash.PluginInstanceCreated"));
131 RecordFlashSizeMetric(bounds.width, bounds.height);
132 }
133
134 bool cross_origin = false;
135 is_peripheral_content_ =
136 IsFlashPlugin(instance->module()) &&
137 power_saver_helper->ShouldThrottleContent(content_origin, bounds.width,
138 bounds.height, &cross_origin);
139
140 power_saver_enabled_ = is_peripheral_content_ &&
141 base::CommandLine::ForCurrentProcess()->HasSwitch(
142 switches::kEnablePluginPowerSaver);
143
144 if (is_peripheral_content_) {
145 // To collect UMAs, register peripheral content even if we don't throttle.
146 power_saver_helper->RegisterPeripheralPlugin(
147 content_origin, base::Bind(&PepperPluginInstanceThrottler::
148 DisablePowerSaverByRetroactiveWhitelist,
149 weak_factory_.GetWeakPtr()));
150
151 if (power_saver_enabled_) {
152 base::MessageLoop::current()->PostDelayedTask(
153 FROM_HERE,
154 base::Bind(&PepperPluginInstanceThrottler::SetPluginThrottled,
155 weak_factory_.GetWeakPtr(), true /* throttled */),
156 base::TimeDelta::FromMilliseconds(kThrottleTimeout));
157 }
158 } else if (cross_origin) {
159 power_saver_helper->WhitelistContentOrigin(content_origin);
160 }
161 }
162
163 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler(
raymes 2014/11/12 06:38:20 It's better to avoid having a separate constructor
tommycli 2014/11/12 21:18:14 Done.
164 const base::Closure& throttle_change_callback,
165 bool power_saver_enabled,
166 bool is_peripheral_content)
167 : instance_(NULL),
168 throttle_change_callback_(throttle_change_callback),
169 has_been_clicked_(false),
170 power_saver_enabled_(power_saver_enabled),
171 is_peripheral_content_(is_peripheral_content),
172 plugin_throttled_(false),
173 weak_factory_(this) {
25 } 174 }
26 175
27 PepperPluginInstanceThrottler::~PepperPluginInstanceThrottler() { 176 PepperPluginInstanceThrottler::~PepperPluginInstanceThrottler() {
28 } 177 }
29 178
179 bool PepperPluginInstanceThrottler::ConsumeInputEvent(
180 const blink::WebInputEvent& event) {
181 if (instance_ && IsFlashPlugin(instance_->module()) &&
182 event.type == blink::WebInputEvent::MouseDown && !has_been_clicked_) {
183 has_been_clicked_ = true;
184 blink::WebRect bounds =
185 instance_->container()->element().boundsInViewportSpace();
186 RecordFlashClickSizeMetric(bounds.width, bounds.height);
187 }
188
189 if (event.type == blink::WebInputEvent::MouseUp && is_peripheral_content_) {
190 is_peripheral_content_ = false;
191 power_saver_enabled_ = false;
192
193 RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_BY_CLICK);
194
195 if (plugin_throttled_) {
196 SetPluginThrottled(false /* throttled */);
197 return true;
198 }
199 }
200
201 return false;
202 }
203
204 void PepperPluginInstanceThrottler::SetPluginThrottled(bool throttled) {
205 // Do not throttle if we've already disabled power saver.
206 if (!power_saver_enabled_ && throttled)
207 return;
208
209 plugin_throttled_ = throttled;
210 throttle_change_callback_.Run();
211 }
212
213 void PepperPluginInstanceThrottler::DisablePowerSaverByRetroactiveWhitelist() {
214 if (!is_peripheral_content_)
215 return;
216
217 is_peripheral_content_ = false;
218 power_saver_enabled_ = false;
219 SetPluginThrottled(false);
220
221 RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_BY_WHITELIST);
222 }
223
30 } // namespace content 224 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698