1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef ASH_WM_VIDEO_DETECTOR_H_
6#define ASH_WM_VIDEO_DETECTOR_H_
7
8#include <map>
9
10#include "ash/ash_export.h"
11#include "ash/shell_observer.h"
12#include "base/basictypes.h"
13#include "base/compiler_specific.h"
14#include "base/memory/linked_ptr.h"
15#include "base/observer_list.h"
16#include "base/scoped_observer.h"
17#include "base/time/time.h"
18#include "ui/aura/env_observer.h"
19#include "ui/aura/window_observer.h"
20
21namespace aura {
22class Window;
23}
24
25namespace gfx {
26class Rect;
27}
28
29namespace ash {
30
31class ASH_EXPORT VideoDetectorObserver {
32 public:
33  // Invoked periodically while a video is being played onscreen.
34  virtual void OnVideoDetected(bool is_fullscreen) = 0;
35
36 protected:
37  virtual ~VideoDetectorObserver() {}
38};
39
40// Watches for updates to windows and tries to detect when a video is playing.
41// We err on the side of false positives and can be fooled by things like
42// continuous scrolling of a page.
43class ASH_EXPORT VideoDetector : public aura::EnvObserver,
44                                 public aura::WindowObserver,
45                                 public ShellObserver  {
46 public:
47  // Minimum dimensions in pixels that a window update must have to be
48  // considered a potential video frame.
49  static const int kMinUpdateWidth;
50  static const int kMinUpdateHeight;
51
52  // Number of video-sized updates that we must see within a second in a window
53  // before we assume that a video is playing.
54  static const int kMinFramesPerSecond;
55
56  // Minimum amount of time between notifications to observers that a video is
57  // playing.
58  static const double kNotifyIntervalSec;
59
60  VideoDetector();
61  virtual ~VideoDetector();
62
63  void set_now_for_test(base::TimeTicks now) { now_for_test_ = now; }
64
65  void AddObserver(VideoDetectorObserver* observer);
66  void RemoveObserver(VideoDetectorObserver* observer);
67
68  // EnvObserver overrides.
69  virtual void OnWindowInitialized(aura::Window* window) OVERRIDE;
70
71  // WindowObserver overrides.
72  virtual void OnDelegatedFrameDamage(aura::Window* window,
73                                      const gfx::Rect& region) OVERRIDE;
74  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
75
76  // ShellObserver overrides.
77  virtual void OnAppTerminating() OVERRIDE;
78
79 private:
80  class WindowInfo;
81  typedef std::map<aura::Window*, linked_ptr<WindowInfo> > WindowInfoMap;
82
83  // Possibly notifies observers in response to detection of a video in
84  // |window|.  Notifications are rate-limited and don't get sent if the window
85  // is invisible or offscreen.
86  void MaybeNotifyObservers(aura::Window* window, base::TimeTicks now);
87
88  // Maps from a window that we're tracking to information about it.
89  WindowInfoMap window_infos_;
90
91  ObserverList<VideoDetectorObserver> observers_;
92
93  // Last time at which we notified observers that a video was playing.
94  base::TimeTicks last_observer_notification_time_;
95
96  // If set, used when the current time is needed.  This can be set by tests to
97  // simulate the passage of time.
98  base::TimeTicks now_for_test_;
99
100  ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
101
102  bool is_shutting_down_;
103
104  DISALLOW_COPY_AND_ASSIGN(VideoDetector);
105};
106
107}  // namespace ash
108
109#endif  // ASH_WM_VIDEO_DETECTOR_H_
110