michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Preferences.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: const reporter = Cc["@mozilla.org/datareporting/service;1"] michael@0: .getService(Ci.nsISupports) michael@0: .wrappedJSObject michael@0: .healthReporter; michael@0: michael@0: const policy = Cc["@mozilla.org/datareporting/service;1"] michael@0: .getService(Ci.nsISupports) michael@0: .wrappedJSObject michael@0: .policy; michael@0: michael@0: const prefs = new Preferences("datareporting.healthreport."); michael@0: michael@0: michael@0: let healthReportWrapper = { michael@0: init: function () { michael@0: if (!reporter) { michael@0: healthReportWrapper.handleInitFailure(); michael@0: return; michael@0: } michael@0: michael@0: reporter.onInit().then(healthReportWrapper.refreshPayload, michael@0: healthReportWrapper.handleInitFailure); michael@0: michael@0: let iframe = document.getElementById("remote-report"); michael@0: iframe.addEventListener("load", healthReportWrapper.initRemotePage, false); michael@0: let report = this._getReportURI(); michael@0: iframe.src = report.spec; michael@0: prefs.observe("uploadEnabled", this.updatePrefState, healthReportWrapper); michael@0: }, michael@0: michael@0: uninit: function () { michael@0: prefs.ignore("uploadEnabled", this.updatePrefState, healthReportWrapper); michael@0: }, michael@0: michael@0: _getReportURI: function () { michael@0: let url = Services.urlFormatter.formatURLPref("datareporting.healthreport.about.reportUrl"); michael@0: return Services.io.newURI(url, null, null); michael@0: }, michael@0: michael@0: onOptIn: function () { michael@0: policy.recordHealthReportUploadEnabled(true, michael@0: "Health report page sent opt-in command."); michael@0: this.updatePrefState(); michael@0: }, michael@0: michael@0: onOptOut: function () { michael@0: policy.recordHealthReportUploadEnabled(false, michael@0: "Health report page sent opt-out command."); michael@0: this.updatePrefState(); michael@0: }, michael@0: michael@0: updatePrefState: function () { michael@0: try { michael@0: let prefs = { michael@0: enabled: policy.healthReportUploadEnabled, michael@0: } michael@0: this.injectData("prefs", prefs); michael@0: } catch (e) { michael@0: this.reportFailure(this.ERROR_PREFS_FAILED); michael@0: } michael@0: }, michael@0: michael@0: refreshPayload: function () { michael@0: reporter.collectAndObtainJSONPayload().then(healthReportWrapper.updatePayload, michael@0: healthReportWrapper.handlePayloadFailure); michael@0: }, michael@0: michael@0: updatePayload: function (data) { michael@0: healthReportWrapper.injectData("payload", data); michael@0: }, michael@0: michael@0: injectData: function (type, content) { michael@0: let report = this._getReportURI(); michael@0: michael@0: // file URIs can't be used for targetOrigin, so we use "*" for this special case michael@0: // in all other cases, pass in the URL to the report so we properly restrict the message dispatch michael@0: let reportUrl = report.scheme == "file" ? "*" : report.spec; michael@0: michael@0: let data = { michael@0: type: type, michael@0: content: content michael@0: } michael@0: michael@0: let iframe = document.getElementById("remote-report"); michael@0: iframe.contentWindow.postMessage(data, reportUrl); michael@0: }, michael@0: michael@0: handleRemoteCommand: function (evt) { michael@0: switch (evt.detail.command) { michael@0: case "DisableDataSubmission": michael@0: this.onOptOut(); michael@0: break; michael@0: case "EnableDataSubmission": michael@0: this.onOptIn(); michael@0: break; michael@0: case "RequestCurrentPrefs": michael@0: this.updatePrefState(); michael@0: break; michael@0: case "RequestCurrentPayload": michael@0: this.refreshPayload(); michael@0: break; michael@0: default: michael@0: Cu.reportError("Unexpected remote command received: " + evt.detail.command + ". Ignoring command."); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: initRemotePage: function () { michael@0: let iframe = document.getElementById("remote-report").contentDocument; michael@0: iframe.addEventListener("RemoteHealthReportCommand", michael@0: function onCommand(e) {healthReportWrapper.handleRemoteCommand(e);}, michael@0: false); michael@0: healthReportWrapper.updatePrefState(); michael@0: }, michael@0: michael@0: // error handling michael@0: ERROR_INIT_FAILED: 1, michael@0: ERROR_PAYLOAD_FAILED: 2, michael@0: ERROR_PREFS_FAILED: 3, michael@0: michael@0: reportFailure: function (error) { michael@0: let details = { michael@0: errorType: error, michael@0: } michael@0: healthReportWrapper.injectData("error", details); michael@0: }, michael@0: michael@0: handleInitFailure: function () { michael@0: healthReportWrapper.reportFailure(healthReportWrapper.ERROR_INIT_FAILED); michael@0: }, michael@0: michael@0: handlePayloadFailure: function () { michael@0: healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED); michael@0: }, michael@0: } michael@0: michael@0: window.addEventListener("load", function () { healthReportWrapper.init(); }); michael@0: window.addEventListener("unload", function () { healthReportWrapper.uninit(); });