mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1685801: Part 2 - Move site origin telemetry to separate module. r=mccr8
Differential Revision: https://phabricator.services.mozilla.com/D101482
This commit is contained in:
parent
4a273b246f
commit
59963809cd
@ -22,6 +22,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
NewTabPagePreloading: "resource:///modules/NewTabPagePreloading.jsm",
|
||||
BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
|
||||
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
|
||||
BrowserTelemetryUtils: "resource://gre/modules/BrowserTelemetryUtils.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
||||
CFRPageActions: "resource://activity-stream/lib/CFRPageActions.jsm",
|
||||
@ -5723,7 +5724,7 @@ var TabsProgressListener = {
|
||||
) {
|
||||
if (recordLoadTelemetry) {
|
||||
TelemetryStopwatch.finish(histogram, aBrowser);
|
||||
BrowserUtils.recordSiteOriginTelemetry(browserWindows());
|
||||
BrowserTelemetryUtils.recordSiteOriginTelemetry(browserWindows());
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
|
@ -19,7 +19,7 @@ const { XPCOMUtils } = ChromeUtils.import(
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
ClientID: "resource://gre/modules/ClientID.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserTelemetryUtils: "resource://gre/modules/BrowserTelemetryUtils.jsm",
|
||||
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
|
||||
PageActions: "resource:///modules/PageActions.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
@ -1208,7 +1208,7 @@ let BrowserUsageTelemetry = {
|
||||
}
|
||||
|
||||
const { loadedTabCount } = getOpenTabsAndWinsCounts();
|
||||
const siteOrigins = BrowserUtils.computeSiteOriginCount(
|
||||
const siteOrigins = BrowserTelemetryUtils.computeSiteOriginCount(
|
||||
Services.wm.getEnumerator("navigator:browser"),
|
||||
false
|
||||
);
|
||||
|
@ -134,9 +134,13 @@ add_task(async function() {
|
||||
],
|
||||
});
|
||||
|
||||
const { BrowserTelemetryUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/BrowserTelemetryUtils.jsm"
|
||||
);
|
||||
|
||||
// Make sure we actually record telemetry for our disqualifying origin
|
||||
// count.
|
||||
BrowserUtils.min_interval = 1;
|
||||
BrowserTelemetryUtils.min_interval = 1;
|
||||
|
||||
let tabs = [];
|
||||
|
||||
@ -184,7 +188,7 @@ add_task(async function() {
|
||||
Services.prefs.clearUserPref(PREF_QUALIFIED);
|
||||
Services.prefs.clearUserPref(PREF_LAST_QUALIFIED);
|
||||
Services.prefs.clearUserPref(PREF_LAST_DISQUALIFIED);
|
||||
BrowserUtils._checkedInitialExperimentQualification = false;
|
||||
BrowserTelemetryUtils._checkedInitialExperimentQualification = false;
|
||||
|
||||
info("Open a new tab to trigger the origin count code again");
|
||||
tabs.push(await openTab(SITE_ORIGINS[0]));
|
||||
@ -205,5 +209,5 @@ add_task(async function() {
|
||||
|
||||
// Clear the cached recording interval so it resets to the default
|
||||
// value on the next call.
|
||||
BrowserUtils.min_interval = null;
|
||||
BrowserTelemetryUtils.min_interval = null;
|
||||
});
|
||||
|
@ -29,7 +29,7 @@ XPCOMUtils.defineLazyServiceGetter(
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserTelemetryUtils: "resource://gre/modules/BrowserTelemetryUtils.jsm",
|
||||
HistogramStopwatch: "resource://gre/modules/GeckoViewTelemetry.jsm",
|
||||
});
|
||||
|
||||
@ -435,7 +435,7 @@ class StateTracker extends Tracker {
|
||||
success: aIsSuccess,
|
||||
});
|
||||
|
||||
BrowserUtils.recordSiteOriginTelemetry(
|
||||
BrowserTelemetryUtils.recordSiteOriginTelemetry(
|
||||
Services.wm.getEnumerator("navigator:geckoview"),
|
||||
true
|
||||
);
|
||||
|
199
toolkit/modules/BrowserTelemetryUtils.jsm
Normal file
199
toolkit/modules/BrowserTelemetryUtils.jsm
Normal file
@ -0,0 +1,199 @@
|
||||
/* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["BrowserTelemetryUtils"];
|
||||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
// The maximum number of concurrently-loaded origins allowed in order to
|
||||
// qualify for the Fission rollout experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentMaxOrigins",
|
||||
"fission.experiment.max-origins.origin-cap",
|
||||
30
|
||||
);
|
||||
// The length of the sliding window during which a user must stay below
|
||||
// the max origin cap. If the last time a user passed the max origin cap
|
||||
// fell outside of this window, they will requalify for the experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentSlidingWindowMS",
|
||||
"fission.experiment.max-origins.sliding-window-ms",
|
||||
7 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
// The pref holding the current qaualification state of the user. If
|
||||
// true, the user is currently qualified from the experiment.
|
||||
const FISSION_EXPERIMENT_PREF_QUALIFIED =
|
||||
"fission.experiment.max-origins.qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentQualified",
|
||||
FISSION_EXPERIMENT_PREF_QUALIFIED,
|
||||
false
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count below the cap while the user was not currently marked as
|
||||
// qualified.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_QUALIFIED =
|
||||
"fission.experiment.max-origins.last-qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentLastQualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
0
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count exceeding the cap.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED =
|
||||
"fission.experiment.max-origins.last-disqualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentLastDisqualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
0
|
||||
);
|
||||
|
||||
var BrowserTelemetryUtils = {
|
||||
recordSiteOriginTelemetry(aWindows, aIsGeckoView) {
|
||||
Services.tm.idleDispatchToMainThread(() => {
|
||||
this._recordSiteOriginTelemetry(aWindows, aIsGeckoView);
|
||||
});
|
||||
},
|
||||
|
||||
computeSiteOriginCount(aWindows, aIsGeckoView) {
|
||||
// Geckoview and Desktop work differently. On desktop, aBrowser objects
|
||||
// holds an array of tabs which we can use to get the <browser> objects.
|
||||
// In Geckoview, it is apps' responsibility to keep track of the tabs, so
|
||||
// there isn't an easy way for us to get the tabs.
|
||||
let tabs = [];
|
||||
if (aIsGeckoView) {
|
||||
// To get all active windows; Each tab has its own window
|
||||
tabs = aWindows;
|
||||
} else {
|
||||
for (const win of aWindows) {
|
||||
tabs = tabs.concat(win.gBrowser.tabs);
|
||||
}
|
||||
}
|
||||
|
||||
let topLevelBCs = [];
|
||||
|
||||
for (const tab of tabs) {
|
||||
let browser;
|
||||
if (aIsGeckoView) {
|
||||
browser = tab.browser;
|
||||
} else {
|
||||
browser = tab.linkedBrowser;
|
||||
}
|
||||
|
||||
if (browser.browsingContext) {
|
||||
// This is the top level browsingContext
|
||||
topLevelBCs.push(browser.browsingContext);
|
||||
}
|
||||
}
|
||||
|
||||
return CanonicalBrowsingContext.countSiteOrigins(topLevelBCs);
|
||||
},
|
||||
|
||||
_recordSiteOriginTelemetry(aWindows, aIsGeckoView) {
|
||||
let currentTime = Date.now();
|
||||
|
||||
// default is 5 minutes
|
||||
if (!this.min_interval) {
|
||||
this.min_interval = Services.prefs.getIntPref(
|
||||
"telemetry.number_of_site_origin.min_interval",
|
||||
300000
|
||||
);
|
||||
}
|
||||
|
||||
let originCount = this.computeSiteOriginCount(aWindows, aIsGeckoView);
|
||||
let histogram = Services.telemetry.getHistogramById(
|
||||
"FX_NUMBER_OF_UNIQUE_SITE_ORIGINS_ALL_TABS"
|
||||
);
|
||||
|
||||
// Discard the first load because most of the time the first load only has 1
|
||||
// tab and 1 window open, so it is useless to report it.
|
||||
if (!this._lastRecordSiteOrigin) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
} else if (currentTime >= this._lastRecordSiteOrigin + this.min_interval) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
|
||||
histogram.add(originCount);
|
||||
}
|
||||
|
||||
// Update the Fission experiment qualification state based on the
|
||||
// current origin count:
|
||||
|
||||
// If we don't already have a last disqualification timestamp, look
|
||||
// through the existing histogram values, and use the existing
|
||||
// maximum value as the initial count. This will prevent us from
|
||||
// enrolling users in the experiment if they have a history of
|
||||
// exceeding our origin cap.
|
||||
if (!this._checkedInitialExperimentQualification) {
|
||||
this._checkedInitialExperimentQualification = true;
|
||||
if (
|
||||
!Services.prefs.prefHasUserValue(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED
|
||||
)
|
||||
) {
|
||||
for (let [bucketStr, entryCount] of Object.entries(
|
||||
histogram.snapshot().values
|
||||
)) {
|
||||
let bucket = Number(bucketStr);
|
||||
if (bucket > originCount && entryCount > 0) {
|
||||
originCount = bucket;
|
||||
}
|
||||
}
|
||||
Services.prefs.setIntPref(FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
let currentTimeSec = currentTime / 1000;
|
||||
if (originCount < fissionExperimentMaxOrigins) {
|
||||
let lastDisqualified = fissionExperimentLastDisqualified;
|
||||
let lastQualified = fissionExperimentLastQualified;
|
||||
|
||||
// If the last time we saw a qualifying origin count was earlier
|
||||
// than the last time we say a disqualifying count, update any
|
||||
// existing last disqualified timestamp to just before now, on the
|
||||
// basis that our origin count has probably just fallen below the
|
||||
// cap.
|
||||
if (lastDisqualified > 0 && lastQualified <= lastDisqualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec - 1
|
||||
);
|
||||
}
|
||||
|
||||
if (!fissionExperimentQualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
|
||||
// We have a qualifying origin count now. If the last time we were
|
||||
// disqualified was prior to the start of our current sliding
|
||||
// window, re-qualify the user.
|
||||
if (
|
||||
currentTimeSec - lastDisqualified >=
|
||||
fissionExperimentSlidingWindowMS / 1000
|
||||
) {
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, false);
|
||||
}
|
||||
},
|
||||
};
|
@ -17,55 +17,6 @@ ChromeUtils.defineModuleGetter(
|
||||
"resource://gre/modules/PlacesUtils.jsm"
|
||||
);
|
||||
|
||||
// The maximum number of concurrently-loaded origins allowed in order to
|
||||
// qualify for the Fission rollout experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentMaxOrigins",
|
||||
"fission.experiment.max-origins.origin-cap",
|
||||
30
|
||||
);
|
||||
// The length of the sliding window during which a user must stay below
|
||||
// the max origin cap. If the last time a user passed the max origin cap
|
||||
// fell outside of this window, they will requalify for the experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentSlidingWindowMS",
|
||||
"fission.experiment.max-origins.sliding-window-ms",
|
||||
7 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
// The pref holding the current qaualification state of the user. If
|
||||
// true, the user is currently qualified from the experiment.
|
||||
const FISSION_EXPERIMENT_PREF_QUALIFIED =
|
||||
"fission.experiment.max-origins.qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentQualified",
|
||||
FISSION_EXPERIMENT_PREF_QUALIFIED,
|
||||
false
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count below the cap while the user was not currently marked as
|
||||
// qualified.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_QUALIFIED =
|
||||
"fission.experiment.max-origins.last-qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentLastQualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
0
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count exceeding the cap.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED =
|
||||
"fission.experiment.max-origins.last-disqualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"fissionExperimentLastDisqualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
0
|
||||
);
|
||||
|
||||
var BrowserUtils = {
|
||||
/**
|
||||
* Prints arguments separated by a space and appends a new line.
|
||||
@ -879,141 +830,6 @@ var BrowserUtils = {
|
||||
? url.substring(this.trimURLProtocol.length)
|
||||
: url;
|
||||
},
|
||||
|
||||
recordSiteOriginTelemetry(aWindows, aIsGeckoView) {
|
||||
Services.tm.idleDispatchToMainThread(() => {
|
||||
this._recordSiteOriginTelemetry(aWindows, aIsGeckoView);
|
||||
});
|
||||
},
|
||||
|
||||
computeSiteOriginCount(aWindows, aIsGeckoView) {
|
||||
// Geckoview and Desktop work differently. On desktop, aBrowser objects
|
||||
// holds an array of tabs which we can use to get the <browser> objects.
|
||||
// In Geckoview, it is apps' responsibility to keep track of the tabs, so
|
||||
// there isn't an easy way for us to get the tabs.
|
||||
let tabs = [];
|
||||
if (aIsGeckoView) {
|
||||
// To get all active windows; Each tab has its own window
|
||||
tabs = aWindows;
|
||||
} else {
|
||||
for (const win of aWindows) {
|
||||
tabs = tabs.concat(win.gBrowser.tabs);
|
||||
}
|
||||
}
|
||||
|
||||
let topLevelBCs = [];
|
||||
|
||||
for (const tab of tabs) {
|
||||
let browser;
|
||||
if (aIsGeckoView) {
|
||||
browser = tab.browser;
|
||||
} else {
|
||||
browser = tab.linkedBrowser;
|
||||
}
|
||||
|
||||
if (browser.browsingContext) {
|
||||
// This is the top level browsingContext
|
||||
topLevelBCs.push(browser.browsingContext);
|
||||
}
|
||||
}
|
||||
|
||||
return CanonicalBrowsingContext.countSiteOrigins(topLevelBCs);
|
||||
},
|
||||
|
||||
_recordSiteOriginTelemetry(aWindows, aIsGeckoView) {
|
||||
let currentTime = Date.now();
|
||||
|
||||
// default is 5 minutes
|
||||
if (!this.min_interval) {
|
||||
this.min_interval = Services.prefs.getIntPref(
|
||||
"telemetry.number_of_site_origin.min_interval",
|
||||
300000
|
||||
);
|
||||
}
|
||||
|
||||
let originCount = this.computeSiteOriginCount(aWindows, aIsGeckoView);
|
||||
let histogram = Services.telemetry.getHistogramById(
|
||||
"FX_NUMBER_OF_UNIQUE_SITE_ORIGINS_ALL_TABS"
|
||||
);
|
||||
|
||||
// Discard the first load because most of the time the first load only has 1
|
||||
// tab and 1 window open, so it is useless to report it.
|
||||
if (!this._lastRecordSiteOrigin) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
} else if (currentTime >= this._lastRecordSiteOrigin + this.min_interval) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
|
||||
histogram.add(originCount);
|
||||
}
|
||||
|
||||
// Update the Fission experiment qualification state based on the
|
||||
// current origin count:
|
||||
|
||||
// If we don't already have a last disqualification timestamp, look
|
||||
// through the existing histogram values, and use the existing
|
||||
// maximum value as the initial count. This will prevent us from
|
||||
// enrolling users in the experiment if they have a history of
|
||||
// exceeding our origin cap.
|
||||
if (!this._checkedInitialExperimentQualification) {
|
||||
this._checkedInitialExperimentQualification = true;
|
||||
if (
|
||||
!Services.prefs.prefHasUserValue(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED
|
||||
)
|
||||
) {
|
||||
for (let [bucketStr, entryCount] of Object.entries(
|
||||
histogram.snapshot().values
|
||||
)) {
|
||||
let bucket = Number(bucketStr);
|
||||
if (bucket > originCount && entryCount > 0) {
|
||||
originCount = bucket;
|
||||
}
|
||||
}
|
||||
Services.prefs.setIntPref(FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
let currentTimeSec = currentTime / 1000;
|
||||
if (originCount < fissionExperimentMaxOrigins) {
|
||||
let lastDisqualified = fissionExperimentLastDisqualified;
|
||||
let lastQualified = fissionExperimentLastQualified;
|
||||
|
||||
// If the last time we saw a qualifying origin count was earlier
|
||||
// than the last time we say a disqualifying count, update any
|
||||
// existing last disqualified timestamp to just before now, on the
|
||||
// basis that our origin count has probably just fallen below the
|
||||
// cap.
|
||||
if (lastDisqualified > 0 && lastQualified <= lastDisqualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec - 1
|
||||
);
|
||||
}
|
||||
|
||||
if (!fissionExperimentQualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
|
||||
// We have a qualifying origin count now. If the last time we were
|
||||
// disqualified was prior to the start of our current sliding
|
||||
// window, re-qualify the user.
|
||||
if (
|
||||
currentTimeSec - lastDisqualified >=
|
||||
fissionExperimentSlidingWindowMS / 1000
|
||||
) {
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, false);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
|
@ -160,6 +160,7 @@ EXTRA_JS_MODULES += [
|
||||
"AppMenuNotifications.jsm",
|
||||
"AsyncPrefs.jsm",
|
||||
"BinarySearch.jsm",
|
||||
"BrowserTelemetryUtils.jsm",
|
||||
"BrowserUtils.jsm",
|
||||
"CanonicalJSON.jsm",
|
||||
"CertUtils.jsm",
|
||||
|
Loading…
Reference in New Issue
Block a user