diff options
Diffstat (limited to 'toolkit/components/reportbrokensite')
5 files changed, 1534 insertions, 0 deletions
diff --git a/toolkit/components/reportbrokensite/ReportBrokenSiteChild.sys.mjs b/toolkit/components/reportbrokensite/ReportBrokenSiteChild.sys.mjs new file mode 100644 index 0000000000..8220f5b4b6 --- /dev/null +++ b/toolkit/components/reportbrokensite/ReportBrokenSiteChild.sys.mjs @@ -0,0 +1,525 @@ +/* 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/. */ + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; + +const SCREENSHOT_FORMAT = { format: "jpeg", quality: 75 }; + +function RunScriptInFrame(win, script) { + const contentPrincipal = win.document.nodePrincipal; + const sandbox = Cu.Sandbox([contentPrincipal], { + sandboxName: "Report Broken Site webcompat.com helper", + sandboxPrototype: win, + sameZoneAs: win, + originAttributes: contentPrincipal.originAttributes, + }); + return Cu.evalInSandbox(script, sandbox, null, "sandbox eval code", 1); +} + +class ConsoleLogHelper { + static PREVIEW_MAX_ITEMS = 10; + static LOG_LEVELS = ["debug", "info", "warn", "error"]; + + #windowId = undefined; + + constructor(windowId) { + this.#windowId = windowId; + } + + getLoggedMessages(alsoIncludePrivate = true) { + return this.getConsoleAPIMessages().concat( + this.getScriptErrors(alsoIncludePrivate) + ); + } + + getConsoleAPIMessages() { + const ConsoleAPIStorage = Cc[ + "@mozilla.org/consoleAPI-storage;1" + ].getService(Ci.nsIConsoleAPIStorage); + let messages = ConsoleAPIStorage.getEvents(this.#windowId); + return messages.map(evt => { + const { columnNumber, filename, level, lineNumber, timeStamp } = evt; + + const args = []; + for (const arg of evt.arguments) { + args.push(this.#getArgs(arg)); + } + + const message = { + level, + log: args, + uri: filename, + pos: `${lineNumber}:${columnNumber}`, + }; + + return { timeStamp, message }; + }); + } + + getScriptErrors(alsoIncludePrivate) { + const messages = Services.console.getMessageArray(); + return messages + .filter(message => { + if (message instanceof Ci.nsIScriptError) { + if (!alsoIncludePrivate && message.isFromPrivateWindow) { + return false; + } + if (this.#windowId && this.#windowId !== message.innerWindowID) { + return false; + } + return true; + } + + // If this is not an nsIScriptError and we need to do window-based + // filtering we skip this message. + return false; + }) + .map(error => { + const { + timeStamp, + errorMessage, + sourceName, + lineNumber, + columnNumber, + logLevel, + } = error; + const message = { + level: ConsoleLogHelper.LOG_LEVELS[logLevel], + log: [errorMessage], + uri: sourceName, + pos: `${lineNumber}:${columnNumber}`, + }; + return { timeStamp, message }; + }); + } + + #getPreview(value) { + switch (typeof value) { + case "symbol": + return value.toString(); + + case "function": + return "function ()"; + + case "object": + if (value === null) { + return null; + } + if (Array.isArray(value)) { + return `(${value.length})[...]`; + } + return "{...}"; + + case "undefined": + return "undefined"; + + default: + try { + structuredClone(value); + } catch (_) { + return `${value}` || "?"; + } + return value; + } + } + + #getArrayPreview(arr) { + const preview = []; + let count = 0; + for (const value of arr) { + if (++count > ConsoleLogHelper.PREVIEW_MAX_ITEMS) { + break; + } + preview.push(this.#getPreview(value)); + } + + return preview; + } + + #getObjectPreview(obj) { + const preview = {}; + let count = 0; + for (const key of Object.keys(obj)) { + if (++count > ConsoleLogHelper.PREVIEW_MAX_ITEMS) { + break; + } + preview[key] = this.#getPreview(obj[key]); + } + + return preview; + } + + #getArgs(value) { + if (typeof value === "object" && value !== null) { + if (Array.isArray(value)) { + return this.#getArrayPreview(value); + } + return this.#getObjectPreview(value); + } + + return this.#getPreview(value); + } +} + +const FrameworkDetector = { + hasFastClickPageScript(window) { + if (window.FastClick) { + return true; + } + + for (const property in window) { + try { + const proto = window[property].prototype; + if (proto && proto.needsClick) { + return true; + } + } catch (_) {} + } + + return false; + }, + + hasMobifyPageScript(window) { + return !!window.Mobify?.Tag; + }, + + hasMarfeelPageScript(window) { + return !!window.marfeel; + }, + + checkWindow(window) { + const script = ` + (function() { + function ${FrameworkDetector.hasFastClickPageScript}; + function ${FrameworkDetector.hasMobifyPageScript}; + function ${FrameworkDetector.hasMarfeelPageScript}; + const win = window.wrappedJSObject || window; + return { + fastclick: hasFastClickPageScript(win), + mobify: hasMobifyPageScript(win), + marfeel: hasMarfeelPageScript(win), + } + })(); + `; + return RunScriptInFrame(window, script); + }, +}; + +function getSysinfoProperty(propertyName, defaultValue) { + try { + return Services.sysinfo.getProperty(propertyName); + } catch (e) {} + return defaultValue; +} + +const BrowserInfo = { + getAppInfo() { + const { userAgent } = Cc[ + "@mozilla.org/network/protocol;1?name=http" + ].getService(Ci.nsIHttpProtocolHandler); + return { + applicationName: Services.appinfo.name, + buildId: Services.appinfo.appBuildID, + defaultUserAgent: userAgent, + updateChannel: AppConstants.MOZ_UPDATE_CHANNEL, + version: AppConstants.MOZ_APP_VERSION_DISPLAY, + }; + }, + + getPrefs() { + const prefs = {}; + for (const [name, dflt] of Object.entries({ + "layers.acceleration.force-enabled": undefined, + "gfx.webrender.software": undefined, + "browser.opaqueResponseBlocking": undefined, + "extensions.InstallTrigger.enabled": undefined, + "privacy.resistFingerprinting": undefined, + "privacy.globalprivacycontrol.enabled": undefined, + })) { + prefs[name] = Services.prefs.getBoolPref(name, dflt); + } + const cookieBehavior = "network.cookie.cookieBehavior"; + prefs[cookieBehavior] = Services.prefs.getIntPref(cookieBehavior); + return prefs; + }, + + getPlatformInfo() { + let memoryMB = getSysinfoProperty("memsize", null); + if (memoryMB) { + memoryMB = Math.round(memoryMB / 1024 / 1024); + } + + const info = { + fissionEnabled: Services.appinfo.fissionAutostart, + memoryMB, + osArchitecture: getSysinfoProperty("arch", null), + osName: getSysinfoProperty("name", null), + osVersion: getSysinfoProperty("version", null), + os: AppConstants.platform, + }; + if (AppConstants.platform === "android") { + info.device = getSysinfoProperty("device", null); + info.isTablet = getSysinfoProperty("tablet", false); + } + return info; + }, + + getAllData() { + return { + app: BrowserInfo.getAppInfo(), + prefs: BrowserInfo.getPrefs(), + platform: BrowserInfo.getPlatformInfo(), + }; + }, +}; + +export class ReportBrokenSiteChild extends JSWindowActorChild { + #getWebCompatInfo(docShell) { + return Promise.all([ + this.#getConsoleLogs(docShell), + this.sendQuery( + "GetWebcompatInfoOnlyAvailableInParentProcess", + SCREENSHOT_FORMAT + ), + ]).then(([consoleLog, infoFromParent]) => { + const { antitracking, graphics, locales, screenshot, security } = + infoFromParent; + + const browser = BrowserInfo.getAllData(); + browser.graphics = graphics; + browser.locales = locales; + browser.security = security; + + const win = docShell.domWindow; + const frameworks = FrameworkDetector.checkWindow(win); + + if (browser.platform.os !== "linux") { + delete browser.prefs["layers.acceleration.force-enabled"]; + } + + return { + antitracking, + browser, + consoleLog, + devicePixelRatio: win.devicePixelRatio, + frameworks, + languages: win.navigator.languages, + screenshot, + url: win.location.href, + userAgent: win.navigator.userAgent, + }; + }); + } + + async #getConsoleLogs(docShell) { + return this.#getLoggedMessages() + .flat() + .sort((a, b) => a.timeStamp - b.timeStamp) + .map(m => m.message); + } + + #getLoggedMessages(alsoIncludePrivate = false) { + const windowId = this.contentWindow.windowGlobalChild.innerWindowId; + const helper = new ConsoleLogHelper(windowId, alsoIncludePrivate); + return helper.getLoggedMessages(); + } + + #formatReportDataForWebcompatCom({ + reason, + description, + reportUrl, + reporterConfig, + webcompatInfo, + }) { + const extra_labels = []; + + const message = Object.assign({}, reporterConfig, { + url: reportUrl, + category: reason, + description, + details: {}, + extra_labels, + }); + + const payload = { + message, + }; + + if (webcompatInfo) { + const { + antitracking, + browser, + devicePixelRatio, + consoleLog, + frameworks, + languages, + screenshot, + url, + userAgent, + } = webcompatInfo; + + const { + blockList, + isPrivateBrowsing, + hasMixedActiveContentBlocked, + hasMixedDisplayContentBlocked, + hasTrackingContentBlocked, + } = antitracking; + + message.blockList = blockList; + + const { app, graphics, prefs, platform, security } = browser; + + const { applicationName, version, updateChannel, defaultUserAgent } = app; + + const { + fissionEnabled, + memoryMb, + osArchitecture, + osName, + osVersion, + device, + isTablet, + } = platform; + + const additionalData = { + applicationName, + blockList, + devicePixelRatio, + finalUserAgent: userAgent, + fissionEnabled, + gfxData: graphics, + hasMixedActiveContentBlocked, + hasMixedDisplayContentBlocked, + hasTrackingContentBlocked, + isPB: isPrivateBrowsing, + languages, + memoryMb, + osArchitecture, + osName, + osVersion, + prefs, + updateChannel, + userAgent: defaultUserAgent, + version, + }; + if (security !== undefined) { + additionalData.sec = security; + } + if (device !== undefined) { + additionalData.device = device; + } + if (isTablet !== undefined) { + additionalData.isTablet = isTablet; + } + + const specialPrefs = {}; + for (const pref of [ + "layers.acceleration.force-enabled", + "gfx.webrender.software", + ]) { + specialPrefs[pref] = prefs[pref]; + } + + const details = Object.assign(message.details, specialPrefs, { + additionalData, + buildId: browser.buildId, + blockList, + channel: browser.updateChannel, + hasTouchScreen: browser.graphics.hasTouchScreen, + }); + + // If the user enters a URL unrelated to the current tab, + // don't bother sending a screnshot or logs/etc + let sendRecordedPageSpecificDetails = false; + try { + const givenUri = new URL(reportUrl); + const recordedUri = new URL(url); + sendRecordedPageSpecificDetails = + givenUri.origin == recordedUri.origin && + givenUri.pathname == recordedUri.pathname; + } catch (_) {} + + if (sendRecordedPageSpecificDetails) { + payload.screenshot = screenshot; + + details.consoleLog = consoleLog; + details.frameworks = frameworks; + details["mixed active content blocked"] = + antitracking.hasMixedActiveContentBlocked; + details["mixed passive content blocked"] = + antitracking.hasMixedDisplayContentBlocked; + details["tracking content blocked"] = + antitracking.hasTrackingContentBlocked + ? `true (${antitracking.blockList})` + : "false"; + + if (antitracking.hasTrackingContentBlocked) { + extra_labels.push( + `type-tracking-protection-${antitracking.blockList}` + ); + } + + for (const [framework, active] of Object.entries(frameworks)) { + if (!active) { + continue; + } + details[framework] = true; + extra_labels.push(`type-${framework}`); + } + } + } + + return payload; + } + + #stripNonASCIIChars(str) { + // eslint-disable-next-line no-control-regex + return str.replace(/[^\x00-\x7F]/g, ""); + } + + async receiveMessage(msg) { + const { docShell } = this; + switch (msg.name) { + case "SendDataToWebcompatCom": { + const win = docShell.domWindow; + const expectedEndpoint = msg.data.endpointUrl; + if (win.location.href == expectedEndpoint) { + // Ensure that the tab has fully loaded and is waiting for messages + const onLoad = () => { + const payload = this.#formatReportDataForWebcompatCom(msg.data); + const json = this.#stripNonASCIIChars(JSON.stringify(payload)); + const expectedOrigin = JSON.stringify( + new URL(expectedEndpoint).origin + ); + // webcompat.com checks that the message comes from its own origin + const script = ` + const wrtReady = window.wrappedJSObject?.wrtReady; + if (wrtReady) { + console.info("Report Broken Site is waiting"); + } + Promise.resolve(wrtReady).then(() => { + console.debug(${json}); + postMessage(${json}, ${expectedOrigin}) + });`; + RunScriptInFrame(win, script); + }; + if (win.document.readyState == "complete") { + onLoad(); + } else { + win.addEventListener("load", onLoad, { once: true }); + } + } + return null; + } + case "GetWebCompatInfo": { + return this.#getWebCompatInfo(docShell); + } + case "GetConsoleLog": { + return this.#getLoggedMessages(); + } + } + return null; + } +} diff --git a/toolkit/components/reportbrokensite/ReportBrokenSiteParent.sys.mjs b/toolkit/components/reportbrokensite/ReportBrokenSiteParent.sys.mjs new file mode 100644 index 0000000000..d6363a4ee1 --- /dev/null +++ b/toolkit/components/reportbrokensite/ReportBrokenSiteParent.sys.mjs @@ -0,0 +1,292 @@ +/* vim: set ts=2 sw=2 et tw=80: */ +/* 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/. */ + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; + +function getSysinfoProperty(propertyName, defaultValue) { + try { + return Services.sysinfo.getProperty(propertyName); + } catch (e) {} + return defaultValue; +} + +function getSecurityInfo() { + const keys = [ + ["registeredAntiVirus", "antivirus"], + ["registeredAntiSpyware", "antispyware"], + ["registeredFirewall", "firewall"], + ]; + + let result = {}; + + for (let [inKey, outKey] of keys) { + const str = getSysinfoProperty(inKey, null); + result[outKey] = !str ? null : str.split(";"); + } + + // Right now, security data is only available for Windows builds, and + // we might as well not return anything at all if no data is available. + if (!Object.values(result).filter(e => e).length) { + return undefined; + } + + return result; +} + +class DriverInfo { + constructor(gl, ext) { + try { + this.extensions = ext.getParameter(ext.EXTENSIONS); + } catch (e) {} + + try { + this.renderer = ext.getParameter(gl.RENDERER); + } catch (e) {} + + try { + this.vendor = ext.getParameter(gl.VENDOR); + } catch (e) {} + + try { + this.version = ext.getParameter(gl.VERSION); + } catch (e) {} + + try { + this.wsiInfo = ext.getParameter(ext.WSI_INFO); + } catch (e) {} + } + + equals(info2) { + return this.renderer == info2.renderer && this.version == info2.version; + } + + static getByType(driver) { + const doc = new DOMParser().parseFromString("<html/>", "text/html"); + const canvas = doc.createElement("canvas"); + canvas.width = 1; + canvas.height = 1; + let error; + canvas.addEventListener("webglcontextcreationerror", function (e) { + error = true; + }); + let gl = null; + try { + gl = canvas.getContext(driver); + } catch (e) { + error = true; + } + if (error || !gl?.getExtension) { + return undefined; + } + + let ext = null; + try { + ext = gl.getExtension("MOZ_debug"); + } catch (e) {} + if (!ext) { + return undefined; + } + + const data = new DriverInfo(gl, ext); + + try { + gl.getExtension("WEBGL_lose_context").loseContext(); + } catch (e) {} + + return data; + } + + static getAll() { + const drivers = []; + + function tryDriver(type) { + const driver = DriverInfo.getByType(type); + if (driver) { + drivers.push(driver); + } + } + + tryDriver("webgl"); + tryDriver("webgl2"); + tryDriver("webgpu"); + + return drivers; + } +} + +export class ReportBrokenSiteParent extends JSWindowActorParent { + #getAntitrackingBlockList() { + // If content-track-digest256 is in the tracking table, + // the user has enabled the strict list. + const trackingTable = Services.prefs.getCharPref( + "urlclassifier.trackingTable" + ); + return trackingTable.includes("content") ? "strict" : "basic"; + } + + #getAntitrackingInfo(browsingContext) { + return { + blockList: this.#getAntitrackingBlockList(), + isPrivateBrowsing: browsingContext.usePrivateBrowsing, + hasTrackingContentBlocked: !!( + browsingContext.currentWindowGlobal.contentBlockingEvents & + Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT + ), + hasMixedActiveContentBlocked: !!( + browsingContext.secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT + ), + hasMixedDisplayContentBlocked: !!( + browsingContext.secureBrowserUI.state & + Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT + ), + }; + } + + #getBasicGraphicsInfo(gfxInfo) { + const get = name => { + try { + return gfxInfo[name]; + } catch (e) {} + return undefined; + }; + + const clean = rawObj => { + const obj = JSON.parse(JSON.stringify(rawObj)); + if (!Object.keys(obj).length) { + return undefined; + } + return obj; + }; + + const cleanDevice = (vendorID, deviceID, subsysID) => { + return clean({ vendorID, deviceID, subsysID }); + }; + + const d1 = cleanDevice( + get("adapterVendorID"), + get("adapterDeviceID"), + get("adapterSubsysID") + ); + const d2 = cleanDevice( + get("adapterVendorID2"), + get("adapterDeviceID2"), + get("adapterSubsysID2") + ); + const devices = (get("isGPU2Active") ? [d2, d1] : [d1, d2]).filter( + v => v !== undefined + ); + + return clean({ + direct2DEnabled: get("direct2DEnabled"), + directWriteEnabled: get("directWriteEnabled"), + directWriteVersion: get("directWriteVersion"), + hasTouchScreen: gfxInfo.getInfo().ApzTouchInput == 1, + cleartypeParameters: get("clearTypeParameters"), + targetFrameRate: get("targetFrameRate"), + devices, + }); + } + + #getGraphicsInfo() { + const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + + const data = this.#getBasicGraphicsInfo(gfxInfo); + + data.drivers = DriverInfo.getAll().map(({ renderer, vendor, version }) => { + return { renderer: `${vendor} -- ${renderer}`, version }; + }); + + try { + const info = gfxInfo.CodecSupportInfo; + if (info) { + const codecs = {}; + for (const item of gfxInfo.CodecSupportInfo.split("\n")) { + const [codec, ...types] = item.split(" "); + if (!codecs[codec]) { + codecs[codec] = { software: false, hardware: false }; + } + if (types.includes("SW")) { + codecs[codec].software = true; + } + if (types.includes("HW")) { + codecs[codec].hardware = true; + } + } + data.codecSupport = codecs; + } + } catch (e) {} + + try { + const { features } = gfxInfo.getFeatureLog(); + data.features = {}; + for (let { name, log, status } of features) { + for (const item of log.reverse()) { + if (!item.failureId || item.status != status) { + continue; + } + status = `${status} (${item.message || item.failureId})`; + } + data.features[name] = status; + } + } catch (e) {} + + try { + if (AppConstants.platform !== "android") { + data.monitors = gfxInfo.getMonitors(); + } + } catch (e) {} + + return data; + } + + async #getScreenshot(browsingContext, format, quality) { + const zoom = browsingContext.fullZoom; + const scale = browsingContext.topChromeWindow?.devicePixelRatio || 1; + const wgp = browsingContext.currentWindowGlobal; + + const image = await wgp.drawSnapshot( + undefined, // rect + scale * zoom, + "white", + undefined // resetScrollPosition + ); + + const doc = Services.appShell.hiddenDOMWindow.document; + const canvas = doc.createElement("canvas"); + canvas.width = image.width; + canvas.height = image.height; + + const ctx = canvas.getContext("2d", { alpha: false }); + ctx.drawImage(image, 0, 0); + image.close(); + + return canvas.toDataURL(`image/${format}`, quality / 100); + } + + async receiveMessage(msg) { + switch (msg.name) { + case "GetWebcompatInfoOnlyAvailableInParentProcess": { + const { format, quality } = msg.data; + const screenshot = await this.#getScreenshot( + msg.target.browsingContext, + format, + quality + ).catch(e => { + console.error("Report Broken Site: getting a screenshot failed", e); + return Promise.resolve(undefined); + }); + return { + antitracking: this.#getAntitrackingInfo(msg.target.browsingContext), + graphics: this.#getGraphicsInfo(), + locales: Services.locale.availableLocales, + screenshot, + security: getSecurityInfo(), + }; + } + } + return null; + } +} diff --git a/toolkit/components/reportbrokensite/metrics.yaml b/toolkit/components/reportbrokensite/metrics.yaml new file mode 100644 index 0000000000..cde4d28ef4 --- /dev/null +++ b/toolkit/components/reportbrokensite/metrics.yaml @@ -0,0 +1,686 @@ +# 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/. + +# Adding a new metric? We have docs for that! +# https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/new_definitions_file.html + +--- +$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0 +$tags: + - "Web Compatibility :: Tooling & Investigations" + +broken_site_report: + breakage_category: + type: string + expires: never + data_sensitivity: + - interaction + description: > + An optional select-box choice (options may eventually change) + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + description: + type: text + expires: never + data_sensitivity: + - highly_sensitive + description: > + An optional description of the site issue the user is experiencing. May contain PII. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + url: + type: url + expires: never + data_sensitivity: + - highly_sensitive + description: > + The URL of the site being reported. May contain PII. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + +broken_site_report.tab_info: + languages: + type: string_list + expires: never + data_sensitivity: + - technical + description: > + The languages the site actually sees (may be overridden) + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + useragent_string: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + The userAgent the site actually sees (may be overridden) + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + +broken_site_report.tab_info.antitracking: + block_list: + type: string + expires: never + data_sensitivity: + - interaction + description: > + Currently either `basic` or `strict`, may change in the future. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + has_mixed_active_content_blocked: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the reported tab has any blocked mixed active content + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + has_mixed_display_content_blocked: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the reported tab has any blocked mixed display content + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + has_tracking_content_blocked: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the reported tab has any blocked tracking content + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + is_private_browsing: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the tab the user was on when reporting is in private browsing mode + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + +broken_site_report.tab_info.frameworks: + fastclick: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the FastClick web library was detected on the original tab. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + marfeel: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the Marfeel web framework was detected on the original tab. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + mobify: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Whether the Mobify web framework was detected on the original tab. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + +broken_site_report.browser_info.app: + default_locales: + type: string_list + expires: never + data_sensitivity: + - interaction + description: > + Locale strings, ie `["en-US", "en"]` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + default_useragent_string: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + The default user-agent string of the browser + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + fission_enabled: + type: boolean + expires: never + data_sensitivity: + - technical + description: > + Whether Fission is enabled + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + +broken_site_report.browser_info.graphics: + device_pixel_ratio: + type: string + expires: never + data_sensitivity: + - technical + description: > + A decimal number + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + has_touch_screen: + type: boolean + expires: never + data_sensitivity: + - technical + description: > + Whether a touch screen was detected + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + devices_json: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + JSON array of objects with `vendorID` and `deviceID`. + For instance, `[{"vendorID":"0x000", "deviceID":"0x001"}]` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + drivers_json: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + JSON array of objects with `renderer` and `version`. + For instance, `[{"renderer":"demo", "version":"0.2"}]` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + features_json: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + JSON object. + For instance, `{"WEBRENDER":"available","WEBRENDER_PARTIAL":"disabled (User disabled via pref)"}` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + monitors_json: + type: text + expires: never + data_sensitivity: + - stored_content + description: > + JSON array of objects with `screenWidth`, 'screenHeight`, and `scale`. + For instance, `[{"screenWidth":3584,"screenHeight":2240,"scale":2}]` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + +broken_site_report.browser_info.system: + is_tablet: + type: boolean + expires: never + data_sensitivity: + - technical + description: > + Whether the device is a tablet + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + memory: + type: quantity + unit: mb + expires: never + data_sensitivity: + - technical + description: > + How many mb of RAM is reported for the system + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + +broken_site_report.browser_info.prefs: + opaque_response_blocking: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `browser.opaqueResponseBlocking` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + installtrigger_enabled: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `extensions.InstallTrigger.enabled` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + software_webrender: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `gfx.webrender.software` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + forced_accelerated_layers: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `layers.acceleration_force.enabled` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + cookie_behavior: + type: quantity + unit: integer + expires: never + data_sensitivity: + - interaction + description: > + Value of `network.cookie.cookieBehavior` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + global_privacy_control_enabled: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `privacy.globalprivacycontrol.enabled` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + resist_fingerprinting_enabled: + type: boolean + expires: never + data_sensitivity: + - interaction + description: > + Value of `privacy.resistFingerprinting` + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + +broken_site_report.browser_info.security: + antivirus: + type: string_list + expires: never + data_sensitivity: + - technical + description: > + Which antivirus software was reported on this system. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + antispyware: + type: string_list + expires: never + data_sensitivity: + - technical + description: > + Which antispyware software was reported on this system. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + firewall: + type: string_list + expires: never + data_sensitivity: + - technical + description: > + Which firewall software was reported on this system. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + send_in_pings: + - broken-site-report + + +webcompatreporting: + opened: + type: event + description: > + Records the method for opening the webcompat reporting window. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + data_sensitivity: + - interaction + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + expires: never + extra_keys: + source: + description: > + From which entry-point the user accessed the reporting window. + One of + * `helpMenu` + * `hamburgerMenu` + * `ETPShieldIconMenu` + type: string + reason_dropdown: + type: event + description: > + Record whether the user has a dropdown enabled + whether the dropdown menu is optional or mandatory. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + data_sensitivity: + - interaction + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + expires: never + extra_keys: + setting: + description: > + One of + * `disabled` + * `optional` + * `required` + type: string + send: + type: event + description: > + Recorded when a user selects the Send button to submit webcompat report data. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + data_sensitivity: + - interaction + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + expires: never + send_more_info: + type: event + description: > + Recorded when a user clicks on the Send More Info link in the reporting UI + The user will be redirected to webcompat.com to submit a more comprehensive report. + (This is only enabled on beta/nightly/pre-release channels). + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + data_sensitivity: + - interaction + notification_emails: + - twisniewski@mozilla.com + - webcompat-reporting-tool-telemetry@mozilla.com + expires: never diff --git a/toolkit/components/reportbrokensite/moz.build b/toolkit/components/reportbrokensite/moz.build new file mode 100644 index 0000000000..e0956c46e3 --- /dev/null +++ b/toolkit/components/reportbrokensite/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +FINAL_TARGET_FILES.actors = [ + "ReportBrokenSiteChild.sys.mjs", + "ReportBrokenSiteParent.sys.mjs", +] + +with Files("**"): + BUG_COMPONENT = ("Web Compatibility", "Tooling & Investigations") diff --git a/toolkit/components/reportbrokensite/pings.yaml b/toolkit/components/reportbrokensite/pings.yaml new file mode 100644 index 0000000000..7b8ee70c3c --- /dev/null +++ b/toolkit/components/reportbrokensite/pings.yaml @@ -0,0 +1,18 @@ +# 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/. + +--- +$schema: moz://mozilla.org/schemas/glean/pings/2-0-0 + +broken-site-report: + description: | + A ping containing the data for a user-initiated report for a broken site. + Does not contain a `client_id`. All report data is self-contained. + include_client_id: false + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852340#c16 + notification_emails: + - twisniewski@mozilla.com |