diff options
Diffstat (limited to 'toolkit/components/webextensions/ext-idle.js')
-rw-r--r-- | toolkit/components/webextensions/ext-idle.js | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/toolkit/components/webextensions/ext-idle.js b/toolkit/components/webextensions/ext-idle.js new file mode 100644 index 000000000..c5be4b600 --- /dev/null +++ b/toolkit/components/webextensions/ext-idle.js @@ -0,0 +1,94 @@ +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/ExtensionUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter", + "resource://devtools/shared/event-emitter.js"); +XPCOMUtils.defineLazyServiceGetter(this, "idleService", + "@mozilla.org/widget/idleservice;1", + "nsIIdleService"); +const { + SingletonEventManager, +} = ExtensionUtils; + +// WeakMap[Extension -> Object] +var observersMap = new WeakMap(); + +function getObserverInfo(extension, context) { + let observerInfo = observersMap.get(extension); + if (!observerInfo) { + observerInfo = { + observer: null, + detectionInterval: 60, + }; + observersMap.set(extension, observerInfo); + context.callOnClose({ + close: () => { + let {observer, detectionInterval} = observersMap.get(extension); + if (observer) { + idleService.removeIdleObserver(observer, detectionInterval); + } + observersMap.delete(extension); + }, + }); + } + return observerInfo; +} + +function getObserver(extension, context) { + let observerInfo = getObserverInfo(extension, context); + let {observer, detectionInterval} = observerInfo; + if (!observer) { + observer = { + observe: function(subject, topic, data) { + if (topic == "idle" || topic == "active") { + this.emit("stateChanged", topic); + } + }, + }; + EventEmitter.decorate(observer); + idleService.addIdleObserver(observer, detectionInterval); + observerInfo.observer = observer; + observerInfo.detectionInterval = detectionInterval; + } + return observer; +} + +function setDetectionInterval(extension, context, newInterval) { + let observerInfo = getObserverInfo(extension, context); + let {observer, detectionInterval} = observerInfo; + if (observer) { + idleService.removeIdleObserver(observer, detectionInterval); + idleService.addIdleObserver(observer, newInterval); + } + observerInfo.detectionInterval = newInterval; +} + +extensions.registerSchemaAPI("idle", "addon_parent", context => { + let {extension} = context; + return { + idle: { + queryState: function(detectionIntervalInSeconds) { + if (idleService.idleTime < detectionIntervalInSeconds * 1000) { + return Promise.resolve("active"); + } + return Promise.resolve("idle"); + }, + setDetectionInterval: function(detectionIntervalInSeconds) { + setDetectionInterval(extension, context, detectionIntervalInSeconds); + }, + onStateChanged: new SingletonEventManager(context, "idle.onStateChanged", fire => { + let listener = (event, data) => { + context.runSafe(fire, data); + }; + + getObserver(extension, context).on("stateChanged", listener); + return () => { + getObserver(extension, context).off("stateChanged", listener); + }; + }).api(), + }, + }; +}); |