1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
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/. */
8 #ifndef nsUserIdleService_h__
9 #define nsUserIdleService_h__
11 #include "nsIUserIdleServiceInternal.h"
15 #include "nsIObserver.h"
16 #include "nsIUserIdleService.h"
17 #include "nsCategoryCache.h"
18 #include "nsWeakReference.h"
19 #include "mozilla/TimeStamp.h"
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".
27 nsCOMPtr
<nsIObserver
> observer
;
31 IdleListener(nsIObserver
* obs
, uint32_t reqIT
, bool aIsIdle
= false)
32 : observer(obs
), reqIdleTime(reqIT
), isIdle(aIsIdle
) {}
33 ~IdleListener() = default;
36 // This one will be declared later.
37 class nsUserIdleService
;
40 * Class to handle the daily idle timer.
42 class nsUserIdleServiceDaily
: public nsIObserver
,
43 public nsSupportsWeakReference
{
48 explicit nsUserIdleServiceDaily(nsIUserIdleService
* aIdleService
);
51 * Initializes the daily idle observer.
52 * Keep this separated from the constructor, since it could cause pointer
53 * corruption due to AddRef/Release of "this".
58 virtual ~nsUserIdleServiceDaily();
61 * StageIdleDaily is the interim call made when an idle-daily event is due.
62 * However we don't want to fire idle-daily until the user is idle for this
63 * session, so this sets up a short wait for an idle event which triggers
64 * the actual idle-daily event.
66 * @param aHasBeenLongWait Pass true indicating nsUserIdleServiceDaily is
67 * having trouble getting the idle-daily event fired. If true StageIdleDaily
68 * will use a shorter idle wait time before firing idle-daily.
70 void StageIdleDaily(bool aHasBeenLongWait
);
73 * @note This is a normal pointer, part to avoid creating a cycle with the
74 * idle service, part to avoid potential pointer corruption due to this class
75 * being instantiated in the constructor of the service itself.
77 nsIUserIdleService
* mIdleService
;
80 * Place to hold the timer used by this class to determine when a day has
81 * passed, after that it will wait for idle time to be detected.
83 nsCOMPtr
<nsITimer
> mTimer
;
86 * Function that is called back once a day.
88 static void DailyCallback(nsITimer
* aTimer
, void* aClosure
);
91 * Cache of observers for the "idle-daily" category.
93 nsCategoryCache
<nsIObserver
> mCategoryObservers
;
96 * Boolean set to true when daily idle notifications should be disabled.
98 bool mShutdownInProgress
;
101 * Next time we expect an idle-daily timer to fire, in case timers aren't
102 * very reliable on the platform. Value is in PR_Now microsecond units.
104 PRTime mExpectedTriggerTime
;
107 * Tracks which idle daily observer callback we ask for. There are two: a
108 * regular long idle wait and a shorter wait if we've been waiting to fire
109 * idle daily for an extended period. Set by StageIdleDaily.
111 int32_t mIdleDailyTriggerWait
;
114 class nsUserIdleService
: public nsIUserIdleServiceInternal
{
117 NS_DECL_NSIUSERIDLESERVICE NS_DECL_NSIUSERIDLESERVICEINTERNAL
119 protected : static already_AddRefed
<nsUserIdleService
>
123 virtual ~nsUserIdleService();
126 * If there is a platform specific function to poll the system idel time
127 * then that must be returned in this function, and the function MUST return
128 * true, otherwise then the function should be left unimplemented or made
129 * to return false (this can also be used for systems where it depends on
130 * the configuration of the system if the idle time can be determined)
133 * The idle time in ms.
135 * @return true if the idle time could be polled, false otherwise.
137 * @note The time returned by this function can be different than the one
138 * returned by GetIdleTime, as that is corrected by any calls to
139 * ResetIdleTimeOut(), unless you overwrite that function too...
141 virtual bool PollIdleTime(uint32_t* aIdleTime
);
145 * Ensure that the timer is expiring at least at the given time
147 * The function might not restart the timer if there is one running currently
149 * @param aNextTimeout
150 * The last absolute time the timer should expire
152 void SetTimerExpiryIfBefore(mozilla::TimeStamp aNextTimeout
);
155 * Stores the next timeout time, 0 means timer not running
157 mozilla::TimeStamp mCurrentlySetToTimeoutAt
;
160 * mTimer holds the internal timer used by this class to detect when to poll
161 * for idle time, when to check if idle timers should expire etc.
163 nsCOMPtr
<nsITimer
> mTimer
;
166 * Array of listeners that wants to be notified about idle time.
168 nsTArray
<IdleListener
> mArrayListeners
;
171 * Object keeping track of the daily idle thingy.
173 RefPtr
<nsUserIdleServiceDaily
> mDailyIdle
;
176 * Number of observers currently in idle mode.
178 uint32_t mIdleObserverCount
;
181 * Delta time from last non idle time to when the next observer should switch
186 * If this value is 0 it means there are no active observers
188 uint32_t mDeltaToNextIdleSwitchInS
;
191 * If true, the idle service is temporarily disabled, and all idle events
194 bool mDisabled
= false;
197 * Absolute value for when the last user interaction took place.
199 mozilla::TimeStamp mLastUserInteraction
;
202 * Function that ensures the timer is running with at least the minimum time
203 * needed. It will kill the timer if there are no active observers.
205 void ReconfigureTimer(void);
208 * Callback function that is called when the internal timer expires.
210 * This in turn calls the IdleTimerCallback that does the real processing
212 static void StaticIdleTimerCallback(nsITimer
* aTimer
, void* aClosure
);
215 * Function that handles when a timer has expired
217 void IdleTimerCallback(void);
220 #endif // nsUserIdleService_h__