1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5var EXPORTED_SYMBOLS = ["CalSleepMonitor"];
6
7var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
8var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
9
10/**
11 * This services watches for sleep/hibernate/standby and notifies observers.
12 * This service is only loaded on Linux (see components.conf), as Windows
13 * and Mac have gecko provided `wake_notification`s.
14 */
15
16function CalSleepMonitor() {
17  this.wrappedJSObject = this;
18}
19
20CalSleepMonitor.prototype = {
21  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
22  classID: Components.ID("9b987a8d-c2ef-4cb9-9602-1261b4b2f6fa"),
23
24  interval: 60000,
25  timer: null,
26  expected: null,
27  tolerance: 1000,
28
29  callback() {
30    let now = Date.now();
31    if (now - this.expected > this.tolerance) {
32      cal.LOG("[CalSleepMonitor] Sleep cycle detected, notifying observers.");
33      Services.obs.notifyObservers(null, "wake_notification");
34    }
35    this.expected = now + this.interval;
36  },
37  start() {
38    this.stop();
39    this.expected = Date.now() + this.interval;
40    this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
41    this.timer.initWithCallback(
42      this.callback.bind(this),
43      this.interval,
44      Ci.nsITimer.TYPE_REPEATING_PRECISE
45    );
46  },
47  stop() {
48    if (this.timer) {
49      this.timer.cancel();
50      this.timer = null;
51    }
52  },
53
54  // nsIObserver:
55  observe(aSubject, aTopic, aData) {
56    if (aTopic == "profile-after-change") {
57      cal.LOG("[CalSleepMonitor] Starting sleep monitor.");
58      this.start();
59
60      Services.obs.addObserver(this, "quit-application");
61    } else if (aTopic == "quit-application") {
62      cal.LOG("[CalSleepMonitor] Stopping sleep monitor.");
63      this.stop();
64    }
65  },
66};
67