Chromium Code Reviews| Index: content/renderer/pepper/plugin_instance_throttler_impl.cc |
| diff --git a/content/renderer/pepper/plugin_instance_throttler_impl.cc b/content/renderer/pepper/plugin_instance_throttler_impl.cc |
| index f1fe7c4a574bc54933278bd1157ab305b35d705f..21aefbe6ac593d0191cd73c4ed6054404b0014e6 100644 |
| --- a/content/renderer/pepper/plugin_instance_throttler_impl.cc |
| +++ b/content/renderer/pepper/plugin_instance_throttler_impl.cc |
| @@ -7,9 +7,11 @@ |
| #include "base/metrics/histogram.h" |
| #include "base/time/time.h" |
| #include "content/public/common/content_constants.h" |
| -#include "content/public/renderer/render_frame.h" |
| #include "content/public/renderer/render_thread.h" |
| +#include "content/renderer/render_frame_impl.h" |
| +#include "third_party/WebKit/public/platform/WebRect.h" |
| #include "third_party/WebKit/public/web/WebInputEvent.h" |
| +#include "third_party/WebKit/public/web/WebPluginParams.h" |
| #include "ui/gfx/color_utils.h" |
| #include "url/gurl.h" |
| @@ -17,10 +19,6 @@ namespace content { |
| namespace { |
| -// When we give up waiting for a suitable preview frame, and simply suspend |
| -// the plugin where it's at. In milliseconds. |
| -const int kThrottleTimeout = 5000; |
| - |
| // Threshold for 'boring' score to accept a frame as good enough to be a |
| // representative keyframe. Units are the ratio of all pixels that are within |
| // the most common luma bin. The same threshold is used for history thumbnails. |
| @@ -28,21 +26,33 @@ const double kAcceptableFrameMaximumBoringness = 0.94; |
| const int kMinimumConsecutiveInterestingFrames = 4; |
| +const char kPosterParamName[] = "poster"; |
|
piman
2015/02/06 22:13:12
We're exposing this to the web, I think this shoul
tommycli
2015/02/06 22:57:10
Okay I will follow through on this. I will email b
|
| + |
| } // namespace |
| // static |
| -scoped_ptr<PluginInstanceThrottler> PluginInstanceThrottler::Get( |
| - RenderFrame* frame, |
| - const GURL& plugin_url, |
| - PluginPowerSaverMode power_saver_mode) { |
| - if (power_saver_mode == PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL) |
| - return nullptr; |
| - |
| - bool power_saver_enabled = |
| - power_saver_mode == |
| - PluginPowerSaverMode::POWER_SAVER_MODE_PERIPHERAL_THROTTLED; |
| - return make_scoped_ptr( |
| - new PluginInstanceThrottlerImpl(frame, plugin_url, power_saver_enabled)); |
| +const int PluginInstanceThrottlerImpl::kMaximumFramesToExamine = 150; |
| + |
| +// static |
| +scoped_ptr<PluginInstanceThrottler> PluginInstanceThrottler::Create( |
| + bool power_saver_enabled) { |
| + return make_scoped_ptr(new PluginInstanceThrottlerImpl(power_saver_enabled)); |
| +} |
| + |
| +// static |
| +GURL PluginInstanceThrottler::GetPluginInstancePosterImage( |
| + const blink::WebPluginParams& params, |
| + const GURL& page_base_url) { |
| + DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); |
| + |
| + for (size_t i = 0; i < params.attributeNames.size(); ++i) { |
| + if (params.attributeNames[i] == kPosterParamName) { |
| + std::string poster_value(params.attributeValues[i].utf8()); |
| + if (!poster_value.empty()) |
| + return page_base_url.Resolve(poster_value); |
| + } |
| + } |
| + return GURL(); |
| } |
| // static |
| @@ -54,35 +64,18 @@ void PluginInstanceThrottler::RecordUnthrottleMethodMetric( |
| } |
| PluginInstanceThrottlerImpl::PluginInstanceThrottlerImpl( |
| - RenderFrame* frame, |
| - const GURL& plugin_url, |
| bool power_saver_enabled) |
| - : state_(power_saver_enabled ? POWER_SAVER_ENABLED_AWAITING_KEYFRAME |
| - : POWER_SAVER_DISABLED), |
| + : state_(power_saver_enabled ? THROTTLER_STATE_AWAITING_KEYFRAME |
| + : THROTTLER_STATE_POWER_SAVER_DISABLED), |
| is_hidden_for_placeholder_(false), |
| consecutive_interesting_frames_(0), |
| - keyframe_extraction_timed_out_(false), |
| + frames_examined_(0), |
| weak_factory_(this) { |
| - // To collect UMAs, register peripheral content even if power saver disabled. |
| - if (frame) { |
| - frame->RegisterPeripheralPlugin( |
| - plugin_url.GetOrigin(), |
| - base::Bind(&PluginInstanceThrottlerImpl::MarkPluginEssential, |
| - weak_factory_.GetWeakPtr(), UNTHROTTLE_METHOD_BY_WHITELIST)); |
| - } |
| - |
| - if (power_saver_enabled) { |
| - base::MessageLoop::current()->PostDelayedTask( |
| - FROM_HERE, |
| - base::Bind(&PluginInstanceThrottlerImpl::TimeoutKeyframeExtraction, |
| - weak_factory_.GetWeakPtr()), |
| - base::TimeDelta::FromMilliseconds(kThrottleTimeout)); |
| - } |
| } |
| PluginInstanceThrottlerImpl::~PluginInstanceThrottlerImpl() { |
| FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottlerDestroyed()); |
| - if (state_ != PLUGIN_INSTANCE_MARKED_ESSENTIAL) |
| + if (state_ != THROTTLER_STATE_MARKED_ESSENTIAL) |
| RecordUnthrottleMethodMetric(UNTHROTTLE_METHOD_NEVER); |
| } |
| @@ -95,7 +88,7 @@ void PluginInstanceThrottlerImpl::RemoveObserver(Observer* observer) { |
| } |
| bool PluginInstanceThrottlerImpl::IsThrottled() const { |
| - return state_ == POWER_SAVER_ENABLED_PLUGIN_THROTTLED; |
| + return state_ == THROTTLER_STATE_PLUGIN_THROTTLED; |
| } |
| bool PluginInstanceThrottlerImpl::IsHiddenForPlaceholder() const { |
| @@ -104,11 +97,11 @@ bool PluginInstanceThrottlerImpl::IsHiddenForPlaceholder() const { |
| void PluginInstanceThrottlerImpl::MarkPluginEssential( |
| PowerSaverUnthrottleMethod method) { |
| - if (state_ == PLUGIN_INSTANCE_MARKED_ESSENTIAL) |
| + if (state_ == THROTTLER_STATE_MARKED_ESSENTIAL) |
| return; |
| bool was_throttled = IsThrottled(); |
| - state_ = PLUGIN_INSTANCE_MARKED_ESSENTIAL; |
| + state_ = THROTTLER_STATE_MARKED_ESSENTIAL; |
| RecordUnthrottleMethodMetric(method); |
| if (was_throttled) |
| @@ -120,18 +113,49 @@ void PluginInstanceThrottlerImpl::SetHiddenForPlaceholder(bool hidden) { |
| FOR_EACH_OBSERVER(Observer, observer_list_, OnHiddenForPlaceholder(hidden)); |
| } |
| +void PluginInstanceThrottlerImpl::Initialize( |
| + RenderFrameImpl* frame, |
| + const GURL& content_origin, |
| + const std::string& plugin_module_name, |
| + const blink::WebRect& bounds) { |
| + // |frame| may be nullptr in tests. |
| + if (frame) { |
| + PluginPowerSaverHelper* helper = frame->plugin_power_saver_helper(); |
| + bool cross_origin_main_content = false; |
| + if (!helper->ShouldThrottleContent(content_origin, plugin_module_name, |
| + bounds.width, bounds.height, |
| + &cross_origin_main_content)) { |
| + state_ = THROTTLER_STATE_MARKED_ESSENTIAL; |
| + |
| + if (cross_origin_main_content) |
| + helper->WhitelistContentOrigin(content_origin); |
| + |
| + return; |
| + } |
| + |
| + // To collect UMAs, register peripheral content even if power saver mode |
| + // is disabled. |
| + helper->RegisterPeripheralPlugin( |
| + content_origin, |
| + base::Bind(&PluginInstanceThrottlerImpl::MarkPluginEssential, |
| + weak_factory_.GetWeakPtr(), UNTHROTTLE_METHOD_BY_WHITELIST)); |
| + } |
| +} |
| + |
| void PluginInstanceThrottlerImpl::OnImageFlush(const SkBitmap* bitmap) { |
| DCHECK(needs_representative_keyframe()); |
| if (!bitmap) |
| return; |
| + ++frames_examined_; |
| + |
| double boring_score = color_utils::CalculateBoringScore(*bitmap); |
| if (boring_score <= kAcceptableFrameMaximumBoringness) |
| ++consecutive_interesting_frames_; |
| else |
| consecutive_interesting_frames_ = 0; |
| - if (keyframe_extraction_timed_out_ || |
| + if (frames_examined_ >= kMaximumFramesToExamine || |
| consecutive_interesting_frames_ >= kMinimumConsecutiveInterestingFrames) { |
| FOR_EACH_OBSERVER(Observer, observer_list_, OnKeyframeExtracted(bitmap)); |
| EngageThrottle(); |
| @@ -147,7 +171,7 @@ bool PluginInstanceThrottlerImpl::ConsumeInputEvent( |
| if (event.modifiers & blink::WebInputEvent::Modifiers::RightButtonDown) |
| return false; |
| - if (state_ != PLUGIN_INSTANCE_MARKED_ESSENTIAL && |
| + if (state_ != THROTTLER_STATE_MARKED_ESSENTIAL && |
| event.type == blink::WebInputEvent::MouseUp && |
| (event.modifiers & blink::WebInputEvent::LeftButtonDown)) { |
| bool was_throttled = IsThrottled(); |
| @@ -159,15 +183,11 @@ bool PluginInstanceThrottlerImpl::ConsumeInputEvent( |
| } |
| void PluginInstanceThrottlerImpl::EngageThrottle() { |
| - if (state_ != POWER_SAVER_ENABLED_AWAITING_KEYFRAME) |
| + if (state_ != THROTTLER_STATE_AWAITING_KEYFRAME) |
| return; |
| - state_ = POWER_SAVER_ENABLED_PLUGIN_THROTTLED; |
| + state_ = THROTTLER_STATE_PLUGIN_THROTTLED; |
| FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); |
| } |
| -void PluginInstanceThrottlerImpl::TimeoutKeyframeExtraction() { |
| - keyframe_extraction_timed_out_ = true; |
| -} |
| - |
| } // namespace content |