summaryrefslogtreecommitdiffstats
path: root/ash/wm/video_detector.h
blob: 61a9e23cb25e7456538e4cd5e74c65db529ca920 (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
// Copyright (c) 2012 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 ASH_WM_VIDEO_DETECTOR_H_
#define ASH_WM_VIDEO_DETECTOR_H_

#include <map>

#include "ash/ash_export.h"
#include "ash/shell_observer.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "ui/aura/env_observer.h"
#include "ui/aura/window_observer.h"

namespace aura {
class Window;
}

namespace gfx {
class Rect;
}

namespace ash {

class ASH_EXPORT VideoDetectorObserver {
 public:
  // Invoked periodically while a video is being played onscreen.
  virtual void OnVideoDetected(bool is_fullscreen) = 0;

 protected:
  virtual ~VideoDetectorObserver() {}
};

// Watches for updates to windows and tries to detect when a video is playing.
// We err on the side of false positives and can be fooled by things like
// continuous scrolling of a page.
class ASH_EXPORT VideoDetector : public aura::EnvObserver,
                                 public aura::WindowObserver,
                                 public ShellObserver  {
 public:
  // Minimum dimensions in pixels that a window update must have to be
  // considered a potential video frame.
  static const int kMinUpdateWidth;
  static const int kMinUpdateHeight;

  // Number of video-sized updates that we must see within a second in a window
  // before we assume that a video is playing.
  static const int kMinFramesPerSecond;

  // Minimum amount of time between notifications to observers that a video is
  // playing.
  static const double kNotifyIntervalSec;

  VideoDetector();
  ~VideoDetector() override;

  void set_now_for_test(base::TimeTicks now) { now_for_test_ = now; }

  void AddObserver(VideoDetectorObserver* observer);
  void RemoveObserver(VideoDetectorObserver* observer);

  // EnvObserver overrides.
  void OnWindowInitialized(aura::Window* window) override;

  // WindowObserver overrides.
  void OnDelegatedFrameDamage(aura::Window* window,
                              const gfx::Rect& region) override;
  void OnWindowDestroyed(aura::Window* window) override;

  // ShellObserver overrides.
  void OnAppTerminating() override;

 private:
  class WindowInfo;
  typedef std::map<aura::Window*, linked_ptr<WindowInfo> > WindowInfoMap;

  // Possibly notifies observers in response to detection of a video in
  // |window|.  Notifications are rate-limited and don't get sent if the window
  // is invisible or offscreen.
  void MaybeNotifyObservers(aura::Window* window, base::TimeTicks now);

  // Maps from a window that we're tracking to information about it.
  WindowInfoMap window_infos_;

  base::ObserverList<VideoDetectorObserver> observers_;

  // Last time at which we notified observers that a video was playing.
  base::TimeTicks last_observer_notification_time_;

  // If set, used when the current time is needed.  This can be set by tests to
  // simulate the passage of time.
  base::TimeTicks now_for_test_;

  ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;

  bool is_shutting_down_;

  DISALLOW_COPY_AND_ASSIGN(VideoDetector);
};

}  // namespace ash

#endif  // ASH_WM_VIDEO_DETECTOR_H_