summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/parent/ext-idle.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/parent/ext-idle.js')
-rw-r--r--toolkit/components/extensions/parent/ext-idle.js113
1 files changed, 113 insertions, 0 deletions
diff --git a/toolkit/components/extensions/parent/ext-idle.js b/toolkit/components/extensions/parent/ext-idle.js
new file mode 100644
index 0000000000..f68ea293d7
--- /dev/null
+++ b/toolkit/components/extensions/parent/ext-idle.js
@@ -0,0 +1,113 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+XPCOMUtils.defineLazyServiceGetter(
+ this,
+ "idleService",
+ "@mozilla.org/widget/useridleservice;1",
+ "nsIUserIdleService"
+);
+
+var { DefaultWeakMap } = ExtensionUtils;
+
+// WeakMap[Extension -> Object]
+const idleObserversMap = new DefaultWeakMap(() => {
+ return {
+ observer: null,
+ detectionInterval: 60,
+ };
+});
+
+const getIdleObserver = extension => {
+ let observerInfo = idleObserversMap.get(extension);
+ let { observer, detectionInterval } = observerInfo;
+ let interval =
+ extension.startupData?.idleDetectionInterval || detectionInterval;
+
+ if (!observer) {
+ observer = new (class extends ExtensionCommon.EventEmitter {
+ observe(subject, topic, data) {
+ if (topic == "idle" || topic == "active") {
+ this.emit("stateChanged", topic);
+ }
+ }
+ })();
+ idleService.addIdleObserver(observer, interval);
+ observerInfo.observer = observer;
+ observerInfo.detectionInterval = interval;
+ }
+ return observer;
+};
+
+this.idle = class extends ExtensionAPIPersistent {
+ PERSISTENT_EVENTS = {
+ onStateChanged({ fire }) {
+ let { extension } = this;
+ let listener = (event, data) => {
+ fire.sync(data);
+ };
+
+ getIdleObserver(extension).on("stateChanged", listener);
+ return {
+ async unregister() {
+ let observerInfo = idleObserversMap.get(extension);
+ let { observer, detectionInterval } = observerInfo;
+ if (observer) {
+ observer.off("stateChanged", listener);
+ if (!observer.has("stateChanged")) {
+ idleService.removeIdleObserver(observer, detectionInterval);
+ observerInfo.observer = null;
+ }
+ }
+ },
+ convert(_fire) {
+ fire = _fire;
+ },
+ };
+ },
+ };
+
+ getAPI(context) {
+ let { extension } = context;
+ let self = this;
+
+ return {
+ idle: {
+ queryState(detectionIntervalInSeconds) {
+ if (idleService.idleTime < detectionIntervalInSeconds * 1000) {
+ return "active";
+ }
+ return "idle";
+ },
+ setDetectionInterval(detectionIntervalInSeconds) {
+ let observerInfo = idleObserversMap.get(extension);
+ let { observer, detectionInterval } = observerInfo;
+ if (detectionInterval == detectionIntervalInSeconds) {
+ return;
+ }
+ if (observer) {
+ idleService.removeIdleObserver(observer, detectionInterval);
+ idleService.addIdleObserver(observer, detectionIntervalInSeconds);
+ }
+ observerInfo.detectionInterval = detectionIntervalInSeconds;
+ // There is no great way to modify a persistent listener param, but we
+ // need to keep this for the startup listener.
+ if (!extension.persistentBackground) {
+ extension.startupData.idleDetectionInterval =
+ detectionIntervalInSeconds;
+ extension.saveStartupData();
+ }
+ },
+ onStateChanged: new EventManager({
+ context,
+ module: "idle",
+ event: "onStateChanged",
+ extensionApi: self,
+ }).api(),
+ },
+ };
+ }
+};