diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index df2080313f97..5d98b89e0719 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -114,6 +114,7 @@ XPIDLSRCS = \ nsIPrintSettings.idl \ nsIPrintSettingsService.idl \ nsIPrintOptions.idl \ + nsIIdleService.idl \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),windows) diff --git a/widget/public/nsIIdleService.idl b/widget/public/nsIIdleService.idl new file mode 100644 index 000000000000..8cb337b5f984 --- /dev/null +++ b/widget/public/nsIIdleService.idl @@ -0,0 +1,97 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Gijs Kruitbosch + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Gijs Kruitbosch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +interface nsIObserver; + +/** + * This interface lets you monitor how long the user has been 'idle', + * i.e. not used their mouse or keyboard. You can get the idle time directly, + * but in most cases you will want to register an observer for a predefined + * interval. The observer will get an 'idle' notification when the user is idle + * for that interval (or longer), and receive a 'back' notification when the + * user starts using their computer again. + */ + +[scriptable, uuid(cc52f19a-63ae-4a1c-9cc3-e79eace0b471)] +interface nsIIdleService : nsISupports +{ + /** + * The amount of time in milliseconds that has passed + * since the last user activity. + */ + readonly attribute unsigned long idleTime; + + /** + * Add an observer to be notified when the user idles for some period of + * time, and when they get back from that. + * + * @param observer the observer to be notified + * @param time the amount of time in minutes the user should idle before + * the observer should be notified. + * + * @note + * The subject of the notification the observer will get is always the + * nsIIdleService itself. + * When the user goes idle, the observer topic is "idle" and when they get + * back, the observer topic is "back". + * The data param for the notification contains the current user idle time. + * + * @note + * You can add the same observer twice. + * @note + * Most implementations need to poll the OS for idle info themselves, + * meaning your notifications could arrive with a delay up to the length + * of the polling interval in that implementation. + * Current implementations use a delay of 5 seconds. + */ + void addIdleObserver(in nsIObserver observer, in unsigned long time); + + /** + * Remove an observer registered with addIdleObserver. + * @param observer the observer that needs to be removed. + * @param time the amount of time they were listening for. + * @note + * Removing an observer will remove it once, for the idle time you specify. + * If you have added an observer multiple times, you will need to remove it + * just as many times. + */ + void removeIdleObserver(in nsIObserver observer, in unsigned long time); +}; + diff --git a/widget/public/nsWidgetsCID.h b/widget/public/nsWidgetsCID.h index 620a7f0c7c80..b4fa344d5b17 100644 --- a/widget/public/nsWidgetsCID.h +++ b/widget/public/nsWidgetsCID.h @@ -144,6 +144,9 @@ #define NS_SCREENMANAGER_CID \ { 0xc401eb80, 0xf9ea, 0x11d3, { 0xbb, 0x6f, 0xe7, 0x32, 0xb7, 0x3e, 0xbe, 0x7c } } +// {6987230e-0089-4e78-bc5f-1493ee7519fa} +#define NS_IDLE_SERVICE_CID \ +{ 0x6987230e, 0x0098, 0x4e78, { 0xbc, 0x5f, 0x14, 0x93, 0xee, 0x75, 0x19, 0xfa } } //----------------------------------------------------------- //Printing diff --git a/widget/src/gtk2/Makefile.in b/widget/src/gtk2/Makefile.in index b0d913435cb2..b46b4b01e2b0 100644 --- a/widget/src/gtk2/Makefile.in +++ b/widget/src/gtk2/Makefile.in @@ -113,6 +113,7 @@ CPPSRCS = \ nsPrintJobFactoryGTK.cpp \ nsPrintJobGTK.cpp \ nsTempfilePS.cpp \ + nsIdleServiceGTK.cpp \ $(NULL) # build our subdirs, too diff --git a/widget/src/gtk2/nsIdleServiceGTK.cpp b/widget/src/gtk2/nsIdleServiceGTK.cpp new file mode 100644 index 000000000000..51cfe05cc1fd --- /dev/null +++ b/widget/src/gtk2/nsIdleServiceGTK.cpp @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Gijs Kruitbosch . + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Gijs Kruitbosch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIdleServiceGTK.h" +#include "nsIServiceManager.h" +#include "nsDebug.h" +#include "prlink.h" +#include "prlog.h" + + +#ifdef PR_LOGGING +static PRLogModuleInfo* sIdleLog = nsnull; +#endif + +typedef PRBool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base, + int* error_base); + +typedef XScreenSaverInfo* (*_XScreenSaverAllocInfo_fn)(void); + +typedef void (*_XScreenSaverQueryInfo_fn)(Display* dpy, Drawable drw, + XScreenSaverInfo *info); + +static PRLibrary* xsslib = nsnull; +static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nsnull; +static _XScreenSaverAllocInfo_fn _XSSAllocInfo = nsnull; +static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nsnull; + + +NS_IMPL_ISUPPORTS1(nsIdleServiceGTK, nsIIdleService) + +nsIdleServiceGTK::nsIdleServiceGTK() + : mXssInfo(nsnull) +{ +#ifdef PR_LOGGING + if (!sIdleLog) + sIdleLog = PR_NewLogModule("nsIIdleService"); +#endif + + xsslib = PR_LoadLibrary("libXss.so.1"); + if (!xsslib) // ouch. + { +#ifdef PR_LOGGING + PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to find libXss.so!\n")); +#endif + return; + } + + _XSSQueryExtension = (_XScreenSaverQueryExtension_fn) + PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension"); + _XSSAllocInfo = (_XScreenSaverAllocInfo_fn) + PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo"); + _XSSQueryInfo = (_XScreenSaverQueryInfo_fn) + PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo"); +#ifdef PR_LOGGING + if (!_XSSQueryExtension) + PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryExtension!\n")); + if (!_XSSAllocInfo) + PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSAllocInfo!\n")); + if (!_XSSQueryInfo) + PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryInfo!\n")); +#endif + +} + +nsIdleServiceGTK::~nsIdleServiceGTK() +{ + if (mXssInfo) + XFree(mXssInfo); + if (xsslib) + PR_UnloadLibrary(xsslib); +} + +NS_IMETHODIMP +nsIdleServiceGTK::GetIdleTime(PRUint32 *aTimeDiff) +{ + // Ask xscreensaver about idle time: + int event_base, error_base; + *aTimeDiff = 0; + + // We might not have a display (cf. in xpcshell) + Display *dplay = GDK_DISPLAY(); + if (!dplay || !_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) + { +#ifdef PR_LOGGING + if (!dplay) + PR_LOG(sIdleLog, PR_LOG_WARNING, ("No display found!\n")); + else + PR_LOG(sIdleLog, PR_LOG_WARNING, ("One of the Xss functions is missing!\n")); +#endif + return NS_ERROR_FAILURE; + } + + if (_XSSQueryExtension(dplay, &event_base, &error_base)) + { + if (!mXssInfo) + mXssInfo = _XSSAllocInfo(); + if (!mXssInfo) + return NS_ERROR_OUT_OF_MEMORY; + _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo); + *aTimeDiff = mXssInfo->idle; + return NS_OK; + } + // If we get here, we couldn't get to XScreenSaver: +#ifdef PR_LOGGING + PR_LOG(sIdleLog, PR_LOG_WARNING, ("XSSQueryExtension returned false!\n")); +#endif + return NS_ERROR_FAILURE; +} + diff --git a/widget/src/gtk2/nsIdleServiceGTK.h b/widget/src/gtk2/nsIdleServiceGTK.h new file mode 100644 index 000000000000..a6059c2817f5 --- /dev/null +++ b/widget/src/gtk2/nsIdleServiceGTK.h @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Gijs Kruitbosch . + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Gijs Kruitbosch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsIdleServiceGTK_h__ +#define nsIdleServiceGTK_h__ + +#include "nsIdleService.h" +#include +#include +#include + +typedef struct { + Window window; // Screen saver window + int state; // ScreenSaver(Off,On,Disabled) + int kind; // ScreenSaver(Blanked,Internal,External) + unsigned long til_or_since; // milliseconds since/til screensaver kicks in + unsigned long idle; // milliseconds idle + unsigned long event_mask; // event stuff +} XScreenSaverInfo; + +class nsIdleServiceGTK : public nsIdleService +{ +public: + NS_DECL_ISUPPORTS + nsIdleServiceGTK(); + + NS_IMETHOD GetIdleTime(PRUint32* idleTime); +private: + ~nsIdleServiceGTK(); + XScreenSaverInfo* mXssInfo; +}; + +#endif // nsIdleServiceGTK_h__ diff --git a/widget/src/gtk2/nsWidgetFactory.cpp b/widget/src/gtk2/nsWidgetFactory.cpp index bcb867b417ad..b2af603b7526 100644 --- a/widget/src/gtk2/nsWidgetFactory.cpp +++ b/widget/src/gtk2/nsWidgetFactory.cpp @@ -59,6 +59,7 @@ #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsImageToPixbuf.h" +#include "nsIdleServiceGTK.h" #ifdef NATIVE_THEME_SUPPORT #include "nsNativeThemeGTK.h" @@ -95,6 +96,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsGTK, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorGTK) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceGTK) static NS_IMETHODIMP nsFilePickerConstructor(nsISupports *aOuter, REFNSIID aIID, @@ -268,6 +270,10 @@ static const nsModuleComponentInfo components[] = NS_IMAGE_TO_PIXBUF_CID, "@mozilla.org/widget/image-to-gdk-pixbuf;1", nsImageToPixbufConstructor }, + { "User Idle Service", + NS_IDLE_SERVICE_CID, + "@mozilla.org/widget/idleservice;1", + nsIdleServiceGTKConstructor }, }; PR_STATIC_CALLBACK(void) diff --git a/widget/src/xpwidgets/Makefile.in b/widget/src/xpwidgets/Makefile.in index cffbbb306a14..5a3487fae4b3 100644 --- a/widget/src/xpwidgets/Makefile.in +++ b/widget/src/xpwidgets/Makefile.in @@ -81,6 +81,7 @@ CPPSRCS = \ nsPrintSettingsImpl.cpp \ nsPrintSession.cpp \ nsWidgetAtoms.cpp \ + nsIdleService.cpp \ $(NULL) ifneq (,$(filter beos os2 mac qt cocoa windows,$(MOZ_WIDGET_TOOLKIT))) diff --git a/widget/src/xpwidgets/nsIdleService.cpp b/widget/src/xpwidgets/nsIdleService.cpp new file mode 100644 index 000000000000..1330d438ac5c --- /dev/null +++ b/widget/src/xpwidgets/nsIdleService.cpp @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Gijs Kruitbosch . + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Gijs Kruitbosch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIdleService.h" +#include "nsString.h" +#include "nsIServiceManager.h" +#include "nsDebug.h" +#include "nsCOMArray.h" + +// observer topics used: +#define OBSERVER_TOPIC_IDLE "idle" +#define OBSERVER_TOPIC_BACK "back" +// interval in milliseconds between internal idle time requests +#define IDLE_POLL_INTERVAL 5000 + + + +// Use this to find previously added observers in our array: +class IdleListenerComparator +{ +public: + PRBool Equals(IdleListener a, IdleListener b) const + { + return (a.observer == b.observer) && + (a.reqIdleTime == b.reqIdleTime); + } +}; + +nsIdleService::nsIdleService() +{ +} + +nsIdleService::~nsIdleService() +{ + if (mTimer) + mTimer->Cancel(); +} + +NS_IMETHODIMP +nsIdleService::AddIdleObserver(nsIObserver* aObserver, PRUint32 aIdleTime) +{ + NS_ENSURE_ARG_POINTER(aObserver); + NS_ENSURE_ARG(aIdleTime); + + // Put the time + observer in a struct we can keep: + IdleListener listener(aObserver, aIdleTime); + + if (!mArrayListeners.AppendElement(listener)) + return NS_ERROR_OUT_OF_MEMORY; + + // Initialize our timer callback if it's not there already. + if (!mTimer) + { + nsresult rv; + mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + mTimer->InitWithFuncCallback(IdleTimerCallback, this, IDLE_POLL_INTERVAL, + nsITimer::TYPE_REPEATING_SLACK); + } + + // Make sure our observer goes into 'idle' immediately if applicable. + CheckAwayState(); + + return NS_OK; +} + +NS_IMETHODIMP +nsIdleService::RemoveIdleObserver(nsIObserver* aObserver, PRUint32 aTime) +{ + NS_ENSURE_ARG_POINTER(aObserver); + NS_ENSURE_ARG(aTime); + IdleListener listener(aObserver, aTime); + + // Find the entry and remove it: + IdleListenerComparator c; + if (mArrayListeners.RemoveElement(listener, c)) + { + if (mTimer && mArrayListeners.IsEmpty()) + { + mTimer->Cancel(); + mTimer = nsnull; + } + return NS_OK; + } + + // If we get here, we haven't removed anything: + return NS_ERROR_FAILURE; +} + +void +nsIdleService::IdleTimerCallback(nsITimer* aTimer, void* aClosure) +{ + NS_STATIC_CAST(nsIdleService*, aClosure)->CheckAwayState(); +} + +void +nsIdleService::CheckAwayState() +{ + // Get the idle time. + PRUint32 idleTime; + if (NS_FAILED(GetIdleTime(&idleTime))) + return; + + nsAutoString timeStr; + timeStr.AppendInt(idleTime); + + // Change state first, and save observers that need notification, so + // removing things will always work without upsetting notifications. + nsCOMArray idleListeners; + nsCOMArray hereListeners; + for (PRUint32 i = 0; i < mArrayListeners.Length(); i++) + { + IdleListener& curListener = mArrayListeners.ElementAt(i); + if ((curListener.reqIdleTime * 60000 <= idleTime) && + !curListener.isIdle) + { + curListener.isIdle = PR_TRUE; + idleListeners.AppendObject(curListener.observer); + } + else if ((curListener.reqIdleTime * 60000 > idleTime) && + curListener.isIdle) + { + curListener.isIdle = PR_FALSE; + hereListeners.AppendObject(curListener.observer); + } + } + + // Notify listeners gone idle: + for (PRInt32 i = 0; i < idleListeners.Count(); i++) + { + idleListeners[i]->Observe(this, OBSERVER_TOPIC_IDLE, timeStr.get()); + } + + // Notify listeners that came back: + for (PRInt32 i = 0; i < hereListeners.Count(); i++) + { + hereListeners[i]->Observe(this, OBSERVER_TOPIC_BACK, timeStr.get()); + } +} + diff --git a/widget/src/xpwidgets/nsIdleService.h b/widget/src/xpwidgets/nsIdleService.h new file mode 100644 index 000000000000..eb2c54c81b47 --- /dev/null +++ b/widget/src/xpwidgets/nsIdleService.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Gijs Kruitbosch . + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Gijs Kruitbosch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsIdleService_h__ +#define nsIdleService_h__ + +#include "nsIIdleService.h" +#include "nsCOMPtr.h" +#include "nsITimer.h" +#include "nsTArray.h" +#include "nsIObserver.h" + +// Class we can use to store an observer with its associated idle time +// requirement and whether or not the observer thinks it's "idle". +class IdleListener { +public: + nsCOMPtr observer; + PRUint32 reqIdleTime; + PRBool isIdle; + + IdleListener(nsIObserver* obs, PRUint32 reqIT, PRBool aIsIdle = PR_FALSE) : + observer(obs), reqIdleTime(reqIT), isIdle(aIsIdle) {} + ~IdleListener() {} +}; + +class nsIdleService : public nsIIdleService +{ +public: + nsIdleService(); + + // Implement nsIIdleService methods, but not the idleTime getter, + // which is platform-dependent. + NS_IMETHOD AddIdleObserver(nsIObserver* aObserver, PRUint32 aIdleTime); + NS_IMETHOD RemoveIdleObserver(nsIObserver* aObserver, PRUint32 aIdleTime); + + static void IdleTimerCallback(nsITimer* aTimer, void* aClosure); + +protected: + void CheckAwayState(); + ~nsIdleService(); + +private: + nsCOMPtr mTimer; + nsTArray mArrayListeners; +}; + +#endif // nsIdleService_h__