Backed out changeset 496886cb30a5 (bug 1867152) for bc failures on browser_user_input...
[gecko.git] / browser / modules / PingCentre.sys.mjs
blobe5c99b15a7289d55d901aae70ebaaa7f5d7206ec
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
7 const lazy = {};
8 ChromeUtils.defineESModuleGetters(lazy, {
9   TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs",
10   UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
11   sendStandalonePing: "resource://gre/modules/TelemetrySend.sys.mjs",
12 });
14 const PREF_BRANCH = "browser.ping-centre.";
16 const TELEMETRY_PREF = `${PREF_BRANCH}telemetry`;
17 const LOGGING_PREF = `${PREF_BRANCH}log`;
19 const FHR_UPLOAD_ENABLED_PREF = "datareporting.healthreport.uploadEnabled";
21 /**
22  * Observe various notifications and send them to a telemetry endpoint.
23  *
24  * @param {Object} options
25  * @param {string} options.topic - a unique ID for users of PingCentre to distinguish
26  *                  their data on the server side.
27  */
28 export class PingCentre {
29   constructor(options) {
30     if (!options.topic) {
31       throw new Error("Must specify topic.");
32     }
34     this._topic = options.topic;
35     this._prefs = Services.prefs.getBranch("");
37     this._enabled = this._prefs.getBoolPref(TELEMETRY_PREF);
38     this._onTelemetryPrefChange = this._onTelemetryPrefChange.bind(this);
39     this._prefs.addObserver(TELEMETRY_PREF, this._onTelemetryPrefChange);
41     this._fhrEnabled = this._prefs.getBoolPref(FHR_UPLOAD_ENABLED_PREF);
42     this._onFhrPrefChange = this._onFhrPrefChange.bind(this);
43     this._prefs.addObserver(FHR_UPLOAD_ENABLED_PREF, this._onFhrPrefChange);
45     this.logging = this._prefs.getBoolPref(LOGGING_PREF);
46     this._onLoggingPrefChange = this._onLoggingPrefChange.bind(this);
47     this._prefs.addObserver(LOGGING_PREF, this._onLoggingPrefChange);
48   }
50   get enabled() {
51     return this._enabled && this._fhrEnabled;
52   }
54   _onLoggingPrefChange(aSubject, aTopic, prefKey) {
55     this.logging = this._prefs.getBoolPref(prefKey);
56   }
58   _onTelemetryPrefChange(aSubject, aTopic, prefKey) {
59     this._enabled = this._prefs.getBoolPref(prefKey);
60   }
62   _onFhrPrefChange(aSubject, aTopic, prefKey) {
63     this._fhrEnabled = this._prefs.getBoolPref(prefKey);
64   }
66   _createExperimentsPayload() {
67     let activeExperiments = lazy.TelemetryEnvironment.getActiveExperiments();
68     let experiments = {};
69     for (let experimentID in activeExperiments) {
70       if (
71         activeExperiments[experimentID] &&
72         activeExperiments[experimentID].branch
73       ) {
74         experiments[experimentID] = {
75           branch: activeExperiments[experimentID].branch,
76         };
77       }
78     }
79     return experiments;
80   }
82   _createStructuredIngestionPing(data) {
83     let experiments = this._createExperimentsPayload();
84     let locale = data.locale || Services.locale.appLocaleAsBCP47;
85     const payload = {
86       experiments,
87       locale,
88       version: AppConstants.MOZ_APP_VERSION,
89       release_channel: lazy.UpdateUtils.getUpdateChannel(false),
90       ...data,
91     };
93     return payload;
94   }
96   // We route through this helper because it gets hooked in testing.
97   static _sendStandalonePing(endpoint, payload) {
98     return lazy.sendStandalonePing(endpoint, payload);
99   }
101   /**
102    * Sends a ping to the Structured Ingestion telemetry pipeline.
103    *
104    * The payload would be compressed using gzip.
105    *
106    * @param {Object} data      The payload to be sent.
107    * @param {String} endpoint  The destination endpoint. Note that Structured Ingestion
108    *                           requires a different endpoint for each ping. It's up to the
109    *                           caller to provide that. See more details at
110    *                           https://github.com/mozilla/gcp-ingestion/blob/master/docs/edge.md#postput-request
111    * @param {String} namespace Optional. The structured ingestion namespace.
112    *                           Used for data collection.
113    */
114   sendStructuredIngestionPing(data, endpoint, namespace = undefined) {
115     if (!this.enabled) {
116       return Promise.resolve();
117     }
119     const ping = this._createStructuredIngestionPing(data);
120     const payload = JSON.stringify(ping);
122     if (this.logging) {
123       Services.console.logStringMessage(
124         `TELEMETRY PING (${this._topic}): ${payload}\n`
125       );
126     }
128     let gleanNamespace = "other";
129     switch (namespace) {
130       case "activity-stream":
131         gleanNamespace = "activity_stream";
132         break;
133       case "messaging-system":
134         gleanNamespace = "messaging_system";
135         break;
136       case "contextual-services":
137         gleanNamespace = "contextual_services";
138         break;
139     }
141     return PingCentre._sendStandalonePing(endpoint, payload).then(
142       () => {
143         Glean.pingCentre.sendSuccessesByNamespace[gleanNamespace].add(1);
144       },
145       event => {
146         Glean.pingCentre.sendFailures.add(1);
147         Glean.pingCentre.sendFailuresByNamespace[gleanNamespace].add(1);
148         console.error(
149           `Structured Ingestion ping failure with error: ${event.type}`
150         );
151       }
152     );
153   }
155   uninit() {
156     try {
157       this._prefs.removeObserver(TELEMETRY_PREF, this._onTelemetryPrefChange);
158       this._prefs.removeObserver(LOGGING_PREF, this._onLoggingPrefChange);
159       this._prefs.removeObserver(
160         FHR_UPLOAD_ENABLED_PREF,
161         this._onFhrPrefChange
162       );
163     } catch (e) {
164       console.error(e);
165     }
166   }
169 export const PingCentreConstants = {
170   FHR_UPLOAD_ENABLED_PREF,
171   TELEMETRY_PREF,
172   LOGGING_PREF,