OLD | NEW |
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" |
8 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| 11 #include "content/public/common/content_constants.h" |
| 12 #include "content/public/common/content_switches.h" |
| 13 #include "content/renderer/pepper/plugin_module.h" |
| 14 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
| 15 #include "content/renderer/pepper/plugin_power_saver_helper.h" |
| 16 #include "content/renderer/render_frame_impl.h" |
| 17 #include "third_party/WebKit/public/platform/WebRect.h" |
| 18 #include "third_party/WebKit/public/web/WebElement.h" |
| 19 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 20 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
9 | 21 |
10 namespace content { | 22 namespace content { |
11 | 23 |
12 namespace { | 24 namespace { |
13 | 25 |
| 26 // How the throttled power saver is unthrottled, if ever. |
| 27 // These numeric values are used in UMA logs; do not change them. |
| 28 enum PowerSaverUnthrottleMethod { |
| 29 UNTHROTTLE_METHOD_NEVER = 0, |
| 30 UNTHROTTLE_METHOD_BY_CLICK = 1, |
| 31 UNTHROTTLE_METHOD_BY_WHITELIST = 2, |
| 32 UNTHROTTLE_METHOD_NUM_ITEMS |
| 33 }; |
| 34 |
14 // When we give up waiting for a suitable preview frame, and simply suspend | 35 // When we give up waiting for a suitable preview frame, and simply suspend |
15 // the plugin where it's at. In milliseconds. | 36 // the plugin where it's at. In milliseconds. |
16 const int kThrottleTimeout = 5000; | 37 const int kThrottleTimeout = 5000; |
| 38 |
| 39 const char kPowerSaverUnthrottleHistogram[] = "Plugin.PowerSaverUnthrottle"; |
| 40 |
| 41 void RecordUnthrottleMethodMetric(PowerSaverUnthrottleMethod method) { |
| 42 UMA_HISTOGRAM_ENUMERATION(kPowerSaverUnthrottleHistogram, method, |
| 43 UNTHROTTLE_METHOD_NUM_ITEMS); |
| 44 } |
17 } | 45 } |
18 | 46 |
19 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler( | 47 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler( |
20 const base::Closure& throttle_closure) { | 48 PepperPluginInstanceImpl* instance, |
21 DCHECK(!throttle_closure.is_null()); | 49 const base::Closure& throttle_change_callback) |
22 base::MessageLoop::current()->PostDelayedTask( | 50 : throttle_change_callback_(throttle_change_callback), |
23 FROM_HERE, throttle_closure, | 51 power_saver_enabled_(false), |
24 base::TimeDelta::FromMilliseconds(kThrottleTimeout)); | 52 is_peripheral_content_(false), |
| 53 plugin_throttled_(false), |
| 54 weak_factory_(this) { |
| 55 DCHECK(instance); |
| 56 |
| 57 PluginPowerSaverHelper* power_saver_helper = |
| 58 instance->render_frame()->plugin_power_saver_helper(); |
| 59 GURL content_origin = instance->GetPluginURL().GetOrigin(); |
| 60 blink::WebRect bounds = |
| 61 instance->container()->element().boundsInViewportSpace(); |
| 62 |
| 63 bool cross_origin = false; |
| 64 is_peripheral_content_ = |
| 65 instance->module()->name() == kFlashPluginName && |
| 66 power_saver_helper->ShouldThrottleContent(content_origin, bounds.width, |
| 67 bounds.height, &cross_origin); |
| 68 |
| 69 power_saver_enabled_ = is_peripheral_content_ && |
| 70 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 71 switches::kEnablePluginPowerSaver); |
| 72 |
| 73 if (is_peripheral_content_) { |
| 74 // To collect UMAs, register peripheral content even if we don't throttle. |
| 75 power_saver_helper->RegisterPeripheralPlugin( |
| 76 content_origin, base::Bind(&PepperPluginInstanceThrottler:: |
| 77 DisablePowerSaverByRetroactiveWhitelist, |
| 78 weak_factory_.GetWeakPtr())); |
| 79 |
| 80 if (power_saver_enabled_) { |
| 81 base::MessageLoop::current()->PostDelayedTask( |
| 82 FROM_HERE, |
| 83 base::Bind(&PepperPluginInstanceThrottler::SetPluginThrottled, |
| 84 weak_factory_.GetWeakPtr(), true /* throttled */), |
| 85 base::TimeDelta::FromMilliseconds(kThrottleTimeout)); |
| 86 } |
| 87 } else if (cross_origin) { |
| 88 power_saver_helper->WhitelistContentOrigin(content_origin); |
| 89 } |
25 } | 90 } |
26 | 91 |
| 92 PepperPluginInstanceThrottler::PepperPluginInstanceThrottler( |
| 93 const base::Closure& throttle_change_callback, |
| 94 bool power_saver_enabled, |
| 95 bool is_peripheral_content) |
| 96 : throttle_change_callback_(throttle_change_callback), |
| 97 power_saver_enabled_(power_saver_enabled), |
| 98 is_peripheral_content_(is_peripheral_content), |
| 99 plugin_throttled_(false), |
| 100 weak_factory_(this) {} |
| 101 |
27 PepperPluginInstanceThrottler::~PepperPluginInstanceThrottler() { | 102 PepperPluginInstanceThrottler::~PepperPluginInstanceThrottler() { |
28 } | 103 } |
29 | 104 |
| 105 bool PepperPluginInstanceThrottler::ConsumeInputEvent( |
| 106 const blink::WebInputEvent& event) { |
| 107 if (event.type == blink::WebInputEvent::MouseUp && is_peripheral_content_) { |
| 108 is_peripheral_content_ = false; |
| 109 power_saver_enabled_ = false; |
| 110 |
| 111 RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_BY_CLICK); |
| 112 |
| 113 if (plugin_throttled_) { |
| 114 SetPluginThrottled(false /* throttled */); |
| 115 return true; |
| 116 } |
| 117 } |
| 118 |
| 119 return false; |
| 120 } |
| 121 |
| 122 void PepperPluginInstanceThrottler::SetPluginThrottled(bool throttled) { |
| 123 // Do not throttle if we've already disabled power saver. |
| 124 if (!power_saver_enabled_ && throttled) |
| 125 return; |
| 126 |
| 127 plugin_throttled_ = throttled; |
| 128 throttle_change_callback_.Run(); |
| 129 } |
| 130 |
| 131 void PepperPluginInstanceThrottler::DisablePowerSaverByRetroactiveWhitelist() { |
| 132 if (!is_peripheral_content_) |
| 133 return; |
| 134 |
| 135 is_peripheral_content_ = false; |
| 136 power_saver_enabled_ = false; |
| 137 SetPluginThrottled(false); |
| 138 |
| 139 RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_BY_WHITELIST); |
| 140 } |
| 141 |
30 } // namespace content | 142 } // namespace content |
OLD | NEW |