michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:expandtab:shiftwidth=2:tabstop=2: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsIdleService_h__ michael@0: #define nsIdleService_h__ michael@0: michael@0: #include "nsIIdleServiceInternal.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsITimer.h" michael@0: #include "nsTArray.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsIIdleService.h" michael@0: #include "nsCategoryCache.h" michael@0: #include "nsWeakReference.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: michael@0: /** michael@0: * Class we can use to store an observer with its associated idle time michael@0: * requirement and whether or not the observer thinks it's "idle". michael@0: */ michael@0: class IdleListener { michael@0: public: michael@0: nsCOMPtr observer; michael@0: uint32_t reqIdleTime; michael@0: bool isIdle; michael@0: michael@0: IdleListener(nsIObserver* obs, uint32_t reqIT, bool aIsIdle = false) : michael@0: observer(obs), reqIdleTime(reqIT), isIdle(aIsIdle) {} michael@0: ~IdleListener() {} michael@0: }; michael@0: michael@0: // This one will be declared later. michael@0: class nsIdleService; michael@0: michael@0: /** michael@0: * Class to handle the daily idle timer. michael@0: */ michael@0: class nsIdleServiceDaily : public nsIObserver, michael@0: public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: nsIdleServiceDaily(nsIIdleService* aIdleService); michael@0: michael@0: /** michael@0: * Initializes the daily idle observer. michael@0: * Keep this separated from the constructor, since it could cause pointer michael@0: * corruption due to AddRef/Release of "this". michael@0: */ michael@0: void Init(); michael@0: michael@0: virtual ~nsIdleServiceDaily(); michael@0: michael@0: private: michael@0: /** michael@0: * StageIdleDaily is the interim call made when an idle-daily event is due. michael@0: * However we don't want to fire idle-daily until the user is idle for this michael@0: * session, so this sets up a short wait for an idle event which triggers michael@0: * the actual idle-daily event. michael@0: * michael@0: * @param aHasBeenLongWait Pass true indicating nsIdleServiceDaily is having michael@0: * trouble getting the idle-daily event fired. If true StageIdleDaily will michael@0: * use a shorter idle wait time before firing idle-daily. michael@0: */ michael@0: void StageIdleDaily(bool aHasBeenLongWait); michael@0: michael@0: /** michael@0: * @note This is a normal pointer, part to avoid creating a cycle with the michael@0: * idle service, part to avoid potential pointer corruption due to this class michael@0: * being instantiated in the constructor of the service itself. michael@0: */ michael@0: nsIIdleService* mIdleService; michael@0: michael@0: /** michael@0: * Place to hold the timer used by this class to determine when a day has michael@0: * passed, after that it will wait for idle time to be detected. michael@0: */ michael@0: nsCOMPtr mTimer; michael@0: michael@0: /** michael@0: * Function that is called back once a day. michael@0: */ michael@0: static void DailyCallback(nsITimer* aTimer, void* aClosure); michael@0: michael@0: /** michael@0: * Cache of observers for the "idle-daily" category. michael@0: */ michael@0: nsCategoryCache mCategoryObservers; michael@0: michael@0: /** michael@0: * Boolean set to true when daily idle notifications should be disabled. michael@0: */ michael@0: bool mShutdownInProgress; michael@0: michael@0: /** michael@0: * Next time we expect an idle-daily timer to fire, in case timers aren't michael@0: * very reliable on the platform. Value is in PR_Now microsecond units. michael@0: */ michael@0: PRTime mExpectedTriggerTime; michael@0: michael@0: /** michael@0: * Tracks which idle daily observer callback we ask for. There are two: a michael@0: * regular long idle wait and a shorter wait if we've been waiting to fire michael@0: * idle daily for an extended period. Set by StageIdleDaily. michael@0: */ michael@0: int32_t mIdleDailyTriggerWait; michael@0: }; michael@0: michael@0: class nsIdleService : public nsIIdleServiceInternal michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIIDLESERVICE michael@0: NS_DECL_NSIIDLESERVICEINTERNAL michael@0: michael@0: protected: michael@0: static already_AddRefed GetInstance(); michael@0: michael@0: nsIdleService(); michael@0: virtual ~nsIdleService(); michael@0: michael@0: /** michael@0: * If there is a platform specific function to poll the system idel time michael@0: * then that must be returned in this function, and the function MUST return michael@0: * true, otherwise then the function should be left unimplemented or made michael@0: * to return false (this can also be used for systems where it depends on michael@0: * the configuration of the system if the idle time can be determined) michael@0: * michael@0: * @param aIdleTime michael@0: * The idle time in ms. michael@0: * michael@0: * @return true if the idle time could be polled, false otherwise. michael@0: * michael@0: * @note The time returned by this function can be different than the one michael@0: * returned by GetIdleTime, as that is corrected by any calls to michael@0: * ResetIdleTimeOut(), unless you overwrite that function too... michael@0: */ michael@0: virtual bool PollIdleTime(uint32_t* aIdleTime); michael@0: michael@0: /** michael@0: * Function that determines if we are in poll mode or not. michael@0: * michael@0: * @return true if polling is supported, false otherwise. michael@0: */ michael@0: virtual bool UsePollMode(); michael@0: michael@0: private: michael@0: /** michael@0: * Ensure that the timer is expiring at least at the given time michael@0: * michael@0: * The function might not restart the timer if there is one running currently michael@0: * michael@0: * @param aNextTimeout michael@0: * The last absolute time the timer should expire michael@0: */ michael@0: void SetTimerExpiryIfBefore(mozilla::TimeStamp aNextTimeout); michael@0: michael@0: /** michael@0: * Stores the next timeout time, 0 means timer not running michael@0: */ michael@0: mozilla::TimeStamp mCurrentlySetToTimeoutAt; michael@0: michael@0: /** michael@0: * mTimer holds the internal timer used by this class to detect when to poll michael@0: * for idle time, when to check if idle timers should expire etc. michael@0: */ michael@0: nsCOMPtr mTimer; michael@0: michael@0: /** michael@0: * Array of listeners that wants to be notified about idle time. michael@0: */ michael@0: nsTArray mArrayListeners; michael@0: michael@0: /** michael@0: * Object keeping track of the daily idle thingy. michael@0: */ michael@0: nsRefPtr mDailyIdle; michael@0: michael@0: /** michael@0: * Number of observers currently in idle mode. michael@0: */ michael@0: uint32_t mIdleObserverCount; michael@0: michael@0: /** michael@0: * Delta time from last non idle time to when the next observer should switch michael@0: * to idle mode michael@0: * michael@0: * Time in seconds michael@0: * michael@0: * If this value is 0 it means there are no active observers michael@0: */ michael@0: uint32_t mDeltaToNextIdleSwitchInS; michael@0: michael@0: /** michael@0: * Absolute value for when the last user interaction took place. michael@0: */ michael@0: mozilla::TimeStamp mLastUserInteraction; michael@0: michael@0: michael@0: /** michael@0: * Function that ensures the timer is running with at least the minimum time michael@0: * needed. It will kill the timer if there are no active observers. michael@0: */ michael@0: void ReconfigureTimer(void); michael@0: michael@0: /** michael@0: * Callback function that is called when the internal timer expires. michael@0: * michael@0: * This in turn calls the IdleTimerCallback that does the real processing michael@0: */ michael@0: static void StaticIdleTimerCallback(nsITimer* aTimer, void* aClosure); michael@0: michael@0: /** michael@0: * Function that handles when a timer has expired michael@0: */ michael@0: void IdleTimerCallback(void); michael@0: }; michael@0: michael@0: #endif // nsIdleService_h__