// 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. #ifndef CONTENT_RENDERER_PEPPER_PLUGIN_INSTANCE_THROTTLER_IMPL_H_ #define CONTENT_RENDERER_PEPPER_PLUGIN_INSTANCE_THROTTLER_IMPL_H_ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/timer/timer.h" #include "content/common/content_export.h" #include "content/public/renderer/plugin_instance_throttler.h" #include "content/renderer/pepper/pepper_webplugin_impl.h" #include "ppapi/shared_impl/ppb_view_shared.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" namespace blink { class WebInputEvent; } namespace url { class Origin; } namespace content { class PepperWebPluginImpl; class RenderFrameImpl; class CONTENT_EXPORT PluginInstanceThrottlerImpl : public PluginInstanceThrottler { public: explicit PluginInstanceThrottlerImpl( RenderFrame::RecordPeripheralDecision record_decision); ~PluginInstanceThrottlerImpl() override; // PluginInstanceThrottler implementation: void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; bool IsThrottled() const override; bool IsHiddenForPlaceholder() const override; void MarkPluginEssential(PowerSaverUnthrottleMethod method) override; void SetHiddenForPlaceholder(bool hidden) override; PepperWebPluginImpl* GetWebPlugin() const override; const gfx::Size& GetSize() const override; void NotifyAudioThrottled() override; void SetWebPlugin(PepperWebPluginImpl* web_plugin); bool needs_representative_keyframe() const { return state_ == THROTTLER_STATE_AWAITING_KEYFRAME; } bool power_saver_enabled() const { return state_ != THROTTLER_STATE_MARKED_ESSENTIAL; } void Initialize(RenderFrameImpl* frame, const url::Origin& content_origin, const std::string& plugin_module_name, const gfx::Size& unobscured_size); // Called when the plugin flushes it's graphics context. Supplies the // throttler with a candidate to use as the representative keyframe. void OnImageFlush(const SkBitmap& bitmap); // Returns true if |event| was handled and shouldn't be further processed. bool ConsumeInputEvent(const blink::WebInputEvent& event); private: friend class PluginInstanceThrottlerImplTest; enum ThrottlerState { // Plugin has been found to be peripheral, Plugin Power Saver is enabled, // and throttler is awaiting a representative keyframe. THROTTLER_STATE_AWAITING_KEYFRAME, // A representative keyframe has been chosen and the plugin is throttled. THROTTLER_STATE_PLUGIN_THROTTLED, // Plugin instance has been marked essential. THROTTLER_STATE_MARKED_ESSENTIAL, }; // Maximum number of frames to examine for a suitable keyframe. After that, we // simply suspend the plugin where it's at. Chosen arbitrarily. static const int kMaximumFramesToExamine; void AudioThrottledFrameTimeout(); void EngageThrottle(); RenderFrame::RecordPeripheralDecision record_decision_; ThrottlerState state_; bool is_hidden_for_placeholder_; PepperWebPluginImpl* web_plugin_; // Holds a reference to the last received frame. This doesn't actually copy // the pixel data, but rather increments the reference count to the pixels. SkBitmap last_received_frame_; // Number of frames we've examined to find a keyframe. int frames_examined_; // Plugin's unobscured dimensions as of initialization. gfx::Size unobscured_size_; // Video plugins with throttled audio often stop generating frames. // This timer is so we don't wait forever for candidate poster frames. bool audio_throttled_; base::DelayTimer audio_throttled_frame_timeout_; base::ObserverList observer_list_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(PluginInstanceThrottlerImpl); }; } #endif // CONTENT_RENDERER_PEPPER_PLUGIN_INSTANCE_THROTTLER_IMPL_H_