Bug 1634508 - Record telemetry about number of loaded tabs r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D73763
This commit is contained in:
Barret Rennie 2020-05-15 19:00:50 +00:00
Родитель 5cb50223f3
Коммит 2be7577ead
3 изменённых файлов: 198 добавлений и 20 удалений

Просмотреть файл

@ -119,19 +119,21 @@ const URLBAR_SELECTED_RESULT_METHODS = {
const MINIMUM_TAB_COUNT_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes, in ms const MINIMUM_TAB_COUNT_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes, in ms
function getOpenTabsAndWinsCounts() { function getOpenTabsAndWinsCounts() {
let loadedTabCount = 0;
let tabCount = 0; let tabCount = 0;
let winCount = 0; let winCount = 0;
for (let win of Services.wm.getEnumerator("navigator:browser")) { for (let win of Services.wm.getEnumerator("navigator:browser")) {
winCount++; winCount++;
tabCount += win.gBrowser.tabs.length; tabCount += win.gBrowser.tabs.length;
for (const tab of win.gBrowser.tabs) {
if (tab.getAttribute("pending") !== "true") {
loadedTabCount += 1;
}
}
} }
return { tabCount, winCount }; return { loadedTabCount, tabCount, winCount };
}
function getTabCount() {
return getOpenTabsAndWinsCounts().tabCount;
} }
function getPinnedTabsCount() { function getPinnedTabsCount() {
@ -264,7 +266,7 @@ let URICountListener = {
Services.telemetry.scalarAdd(TOTAL_URI_COUNT_SCALAR_NAME, 1); Services.telemetry.scalarAdd(TOTAL_URI_COUNT_SCALAR_NAME, 1);
// Update tab count // Update tab count
BrowserUsageTelemetry._recordTabCount(); BrowserUsageTelemetry._recordTabCounts(getOpenTabsAndWinsCounts());
// Unique domains should be aggregated by (eTLD + 1): x.test.com and y.test.com // Unique domains should be aggregated by (eTLD + 1): x.test.com and y.test.com
// are counted once as test.com. // are counted once as test.com.
@ -332,6 +334,7 @@ let BrowserUsageTelemetry = {
init() { init() {
this._lastRecordTabCount = 0; this._lastRecordTabCount = 0;
this._lastRecordLoadedTabCount = 0;
this._setupAfterRestore(); this._setupAfterRestore();
this._inited = true; this._inited = true;
}, },
@ -384,7 +387,7 @@ let BrowserUsageTelemetry = {
handleEvent(event) { handleEvent(event) {
switch (event.type) { switch (event.type) {
case "TabOpen": case "TabOpen":
this._onTabOpen(); this._onTabOpen(getOpenTabsAndWinsCounts());
break; break;
case "TabPinned": case "TabPinned":
this._onTabPinned(); this._onTabPinned();
@ -398,6 +401,9 @@ let BrowserUsageTelemetry = {
// |URICountListener| know about them. // |URICountListener| know about them.
let browser = event.target.linkedBrowser; let browser = event.target.linkedBrowser;
URICountListener.addRestoredURI(browser, browser.currentURI); URICountListener.addRestoredURI(browser, browser.currentURI);
const { loadedTabCount } = getOpenTabsAndWinsCounts();
this._recordTabCounts({ loadedTabCount });
break; break;
} }
}, },
@ -686,17 +692,14 @@ let BrowserUsageTelemetry = {
/** /**
* Updates the tab counts. * Updates the tab counts.
* @param {Number} [newTabCount=0] The count of the opened tabs across all windows. This * @param {Object} [counts] The counts returned by `getOpenTabsAndWindowCounts`.
* is computed manually if not provided.
*/ */
_onTabOpen(tabCount = 0) { _onTabOpen({ tabCount, loadedTabCount }) {
// Use the provided tab count if available. Otherwise, go on and compute it.
tabCount = tabCount || getOpenTabsAndWinsCounts().tabCount;
// Update the "tab opened" count and its maximum. // Update the "tab opened" count and its maximum.
Services.telemetry.scalarAdd(TAB_OPEN_EVENT_COUNT_SCALAR_NAME, 1); Services.telemetry.scalarAdd(TAB_OPEN_EVENT_COUNT_SCALAR_NAME, 1);
Services.telemetry.scalarSetMaximum(MAX_TAB_COUNT_SCALAR_NAME, tabCount); Services.telemetry.scalarSetMaximum(MAX_TAB_COUNT_SCALAR_NAME, tabCount);
this._recordTabCount(tabCount); this._recordTabCounts({ tabCount, loadedTabCount });
}, },
_onTabPinned(target) { _onTabPinned(target) {
@ -742,23 +745,42 @@ let BrowserUsageTelemetry = {
// We won't receive the "TabOpen" event for the first tab within a new window. // We won't receive the "TabOpen" event for the first tab within a new window.
// Account for that. // Account for that.
this._onTabOpen(counts.tabCount); this._onTabOpen(counts);
}; };
win.addEventListener("load", onLoad); win.addEventListener("load", onLoad);
}, },
_recordTabCount(tabCount) { /**
* Record telemetry about the given tab counts.
*
* Telemetry for each count will only be recorded if the value isn't
* `undefined`.
*
* @param {object} [counts] The tab counts to register with telemetry.
* @param {number} [counts.tabCount] The number of tabs in all browsers.
* @param {number} [counts.loadedTabCount] The number of loaded (i.e., not
* pending) tabs in all browsers.
*/
_recordTabCounts({ tabCount, loadedTabCount }) {
let currentTime = Date.now(); let currentTime = Date.now();
if ( if (
currentTime > tabCount !== undefined &&
this._lastRecordTabCount + MINIMUM_TAB_COUNT_INTERVAL_MS currentTime > this._lastRecordTabCount + MINIMUM_TAB_COUNT_INTERVAL_MS
) { ) {
if (tabCount === undefined) {
tabCount = getTabCount();
}
Services.telemetry.getHistogramById("TAB_COUNT").add(tabCount); Services.telemetry.getHistogramById("TAB_COUNT").add(tabCount);
this._lastRecordTabCount = currentTime; this._lastRecordTabCount = currentTime;
} }
if (
loadedTabCount !== undefined &&
currentTime >
this._lastRecordLoadedTabCount + MINIMUM_TAB_COUNT_INTERVAL_MS
) {
Services.telemetry
.getHistogramById("LOADED_TAB_COUNT")
.add(loadedTabCount);
this._lastRecordLoadedTabCount = currentTime;
}
}, },
}; };

Просмотреть файл

@ -12,12 +12,18 @@ const UNFILTERED_URI_COUNT = "browser.engagement.unfiltered_uri_count";
const TELEMETRY_SUBSESSION_TOPIC = "internal-telemetry-after-subsession-split"; const TELEMETRY_SUBSESSION_TOPIC = "internal-telemetry-after-subsession-split";
const RESTORE_ON_DEMAND_PREF = "browser.sessionstore.restore_on-demand";
ChromeUtils.defineModuleGetter( ChromeUtils.defineModuleGetter(
this, this,
"MINIMUM_TAB_COUNT_INTERVAL_MS", "MINIMUM_TAB_COUNT_INTERVAL_MS",
"resource:///modules/BrowserUsageTelemetry.jsm" "resource:///modules/BrowserUsageTelemetry.jsm"
); );
const { SessionStore } = ChromeUtils.import(
"resource:///modules/sessionstore/SessionStore.jsm"
);
// Reset internal URI counter in case URIs were opened by other tests. // Reset internal URI counter in case URIs were opened by other tests.
Services.obs.notifyObservers(null, TELEMETRY_SUBSESSION_TOPIC); Services.obs.notifyObservers(null, TELEMETRY_SUBSESSION_TOPIC);
@ -418,3 +424,141 @@ add_task(async function test_tabsHistogram() {
} }
await BrowserTestUtils.closeWindow(win); await BrowserTestUtils.closeWindow(win);
}); });
add_task(async function test_loadedTabsHistogram() {
Services.prefs.setBoolPref(RESTORE_ON_DEMAND_PREF, true);
registerCleanupFunction(() =>
Services.prefs.clearUserPref(RESTORE_ON_DEMAND_PREF)
);
function resetTimestamps() {
BrowserUsageTelemetry._lastRecordTabCount = 0;
BrowserUsageTelemetry._lastRecordLoadedTabCount = 0;
}
resetTimestamps();
const tabCount = TelemetryTestUtils.getAndClearHistogram("TAB_COUNT");
const loadedTabCount = TelemetryTestUtils.getAndClearHistogram(
"LOADED_TAB_COUNT"
);
checkTabCountHistogram(tabCount.snapshot(), {}, "TAB_COUNT - initial count");
checkTabCountHistogram(
loadedTabCount.snapshot(),
{},
"LOADED_TAB_COUNT - initial count"
);
resetTimestamps();
const tabs = [
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"),
];
// There are two tabs open: the mochi.test tab and the foreground tab.
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 0 },
"TAB_COUNT - new tab"
);
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 1, 3: 0 },
"TAB_COUNT - new tab"
);
// Open a pending tab, as if by session restore.
resetTimestamps();
const lazyTab = BrowserTestUtils.addTab(gBrowser, "about:mozilla", {
createLazyBrowser: true,
});
tabs.push(lazyTab);
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 1, 4: 0 },
"TAB_COUNT - Added pending tab"
);
// Only the mochi.test and foreground tab are loaded.
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 2, 3: 0 },
"LOADED_TAB_COUNT - Added pending tab"
);
resetTimestamps();
const restoredEvent = BrowserTestUtils.waitForEvent(lazyTab, "SSTabRestored");
await BrowserTestUtils.switchTab(gBrowser, lazyTab);
await restoredEvent;
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 1, 4: 0 },
"TAB_COUNT - Restored pending tab"
);
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 2, 3: 1, 4: 0 },
"LOADED_TAB_COUNT - Restored pending tab"
);
resetTimestamps();
await Promise.all([
BrowserTestUtils.loadURI(lazyTab.linkedBrowser, "http://example.com/"),
BrowserTestUtils.browserLoaded(
lazyTab.linkedBrowser,
false,
"http://example.com/"
),
]);
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 2, 4: 0 },
"TAB_COUNT - Navigated in existing tab"
);
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 2, 3: 2, 4: 0 },
"LOADED_TAB_COUNT - Navigated in existing tab"
);
resetTimestamps();
let win = await BrowserTestUtils.openNewBrowserWindow();
// The new window will have a new tab.
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 2, 4: 1, 5: 0 },
"TAB_COUNT - Opened new window"
);
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 2, 3: 2, 4: 1, 5: 0 },
"LOADED_TAB_COUNT - Opened new window"
);
resetTimestamps();
await BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:robots");
checkTabCountHistogram(
tabCount.snapshot(),
{ 1: 0, 2: 1, 3: 2, 4: 1, 5: 1, 6: 0 },
"TAB_COUNT - Opened new tab in new window"
);
checkTabCountHistogram(
loadedTabCount.snapshot(),
{ 1: 0, 2: 2, 3: 2, 4: 1, 5: 1, 6: 0 },
"LOADED_TAB_COUNT - Opened new tab in new window"
);
for (const tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
await BrowserTestUtils.closeWindow(win);
});

Просмотреть файл

@ -4463,6 +4463,18 @@
"releaseChannelCollection": "opt-out", "releaseChannelCollection": "opt-out",
"description": "Number of tabs opened across all windows, collected at most every 5 minutes whenever the user interacts with the browser in the following ways: open tab/window, page load." "description": "Number of tabs opened across all windows, collected at most every 5 minutes whenever the user interacts with the browser in the following ways: open tab/window, page load."
}, },
"LOADED_TAB_COUNT": {
"record_in_processes": ["main"],
"products": ["firefox"],
"alert_emails": ["barret@mozilla.com", "perfteam@mozilla.com"],
"bug_numbers": [1634508],
"expires_in_version": "never",
"kind": "exponential",
"high": 1000,
"n_buckets": 100,
"releaseChannelCollection": "opt-out",
"description": "Number of fully loaded (i.e., not pending from session restore) tabs opened across all windows, collected at most every 5 minutes whenever the user interacts with the browser in the following ways: open tab/window, page load, restoring a pending tab."
},
"TAP_TO_LOAD_IMAGE_SIZE": { "TAP_TO_LOAD_IMAGE_SIZE": {
"record_in_processes": ["main", "content"], "record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"], "products": ["firefox", "fennec", "geckoview"],