Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 #filter substitution
2 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 "use strict";
9 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
11 Cu.import("resource://gre/modules/Services.jsm");
12 Cu.import("resource://gre/modules/Messaging.jsm");
13 Cu.import("resource://gre/modules/SharedPreferences.jsm");
15 // Name of Android SharedPreference controlling whether to upload
16 // health reports.
17 const PREF_UPLOAD_ENABLED = "android.not_a_preference.healthreport.uploadEnabled";
19 // Name of Gecko Pref specifying report content location.
20 const PREF_REPORTURL = "datareporting.healthreport.about.reportUrl";
22 // Monotonically increasing wrapper API version number.
23 const WRAPPER_VERSION = 1;
25 const EVENT_HEALTH_REQUEST = "HealthReport:Request";
26 const EVENT_HEALTH_RESPONSE = "HealthReport:Response";
28 // about:healthreport prefs are stored in Firefox's default Android
29 // SharedPreferences.
30 let sharedPrefs = new SharedPreferences();
32 let healthReportWrapper = {
33 init: function () {
34 let iframe = document.getElementById("remote-report");
35 iframe.addEventListener("load", healthReportWrapper.initRemotePage, false);
36 let report = this._getReportURI();
37 iframe.src = report.spec;
38 console.log("AboutHealthReport: loading content from " + report.spec);
40 sharedPrefs.addObserver(PREF_UPLOAD_ENABLED, this, false);
41 Services.obs.addObserver(this, EVENT_HEALTH_RESPONSE, false);
42 },
44 observe: function (subject, topic, data) {
45 if (topic == PREF_UPLOAD_ENABLED) {
46 this.updatePrefState();
47 } else if (topic == EVENT_HEALTH_RESPONSE) {
48 this.updatePayload(data);
49 }
50 },
52 uninit: function () {
53 sharedPrefs.removeObserver(PREF_UPLOAD_ENABLED, this);
54 Services.obs.removeObserver(this, EVENT_HEALTH_RESPONSE);
55 },
57 _getReportURI: function () {
58 let url = Services.urlFormatter.formatURLPref(PREF_REPORTURL);
59 // This handles URLs that already have query parameters.
60 let uri = Services.io.newURI(url, null, null).QueryInterface(Ci.nsIURL);
61 uri.query += ((uri.query != "") ? "&v=" : "v=") + WRAPPER_VERSION;
62 return uri;
63 },
65 onOptIn: function () {
66 console.log("AboutHealthReport: page sent opt-in command.");
67 sharedPrefs.setBoolPref(PREF_UPLOAD_ENABLED, true);
68 this.updatePrefState();
69 },
71 onOptOut: function () {
72 console.log("AboutHealthReport: page sent opt-out command.");
73 sharedPrefs.setBoolPref(PREF_UPLOAD_ENABLED, false);
74 this.updatePrefState();
75 },
77 updatePrefState: function () {
78 console.log("AboutHealthReport: sending pref state to page.");
79 try {
80 let prefs = {
81 enabled: sharedPrefs.getBoolPref(PREF_UPLOAD_ENABLED),
82 };
83 this.injectData("prefs", prefs);
84 } catch (e) {
85 this.reportFailure(this.ERROR_PREFS_FAILED);
86 }
87 },
89 refreshPayload: function () {
90 console.log("AboutHealthReport: page requested fresh payload.");
91 sendMessageToJava({
92 type: EVENT_HEALTH_REQUEST,
93 });
94 },
96 updatePayload: function (data) {
97 healthReportWrapper.injectData("payload", data);
98 // Data is supposed to be a string, so the length should be
99 // defined. Just in case, we do this after injecting the data.
100 console.log("AboutHealthReport: sending payload to page " +
101 "(" + typeof(data) + " of length " + data.length + ").");
102 },
104 injectData: function (type, content) {
105 let report = this._getReportURI();
107 // file: URIs can't be used for targetOrigin, so we use "*" for
108 // this special case. In all other cases, pass in the URL to the
109 // report so we properly restrict the message dispatch.
110 let reportUrl = (report.scheme == "file") ? "*" : report.spec;
112 let data = {
113 type: type,
114 content: content,
115 };
117 let iframe = document.getElementById("remote-report");
118 iframe.contentWindow.postMessage(data, reportUrl);
119 },
121 showSettings: function () {
122 console.log("AboutHealthReport: showing settings.");
123 sendMessageToJava({
124 type: "Settings:Show",
125 resource: "preferences_vendor",
126 });
127 },
129 launchUpdater: function () {
130 console.log("AboutHealthReport: launching updater.");
131 sendMessageToJava({
132 type: "Updater:Launch",
133 });
134 },
136 handleRemoteCommand: function (evt) {
137 switch (evt.detail.command) {
138 case "DisableDataSubmission":
139 this.onOptOut();
140 break;
141 case "EnableDataSubmission":
142 this.onOptIn();
143 break;
144 case "RequestCurrentPrefs":
145 this.updatePrefState();
146 break;
147 case "RequestCurrentPayload":
148 this.refreshPayload();
149 break;
150 case "ShowSettings":
151 this.showSettings();
152 break;
153 case "LaunchUpdater":
154 this.launchUpdater();
155 break;
156 default:
157 Cu.reportError("Unexpected remote command received: " + evt.detail.command +
158 ". Ignoring command.");
159 break;
160 }
161 },
163 initRemotePage: function () {
164 let iframe = document.getElementById("remote-report").contentDocument;
165 iframe.addEventListener("RemoteHealthReportCommand",
166 function onCommand(e) {healthReportWrapper.handleRemoteCommand(e);},
167 false);
168 healthReportWrapper.injectData("begin", null);
169 },
171 // error handling
172 ERROR_INIT_FAILED: 1,
173 ERROR_PAYLOAD_FAILED: 2,
174 ERROR_PREFS_FAILED: 3,
176 reportFailure: function (error) {
177 let details = {
178 errorType: error,
179 };
180 healthReportWrapper.injectData("error", details);
181 },
183 handleInitFailure: function () {
184 healthReportWrapper.reportFailure(healthReportWrapper.ERROR_INIT_FAILED);
185 },
187 handlePayloadFailure: function () {
188 healthReportWrapper.reportFailure(healthReportWrapper.ERROR_PAYLOAD_FAILED);
189 },
190 };
192 window.addEventListener("load", healthReportWrapper.init.bind(healthReportWrapper), false);
193 window.addEventListener("unload", healthReportWrapper.uninit.bind(healthReportWrapper), false);