diff --git a/.eslintignore b/.eslintignore index 0e772fdd6d97..57ea5a029689 100644 --- a/.eslintignore +++ b/.eslintignore @@ -275,6 +275,7 @@ mobile/android/tests/browser/chrome/tp5/** # Uses `#filter substitution` mobile/android/app/mobile.js +mobile/android/chrome/content/healthreport-prefs.js # Uses `#expand` mobile/android/chrome/content/about.js diff --git a/browser/base/content/abouthealthreport/abouthealth.css b/browser/base/content/abouthealthreport/abouthealth.css new file mode 100644 index 000000000000..3dd40fc24312 --- /dev/null +++ b/browser/base/content/abouthealthreport/abouthealth.css @@ -0,0 +1,15 @@ +* { + margin: 0; + padding: 0; +} + +html, body { + height: 100%; +} + +#remote-report { + width: 100%; + height: 100%; + border: 0; + display: flex; +} diff --git a/browser/base/content/abouthealthreport/abouthealth.js b/browser/base/content/abouthealthreport/abouthealth.js new file mode 100644 index 000000000000..d5c09a691243 --- /dev/null +++ b/browser/base/content/abouthealthreport/abouthealth.js @@ -0,0 +1,172 @@ +/* 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/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +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; + XPCOMUtils.defineLazyPreferenceGetter(this, /* unused */ "_isUploadEnabled", + "datareporting.healthreport.uploadEnabled", + false, () => this.updatePrefState()); + }, + + _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.createCodebasePrincipal(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(); }); diff --git a/browser/base/content/abouthealthreport/abouthealth.xhtml b/browser/base/content/abouthealthreport/abouthealth.xhtml new file mode 100644 index 000000000000..ff57bd15d7e0 --- /dev/null +++ b/browser/base/content/abouthealthreport/abouthealth.xhtml @@ -0,0 +1,31 @@ + + + + %htmlDTD; + + %brandDTD; + + %securityPrefsDTD; + + %aboutHealthReportDTD; +]> + + + + &abouthealth.pagetitle; + + + + + + + + diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js index 78f885f7b5e4..2cc27580f2fa 100644 --- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -817,6 +817,14 @@ function openTroubleshootingPage() { openUILinkIn("about:support", "tab"); } +/** + * Opens the troubleshooting information (about:support) page for this version + * of the application. + */ +function openHealthReport() { + openUILinkIn("about:healthreport", "tab"); +} + /** * Opens the feedback page for this version of the application. */ diff --git a/browser/base/jar.mn b/browser/base/jar.mn index 9c8b5f8013b0..77aa3a7ecf25 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -42,6 +42,13 @@ browser.jar: content/browser/illustrations/error-server-not-found.svg (content/illustrations/error-server-not-found.svg) content/browser/illustrations/error-malformed-url.svg (content/illustrations/error-malformed-url.svg) content/browser/aboutNetError.xhtml (content/aboutNetError.xhtml) + +#ifdef MOZ_SERVICES_HEALTHREPORT + content/browser/abouthealthreport/abouthealth.xhtml (content/abouthealthreport/abouthealth.xhtml) + content/browser/abouthealthreport/abouthealth.js (content/abouthealthreport/abouthealth.js) + content/browser/abouthealthreport/abouthealth.css (content/abouthealthreport/abouthealth.css) +#endif + content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png) content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png) content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css) diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp index 581882ac5e9e..80b7c877c9b1 100644 --- a/browser/components/about/AboutRedirector.cpp +++ b/browser/components/about/AboutRedirector.cpp @@ -91,6 +91,10 @@ static const RedirEntry kRedirMap[] = { nsIAboutModule::ALLOW_SCRIPT }, { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", nsIAboutModule::ALLOW_SCRIPT }, +#ifdef MOZ_SERVICES_HEALTHREPORT + { "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml", + nsIAboutModule::ALLOW_SCRIPT }, +#endif { "reader", "chrome://global/content/reader/aboutReader.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp index d4070832fda3..8860b6f2eb87 100644 --- a/browser/components/build/nsModule.cpp +++ b/browser/components/build/nsModule.cpp @@ -105,6 +105,9 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, +#ifdef MOZ_SERVICES_HEALTHREPORT + { NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, +#endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "reader", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, #if defined(XP_WIN) { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID }, diff --git a/browser/locales/en-US/chrome/browser/aboutHealthReport.dtd b/browser/locales/en-US/chrome/browser/aboutHealthReport.dtd new file mode 100644 index 000000000000..0cc20e38efd1 --- /dev/null +++ b/browser/locales/en-US/chrome/browser/aboutHealthReport.dtd @@ -0,0 +1,6 @@ + + + + diff --git a/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd b/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd index e37e97bb3380..de92ad3aab68 100644 --- a/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd +++ b/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd @@ -28,6 +28,9 @@ + + + diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index e0607e9641da..24d99d9b17f5 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -19,6 +19,9 @@ locale/browser/aboutRobots.dtd (%chrome/browser/aboutRobots.dtd) locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd) locale/browser/accounts.properties (%chrome/browser/accounts.properties) +#ifdef MOZ_SERVICES_HEALTHREPORT + locale/browser/aboutHealthReport.dtd (%chrome/browser/aboutHealthReport.dtd) +#endif locale/browser/aboutSearchReset.dtd (%chrome/browser/aboutSearchReset.dtd) locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd) locale/browser/aboutTabCrashed.dtd (%chrome/browser/aboutTabCrashed.dtd) diff --git a/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js index 99b3082f8041..3cbca0bb4cdb 100644 --- a/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js +++ b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js @@ -13,9 +13,9 @@ add_task(async function runTests() { let browser = tab.linkedBrowser; - browser.loadURI("about:about"); + browser.loadURI("about:healthreport"); let href = await BrowserTestUtils.browserLoaded(browser); - is(href, "about:about", "Check about:about loaded"); + is(href, "about:healthreport", "Check about:healthreport loaded"); // Using a dummy onunload listener to disable the bfcache as that can prevent // the test browser load detection mechanism from working. @@ -26,7 +26,7 @@ add_task(async function runTests() { browser.goBack(); href = await BrowserTestUtils.browserLoaded(browser); - is(href, "about:about", "Check we've gone back to about:about"); + is(href, "about:healthreport", "Check we've gone back to about:healthreport"); browser.goForward(); href = await BrowserTestUtils.browserLoaded(browser); diff --git a/mobile/android/app/src/main/res/xml/preferences_privacy.xml b/mobile/android/app/src/main/res/xml/preferences_privacy.xml index 68a2066976c8..04331a707f5b 100644 --- a/mobile/android/app/src/main/res/xml/preferences_privacy.xml +++ b/mobile/android/app/src/main/res/xml/preferences_privacy.xml @@ -96,6 +96,11 @@ android:summary="@string/datareporting_fhr_summary2" android:defaultValue="true" /> + + diff --git a/mobile/android/app/src/test/java/org/mozilla/gecko/icons/preparation/TestAboutPagesPreparer.java b/mobile/android/app/src/test/java/org/mozilla/gecko/icons/preparation/TestAboutPagesPreparer.java index b26004350c98..db73611dd705 100644 --- a/mobile/android/app/src/test/java/org/mozilla/gecko/icons/preparation/TestAboutPagesPreparer.java +++ b/mobile/android/app/src/test/java/org/mozilla/gecko/icons/preparation/TestAboutPagesPreparer.java @@ -19,6 +19,7 @@ public class TestAboutPagesPreparer { AboutPages.CONFIG, AboutPages.DOWNLOADS, AboutPages.FIREFOX, + AboutPages.HEALTHREPORT, AboutPages.HOME }; diff --git a/mobile/android/base/java/org/mozilla/gecko/AboutPages.java b/mobile/android/base/java/org/mozilla/gecko/AboutPages.java index 4db20df18374..38017f239267 100644 --- a/mobile/android/base/java/org/mozilla/gecko/AboutPages.java +++ b/mobile/android/base/java/org/mozilla/gecko/AboutPages.java @@ -21,6 +21,7 @@ public class AboutPages { public static final String CONFIG = "about:config"; public static final String DOWNLOADS = "about:downloads"; public static final String FIREFOX = "about:firefox"; + public static final String HEALTHREPORT = "about:healthreport"; public static final String HOME = "about:home"; public static final String LOGINS = "about:logins"; public static final String PRIVATEBROWSING = "about:privatebrowsing"; @@ -80,7 +81,8 @@ public class AboutPages { ADDONS, CONFIG, DOWNLOADS, - FIREFOX + FIREFOX, + HEALTHREPORT )); public static boolean isBuiltinIconPage(final String url) { diff --git a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java index 3675afa9c052..e79cd90d3e33 100644 --- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java +++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java @@ -129,6 +129,7 @@ public class GeckoPreferences private static final String PREFS_UPDATER_URL = "app.update.url.android"; private static final String PREFS_GEO_REPORTING = NON_PREF_PREFIX + "app.geo.reportdata"; private static final String PREFS_GEO_LEARN_MORE = NON_PREF_PREFIX + "geo.learn_more"; + private static final String PREFS_HEALTHREPORT_LINK = NON_PREF_PREFIX + "healthreport.link"; public static final String PREFS_DEVTOOLS_REMOTE_USB_ENABLED = "devtools.remote.usb.enabled"; public static final String PREFS_DEVTOOLS_REMOTE_WIFI_ENABLED = "devtools.remote.wifi.enabled"; private static final String PREFS_DEVTOOLS_REMOTE_LINK = NON_PREF_PREFIX + "remote_debugging.link"; @@ -674,7 +675,8 @@ public class GeckoPreferences i--; continue; } - } else if (PREFS_HEALTHREPORT_UPLOAD_ENABLED.equals(key)) { + } else if (PREFS_HEALTHREPORT_UPLOAD_ENABLED.equals(key) || + PREFS_HEALTHREPORT_LINK.equals(key)) { if (!AppConstants.MOZ_SERVICES_HEALTHREPORT || !Restrictions.isAllowed(this, Restrictable.DATA_CHOICES)) { preferences.removePreference(pref); i--; diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd index 393bca743039..b8582b5b3dae 100644 --- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -422,6 +422,7 @@ crashReporterDesc.label). --> + @@ -869,4 +870,4 @@ displayed when there are more than 3 actions available for a page. See also https://bug1409261.bmoattachments.org/attachment.cgi?id=8919897 --> - + \ No newline at end of file diff --git a/mobile/android/base/strings.xml.in b/mobile/android/base/strings.xml.in index d7db3e25ddf5..11ccf7cb8774 100644 --- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -337,6 +337,7 @@ &datareporting_telemetry_summary; &datareporting_fhr_title; &datareporting_fhr_summary2; + &datareporting_abouthr_title; &datareporting_crashreporter_title_short; &datareporting_crashreporter_summary; &datareporting_wifi_title2; diff --git a/mobile/android/chrome/content/aboutHealthReport.js b/mobile/android/chrome/content/aboutHealthReport.js new file mode 100644 index 000000000000..7c2d70b707c0 --- /dev/null +++ b/mobile/android/chrome/content/aboutHealthReport.js @@ -0,0 +1,194 @@ +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- +/* 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/Services.jsm"); +Cu.import("resource://gre/modules/SharedPreferences.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher", + "resource://gre/modules/Messaging.jsm"); + +// Name of Android SharedPreference controlling whether to upload +// health reports. +const PREF_UPLOAD_ENABLED = "android.not_a_preference.healthreport.uploadEnabled"; + +// Name of Gecko Pref specifying report content location. +const PREF_REPORTURL = "datareporting.healthreport.about.reportUrl"; + +// Monotonically increasing wrapper API version number. +const WRAPPER_VERSION = 1; + +const EVENT_HEALTH_REQUEST = "HealthReport:Request"; +const EVENT_HEALTH_RESPONSE = "HealthReport:Response"; + +// about:healthreport prefs are stored in Firefox's default Android +// SharedPreferences. +var sharedPrefs = SharedPreferences.forApp(); + +var healthReportWrapper = { + init: function() { + let iframe = document.getElementById("remote-report"); + iframe.addEventListener("load", healthReportWrapper.initRemotePage); + let report = this._getReportURI(); + iframe.src = report.spec; + console.log("AboutHealthReport: loading content from " + report.spec); + + sharedPrefs.addObserver(PREF_UPLOAD_ENABLED, this); + Services.obs.addObserver(this, EVENT_HEALTH_RESPONSE); + }, + + observe: function(subject, topic, data) { + if (topic == PREF_UPLOAD_ENABLED) { + this.updatePrefState(); + } else if (topic == EVENT_HEALTH_RESPONSE) { + this.updatePayload(data); + } + }, + + uninit: function() { + sharedPrefs.removeObserver(PREF_UPLOAD_ENABLED, this); + Services.obs.removeObserver(this, EVENT_HEALTH_RESPONSE); + }, + + _getReportURI: function() { + let url = Services.urlFormatter.formatURLPref(PREF_REPORTURL); + // This handles URLs that already have query parameters. + let uri = Services.io.newURI(url).QueryInterface(Ci.nsIURL); + uri.query += ((uri.query != "") ? "&v=" : "v=") + WRAPPER_VERSION; + return uri; + }, + + onOptIn: function() { + console.log("AboutHealthReport: page sent opt-in command."); + sharedPrefs.setBoolPref(PREF_UPLOAD_ENABLED, true); + this.updatePrefState(); + }, + + onOptOut: function() { + console.log("AboutHealthReport: page sent opt-out command."); + sharedPrefs.setBoolPref(PREF_UPLOAD_ENABLED, false); + this.updatePrefState(); + }, + + updatePrefState: function() { + console.log("AboutHealthReport: sending pref state to page."); + try { + let prefs = { + enabled: sharedPrefs.getBoolPref(PREF_UPLOAD_ENABLED), + }; + this.injectData("prefs", prefs); + } catch (e) { + this.reportFailure(this.ERROR_PREFS_FAILED); + } + }, + + refreshPayload: function() { + console.log("AboutHealthReport: page requested fresh payload."); + EventDispatcher.instance.sendRequest({ + type: EVENT_HEALTH_REQUEST, + }); + }, + + updatePayload: function(data) { + healthReportWrapper.injectData("payload", data); + // Data is supposed to be a string, so the length should be + // defined. Just in case, we do this after injecting the data. + console.log("AboutHealthReport: sending payload to page " + + "(" + typeof(data) + " of length " + data.length + ")."); + }, + + injectData: function(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: type, + content: content, + }; + + let iframe = document.getElementById("remote-report"); + iframe.contentWindow.postMessage(data, reportUrl); + }, + + showSettings: function() { + console.log("AboutHealthReport: showing settings."); + EventDispatcher.instance.sendRequest({ + type: "Settings:Show", + resource: "preferences_privacy", + }); + }, + + launchUpdater: function() { + console.log("AboutHealthReport: launching updater."); + EventDispatcher.instance.sendRequest({ + type: "Updater:Launch", + }); + }, + + handleRemoteCommand: function(evt) { + switch (evt.detail.command) { + case "DisableDataSubmission": + this.onOptOut(); + break; + case "EnableDataSubmission": + this.onOptIn(); + break; + case "RequestCurrentPrefs": + this.updatePrefState(); + break; + case "RequestCurrentPayload": + this.refreshPayload(); + break; + case "ShowSettings": + this.showSettings(); + break; + case "LaunchUpdater": + this.launchUpdater(); + break; + default: + Cu.reportError("Unexpected remote command received: " + evt.detail.command + + ". Ignoring command."); + break; + } + }, + + initRemotePage: function() { + let iframe = document.getElementById("remote-report").contentDocument; + iframe.addEventListener("RemoteHealthReportCommand", + function onCommand(e) { healthReportWrapper.handleRemoteCommand(e); }); + healthReportWrapper.injectData("begin", null); + }, + + // error handling + ERROR_INIT_FAILED: 1, + ERROR_PAYLOAD_FAILED: 2, + ERROR_PREFS_FAILED: 3, + + reportFailure: function(error) { + let details = { + errorType: error, + }; + healthReportWrapper.injectData("error", details); + }, + + handleInitFailure: function() { + healthReportWrapper.reportFailure(healthReportWrapper.ERROR_INIT_FAILED); + }, + + handlePayloadFailure: function() { + healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED); + }, +}; + +window.addEventListener("load", healthReportWrapper.init.bind(healthReportWrapper)); +window.addEventListener("unload", healthReportWrapper.uninit.bind(healthReportWrapper)); diff --git a/mobile/android/chrome/content/aboutHealthReport.xhtml b/mobile/android/chrome/content/aboutHealthReport.xhtml new file mode 100644 index 000000000000..4135340e36ce --- /dev/null +++ b/mobile/android/chrome/content/aboutHealthReport.xhtml @@ -0,0 +1,32 @@ + + + +%brandDTD; + +%globalDTD; + +%aboutHealthReportDTD; +]> + + + + + + + &abouthealth.pagetitle; + + +