author | Erica Wright <ewright@mozilla.com> |
Wed, 05 Aug 2020 16:25:57 +0000 | |
changeset 543420 | 87c14534121fff5bd4348739ce512f0e335be6a1 |
parent 543419 | c72d8188a88d3b7923f6bd5560bc4026f8ae1a6f |
child 543421 | 330c4fd5259d03cd63291b5d235f35240f98010c |
push id | 37673 |
push user | apavel@mozilla.com |
push date | Wed, 05 Aug 2020 21:44:54 +0000 |
treeherder | mozilla-central@26de281d4c21 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | prathiksha |
bugs | 1650468 |
milestone | 81.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/actors/AboutProtectionsParent.jsm +++ b/browser/actors/AboutProtectionsParent.jsm @@ -62,16 +62,17 @@ const MONITOR_RESPONSE_PROPS = [ "numBreaches", "passwords", "numBreachesResolved", "passwordsResolved", ]; let gTestOverride = null; let monitorResponse = null; +let entrypoint = "direct"; class AboutProtectionsParent extends JSWindowActorParent { constructor() { super(); } // Some tests wish to override certain functions with ones that mostly do nothing. static setTestOverride(callback) { @@ -374,13 +375,20 @@ class AboutProtectionsParent extends JSW case "ClearMonitorCache": monitorResponse = null; break; case "GetShowProxyCard": let card = await this.shouldShowProxyCard(); return card; + + case "RecordEntryPoint": + entrypoint = aMessage.data.entrypoint; + break; + + case "FetchEntryPoint": + return entrypoint; } return undefined; } }
--- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -196,17 +196,17 @@ let JSWINDOWACTORS = { child: { moduleURI: "resource:///actors/AboutProtectionsChild.jsm", events: { DOMWindowCreated: { capture: true }, }, }, - matches: ["about:protections"], + matches: ["about:protections", "about:protections?*"], }, AboutReader: { parent: { moduleURI: "resource:///actors/AboutReaderParent.jsm", }, child: { moduleURI: "resource:///actors/AboutReaderChild.jsm",
--- a/browser/components/protections/content/protections.js +++ b/browser/components/protections/content/protections.js @@ -3,22 +3,59 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* eslint-env mozilla/frame-script */ import LockwiseCard from "./lockwise-card.js"; import MonitorCard from "./monitor-card.js"; import ProxyCard from "./proxy-card.js"; -// We need to send the close telemetry before unload while we still have a connection to RPM. -window.addEventListener("beforeunload", () => { - document.sendTelemetryEvent("close", "protection_report"); -}); +let cbCategory = RPMGetStringPref("browser.contentblocking.category"); +document.sendTelemetryEvent = (action, object, value = "") => { + // eslint-disable-next-line no-undef + RPMRecordTelemetryEvent("security.ui.protections", action, object, value, { + category: cbCategory, + }); +}; + +let { protocol, pathname, searchParams } = new URL(document.location); + +let searchParamsChanged = false; +if (searchParams.has("entrypoint")) { + RPMSendAsyncMessage("RecordEntryPoint", { + entrypoint: searchParams.get("entrypoint"), + }); + // Remove this parameter from the URL (after recording above) to make it + // cleaner for bookmarking and switch-to-tab and so that bookmarked values + // don't skew telemetry. + searchParams.delete("entrypoint"); + searchParamsChanged = true; +} document.addEventListener("DOMContentLoaded", e => { + if (searchParamsChanged) { + let newURL = protocol + pathname; + let params = searchParams.toString(); + if (params) { + newURL += "?" + params; + } + window.location.replace(newURL); + return; + } + + RPMSendQuery("FetchEntryPoint", {}).then(entrypoint => { + // Send telemetry on arriving on this page + document.sendTelemetryEvent("show", "protection_report", entrypoint); + }); + + // We need to send the close telemetry before unload while we still have a connection to RPM. + window.addEventListener("beforeunload", () => { + document.sendTelemetryEvent("close", "protection_report"); + }); + let todayInMs = Date.now(); let weekAgoInMs = todayInMs - 6 * 24 * 60 * 60 * 1000; let dataTypes = [ "cryptominer", "fingerprinter", "tracker", "cookie", @@ -48,32 +85,20 @@ document.addEventListener("DOMContentLoa manageProtectionsLink.addEventListener("click", protectionSettingsEvtHandler); manageProtectionsLink.addEventListener( "keypress", protectionSettingsEvtHandler ); manageProtections.addEventListener("click", protectionSettingsEvtHandler); manageProtections.addEventListener("keypress", protectionSettingsEvtHandler); - let cbCategory = RPMGetStringPref("browser.contentblocking.category"); - let legend = document.getElementById("legend"); legend.style.gridTemplateAreas = "'social cookie tracker fingerprinter cryptominer'"; - document.sendTelemetryEvent = (action, object, value = "") => { - // eslint-disable-next-line no-undef - RPMRecordTelemetryEvent("security.ui.protections", action, object, value, { - category: cbCategory, - }); - }; - - // Send telemetry on arriving and closing this page - document.sendTelemetryEvent("show", "protection_report"); - let createGraph = data => { let graph = document.getElementById("graph"); let summary = document.getElementById("graph-total-summary"); let weekSummary = document.getElementById("graph-week-summary"); // User is in private mode, show no data on the graph if (data.isPrivate) { graph.classList.add("private-window");
--- a/browser/components/protections/test/browser/browser_protections_telemetry.js +++ b/browser/components/protections/test/browser/browser_protections_telemetry.js @@ -815,8 +815,95 @@ add_task(async function test_save_teleme const scalars = Services.telemetry.getSnapshotForScalars("main", false) .parent; is(scalars["contentblocking.trackers_blocked_count"], 6); // Use the TrackingDBService API to delete the data. await TrackingDBService.clearAll(); }); + +// Test that telemetry is sent if entrypoint param is included, +// and test that it is recorded as default if entrypoint param is not properly included +add_task(async function checkTelemetryLoadEventForEntrypoint() { + // There's an arbitrary interval of 2 seconds in which the content + // processes sync their event data with the parent process, we wait + // this out to ensure that we clear everything that is left over from + // previous tests and don't receive random events in the middle of our tests. + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + await new Promise(c => setTimeout(c, 2000)); + + // Clear everything. + Services.telemetry.clearEvents(); + await TestUtils.waitForCondition(() => { + let events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, + true + ).content; + return !events || !events.length; + }); + + Services.telemetry.setEventRecordingEnabled("security.ui.protections", true); + + info("Typo in 'entrypoint' should not be recorded"); + let tab = await BrowserTestUtils.openNewForegroundTab({ + url: "about:protections?entryPoint=newPage", + gBrowser, + }); + + let loadEvents = await TestUtils.waitForCondition(() => { + let events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, + true + ).content; + if (events && events.length) { + events = events.filter( + e => + e[1] == "security.ui.protections" && + e[2] == "show" && + e[4] == "direct" + ); + if (events.length == 1) { + return events; + } + } + return null; + }, "recorded telemetry for showing the report contains default 'direct' entrypoint"); + + is( + loadEvents.length, + 1, + `recorded telemetry for showing the report contains default 'direct' entrypoint` + ); + + await BrowserTestUtils.removeTab(tab); + + tab = await BrowserTestUtils.openNewForegroundTab({ + url: "about:protections?entrypoint=page", + gBrowser, + }); + + loadEvents = await TestUtils.waitForCondition(() => { + let events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, + true + ).content; + if (events && events.length) { + events = events.filter( + e => + e[1] == "security.ui.protections" && e[2] == "show" && e[4] == "page" + ); + if (events.length == 1) { + return events; + } + } + return null; + }, "recorded telemetry for showing the report contains correct entrypoint"); + + is( + loadEvents.length, + 1, + "recorded telemetry for showing the report contains correct entrypoint" + ); + + // Clean up. + await BrowserTestUtils.removeTab(tab); +});
--- a/toolkit/components/telemetry/Events.yaml +++ b/toolkit/components/telemetry/Events.yaml @@ -1820,18 +1820,19 @@ security.ui.protections: show: objects: [ "protection_report", ] bug_numbers: - 1557050 - 1610897 - 1643428 + - 1650468 description: > - User arrived on the protection report. + User arrived on the protection report. This also includes a 'value' attribute which defaults to 'direct' or will be the value that a referring website addds to the url. expiry_version: "86" record_in_processes: ["content"] release_channel_collection: opt-out notification_emails: - ewright@mozilla.com - chsiang@mozilla.com - seceng-telemetry@mozilla.com products:
--- a/toolkit/modules/RemotePageAccessManager.jsm +++ b/toolkit/modules/RemotePageAccessManager.jsm @@ -125,23 +125,25 @@ let RemotePageAccessManager = { RPMIsWindowPrivate: ["*"], }, "about:protections": { RPMSendAsyncMessage: [ "OpenContentBlockingPreferences", "OpenAboutLogins", "OpenSyncPreferences", "ClearMonitorCache", + "RecordEntryPoint", ], RPMSendQuery: [ "FetchUserLoginsData", "FetchMonitorData", "FetchContentBlockingEvents", "FetchMobileDeviceConnected", "GetShowProxyCard", + "FetchEntryPoint", ], RPMAddMessageListener: ["*"], RPMRemoveMessageListener: ["*"], RPMSetBoolPref: [ "browser.contentblocking.report.hide_lockwise_app", "browser.contentblocking.report.show_mobile_app", ], RPMGetBoolPref: [