Chromium Code Reviews| Index: content/renderer/pepper/plugin_power_saver_helper.cc |
| diff --git a/content/renderer/pepper/plugin_power_saver_helper.cc b/content/renderer/pepper/plugin_power_saver_helper.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ed20a658d864a893a1182f916a12e0472242556c |
| --- /dev/null |
| +++ b/content/renderer/pepper/plugin_power_saver_helper.cc |
| @@ -0,0 +1,128 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/callback.h" |
| +#include "content/common/frame_messages.h" |
| +#include "content/public/renderer/document_state.h" |
| +#include "content/public/renderer/navigation_state.h" |
| +#include "content/public/renderer/render_frame.h" |
| +#include "content/renderer/pepper/plugin_power_saver_helper.h" |
| +#include "third_party/WebKit/public/web/WebDocument.h" |
| +#include "third_party/WebKit/public/web/WebLocalFrame.h" |
| +#include "third_party/WebKit/public/web/WebView.h" |
| + |
| +namespace content { |
| + |
| +namespace { |
| + |
| +// Maximum dimensions plug-in content may have while still being considered |
| +// peripheral content. These match the sizes used by Safari. |
| +const int kPeripheralContentMaxWidth = 400; |
| +const int kPeripheralContentMaxHeight = 300; |
| + |
| +} // namespace |
| + |
| +PluginPowerSaverHelper::PeripheralPlugin::PeripheralPlugin( |
| + const GURL& content_origin, |
| + const base::Closure& unthrottle_callback) |
| + : content_origin(content_origin), unthrottle_callback(unthrottle_callback) { |
| +} |
| + |
| +PluginPowerSaverHelper::PeripheralPlugin::~PeripheralPlugin() { |
| +} |
| + |
| +PluginPowerSaverHelper::PluginPowerSaverHelper(RenderFrame* render_frame) |
| + : RenderFrameObserver(render_frame) { |
| +} |
| + |
| +PluginPowerSaverHelper::~PluginPowerSaverHelper() { |
| +} |
| + |
| +void PluginPowerSaverHelper::DidCommitProvisionalLoad(bool is_new_navigation) { |
| + blink::WebFrame* frame = render_frame()->GetWebFrame(); |
| + if (frame->parent()) |
| + return; // Not a top-level navigation. |
| + |
| + DocumentState* document_state = |
| + DocumentState::FromDataSource(frame->dataSource()); |
| + NavigationState* navigation_state = document_state->navigation_state(); |
| + if (!navigation_state->was_within_same_page()) |
| + origin_whitelist_.clear(); |
| +} |
| + |
| +bool PluginPowerSaverHelper::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PluginPowerSaverHelper, message) |
| + IPC_MESSAGE_HANDLER(FrameMsg_UpdatePluginContentOriginWhitelist, |
| + OnUpdatePluginContentOriginWhitelist) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void PluginPowerSaverHelper::OnUpdatePluginContentOriginWhitelist( |
| + const std::set<GURL>& origin_whitelist) { |
| + origin_whitelist_ = origin_whitelist; |
| + |
| + // Check throttled plugin instances to see if any can be unthrottled. |
| + auto it = peripheral_plugins_.begin(); |
| + while (it != peripheral_plugins_.end()) { |
| + if (origin_whitelist.count(it->content_origin)) { |
| + it->unthrottle_callback.Run(); |
| + it = peripheral_plugins_.erase(it); |
| + } else { |
| + ++it; |
| + } |
| + } |
| +} |
| + |
| +bool PluginPowerSaverHelper::ShouldThrottleContent(const GURL& content_origin, |
| + int width, |
| + int height, |
| + bool* cross_origin) const { |
| + DCHECK(cross_origin); |
| + *cross_origin = true; |
| + |
| + // TODO(alexmos): Update this to use the origin of the RemoteFrame when 426512 |
| + // is fixed. For now, case 3 in the comment above doesn't work in |
|
Charlie Reis
2014/10/30 22:13:16
nit: comment above -> class level comment
tommycli
2014/10/31 00:01:22
Done.
|
| + // --site-per-process mode. |
| + blink::WebFrame* main_frame = |
| + render_frame()->GetWebFrame()->view()->mainFrame(); |
| + if (main_frame->isWebRemoteFrame()) |
| + return true; |
| + |
| + // All same-origin plugin content is essential. |
| + GURL main_frame_origin = GURL(main_frame->document().url()).GetOrigin(); |
| + if (content_origin == main_frame_origin) { |
| + *cross_origin = false; |
| + return false; |
| + } |
| + |
| + // Whitelisted plugin origins are also essential. |
| + if (origin_whitelist_.count(content_origin)) |
| + return false; |
| + |
| + // Cross-origin plugin content is peripheral if smaller than a maximum size. |
| + bool content_is_small = width < kPeripheralContentMaxWidth || |
| + height < kPeripheralContentMaxHeight; |
| + |
| + return content_is_small; |
| +} |
| + |
| +void PluginPowerSaverHelper::RegisterPeripheralPlugin( |
| + const GURL& content_origin, |
| + const base::Closure& unthrottle_callback) { |
| + peripheral_plugins_.push_back( |
| + PeripheralPlugin(content_origin, unthrottle_callback)); |
| +} |
| + |
| +void PluginPowerSaverHelper::WhitelistContentOrigin( |
| + const GURL& content_origin) { |
| + if (origin_whitelist_.insert(content_origin).second) { |
| + Send(new FrameHostMsg_PluginContentOriginAllowed( |
| + render_frame()->GetRoutingID(), content_origin)); |
| + } |
| +} |
| + |
| +} // namespace content |