diff options
Diffstat (limited to 'application/basilisk/base/content/abouthealthreport/abouthealth.js')
-rw-r--r-- | application/basilisk/base/content/abouthealthreport/abouthealth.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/application/basilisk/base/content/abouthealthreport/abouthealth.js b/application/basilisk/base/content/abouthealthreport/abouthealth.js new file mode 100644 index 000000000..e04497eae --- /dev/null +++ b/application/basilisk/base/content/abouthealthreport/abouthealth.js @@ -0,0 +1,178 @@ +/* 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/. */ + +"use strict"; + +var {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/Preferences.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +const prefs = new Preferences("datareporting.healthreport."); + +const PREF_UNIFIED = "toolkit.telemetry.unified"; +const PREF_REPORTING_URL = "datareporting.healthreport.about.reportUrl"; + +var healthReportWrapper = { + init() { + let iframe = document.getElementById("remote-report"); + iframe.addEventListener("load", healthReportWrapper.initRemotePage); + iframe.src = this._getReportURI().spec; + prefs.observe("uploadEnabled", this.updatePrefState, healthReportWrapper); + }, + + uninit() { + prefs.ignore("uploadEnabled", this.updatePrefState, healthReportWrapper); + }, + + _getReportURI() { + let url = Services.urlFormatter.formatURLPref(PREF_REPORTING_URL); + return Services.io.newURI(url); + }, + + setDataSubmission(enabled) { + MozSelfSupport.healthReportDataSubmissionEnabled = enabled; + this.updatePrefState(); + }, + + updatePrefState() { + try { + let prefsObj = { + enabled: MozSelfSupport.healthReportDataSubmissionEnabled, + }; + healthReportWrapper.injectData("prefs", prefsObj); + } catch (ex) { + healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PREFS_FAILED); + } + }, + + sendTelemetryPingList() { + console.log("AboutHealthReport: Collecting Telemetry ping list."); + MozSelfSupport.getTelemetryPingList().then((list) => { + console.log("AboutHealthReport: Sending Telemetry ping list."); + this.injectData("telemetry-ping-list", list); + }).catch((ex) => { + console.log("AboutHealthReport: Collecting ping list failed: " + ex); + }); + }, + + sendTelemetryPingData(pingId) { + console.log("AboutHealthReport: Collecting Telemetry ping data."); + MozSelfSupport.getTelemetryPing(pingId).then((ping) => { + console.log("AboutHealthReport: Sending Telemetry ping data."); + this.injectData("telemetry-ping-data", { + id: pingId, + pingData: ping, + }); + }).catch((ex) => { + console.log("AboutHealthReport: Loading ping data failed: " + ex); + this.injectData("telemetry-ping-data", { + id: pingId, + error: "error-generic", + }); + }); + }, + + sendCurrentEnvironment() { + console.log("AboutHealthReport: Sending Telemetry environment data."); + MozSelfSupport.getCurrentTelemetryEnvironment().then((environment) => { + this.injectData("telemetry-current-environment-data", environment); + }).catch((ex) => { + console.log("AboutHealthReport: Collecting current environment data failed: " + ex); + }); + }, + + sendCurrentPingData() { + console.log("AboutHealthReport: Sending current Telemetry ping data."); + MozSelfSupport.getCurrentTelemetrySubsessionPing().then((ping) => { + this.injectData("telemetry-current-ping-data", ping); + }).catch((ex) => { + console.log("AboutHealthReport: Collecting current ping data failed: " + ex); + }); + }, + + injectData(type, content) { + let report = this._getReportURI(); + + // file URIs can't be used for targetOrigin, so we use "*" for this special case + // in all other cases, pass in the URL to the report so we properly restrict the message dispatch + let reportUrl = report.scheme == "file" ? "*" : report.spec; + + let data = { + type, + content + } + + let iframe = document.getElementById("remote-report"); + iframe.contentWindow.postMessage(data, reportUrl); + }, + + handleRemoteCommand(evt) { + // Do an origin check to harden against the frame content being loaded from unexpected locations. + let allowedPrincipal = Services.scriptSecurityManager.getCodebasePrincipal(this._getReportURI()); + let targetPrincipal = evt.target.nodePrincipal; + if (!allowedPrincipal.equals(targetPrincipal)) { + Cu.reportError(`Origin check failed for message "${evt.detail.command}": ` + + `target origin is "${targetPrincipal.origin}", expected "${allowedPrincipal.origin}"`); + return; + } + + switch (evt.detail.command) { + case "DisableDataSubmission": + this.setDataSubmission(false); + break; + case "EnableDataSubmission": + this.setDataSubmission(true); + break; + case "RequestCurrentPrefs": + this.updatePrefState(); + break; + case "RequestTelemetryPingList": + this.sendTelemetryPingList(); + break; + case "RequestTelemetryPingData": + this.sendTelemetryPingData(evt.detail.id); + break; + case "RequestCurrentEnvironment": + this.sendCurrentEnvironment(); + break; + case "RequestCurrentPingData": + this.sendCurrentPingData(); + break; + default: + Cu.reportError("Unexpected remote command received: " + evt.detail.command + ". Ignoring command."); + break; + } + }, + + initRemotePage() { + let iframe = document.getElementById("remote-report").contentDocument; + iframe.addEventListener("RemoteHealthReportCommand", + function onCommand(e) { healthReportWrapper.handleRemoteCommand(e); }); + healthReportWrapper.updatePrefState(); + }, + + // error handling + ERROR_INIT_FAILED: 1, + ERROR_PAYLOAD_FAILED: 2, + ERROR_PREFS_FAILED: 3, + + reportFailure(error) { + let details = { + errorType: error, + } + healthReportWrapper.injectData("error", details); + }, + + handleInitFailure() { + healthReportWrapper.reportFailure(healthReportWrapper.ERROR_INIT_FAILED); + }, + + handlePayloadFailure() { + healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED); + }, +} + +window.addEventListener("load", function() { healthReportWrapper.init(); }); +window.addEventListener("unload", function() { healthReportWrapper.uninit(); }); |