Line data Source code
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 3 : class IdleListener {
26 : public:
27 : nsCOMPtr<nsIObserver> observer;
28 : uint32_t reqIdleTime;
29 : bool isIdle;
30 :
31 3 : IdleListener(nsIObserver* obs, uint32_t reqIT, bool aIsIdle = false) :
32 3 : observer(obs), reqIdleTime(reqIT), isIdle(aIsIdle) {}
33 3 : ~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 : explicit 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 : private:
59 : virtual ~nsIdleServiceDaily();
60 :
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 : RefPtr<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__
|