зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1634508 - Record telemetry about number of loaded tabs r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D73763
This commit is contained in:
Родитель
5cb50223f3
Коммит
2be7577ead
|
@ -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"],
|
||||||
|
|
Загрузка…
Ссылка в новой задаче