|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:expandtab:shiftwidth=2:tabstop=2: |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #ifndef nsIdleService_h__ |
|
9 #define nsIdleService_h__ |
|
10 |
|
11 #include "nsIIdleServiceInternal.h" |
|
12 #include "nsCOMPtr.h" |
|
13 #include "nsITimer.h" |
|
14 #include "nsTArray.h" |
|
15 #include "nsIObserver.h" |
|
16 #include "nsIIdleService.h" |
|
17 #include "nsCategoryCache.h" |
|
18 #include "nsWeakReference.h" |
|
19 #include "mozilla/TimeStamp.h" |
|
20 |
|
21 /** |
|
22 * Class we can use to store an observer with its associated idle time |
|
23 * requirement and whether or not the observer thinks it's "idle". |
|
24 */ |
|
25 class IdleListener { |
|
26 public: |
|
27 nsCOMPtr<nsIObserver> observer; |
|
28 uint32_t reqIdleTime; |
|
29 bool isIdle; |
|
30 |
|
31 IdleListener(nsIObserver* obs, uint32_t reqIT, bool aIsIdle = false) : |
|
32 observer(obs), reqIdleTime(reqIT), isIdle(aIsIdle) {} |
|
33 ~IdleListener() {} |
|
34 }; |
|
35 |
|
36 // This one will be declared later. |
|
37 class nsIdleService; |
|
38 |
|
39 /** |
|
40 * Class to handle the daily idle timer. |
|
41 */ |
|
42 class nsIdleServiceDaily : public nsIObserver, |
|
43 public nsSupportsWeakReference |
|
44 { |
|
45 public: |
|
46 NS_DECL_ISUPPORTS |
|
47 NS_DECL_NSIOBSERVER |
|
48 |
|
49 nsIdleServiceDaily(nsIIdleService* aIdleService); |
|
50 |
|
51 /** |
|
52 * Initializes the daily idle observer. |
|
53 * Keep this separated from the constructor, since it could cause pointer |
|
54 * corruption due to AddRef/Release of "this". |
|
55 */ |
|
56 void Init(); |
|
57 |
|
58 virtual ~nsIdleServiceDaily(); |
|
59 |
|
60 private: |
|
61 /** |
|
62 * StageIdleDaily is the interim call made when an idle-daily event is due. |
|
63 * However we don't want to fire idle-daily until the user is idle for this |
|
64 * session, so this sets up a short wait for an idle event which triggers |
|
65 * the actual idle-daily event. |
|
66 * |
|
67 * @param aHasBeenLongWait Pass true indicating nsIdleServiceDaily is having |
|
68 * trouble getting the idle-daily event fired. If true StageIdleDaily will |
|
69 * use a shorter idle wait time before firing idle-daily. |
|
70 */ |
|
71 void StageIdleDaily(bool aHasBeenLongWait); |
|
72 |
|
73 /** |
|
74 * @note This is a normal pointer, part to avoid creating a cycle with the |
|
75 * idle service, part to avoid potential pointer corruption due to this class |
|
76 * being instantiated in the constructor of the service itself. |
|
77 */ |
|
78 nsIIdleService* mIdleService; |
|
79 |
|
80 /** |
|
81 * Place to hold the timer used by this class to determine when a day has |
|
82 * passed, after that it will wait for idle time to be detected. |
|
83 */ |
|
84 nsCOMPtr<nsITimer> mTimer; |
|
85 |
|
86 /** |
|
87 * Function that is called back once a day. |
|
88 */ |
|
89 static void DailyCallback(nsITimer* aTimer, void* aClosure); |
|
90 |
|
91 /** |
|
92 * Cache of observers for the "idle-daily" category. |
|
93 */ |
|
94 nsCategoryCache<nsIObserver> mCategoryObservers; |
|
95 |
|
96 /** |
|
97 * Boolean set to true when daily idle notifications should be disabled. |
|
98 */ |
|
99 bool mShutdownInProgress; |
|
100 |
|
101 /** |
|
102 * Next time we expect an idle-daily timer to fire, in case timers aren't |
|
103 * very reliable on the platform. Value is in PR_Now microsecond units. |
|
104 */ |
|
105 PRTime mExpectedTriggerTime; |
|
106 |
|
107 /** |
|
108 * Tracks which idle daily observer callback we ask for. There are two: a |
|
109 * regular long idle wait and a shorter wait if we've been waiting to fire |
|
110 * idle daily for an extended period. Set by StageIdleDaily. |
|
111 */ |
|
112 int32_t mIdleDailyTriggerWait; |
|
113 }; |
|
114 |
|
115 class nsIdleService : public nsIIdleServiceInternal |
|
116 { |
|
117 public: |
|
118 NS_DECL_ISUPPORTS |
|
119 NS_DECL_NSIIDLESERVICE |
|
120 NS_DECL_NSIIDLESERVICEINTERNAL |
|
121 |
|
122 protected: |
|
123 static already_AddRefed<nsIdleService> GetInstance(); |
|
124 |
|
125 nsIdleService(); |
|
126 virtual ~nsIdleService(); |
|
127 |
|
128 /** |
|
129 * If there is a platform specific function to poll the system idel time |
|
130 * then that must be returned in this function, and the function MUST return |
|
131 * true, otherwise then the function should be left unimplemented or made |
|
132 * to return false (this can also be used for systems where it depends on |
|
133 * the configuration of the system if the idle time can be determined) |
|
134 * |
|
135 * @param aIdleTime |
|
136 * The idle time in ms. |
|
137 * |
|
138 * @return true if the idle time could be polled, false otherwise. |
|
139 * |
|
140 * @note The time returned by this function can be different than the one |
|
141 * returned by GetIdleTime, as that is corrected by any calls to |
|
142 * ResetIdleTimeOut(), unless you overwrite that function too... |
|
143 */ |
|
144 virtual bool PollIdleTime(uint32_t* aIdleTime); |
|
145 |
|
146 /** |
|
147 * Function that determines if we are in poll mode or not. |
|
148 * |
|
149 * @return true if polling is supported, false otherwise. |
|
150 */ |
|
151 virtual bool UsePollMode(); |
|
152 |
|
153 private: |
|
154 /** |
|
155 * Ensure that the timer is expiring at least at the given time |
|
156 * |
|
157 * The function might not restart the timer if there is one running currently |
|
158 * |
|
159 * @param aNextTimeout |
|
160 * The last absolute time the timer should expire |
|
161 */ |
|
162 void SetTimerExpiryIfBefore(mozilla::TimeStamp aNextTimeout); |
|
163 |
|
164 /** |
|
165 * Stores the next timeout time, 0 means timer not running |
|
166 */ |
|
167 mozilla::TimeStamp mCurrentlySetToTimeoutAt; |
|
168 |
|
169 /** |
|
170 * mTimer holds the internal timer used by this class to detect when to poll |
|
171 * for idle time, when to check if idle timers should expire etc. |
|
172 */ |
|
173 nsCOMPtr<nsITimer> mTimer; |
|
174 |
|
175 /** |
|
176 * Array of listeners that wants to be notified about idle time. |
|
177 */ |
|
178 nsTArray<IdleListener> mArrayListeners; |
|
179 |
|
180 /** |
|
181 * Object keeping track of the daily idle thingy. |
|
182 */ |
|
183 nsRefPtr<nsIdleServiceDaily> mDailyIdle; |
|
184 |
|
185 /** |
|
186 * Number of observers currently in idle mode. |
|
187 */ |
|
188 uint32_t mIdleObserverCount; |
|
189 |
|
190 /** |
|
191 * Delta time from last non idle time to when the next observer should switch |
|
192 * to idle mode |
|
193 * |
|
194 * Time in seconds |
|
195 * |
|
196 * If this value is 0 it means there are no active observers |
|
197 */ |
|
198 uint32_t mDeltaToNextIdleSwitchInS; |
|
199 |
|
200 /** |
|
201 * Absolute value for when the last user interaction took place. |
|
202 */ |
|
203 mozilla::TimeStamp mLastUserInteraction; |
|
204 |
|
205 |
|
206 /** |
|
207 * Function that ensures the timer is running with at least the minimum time |
|
208 * needed. It will kill the timer if there are no active observers. |
|
209 */ |
|
210 void ReconfigureTimer(void); |
|
211 |
|
212 /** |
|
213 * Callback function that is called when the internal timer expires. |
|
214 * |
|
215 * This in turn calls the IdleTimerCallback that does the real processing |
|
216 */ |
|
217 static void StaticIdleTimerCallback(nsITimer* aTimer, void* aClosure); |
|
218 |
|
219 /** |
|
220 * Function that handles when a timer has expired |
|
221 */ |
|
222 void IdleTimerCallback(void); |
|
223 }; |
|
224 |
|
225 #endif // nsIdleService_h__ |