gecko/services/aitc/modules/main.js
Kyle Huey 1482122303 Bug 798491: Add an option to stick all chrome JSMs/JS components in the same compartment. r=mrbkap,philikon
--HG--
extra : rebase_source : 98337b6a8c07d05e8c961a452dd05a7d75c3c60b
2012-10-31 09:13:28 -07:00

175 lines
5.9 KiB
JavaScript

/* 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";
this.EXPORTED_SYMBOLS = ["Aitc"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-aitc/manager.js");
Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-common/log4moz.js");
Cu.import("resource://services-common/preferences.js");
this.Aitc = function Aitc() {
this._log = Log4Moz.repository.getLogger("Service.AITC");
this._log.level = Log4Moz.Level[Preferences.get(
"services.aitc.service.log.level"
)];
this._log.info("Loading AitC");
this.DASHBOARD_ORIGIN = CommonUtils.makeURI(
Preferences.get("services.aitc.dashboard.url")
).prePath;
let self = this;
this._manager = new AitcManager(function managerDone() {
CommonUtils.nextTick(self._init, self);
});
}
Aitc.prototype = {
// The goal of the init function is to be ready to activate the AITC
// client whenever the user is looking at the dashboard. It also calls
// the initialSchedule function on the manager.
_init: function _init() {
let self = this;
// Do an initial upload.
this._manager.initialSchedule(function queueDone(num) {
if (num == -1) {
self._log.debug("No initial upload was required");
return;
}
self._log.debug(num + " initial apps queued successfully");
});
// This is called iff the user is currently looking the dashboard.
function dashboardLoaded(browser) {
let win = browser.contentWindow;
self._log.info("Dashboard was accessed " + win);
// If page is ready to go, fire immediately.
if (win.document && win.document.readyState == "complete") {
self._manager.userActive(win);
return;
}
// Only fire event after the page fully loads.
browser.contentWindow.addEventListener(
"DOMContentLoaded",
function _contentLoaded(event) {
self._manager.userActive(win);
},
false
);
}
// This is called when the user's attention is elsewhere.
function dashboardUnloaded() {
self._log.info("Dashboard closed or in background");
self._manager.userIdle();
}
// Called when a URI is loaded in any tab. We have to listen for this
// because tabSelected is not called if I open a new tab which loads
// about:home and then navigate to the dashboard, or navigation via
// links on the currently open tab.
let listener = {
onLocationChange: function onLocationChange(browser, pr, req, loc, flag) {
let win = Services.wm.getMostRecentWindow("navigator:browser");
if (win.gBrowser.selectedBrowser == browser) {
if (loc.prePath == self.DASHBOARD_ORIGIN) {
dashboardLoaded(browser);
}
}
}
};
// Called when the current tab selection changes.
function tabSelected(event) {
let browser = event.target.linkedBrowser;
if (browser.currentURI.prePath == self.DASHBOARD_ORIGIN) {
dashboardLoaded(browser);
} else {
dashboardUnloaded();
}
}
// Add listeners for all windows opened in the future.
function winWatcher(subject, topic) {
if (topic != "domwindowopened") {
return;
}
subject.addEventListener("load", function winWatcherLoad() {
subject.removeEventListener("load", winWatcherLoad, false);
let doc = subject.document.documentElement;
if (doc.getAttribute("windowtype") == "navigator:browser") {
let browser = subject.gBrowser;
browser.addTabsProgressListener(listener);
browser.tabContainer.addEventListener("TabSelect", tabSelected);
}
}, false);
}
Services.ww.registerNotification(winWatcher);
// Add listeners for all current open windows.
let enumerator = Services.wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
let browser = enumerator.getNext().gBrowser;
browser.addTabsProgressListener(listener);
browser.tabContainer.addEventListener("TabSelect", tabSelected);
// Also check the currently open URI.
if (browser.currentURI.prePath == this.DASHBOARD_ORIGIN) {
dashboardLoaded(browser);
}
}
// Add listeners for app installs/uninstall.
Services.obs.addObserver(this, "webapps-sync-install", false);
Services.obs.addObserver(this, "webapps-sync-uninstall", false);
// Add listener for idle service.
let idleSvc = Cc["@mozilla.org/widget/idleservice;1"].
getService(Ci.nsIIdleService);
idleSvc.addIdleObserver(this,
Preferences.get("services.aitc.main.idleTime"));
},
observe: function(subject, topic, data) {
let app;
switch (topic) {
case "webapps-sync-install":
app = JSON.parse(data);
this._log.info(app.origin + " was installed, initiating PUT");
this._manager.appEvent("install", app);
break;
case "webapps-sync-uninstall":
app = JSON.parse(data);
this._log.info(app.origin + " was uninstalled, initiating PUT");
this._manager.appEvent("uninstall", app);
break;
case "idle":
this._log.info("User went idle");
if (this._manager) {
this._manager.userIdle();
}
break;
case "back":
this._log.info("User is no longer idle");
let win = Services.wm.getMostRecentWindow("navigator:browser");
if (win && win.gBrowser.currentURI.prePath == this.DASHBOARD_ORIGIN &&
this._manager) {
this._manager.userActive();
}
break;
}
},
};