// 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/basictypes.h"
#include "base/compiler_specific.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();
virtual ~VideoDetector();
void set_now_for_test(base::TimeTicks now) { now_for_test_ = now; }
void AddObserver(VideoDetectorObserver* observer);
void RemoveObserver(VideoDetectorObserver* observer);
// EnvObserver overrides.
virtual void OnWindowInitialized(aura::Window* window) OVERRIDE;
// WindowObserver overrides.
virtual void OnWindowPaintScheduled(aura::Window* window,
const gfx::Rect& region) OVERRIDE;
virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
// ShellObserver overrides.
virtual 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_;
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_