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 CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
6#define CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
7
8#include <map>
9#include <string>
10
11#include "base/callback_forward.h"
12#include "base/gtest_prod_util.h"
13#include "base/memory/weak_ptr.h"
14#include "base/threading/thread_checker.h"
15#include "base/timer/timer.h"
16#include "chrome/browser/extensions/event_router.h"
17#include "chrome/browser/idle.h"
18#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
19#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
21
22namespace base {
23class StringValue;
24}  // namespace base
25
26class Profile;
27
28namespace extensions {
29
30typedef base::Callback<void(IdleState)> QueryStateCallback;
31
32struct IdleMonitor {
33  explicit IdleMonitor(IdleState initial_state);
34
35  IdleState last_state;
36  int listeners;
37  int threshold;
38};
39
40class IdleManager : public content::NotificationObserver,
41                    public EventRouter::Observer,
42                    public BrowserContextKeyedService {
43 public:
44  class IdleTimeProvider {
45   public:
46    IdleTimeProvider() {}
47    virtual ~IdleTimeProvider() {}
48    virtual void CalculateIdleState(int idle_threshold,
49                                    IdleCallback notify) = 0;
50    virtual void CalculateIdleTime(IdleTimeCallback notify) = 0;
51    virtual bool CheckIdleStateIsLocked() = 0;
52
53   private:
54    DISALLOW_COPY_AND_ASSIGN(IdleTimeProvider);
55  };
56
57  class EventDelegate {
58   public:
59    EventDelegate() {}
60    virtual ~EventDelegate() {}
61    virtual void OnStateChanged(const std::string& extension_id,
62                                IdleState new_state) = 0;
63    virtual void RegisterObserver(EventRouter::Observer* observer) = 0;
64    virtual void UnregisterObserver(EventRouter::Observer* observer) = 0;
65
66   private:
67    DISALLOW_COPY_AND_ASSIGN(EventDelegate);
68  };
69
70  explicit IdleManager(Profile* profile);
71  virtual ~IdleManager();
72
73  void Init();
74
75  // BrowserContextKeyedService implementation.
76  virtual void Shutdown() OVERRIDE;
77
78  // content::NotificationDelegate implementation.
79  virtual void Observe(int type,
80                       const content::NotificationSource& source,
81                       const content::NotificationDetails& details) OVERRIDE;
82
83  // EventRouter::Observer implementation.
84  virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
85  virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
86
87  void QueryState(int threshold, QueryStateCallback notify);
88  void SetThreshold(const std::string& extension_id, int threshold);
89  static base::StringValue* CreateIdleValue(IdleState idle_state);
90
91  // Override default event class. Callee assumes ownership. Used for testing.
92  void SetEventDelegateForTest(scoped_ptr<EventDelegate> event_delegate);
93
94  // Override default idle time calculations. Callee assumes ownership. Used
95  // for testing.
96  void SetIdleTimeProviderForTest(scoped_ptr<IdleTimeProvider> idle_provider);
97
98 private:
99  FRIEND_TEST_ALL_PREFIXES(IdleTest, ActiveToIdle);
100  FRIEND_TEST_ALL_PREFIXES(IdleTest, ActiveToLocked);
101  FRIEND_TEST_ALL_PREFIXES(IdleTest, IdleToActive);
102  FRIEND_TEST_ALL_PREFIXES(IdleTest, IdleToLocked);
103  FRIEND_TEST_ALL_PREFIXES(IdleTest, LockedToActive);
104  FRIEND_TEST_ALL_PREFIXES(IdleTest, LockedToIdle);
105  FRIEND_TEST_ALL_PREFIXES(IdleTest, MultipleExtensions);
106  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionInterval);
107  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalBeforeListener);
108  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalMaximum);
109  FRIEND_TEST_ALL_PREFIXES(IdleTest, SetDetectionIntervalMinimum);
110  FRIEND_TEST_ALL_PREFIXES(IdleTest, UnloadCleanup);
111
112  typedef std::map<const std::string, IdleMonitor> MonitorMap;
113
114  IdleMonitor* GetMonitor(const std::string& extension_id);
115  void StartPolling();
116  void StopPolling();
117  void UpdateIdleState();
118  void UpdateIdleStateCallback(int idle_time);
119
120  Profile* profile_;
121
122  IdleState last_state_;
123  MonitorMap monitors_;
124
125  base::RepeatingTimer<IdleManager> poll_timer_;
126  base::WeakPtrFactory<IdleManager> weak_factory_;
127  content::NotificationRegistrar registrar_;
128
129  scoped_ptr<IdleTimeProvider> idle_time_provider_;
130  scoped_ptr<EventDelegate> event_delegate_;
131
132  base::ThreadChecker thread_checker_;
133
134  DISALLOW_COPY_AND_ASSIGN(IdleManager);
135};
136
137}  // namespace extensions
138
139#endif  // CHROME_BROWSER_EXTENSIONS_API_IDLE_IDLE_MANAGER_H_
140