зеркало из https://github.com/mozilla/gecko-dev.git
Bug 974086 - [australis-measuring] UITour.seenPageIDs should persist across sessions. r=MattN sr=taras
This commit is contained in:
Родитель
72e872508d
Коммит
8b81ea1fd3
|
@ -26,6 +26,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
|
||||||
|
|
||||||
const UITOUR_PERMISSION = "uitour";
|
const UITOUR_PERMISSION = "uitour";
|
||||||
const PREF_PERM_BRANCH = "browser.uitour.";
|
const PREF_PERM_BRANCH = "browser.uitour.";
|
||||||
|
const PREF_SEENPAGEIDS = "browser.uitour.seenPageIDs";
|
||||||
const MAX_BUTTONS = 4;
|
const MAX_BUTTONS = 4;
|
||||||
|
|
||||||
const BUCKET_NAME = "UITour";
|
const BUCKET_NAME = "UITour";
|
||||||
|
@ -36,10 +37,12 @@ const BUCKET_TIMESTEPS = [
|
||||||
60 * 60 * 1000, // Until 1 hour after tab is closed/inactive.
|
60 * 60 * 1000, // Until 1 hour after tab is closed/inactive.
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Time after which seen Page IDs expire.
|
||||||
|
const SEENPAGEID_EXPIRY = 2 * 7 * 24 * 60 * 60 * 1000; // 2 weeks.
|
||||||
|
|
||||||
|
|
||||||
this.UITour = {
|
this.UITour = {
|
||||||
seenPageIDs: new Set(),
|
seenPageIDs: null,
|
||||||
pageIDSourceTabs: new WeakMap(),
|
pageIDSourceTabs: new WeakMap(),
|
||||||
pageIDSourceWindows: new WeakMap(),
|
pageIDSourceWindows: new WeakMap(),
|
||||||
/* Map from browser windows to a set of tabs in which a tour is open */
|
/* Map from browser windows to a set of tabs in which a tour is open */
|
||||||
|
@ -115,10 +118,72 @@ this.UITour = {
|
||||||
]),
|
]),
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
|
// Lazy getter is initialized here so it can be replicated any time
|
||||||
|
// in a test.
|
||||||
|
delete this.seenPageIDs;
|
||||||
|
Object.defineProperty(this, "seenPageIDs", {
|
||||||
|
get: this.restoreSeenPageIDs.bind(this),
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
UITelemetry.addSimpleMeasureFunction("UITour",
|
UITelemetry.addSimpleMeasureFunction("UITour",
|
||||||
this.getTelemetry.bind(this));
|
this.getTelemetry.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
restoreSeenPageIDs: function() {
|
||||||
|
delete this.seenPageIDs;
|
||||||
|
|
||||||
|
if (UITelemetry.enabled) {
|
||||||
|
let dateThreshold = Date.now() - SEENPAGEID_EXPIRY;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let data = Services.prefs.getCharPref(PREF_SEENPAGEIDS);
|
||||||
|
data = new Map(JSON.parse(data));
|
||||||
|
|
||||||
|
for (let [pageID, details] of data) {
|
||||||
|
|
||||||
|
if (typeof pageID != "string" ||
|
||||||
|
typeof details != "object" ||
|
||||||
|
typeof details.lastSeen != "number" ||
|
||||||
|
details.lastSeen < dateThreshold) {
|
||||||
|
|
||||||
|
data.delete(pageID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.seenPageIDs = data;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.seenPageIDs)
|
||||||
|
this.seenPageIDs = new Map();
|
||||||
|
|
||||||
|
this.persistSeenIDs();
|
||||||
|
|
||||||
|
return this.seenPageIDs;
|
||||||
|
},
|
||||||
|
|
||||||
|
addSeenPageID: function(aPageID) {
|
||||||
|
if (!UITelemetry.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.seenPageIDs.set(aPageID, {
|
||||||
|
lastSeen: Date.now(),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.persistSeenIDs();
|
||||||
|
},
|
||||||
|
|
||||||
|
persistSeenIDs: function() {
|
||||||
|
if (this.seenPageIDs.size === 0) {
|
||||||
|
Services.prefs.clearUserPref(PREF_SEENPAGEIDS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.prefs.setCharPref(PREF_SEENPAGEIDS,
|
||||||
|
JSON.stringify([...this.seenPageIDs]));
|
||||||
|
},
|
||||||
|
|
||||||
onPageEvent: function(aEvent) {
|
onPageEvent: function(aEvent) {
|
||||||
let contentDocument = null;
|
let contentDocument = null;
|
||||||
if (aEvent.target instanceof Ci.nsIDOMHTMLDocument)
|
if (aEvent.target instanceof Ci.nsIDOMHTMLDocument)
|
||||||
|
@ -161,11 +226,15 @@ this.UITour = {
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "registerPageID": {
|
case "registerPageID": {
|
||||||
|
// This is only relevant if Telemtry is enabled.
|
||||||
|
if (!UITelemetry.enabled)
|
||||||
|
break;
|
||||||
|
|
||||||
// We don't want to allow BrowserUITelemetry.BUCKET_SEPARATOR in the
|
// We don't want to allow BrowserUITelemetry.BUCKET_SEPARATOR in the
|
||||||
// pageID, as it could make parsing the telemetry bucket name difficult.
|
// pageID, as it could make parsing the telemetry bucket name difficult.
|
||||||
if (typeof data.pageID == "string" &&
|
if (typeof data.pageID == "string" &&
|
||||||
!data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
|
!data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
|
||||||
this.seenPageIDs.add(data.pageID);
|
this.addSeenPageID(data.pageID);
|
||||||
|
|
||||||
// Store tabs and windows separately so we don't need to loop over all
|
// Store tabs and windows separately so we don't need to loop over all
|
||||||
// tabs when a window is closed.
|
// tabs when a window is closed.
|
||||||
|
@ -444,7 +513,7 @@ this.UITour = {
|
||||||
|
|
||||||
getTelemetry: function() {
|
getTelemetry: function() {
|
||||||
return {
|
return {
|
||||||
seenPageIDs: [...this.seenPageIDs],
|
seenPageIDs: [...this.seenPageIDs.keys()],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,68 @@ let gContentAPI;
|
||||||
let gContentWindow;
|
let gContentWindow;
|
||||||
|
|
||||||
Components.utils.import("resource:///modules/UITour.jsm");
|
Components.utils.import("resource:///modules/UITour.jsm");
|
||||||
|
Components.utils.import("resource://gre/modules/UITelemetry.jsm");
|
||||||
Components.utils.import("resource:///modules/BrowserUITelemetry.jsm");
|
Components.utils.import("resource:///modules/BrowserUITelemetry.jsm");
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
|
UITelemetry._enabled = true;
|
||||||
|
|
||||||
registerCleanupFunction(function() {
|
registerCleanupFunction(function() {
|
||||||
UITour.seenPageIDs.clear();
|
Services.prefs.clearUserPref("browser.uitour.seenPageIDs");
|
||||||
|
resetSeenPageIDsLazyGetter();
|
||||||
|
UITelemetry._enabled = undefined;
|
||||||
BrowserUITelemetry.setBucket(null);
|
BrowserUITelemetry.setBucket(null);
|
||||||
|
delete window.UITelemetry;
|
||||||
delete window.BrowserUITelemetry;
|
delete window.BrowserUITelemetry;
|
||||||
});
|
});
|
||||||
UITourTest();
|
UITourTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetSeenPageIDsLazyGetter() {
|
||||||
|
delete UITour.seenPageIDs;
|
||||||
|
// This should be kept in sync with how UITour.init() sets this.
|
||||||
|
Object.defineProperty(UITour, "seenPageIDs", {
|
||||||
|
get: UITour.restoreSeenPageIDs.bind(UITour),
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkExpectedSeenPageIDs(expected) {
|
||||||
|
is(UITour.seenPageIDs.size, expected.length, "Should be " + expected.length + " total seen page IDs");
|
||||||
|
|
||||||
|
for (let id of expected)
|
||||||
|
ok(UITour.seenPageIDs.has(id), "Should have seen '" + id + "' page ID");
|
||||||
|
|
||||||
|
let prefData = Services.prefs.getCharPref("browser.uitour.seenPageIDs");
|
||||||
|
prefData = new Map(JSON.parse(prefData));
|
||||||
|
|
||||||
|
is(prefData.size, expected.length, "Should be " + expected.length + " total seen page IDs persisted");
|
||||||
|
|
||||||
|
for (let id of expected)
|
||||||
|
ok(prefData.has(id), "Should have seen '" + id + "' page ID persisted");
|
||||||
|
}
|
||||||
|
|
||||||
let tests = [
|
let tests = [
|
||||||
function test_seenPageIDs_1(done) {
|
function test_seenPageIDs_restore(done) {
|
||||||
|
info("Setting up seenPageIDs to be restored from pref");
|
||||||
|
let data = JSON.stringify([
|
||||||
|
["savedID1", { lastSeen: Date.now() }],
|
||||||
|
["savedID2", { lastSeen: Date.now() }],
|
||||||
|
// 3 weeks ago, should auto expire.
|
||||||
|
["savedID3", { lastSeen: Date.now() - 3 * 7 * 24 * 60 * 60 * 1000 }],
|
||||||
|
]);
|
||||||
|
Services.prefs.setCharPref("browser.uitour.seenPageIDs",
|
||||||
|
data);
|
||||||
|
|
||||||
|
resetSeenPageIDsLazyGetter();
|
||||||
|
checkExpectedSeenPageIDs(["savedID1", "savedID2"]);
|
||||||
|
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
function test_seenPageIDs_set_1(done) {
|
||||||
gContentAPI.registerPageID("testpage1");
|
gContentAPI.registerPageID("testpage1");
|
||||||
|
|
||||||
is(UITour.seenPageIDs.size, 1, "Should be 1 seen page ID");
|
checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1"]);
|
||||||
ok(UITour.seenPageIDs.has("testpage1"), "Should have seen 'testpage1' page ID");
|
|
||||||
|
|
||||||
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
|
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
|
||||||
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
|
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
|
||||||
|
@ -42,12 +87,10 @@ let tests = [
|
||||||
BrowserUITelemetry.setBucket(null);
|
BrowserUITelemetry.setBucket(null);
|
||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
function test_seenPageIDs_2(done) {
|
function test_seenPageIDs_set_2(done) {
|
||||||
gContentAPI.registerPageID("testpage2");
|
gContentAPI.registerPageID("testpage2");
|
||||||
|
|
||||||
is(UITour.seenPageIDs.size, 2, "Should be 2 seen page IDs");
|
checkExpectedSeenPageIDs(["savedID1", "savedID2", "testpage1", "testpage2"]);
|
||||||
ok(UITour.seenPageIDs.has("testpage1"), "Should have seen 'testpage1' page ID");
|
|
||||||
ok(UITour.seenPageIDs.has("testpage2"), "Should have seen 'testpage2' page ID");
|
|
||||||
|
|
||||||
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
|
const PREFIX = BrowserUITelemetry.BUCKET_PREFIX;
|
||||||
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
|
const SEP = BrowserUITelemetry.BUCKET_SEPARATOR;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче