OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ |
6 #define CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ | 6 #define CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <map> | 10 #include <map> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
14 #include "base/timer.h" | 14 #include "base/timer.h" |
15 #include "chrome/browser/extensions/extension_function.h" | 15 #include "chrome/browser/extensions/extension_function.h" |
16 #include "chrome/common/extensions/api/alarms.h" | 16 #include "chrome/common/extensions/api/alarms.h" |
17 #include "content/public/browser/notification_observer.h" | 17 #include "content/public/browser/notification_observer.h" |
18 #include "content/public/browser/notification_registrar.h" | 18 #include "content/public/browser/notification_registrar.h" |
19 | 19 |
20 class Profile; | 20 class Profile; |
21 | 21 |
22 namespace extensions { | 22 namespace extensions { |
23 | 23 |
24 class ExtensionAlarmsSchedulingTest; | 24 class ExtensionAlarmsSchedulingTest; |
25 | 25 |
| 26 struct Alarm { |
| 27 typedef base::Time (*TimeProvider)(); |
| 28 |
| 29 Alarm(); |
| 30 Alarm(const std::string& name, |
| 31 const api::alarms::AlarmCreateInfo& create_info, |
| 32 base::TimeDelta min_granularity, |
| 33 TimeProvider now); |
| 34 ~Alarm(); |
| 35 |
| 36 linked_ptr<api::alarms::Alarm> js_alarm; |
| 37 // The granularity isn't exposed to the extension's javascript, but we poll at |
| 38 // least as often as the shortest alarm's granularity. It's initialized as |
| 39 // the relative delay requested in creation, even if creation uses an absolute |
| 40 // time. This will always be at least as large as the min_granularity |
| 41 // constructor argument. |
| 42 base::TimeDelta granularity; |
| 43 }; |
| 44 |
26 // Manages the currently pending alarms for every extension in a profile. | 45 // Manages the currently pending alarms for every extension in a profile. |
27 // There is one manager per virtual Profile. | 46 // There is one manager per virtual Profile. |
28 class AlarmManager | 47 class AlarmManager |
29 : public content::NotificationObserver, | 48 : public content::NotificationObserver, |
30 public base::SupportsWeakPtr<AlarmManager> { | 49 public base::SupportsWeakPtr<AlarmManager> { |
31 public: | 50 public: |
32 typedef extensions::api::alarms::Alarm Alarm; | 51 typedef base::Time (*TimeProvider)(); |
33 typedef std::vector<linked_ptr<Alarm> > AlarmList; | 52 typedef std::vector<Alarm> AlarmList; |
34 | 53 |
35 class Delegate { | 54 class Delegate { |
36 public: | 55 public: |
37 virtual ~Delegate() {} | 56 virtual ~Delegate() {} |
38 // Called when an alarm fires. | 57 // Called when an alarm fires. |
39 virtual void OnAlarm(const std::string& extension_id, | 58 virtual void OnAlarm(const std::string& extension_id, |
40 const Alarm& alarm) = 0; | 59 const Alarm& alarm) = 0; |
41 }; | 60 }; |
42 | 61 |
43 explicit AlarmManager(Profile* profile); | 62 // 'now' is usually &base::Time::Now. |
| 63 explicit AlarmManager(Profile* profile, TimeProvider now); |
44 virtual ~AlarmManager(); | 64 virtual ~AlarmManager(); |
45 | 65 |
46 // Override the default delegate. Callee assumes onwership. Used for testing. | 66 // Override the default delegate. Callee assumes onwership. Used for testing. |
47 void set_delegate(Delegate* delegate) { delegate_.reset(delegate); } | 67 void set_delegate(Delegate* delegate) { delegate_.reset(delegate); } |
48 | 68 |
49 // Adds |alarm| for the given extension, and starts the timer. | 69 // Adds |alarm| for the given extension, and starts the timer. |
50 void AddAlarm(const std::string& extension_id, | 70 void AddAlarm(const std::string& extension_id, |
51 const linked_ptr<Alarm>& alarm); | 71 const Alarm& alarm); |
52 | 72 |
53 // Returns the alarm with the given name, or NULL if none exists. | 73 // Returns the alarm with the given name, or NULL if none exists. |
54 const Alarm* GetAlarm(const std::string& extension_id, | 74 const Alarm* GetAlarm(const std::string& extension_id, |
55 const std::string& name); | 75 const std::string& name); |
56 | 76 |
57 // Returns the list of pending alarms for the given extension, or NULL | 77 // Returns the list of pending alarms for the given extension, or NULL |
58 // if none exist. | 78 // if none exist. |
59 const AlarmList* GetAllAlarms(const std::string& extension_id); | 79 const AlarmList* GetAllAlarms(const std::string& extension_id); |
60 | 80 |
61 // Cancels and removes the alarm with the given name. | 81 // Cancels and removes the alarm with the given name. |
62 bool RemoveAlarm(const std::string& extension_id, | 82 bool RemoveAlarm(const std::string& extension_id, |
63 const std::string& name); | 83 const std::string& name); |
64 | 84 |
65 // Cancels and removes all alarms for the given extension. | 85 // Cancels and removes all alarms for the given extension. |
66 void RemoveAllAlarms(const std::string& extension_id); | 86 void RemoveAllAlarms(const std::string& extension_id); |
67 | 87 |
68 private: | 88 private: |
69 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, CreateRepeating); | 89 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, CreateRepeating); |
70 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, Clear); | 90 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsTest, Clear); |
71 friend class ExtensionAlarmsSchedulingTest; | 91 friend class ExtensionAlarmsSchedulingTest; |
72 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, PollScheduling); | 92 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, PollScheduling); |
| 93 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, |
| 94 ReleasedExtensionPollsInfrequently); |
73 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, TimerRunning); | 95 FRIEND_TEST_ALL_PREFIXES(ExtensionAlarmsSchedulingTest, TimerRunning); |
74 | 96 |
75 typedef std::string ExtensionId; | 97 typedef std::string ExtensionId; |
76 typedef std::map<ExtensionId, AlarmList> AlarmMap; | 98 typedef std::map<ExtensionId, AlarmList> AlarmMap; |
77 | 99 |
78 // Iterator used to identify a particular alarm within the Map/List pair. | 100 // Iterator used to identify a particular alarm within the Map/List pair. |
79 // "Not found" is represented by <alarms_.end(), invalid_iterator>. | 101 // "Not found" is represented by <alarms_.end(), invalid_iterator>. |
80 typedef std::pair<AlarmMap::iterator, AlarmList::iterator> AlarmIterator; | 102 typedef std::pair<AlarmMap::iterator, AlarmList::iterator> AlarmIterator; |
81 | 103 |
82 struct AlarmRuntimeInfo { | |
83 std::string extension_id; | |
84 base::Time time; | |
85 }; | |
86 typedef std::map<const Alarm*, AlarmRuntimeInfo> AlarmRuntimeInfoMap; | |
87 | |
88 // Helper to return the iterators within the AlarmMap and AlarmList for the | 104 // Helper to return the iterators within the AlarmMap and AlarmList for the |
89 // matching alarm, or an iterator to the end of the AlarmMap if none were | 105 // matching alarm, or an iterator to the end of the AlarmMap if none were |
90 // found. | 106 // found. |
91 AlarmIterator GetAlarmIterator(const std::string& extension_id, | 107 AlarmIterator GetAlarmIterator(const std::string& extension_id, |
92 const std::string& name); | 108 const std::string& name); |
93 | 109 |
94 // Helper to cancel and remove the alarm at the given iterator. The iterator | 110 // Helper to cancel and remove the alarm at the given iterator. The iterator |
95 // must be valid. | 111 // must be valid. |
96 void RemoveAlarmIterator(const AlarmIterator& iter); | 112 void RemoveAlarmIterator(const AlarmIterator& iter); |
97 | 113 |
98 // Callback for when an alarm fires. | 114 // Callback for when an alarm fires. |
99 void OnAlarm(const std::string& extension_id, const std::string& name); | 115 void OnAlarm(AlarmIterator iter); |
100 | 116 |
101 // Internal helper to add an alarm and start the timer with the given delay. | 117 // Internal helper to add an alarm and start the timer with the given delay. |
102 void AddAlarmImpl(const std::string& extension_id, | 118 void AddAlarmImpl(const std::string& extension_id, |
103 const linked_ptr<Alarm>& alarm, | 119 const Alarm& alarm); |
104 base::TimeDelta time_delay); | |
105 | 120 |
106 // Syncs our alarm data for the given extension to/from the state storage. | 121 // Syncs our alarm data for the given extension to/from the state storage. |
107 void WriteToStorage(const std::string& extension_id); | 122 void WriteToStorage(const std::string& extension_id); |
108 void ReadFromStorage(const std::string& extension_id, | 123 void ReadFromStorage(const std::string& extension_id, |
109 scoped_ptr<base::Value> value); | 124 scoped_ptr<base::Value> value); |
110 | 125 |
111 // Schedules the next poll of alarms for when the next soonest alarm runs, | 126 // Schedules the next poll of alarms for when the next soonest alarm runs, |
112 // but do not more often than min_period. | 127 // but do not more often than min_period. |
113 void ScheduleNextPoll(base::TimeDelta min_period); | 128 void ScheduleNextPoll(base::TimeDelta min_period); |
114 | 129 |
115 // Polls the alarms, running any that have elapsed. After running them and | 130 // Polls the alarms, running any that have elapsed. After running them and |
116 // rescheduling repeating alarms, schedule the next poll. | 131 // rescheduling repeating alarms, schedule the next poll. |
117 void PollAlarms(); | 132 void PollAlarms(); |
118 | 133 |
119 // NotificationObserver: | 134 // NotificationObserver: |
120 virtual void Observe(int type, | 135 virtual void Observe(int type, |
121 const content::NotificationSource& source, | 136 const content::NotificationSource& source, |
122 const content::NotificationDetails& details) OVERRIDE; | 137 const content::NotificationDetails& details) OVERRIDE; |
123 | 138 |
124 Profile* profile_; | 139 Profile* profile_; |
| 140 const TimeProvider now_; |
125 content::NotificationRegistrar registrar_; | 141 content::NotificationRegistrar registrar_; |
126 scoped_ptr<Delegate> delegate_; | 142 scoped_ptr<Delegate> delegate_; |
127 | 143 |
128 // The timer for this alarm manager. | 144 // The timer for this alarm manager. |
129 base::OneShotTimer<AlarmManager> timer_; | 145 base::OneShotTimer<AlarmManager> timer_; |
130 | 146 |
131 // A map of our pending alarms, per extension. | 147 // A map of our pending alarms, per extension. |
| 148 // Invariant: None of the AlarmLists are empty. |
132 AlarmMap alarms_; | 149 AlarmMap alarms_; |
133 | 150 |
134 // A map of the next scheduled times associated with each alarm. | |
135 AlarmRuntimeInfoMap scheduled_times_; | |
136 | |
137 // The previous and next time that alarms were and will be run. | 151 // The previous and next time that alarms were and will be run. |
138 base::Time last_poll_time_; | 152 base::Time last_poll_time_; |
139 base::Time next_poll_time_; | 153 base::Time next_poll_time_; |
140 }; | 154 }; |
141 | 155 |
142 } // namespace extensions | 156 } // namespace extensions |
143 | 157 |
144 #endif // CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ | 158 #endif // CHROME_BROWSER_EXTENSIONS_API_ALARMS_ALARM_MANAGER_H__ |
OLD | NEW |