Bug 1538276 - Implement the "prio" ping. r=janerik

The "prio" ping contains Origin Telemetry and not much else.

It is enabled only on Firefox Nightly for now.

Differential Revision: https://phabricator.services.mozilla.com/D24781

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Chris H-C 2019-03-27 19:29:48 +00:00
Родитель 7d6860c063
Коммит a773e93e99
7 изменённых файлов: 197 добавлений и 0 удалений

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

@ -1831,6 +1831,10 @@ pref("toolkit.coverage.endpoint.base", "https://coverage.mozilla.org");
#if defined(NIGHTLY_BUILD)
pref("prio.enabled", true);
#endif
// Whether Prio-encoded Telemetry will be sent in the prio ping.
#if defined(NIGHTLY_BUILD)
pref("toolkit.telemetry.prioping.enabled", true);
#endif
// Discovery prefs
pref("browser.discovery.enabled", true);

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

@ -6081,6 +6081,8 @@ pref("dom.datatransfer.mozAtAPIs", true);
// Whether or not Prio is supported on this platform.
pref("prio.enabled", false);
// Whether or not the Prio Ping is supported on this platform.
pref("toolkit.telemetry.prioping.enabled", false);
// External.AddSearchProvider is deprecated and it will be removed in the next
// cycles.

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

@ -65,6 +65,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
TelemetryHealthPing: "resource://gre/modules/HealthPing.jsm",
TelemetryEventPing: "resource://gre/modules/EventPing.jsm",
EcosystemTelemetry: "resource://gre/modules/EcosystemTelemetry.jsm",
TelemetryPrioPing: "resource://gre/modules/PrioPing.jsm",
OS: "resource://gre/modules/osfile.jsm",
});
@ -728,6 +729,7 @@ var Impl = {
TelemetryEventPing.startup();
EcosystemTelemetry.startup();
TelemetryPrioPing.startup();
this._delayedInitTaskDeferred.resolve();
} catch (e) {
@ -789,6 +791,7 @@ var Impl = {
TelemetryEventPing.shutdown();
EcosystemTelemetry.shutdown();
await TelemetryPrioPing.shutdown();
// Stop the datachoices infobar display.
TelemetryReportingPolicy.shutdown();

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

@ -60,6 +60,11 @@ var TelemetryUtils = {
// Ecosystem Telemetry Preferences
EcosystemTelemetryEnabled: "toolkit.telemetry.ecosystemtelemetry.enabled",
// Prio Ping Preferences
PrioPingEnabled: "toolkit.telemetry.prioping.enabled",
PrioPingFrequency: "toolkit.telemetry.prioping.frequency",
PrioPingDataLimit: "toolkit.telemetry.prioping.dataLimit",
// Log Preferences
LogLevel: "toolkit.telemetry.log.level",
LogDump: "toolkit.telemetry.log.dump",

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

@ -179,6 +179,21 @@ Preferences
sending them to the parent process.
Default is 2000 (milliseconds).
``toolkit.telemetry.prioping.enabled``
Whether the :doc:`../data/prio-ping` is enabled.
Defaults to false except on Firefox Nightly where it is true. Change requires restart.
``toolkit.telemetry.prioping.frequency``
The default frequency at which we send the :doc:`../data/prio-ping`.
Default is 24 (hours).
``toolkit.telemetry.prioping.dataLimit``
The number of encoded prio payloads which triggers an immediate :doc:`../data/prio-ping` with reason "max".
Default is 10 payloads.
Data-choices notification
-------------------------

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

@ -116,6 +116,7 @@ EXTRA_JS_MODULES += [
'pings/EventPing.jsm',
'pings/HealthPing.jsm',
'pings/ModulesPing.jsm',
'pings/PrioPing.jsm',
'pings/TelemetrySession.jsm',
'pings/UntrustedModulesPing.jsm',
'pings/UpdatePing.jsm',

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

@ -0,0 +1,167 @@
/* 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/. */
/*
* This module sends Origin Telemetry periodically:
* https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/prio-ping.html
*/
"use strict";
var EXPORTED_SYMBOLS = [
"TelemetryPrioPing",
];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
XPCOMUtils.defineLazyModuleGetters(this, {
TelemetryController: "resource://gre/modules/TelemetryController.jsm",
Log: "resource://gre/modules/Log.jsm",
});
XPCOMUtils.defineLazyServiceGetters(this, {
Telemetry: ["@mozilla.org/base/telemetry;1", "nsITelemetry"],
});
const {setTimeout, clearTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
const {TelemetryUtils} = ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const Utils = TelemetryUtils;
const MILLISECONDS_PER_HOUR = 60 * 60 * 1000;
const DEFAULT_PING_FREQUENCY_HOURS = 24;
const LOGGER_NAME = "Toolkit.Telemetry";
const LOGGER_PREFIX = "TelemetryPrioPing";
// Triggered from native Origin Telemetry storage.
const PRIO_LIMIT_REACHED_TOPIC = "origin-telemetry-storage-limit-reached";
const PRIO_PING_VERSION = "1";
var Policy = {
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
clearTimeout: (id) => clearTimeout(id),
sendPing: (type, payload, options) => TelemetryController.submitExternalPing(type, payload, options),
getEncodedOriginSnapshot: async (aClear) => Telemetry.getEncodedOriginSnapshot(aClear),
};
var TelemetryPrioPing = {
Reason: Object.freeze({
PERIODIC: "periodic", // Sent the ping containing Origin Telemetry from the past periodic interval (default 24h).
MAX: "max", // Sent the ping containing at least the maximum number (default 10) of prioData elements, earlier than the periodic interval.
SHUTDOWN: "shutdown", // Recorded data was sent on shutdown.
}),
PRIO_PING_TYPE: "prio",
_logger: null,
_testing: false,
_timeoutId: null,
startup() {
if (!this._testing && !Services.prefs.getBoolPref(Utils.Preferences.PrioPingEnabled, false)) {
this._log.trace("Prio ping disabled.");
return;
}
this._log.trace("Starting up.");
Services.obs.addObserver(this, PRIO_LIMIT_REACHED_TOPIC);
XPCOMUtils.defineLazyPreferenceGetter(this, "pingFrequency",
Utils.Preferences.PrioPingFrequency,
DEFAULT_PING_FREQUENCY_HOURS);
this._startTimer();
},
async shutdown() {
this._log.trace("Shutting down.");
// removeObserver may throw, which could interrupt shutdown.
try {
Services.obs.removeObserver(this, PRIO_LIMIT_REACHED_TOPIC);
} catch (ex) {}
await this._submitPing(this.Reason.SHUTDOWN);
this._clearTimer();
},
observe(aSubject, aTopic, aData) {
switch (aTopic) {
case PRIO_LIMIT_REACHED_TOPIC:
this._log.trace("prio limit reached");
this._submitPing(this.Reason.MAX);
break;
}
},
_startTimer(delay = this.pingFrequency * MILLISECONDS_PER_HOUR, reason = this.Reason.PERIODIC, discardLeftovers = false) {
this._clearTimer();
this._timeoutId =
Policy.setTimeout(() => TelemetryPrioPing._submitPing(reason), delay);
},
_clearTimer() {
if (this._timeoutId) {
Policy.clearTimeout(this._timeoutId);
this._timeoutId = null;
}
},
/**
* Submits an "prio" ping and restarts the timer for the next interval.
*
* @param {String} reason The reason we're sending the ping. One of TelemetryPrioPing.Reason.
*/
async _submitPing(reason) {
this._log.trace("_submitPing");
if (reason !== this.Reason.SHUTDOWN) {
this._startTimer();
}
let snapshot = await Policy.getEncodedOriginSnapshot(true /* clear */);
if (!this._testing) {
snapshot = snapshot.filter(({encoding}) => !encoding.startsWith("telemetry.test"));
}
if (snapshot.length === 0) {
// Don't send a ping if we haven't anything to send
this._log.trace("nothing to send");
return;
}
let payload = {
version: PRIO_PING_VERSION,
reason,
prioData: snapshot,
};
const options = {
addClientId: false,
addEnvironment: false,
usePingSender: reason === this.Reason.SHUTDOWN,
};
Policy.sendPing(this.PRIO_PING_TYPE, payload, options);
},
/**
* Test-only, restore to initial state.
*/
testReset() {
this._clearTimer();
this._testing = true;
},
get _log() {
if (!this._logger) {
this._logger = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX + "::");
}
return this._logger;
},
};