CLOSED TREE Backed out changeset 2d42350d209a (bug 1203330) Backed out changeset 3a12c51c3eca (bug 1203330) Backed out changeset 31fac390e15d (bug 1203330)
156 lines
3.9 KiB
JavaScript
156 lines
3.9 KiB
JavaScript
"use strict";
|
|
|
|
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
|
|
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
|
var {
|
|
SingletonEventManager,
|
|
} = ExtensionUtils;
|
|
|
|
// WeakMap[Extension -> Map[name -> Alarm]]
|
|
var alarmsMap = new WeakMap();
|
|
|
|
// WeakMap[Extension -> Set[callback]]
|
|
var alarmCallbacksMap = new WeakMap();
|
|
|
|
// Manages an alarm created by the extension (alarms API).
|
|
function Alarm(extension, name, alarmInfo) {
|
|
this.extension = extension;
|
|
this.name = name;
|
|
this.when = alarmInfo.when;
|
|
this.delayInMinutes = alarmInfo.delayInMinutes;
|
|
this.periodInMinutes = alarmInfo.periodInMinutes;
|
|
this.canceled = false;
|
|
|
|
let delay, scheduledTime;
|
|
if (this.when) {
|
|
scheduledTime = this.when;
|
|
delay = this.when - Date.now();
|
|
} else {
|
|
if (!this.delayInMinutes) {
|
|
this.delayInMinutes = this.periodInMinutes;
|
|
}
|
|
delay = this.delayInMinutes * 60 * 1000;
|
|
scheduledTime = Date.now() + delay;
|
|
}
|
|
|
|
this.scheduledTime = scheduledTime;
|
|
|
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
timer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
|
this.timer = timer;
|
|
}
|
|
|
|
Alarm.prototype = {
|
|
clear() {
|
|
this.timer.cancel();
|
|
alarmsMap.get(this.extension).delete(this.name);
|
|
this.canceled = true;
|
|
},
|
|
|
|
observe(subject, topic, data) {
|
|
if (this.canceled) {
|
|
return;
|
|
}
|
|
|
|
for (let callback of alarmCallbacksMap.get(this.extension)) {
|
|
callback(this);
|
|
}
|
|
|
|
if (!this.periodInMinutes) {
|
|
this.clear();
|
|
return;
|
|
}
|
|
|
|
let delay = this.periodInMinutes * 60 * 1000;
|
|
this.scheduledTime = Date.now() + delay;
|
|
this.timer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
|
},
|
|
|
|
get data() {
|
|
return {
|
|
name: this.name,
|
|
scheduledTime: this.scheduledTime,
|
|
periodInMinutes: this.periodInMinutes,
|
|
};
|
|
},
|
|
};
|
|
|
|
/* eslint-disable mozilla/balanced-listeners */
|
|
extensions.on("startup", (type, extension) => {
|
|
alarmsMap.set(extension, new Map());
|
|
alarmCallbacksMap.set(extension, new Set());
|
|
});
|
|
|
|
extensions.on("shutdown", (type, extension) => {
|
|
if (alarmsMap.has(extension)) {
|
|
for (let alarm of alarmsMap.get(extension).values()) {
|
|
alarm.clear();
|
|
}
|
|
alarmsMap.delete(extension);
|
|
alarmCallbacksMap.delete(extension);
|
|
}
|
|
});
|
|
/* eslint-enable mozilla/balanced-listeners */
|
|
|
|
extensions.registerSchemaAPI("alarms", "addon_parent", context => {
|
|
let {extension} = context;
|
|
return {
|
|
alarms: {
|
|
create: function(name, alarmInfo) {
|
|
name = name || "";
|
|
let alarms = alarmsMap.get(extension);
|
|
if (alarms.has(name)) {
|
|
alarms.get(name).clear();
|
|
}
|
|
let alarm = new Alarm(extension, name, alarmInfo);
|
|
alarms.set(alarm.name, alarm);
|
|
},
|
|
|
|
get: function(name) {
|
|
name = name || "";
|
|
let alarms = alarmsMap.get(extension);
|
|
if (alarms.has(name)) {
|
|
return Promise.resolve(alarms.get(name).data);
|
|
}
|
|
return Promise.resolve();
|
|
},
|
|
|
|
getAll: function() {
|
|
let result = Array.from(alarmsMap.get(extension).values(), alarm => alarm.data);
|
|
return Promise.resolve(result);
|
|
},
|
|
|
|
clear: function(name) {
|
|
name = name || "";
|
|
let alarms = alarmsMap.get(extension);
|
|
if (alarms.has(name)) {
|
|
alarms.get(name).clear();
|
|
return Promise.resolve(true);
|
|
}
|
|
return Promise.resolve(false);
|
|
},
|
|
|
|
clearAll: function() {
|
|
let cleared = false;
|
|
for (let alarm of alarmsMap.get(extension).values()) {
|
|
alarm.clear();
|
|
cleared = true;
|
|
}
|
|
return Promise.resolve(cleared);
|
|
},
|
|
|
|
onAlarm: new SingletonEventManager(context, "alarms.onAlarm", fire => {
|
|
let callback = alarm => {
|
|
fire.sync(alarm.data);
|
|
};
|
|
|
|
alarmCallbacksMap.get(extension).add(callback);
|
|
return () => {
|
|
alarmCallbacksMap.get(extension).delete(callback);
|
|
};
|
|
}).api(),
|
|
},
|
|
};
|
|
});
|