summaryrefslogtreecommitdiffstats
path: root/chromium/content/renderer/pepper/plugin_instance_throttler_impl.h
blob: b98f914e2d477c3f73b58141bc44ea29c42c3e28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// 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> observer_list_;

  base::WeakPtrFactory<PluginInstanceThrottlerImpl> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(PluginInstanceThrottlerImpl);
};
}

#endif  // CONTENT_RENDERER_PEPPER_PLUGIN_INSTANCE_THROTTLER_IMPL_H_