summaryrefslogtreecommitdiff
path: root/services/sync/Weave.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/Weave.js')
-rw-r--r--services/sync/Weave.js101
1 files changed, 87 insertions, 14 deletions
diff --git a/services/sync/Weave.js b/services/sync/Weave.js
index f39eb12f5..80b81d36e 100644
--- a/services/sync/Weave.js
+++ b/services/sync/Weave.js
@@ -9,6 +9,8 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+Cu.import("resource://services-sync/util.js");
const SYNC_PREFS_BRANCH = "services.sync.";
@@ -24,13 +26,25 @@ const SYNC_PREFS_BRANCH = "services.sync.";
*
* If Sync is not configured, no extra Sync code is loaded. If an
* external component (say the UI) needs to interact with Sync, it
- * should do something like the following:
+ * should use the promise-base function whenLoaded() - something like the
+ * following:
*
* // 1. Grab a handle to the Sync XPCOM service.
* let service = Cc["@mozilla.org/weave/service;1"]
* .getService(Components.interfaces.nsISupports)
* .wrappedJSObject;
*
+ * // 2. Use the .then method of the promise.
+ * service.whenLoaded().then(() => {
+ * // You are free to interact with "Weave." objects.
+ * return;
+ * });
+ *
+ * And that's it! However, if you really want to avoid promises and do it
+ * old-school, then
+ *
+ * // 1. Get a reference to the service as done in (1) above.
+ *
* // 2. Check if the service has been initialized.
* if (service.ready) {
* // You are free to interact with "Weave." objects.
@@ -58,12 +72,68 @@ WeaveService.prototype = {
Ci.nsISupportsWeakReference]),
ensureLoaded: function () {
+ // If we are loaded and not using FxA, load the migration module.
+ if (!this.fxAccountsEnabled) {
+ Cu.import("resource://services-sync/FxaMigrator.jsm");
+ }
+
Components.utils.import("resource://services-sync/main.js");
// Side-effect of accessing the service is that it is instantiated.
Weave.Service;
},
+ whenLoaded: function() {
+ if (this.ready) {
+ return Promise.resolve();
+ }
+ let deferred = Promise.defer();
+
+ Services.obs.addObserver(function onReady() {
+ Services.obs.removeObserver(onReady, "weave:service:ready");
+ deferred.resolve();
+ }, "weave:service:ready", false);
+ this.ensureLoaded();
+ return deferred.promise;
+ },
+
+ /**
+ * Whether Firefox Accounts is enabled.
+ *
+ * @return bool
+ *
+ * This function is currently always returning false because we don't support
+ * the use of FxA/Sync-1.5 but do want to keep the code "just in case".
+ */
+ get fxAccountsEnabled() {
+ // Early exit: FxA not supported.
+ return false;
+
+ try {
+ // Old sync guarantees '@' will never appear in the username while FxA
+ // uses the FxA email address - so '@' is the flag we use.
+ let username = Services.prefs.getCharPref(SYNC_PREFS_BRANCH + "username");
+ return !username || username.includes('@');
+ } catch (_) {
+ return true; // No username == only allow FxA to be configured.
+ }
+ },
+
+ /**
+ * Whether Sync appears to be enabled.
+ *
+ * This returns true if all the Sync preferences for storing account
+ * and server configuration are populated.
+ *
+ * It does *not* perform a robust check to see if the client is working.
+ * For that, you'll want to check Weave.Status.checkSetup().
+ */
+ get enabled() {
+ let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
+ return prefs.prefHasUserValue("username") &&
+ prefs.prefHasUserValue("clusterURL");
+ },
+
observe: function (subject, topic, data) {
switch (topic) {
case "app-startup":
@@ -77,20 +147,22 @@ WeaveService.prototype = {
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.timer.initWithCallback({
notify: function() {
+ let isConfigured = false;
// We only load more if it looks like Sync is configured.
let prefs = Services.prefs.getBranch(SYNC_PREFS_BRANCH);
-
- if (!prefs.prefHasUserValue("username")) {
- return;
+ if (prefs.prefHasUserValue("username")) {
+ // We have a username. So, do a more thorough check. This will
+ // import a number of modules and thus increase memory
+ // accordingly. We could potentially copy code performed by
+ // this check into this file if our above code is yielding too
+ // many false positives.
+ Components.utils.import("resource://services-sync/main.js");
+ isConfigured = Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED;
}
-
- // We have a username. So, do a more thorough check. This will
- // import a number of modules and thus increase memory
- // accordingly. We could potentially copy code performed by
- // this check into this file if our above code is yielding too
- // many false positives.
- Components.utils.import("resource://services-sync/main.js");
- if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
+ let getHistogramById = Services.telemetry.getHistogramById;
+ getHistogramById("WEAVE_CONFIGURED").add(isConfigured);
+ if (isConfigured) {
+ getHistogramById("WEAVE_CONFIGURED_MASTER_PASSWORD").add(Utils.mpEnabled());
this.ensureLoaded();
}
}.bind(this)
@@ -111,10 +183,11 @@ AboutWeaveLog.prototype = {
return 0;
},
- newChannel: function(aURI) {
+ newChannel: function(aURI, aLoadInfo) {
let dir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
let uri = Services.io.newFileURI(dir);
- let channel = Services.io.newChannelFromURI(uri);
+ let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
+
channel.originalURI = aURI;
// Ensure that the about page has the same privileges as a regular directory