Bug 584241 - Disable trackers when client isn't configured [r=mconnor]

This commit is contained in:
Philipp von Weitershausen 2010-08-06 17:30:58 +02:00
parent 905ac1573e
commit 57c4f23de7
7 changed files with 189 additions and 59 deletions

View File

@ -54,7 +54,6 @@ catch(ex) {
} }
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/ext/Observers.js");
Cu.import("resource://services-sync/stores.js"); Cu.import("resource://services-sync/stores.js");
Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/trackers.js");
Cu.import("resource://services-sync/type_records/bookmark.js"); Cu.import("resource://services-sync/type_records/bookmark.js");
@ -115,12 +114,12 @@ BookmarksEngine.prototype = {
_trackerObj: BookmarksTracker, _trackerObj: BookmarksTracker,
_handleImport: function _handleImport() { _handleImport: function _handleImport() {
Observers.add("bookmarks-restore-begin", function() { Svc.Obs.add("bookmarks-restore-begin", function() {
this._log.debug("Ignoring changes from importing bookmarks"); this._log.debug("Ignoring changes from importing bookmarks");
this._tracker.ignoreAll = true; this._tracker.ignoreAll = true;
}, this); }, this);
Observers.add("bookmarks-restore-success", function() { Svc.Obs.add("bookmarks-restore-success", function() {
this._log.debug("Tracking all items on successful import"); this._log.debug("Tracking all items on successful import");
this._tracker.ignoreAll = false; this._tracker.ignoreAll = false;
@ -129,7 +128,7 @@ BookmarksEngine.prototype = {
this._tracker.addChangedID(id); this._tracker.addChangedID(id);
}, this); }, this);
Observers.add("bookmarks-restore-failed", function() { Svc.Obs.add("bookmarks-restore-failed", function() {
this._tracker.ignoreAll = false; this._tracker.ignoreAll = false;
}, this); }, this);
}, },
@ -251,7 +250,7 @@ function BookmarksStore(name) {
Store.call(this, name); Store.call(this, name);
// Explicitly nullify our references to our cached services so we don't leak // Explicitly nullify our references to our cached services so we don't leak
Observers.add("places-shutdown", function() { Svc.Obs.add("places-shutdown", function() {
this.__bms = null; this.__bms = null;
this.__hsvc = null; this.__hsvc = null;
this.__ls = null; this.__ls = null;
@ -1001,17 +1000,37 @@ function BookmarksTracker(name) {
for (let guid in kSpecialIds) for (let guid in kSpecialIds)
this.ignoreID(guid); this.ignoreID(guid);
Svc.Bookmark.addObserver(this, true); Svc.Obs.add("places-shutdown", this);
Svc.Obs.add("weave:engine:start-tracking", this);
// Explicitly nullify our references to our cached services so we don't leak Svc.Obs.add("weave:engine:stop-tracking", this);
Observers.add("places-shutdown", function() {
this.__ls = null;
this.__bms = null;
}, this);
} }
BookmarksTracker.prototype = { BookmarksTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
_enabled: false,
observe: function observe(subject, topic, data) {
switch (topic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
Svc.Bookmark.addObserver(this, true);
this._enabled = true;
}
break;
case "weave:engine:stop-tracking":
if (this._enabled) {
Svc.Bookmark.removeObserver(this);
this._enabled = false;
}
// Fall through to clean up.
case "places-shutdown":
// Explicitly nullify our references to our cached services so
// we don't leak
this.__ls = null;
this.__bms = null;
break;
}
},
__bms: null, __bms: null,
get _bms() { get _bms() {
if (!this.__bms) if (!this.__bms)

View File

@ -202,12 +202,8 @@ FormStore.prototype = {
function FormTracker(name) { function FormTracker(name) {
Tracker.call(this, name); Tracker.call(this, name);
Svc.Obs.add("form-notifier", this); Svc.Obs.add("weave:engine:start-tracking", this);
Svc.Obs.add("weave:engine:stop-tracking", this);
// nsHTMLFormElement doesn't use the normal observer/observe pattern and looks
// up nsIFormSubmitObservers to .notify() them so add manually to observers
Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService).
addObserver(this, "earlyformsubmit", true);
} }
FormTracker.prototype = { FormTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
@ -222,7 +218,37 @@ FormTracker.prototype = {
this.score += 10; this.score += 10;
}, },
_enabled: false,
observe: function observe(subject, topic, data) { observe: function observe(subject, topic, data) {
switch (topic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
Svc.Obs.add("form-notifier", this);
// nsHTMLFormElement doesn't use the normal observer/observe
// pattern and looks up nsIFormSubmitObservers to .notify()
// them so add manually to observers
Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService)
.addObserver(this, "earlyformsubmit", true);
this._enabled = true;
}
break;
case "weave:engine:stop-tracking":
if (this._enabled) {
Svc.Obs.remove("form-notifier", this);
Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService)
.removeObserver(this, "earlyformsubmit");
this._enabled = false;
}
break;
case "form-notifier":
this.onFormNotifier(data);
break;
}
},
onFormNotifier: function onFormNotifier(data) {
let name, value; let name, value;
// Figure out if it's a function that we care about tracking // Figure out if it's a function that we care about tracking

View File

@ -257,11 +257,30 @@ HistoryStore.prototype = {
function HistoryTracker(name) { function HistoryTracker(name) {
Tracker.call(this, name); Tracker.call(this, name);
Svc.History.addObserver(this, true); Svc.Obs.add("weave:engine:start-tracking", this);
Svc.Obs.add("weave:engine:stop-tracking", this);
} }
HistoryTracker.prototype = { HistoryTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
_enabled: false,
observe: function observe(subject, topic, data) {
switch (topic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
Svc.History.addObserver(this, true);
this._enabled = true;
}
break;
case "weave:engine:stop-tracking":
if (this._enabled) {
Svc.History.removeObserver(this);
this._enabled = false;
}
break;
}
},
QueryInterface: XPCOMUtils.generateQI([ QueryInterface: XPCOMUtils.generateQI([
Ci.nsINavHistoryObserver, Ci.nsINavHistoryObserver,
Ci.nsINavHistoryObserver_MOZILLA_1_9_1_ADDITIONS, Ci.nsINavHistoryObserver_MOZILLA_1_9_1_ADDITIONS,

View File

@ -44,7 +44,6 @@ const Ci = Components.interfaces;
Cu.import("resource://services-sync/base_records/collection.js"); Cu.import("resource://services-sync/base_records/collection.js");
Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/ext/Observers.js");
Cu.import("resource://services-sync/stores.js"); Cu.import("resource://services-sync/stores.js");
Cu.import("resource://services-sync/trackers.js"); Cu.import("resource://services-sync/trackers.js");
Cu.import("resource://services-sync/type_records/passwords.js"); Cu.import("resource://services-sync/type_records/passwords.js");
@ -224,16 +223,33 @@ PasswordStore.prototype = {
function PasswordTracker(name) { function PasswordTracker(name) {
Tracker.call(this, name); Tracker.call(this, name);
Observers.add("passwordmgr-storage-changed", this); Svc.Obs.add("weave:engine:start-tracking", this);
Svc.Obs.add("weave:engine:stop-tracking", this);
} }
PasswordTracker.prototype = { PasswordTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
/* A single add, remove or change is 15 points, all items removed is 50 */ _enabled: false,
observe: function PasswordTracker_observe(aSubject, aTopic, aData) { observe: function PasswordTracker_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
Svc.Obs.add("passwordmgr-storage-changed", this);
this._enabled = true;
}
return;
case "weave:engine:stop-tracking":
if (this._enabled) {
Svc.Obs.remove("passwordmgr-storage-changed", this);
this._enabled = false;
}
return;
}
if (this.ignoreAll) if (this.ignoreAll)
return; return;
// A single add, remove or change is 15 points, all items removed is 50
switch (aData) { switch (aData) {
case 'modifyLogin': case 'modifyLogin':
aSubject = aSubject.QueryInterface(Ci.nsIArray). aSubject = aSubject.QueryInterface(Ci.nsIArray).

View File

@ -231,8 +231,9 @@ PrefStore.prototype = {
function PrefTracker(name) { function PrefTracker(name) {
Tracker.call(this, name); Tracker.call(this, name);
this._prefs.addObserver("", this, false);
Svc.Obs.add("profile-before-change", this); Svc.Obs.add("profile-before-change", this);
Svc.Obs.add("weave:engine:start-tracking", this);
Svc.Obs.add("weave:engine:stop-tracking", this);
} }
PrefTracker.prototype = { PrefTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
@ -255,8 +256,21 @@ PrefTracker.prototype = {
return this.__syncPrefs; return this.__syncPrefs;
}, },
_enabled: false,
observe: function(aSubject, aTopic, aData) { observe: function(aSubject, aTopic, aData) {
switch (aTopic) { switch (aTopic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
this._prefs.addObserver("", this, false);
this._enabled = true;
}
break;
case "weave:engine:stop-tracking":
if (this._enabled) {
this._prefs.removeObserver("", this);
this._enabled = false;
}
// Fall through to clean up.
case "profile-before-change": case "profile-before-change":
this.__prefs = null; this.__prefs = null;
this.__syncPrefs = null; this.__syncPrefs = null;

View File

@ -225,53 +225,75 @@ TabStore.prototype = {
function TabTracker(name) { function TabTracker(name) {
Tracker.call(this, name); Tracker.call(this, name);
Svc.Obs.add("weave:engine:start-tracking", this);
Svc.Obs.add("private-browsing", this); Svc.Obs.add("weave:engine:stop-tracking", this);
// Make sure "this" pointer is always set correctly for event listeners // Make sure "this" pointer is always set correctly for event listeners
this.onTab = Utils.bind2(this, this.onTab); this.onTab = Utils.bind2(this, this.onTab);
this._unregisterListeners = Utils.bind2(this, this._unregisterListeners);
// Register as an observer so we can catch windows opening and closing:
Svc.Obs.add("domwindowopened", this);
// Also register listeners on already open windows
let wins = Svc.WinMediator.getEnumerator("navigator:browser");
while (wins.hasMoreElements())
this._registerListenersForWindow(wins.getNext());
} }
TabTracker.prototype = { TabTracker.prototype = {
__proto__: Tracker.prototype, __proto__: Tracker.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
_registerListenersForWindow: function TabTracker__registerListen(window) { _topics: ["pageshow", "TabOpen", "TabClose", "TabSelect"],
this._log.trace("Registering tab listeners in new window"); _registerListenersForWindow: function registerListenersFW(window) {
this._log.trace("Registering tab listeners in window");
// For each topic, add or remove onTab as the listener for each (let topic in this._topics) {
let topics = ["pageshow", "TabOpen", "TabClose", "TabSelect"]; window.addEventListener(topic, this.onTab, false);
let onTab = this.onTab; }
let addRem = function(add) topics.forEach(function(topic) { window.addEventListener("unload", this._unregisterListeners, false);
window[(add ? "add" : "remove") + "EventListener"](topic, onTab, false);
});
// Add the listeners now and remove them on unload
addRem(true);
window.addEventListener("unload", function() addRem(false), false);
}, },
observe: function TabTracker_observe(aSubject, aTopic, aData) { _unregisterListeners: function unregisterListeners(event) {
// Add tab listeners now that a window has opened this._unregisterListenersForWindow(event.target);
if (aTopic == "domwindowopened") { },
let self = this;
aSubject.addEventListener("load", function onLoad(event) { _unregisterListenersForWindow: function unregisterListenersFW(window) {
aSubject.removeEventListener("load", onLoad, false); this._log.trace("Removing tab listeners in window");
// Only register after the window is done loading to avoid unloads window.removeEventListener("unload", this._unregisterListeners, false);
self._registerListenersForWindow(aSubject); for each (let topic in this._topics) {
}, false); window.removeEventListener(topic, this.onTab, false);
}
},
_enabled: false,
observe: function TabTracker_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "weave:engine:start-tracking":
if (!this._enabled) {
Svc.Obs.add("private-browsing", this);
Svc.Obs.add("domwindowopened", this);
let wins = Svc.WinMediator.getEnumerator("navigator:browser");
while (wins.hasMoreElements())
this._registerListenersForWindow(wins.getNext());
this._enabled = true;
}
break;
case "weave:engine:stop-tracking":
if (this._enabled) {
Svc.Obs.remove("private-browsing", this);
Svc.Obs.remove("domwindowopened", this);
let wins = Svc.WinMediator.getEnumerator("navigator:browser");
while (wins.hasMoreElements())
this._unregisterListenersForWindow(wins.getNext());
this._enabled = false;
}
return;
case "domwindowopened":
// Add tab listeners now that a window has opened
let self = this;
aSubject.addEventListener("load", function onLoad(event) {
aSubject.removeEventListener("load", onLoad, false);
// Only register after the window is done loading to avoid unloads
self._registerListenersForWindow(aSubject);
}, false);
break;
case "private-browsing":
if (aData == "enter" && !PBPrefs.get("autostart"))
this.clearChangedIDs();
} }
else if (aTopic == "private-browsing" && aData == "enter"
&& !PBPrefs.get("autostart"))
this.clearChangedIDs();
}, },
onTab: function onTab(event) { onTab: function onTab(event) {

View File

@ -273,6 +273,7 @@ WeaveSvc.prototype = {
"Weave, since it will not work correctly."); "Weave, since it will not work correctly.");
} }
Svc.Obs.add("weave:service:setup-complete", this);
Svc.Obs.add("network:offline-status-changed", this); Svc.Obs.add("network:offline-status-changed", this);
Svc.Obs.add("weave:service:sync:finish", this); Svc.Obs.add("weave:service:sync:finish", this);
Svc.Obs.add("weave:service:sync:error", this); Svc.Obs.add("weave:service:sync:error", this);
@ -292,6 +293,10 @@ WeaveSvc.prototype = {
this._updateCachedURLs(); this._updateCachedURLs();
let status = this._checkSetup();
if (status != STATUS_DISABLED && status != CLIENT_NOT_CONFIGURED)
Svc.Obs.notify("weave:engine:start-tracking");
// Applications can specify this preference if they want autoconnect // Applications can specify this preference if they want autoconnect
// to happen after a fixed delay. // to happen after a fixed delay.
let delay = Svc.Prefs.get("autoconnectDelay"); let delay = Svc.Prefs.get("autoconnectDelay");
@ -306,7 +311,10 @@ WeaveSvc.prototype = {
}, },
_checkSetup: function WeaveSvc__checkSetup() { _checkSetup: function WeaveSvc__checkSetup() {
if (!this.username) { if (!this.enabled) {
Status.service = STATUS_DISABLED;
}
else if (!this.username) {
this._log.debug("checkSetup: no username set"); this._log.debug("checkSetup: no username set");
Status.login = LOGIN_FAILED_NO_USERNAME; Status.login = LOGIN_FAILED_NO_USERNAME;
} }
@ -404,6 +412,11 @@ WeaveSvc.prototype = {
observe: function WeaveSvc__observe(subject, topic, data) { observe: function WeaveSvc__observe(subject, topic, data) {
switch (topic) { switch (topic) {
case "weave:service:setup-complete":
let status = this._checkSetup();
if (status != STATUS_DISABLED && status != CLIENT_NOT_CONFIGURED)
Svc.Obs.notify("weave:engine:start-tracking");
break;
case "network:offline-status-changed": case "network:offline-status-changed":
// Whether online or offline, we'll reschedule syncs // Whether online or offline, we'll reschedule syncs
this._log.trace("Network offline status change: " + data); this._log.trace("Network offline status change: " + data);
@ -704,6 +717,7 @@ WeaveSvc.prototype = {
Svc.Login.removeLogin(login); Svc.Login.removeLogin(login);
}); });
Svc.Obs.notify("weave:service:start-over"); Svc.Obs.notify("weave:service:start-over");
Svc.Obs.notify("weave:engine:stop-tracking");
}, },
delayedAutoConnect: function delayedAutoConnect(delay) { delayedAutoConnect: function delayedAutoConnect(delay) {