mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 828829 - Refactor Health Report policy out of services/healthreport; r=rnewman
--HG-- rename : services/healthreport/HealthReportService.js => services/datareporting/DataReportingService.js rename : services/healthreport/modules-testing/mocks.jsm => services/datareporting/modules-testing/mocks.jsm rename : services/healthreport/policy.jsm => services/datareporting/policy.jsm rename : services/healthreport/tests/xpcshell/test_policy.js => services/datareporting/tests/xpcshell/test_policy.js extra : rebase_source : cf766bc99ff843f2d31f82b1c4be71313fbc65a8
This commit is contained in:
parent
cc3187175f
commit
a6c8da1aba
@ -469,9 +469,9 @@
|
||||
@BINPATH@/components/AitcComponents.manifest
|
||||
@BINPATH@/components/Aitc.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/components/HealthReportComponents.manifest
|
||||
@BINPATH@/components/HealthReportService.js
|
||||
#ifdef MOZ_DATA_REPORTING
|
||||
@BINPATH@/components/DataReporting.manifest
|
||||
@BINPATH@/components/DataReportingService.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
@BINPATH@/components/SyncComponents.manifest
|
||||
|
@ -899,6 +899,7 @@ xpicleanup@BIN_SUFFIX@
|
||||
components/GPSDGeolocationProvider.js
|
||||
components/interfaces.manifest
|
||||
components/jsconsole-clhandler.js
|
||||
components/MetricsCollectionService.js
|
||||
components/NetworkGeolocationProvider.js
|
||||
components/NotificationsComponents.manifest
|
||||
components/nsBadCertHandler.js
|
||||
|
@ -8719,6 +8719,15 @@ if test "$MOZ_TELEMETRY_REPORTING"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl If we have any service that uploads data (and requires data submission
|
||||
dnl policy alert), set MOZ_DATA_REPORTING.
|
||||
dnl We need SUBST for build system and DEFINE for xul preprocessor.
|
||||
if test -n "$MOZ_TELEMETRY_REPORTING" || test -n "$MOZ_SERVICES_HEALTHREPORT" || test -n "MOZ_CRASHREPORTER"; then
|
||||
MOZ_DATA_REPORTING=1
|
||||
AC_DEFINE(MOZ_DATA_REPORTING)
|
||||
AC_SUBST(MOZ_DATA_REPORTING)
|
||||
fi
|
||||
|
||||
dnl win32 options
|
||||
AC_SUBST(MOZ_MAPINFO)
|
||||
AC_SUBST(MOZ_BROWSE_INFO)
|
||||
|
@ -43,6 +43,10 @@ GARBAGE += greprefs.js
|
||||
# TODO bug 813259 external files should be defined near their location in the source tree.
|
||||
grepref_files = $(topsrcdir)/netwerk/base/public/security-prefs.js $(srcdir)/init/all.js
|
||||
|
||||
ifdef MOZ_DATA_REPORTING
|
||||
grepref_files += $(topsrcdir)/services/datareporting/datareporting-prefs.js
|
||||
endif
|
||||
|
||||
ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
grepref_files += $(topsrcdir)/services/healthreport/healthreport-prefs.js
|
||||
endif
|
||||
|
@ -9,9 +9,10 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
PARALLEL_DIRS += common
|
||||
|
||||
PARALLEL_DIRS += crypto
|
||||
PARALLEL_DIRS += \
|
||||
common \
|
||||
crypto \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_SERVICES_AITC
|
||||
PARALLEL_DIRS += aitc
|
||||
@ -21,6 +22,10 @@ ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
PARALLEL_DIRS += healthreport
|
||||
endif
|
||||
|
||||
ifdef MOZ_DATA_REPORTING
|
||||
PARALLEL_DIRS += datareporting
|
||||
endif
|
||||
|
||||
ifdef MOZ_SERVICES_METRICS
|
||||
PARALLEL_DIRS += metrics
|
||||
endif
|
||||
|
16
services/datareporting/DataReporting.manifest
Normal file
16
services/datareporting/DataReporting.manifest
Normal file
@ -0,0 +1,16 @@
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
# suite (comm): {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}
|
||||
# metro browser: {99bceaaa-e3c6-48c1-b981-ef9b46b67d60}
|
||||
|
||||
# The Data Reporting Service drives collection and submission of metrics
|
||||
# and other useful data to Mozilla. It drives the display of the data
|
||||
# submission notification info bar and thus is required by Firefox Health
|
||||
# Report and Telemetry.
|
||||
|
||||
component {41f6ae36-a79f-4613-9ac3-915e70f83789} DataReportingService.js
|
||||
contract @mozilla.org/datareporting/service;1 {41f6ae36-a79f-4613-9ac3-915e70f83789}
|
||||
category app-startup DataReportingService service,@mozilla.org/datareporting/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
|
@ -6,11 +6,16 @@
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://services-common/observers.js");
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
|
||||
|
||||
const BRANCH = "healthreport.";
|
||||
const ROOT_BRANCH = "datareporting.";
|
||||
const POLICY_BRANCH = ROOT_BRANCH + "policy.";
|
||||
const HEALTHREPORT_BRANCH = ROOT_BRANCH + "healthreport.";
|
||||
const HEALTHREPORT_LOGGING_BRANCH = HEALTHREPORT_BRANCH + "logging.";
|
||||
const DEFAULT_LOAD_DELAY_MSEC = 10 * 1000;
|
||||
|
||||
/**
|
||||
@ -27,7 +32,7 @@ const DEFAULT_LOAD_DELAY_MSEC = 10 * 1000;
|
||||
* let reporter = Cc["@mozilla.org/healthreport/service;1"]
|
||||
* .getService(Ci.nsISupports)
|
||||
* .wrappedJSObject
|
||||
* .reporter;
|
||||
* .healthReporter;
|
||||
*
|
||||
* if (reporter.haveRemoteData) {
|
||||
* // ...
|
||||
@ -45,36 +50,77 @@ const DEFAULT_LOAD_DELAY_MSEC = 10 * 1000;
|
||||
* instance (it registers observers on initialization). See the notes on that
|
||||
* type for more.
|
||||
*/
|
||||
this.HealthReportService = function HealthReportService() {
|
||||
this.DataReportingService = function () {
|
||||
this.wrappedJSObject = this;
|
||||
|
||||
this._prefs = new Preferences(BRANCH);
|
||||
|
||||
this._reporter = null;
|
||||
this._os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
}
|
||||
|
||||
HealthReportService.prototype = {
|
||||
classID: Components.ID("{e354c59b-b252-4040-b6dd-b71864e3e35c}"),
|
||||
DataReportingService.prototype = Object.freeze({
|
||||
classID: Components.ID("{41f6ae36-a79f-4613-9ac3-915e70f83789}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
// If the background service is disabled, don't do anything.
|
||||
if (!this._prefs.get("service.enabled", true)) {
|
||||
//---------------------------------------------
|
||||
// Start of policy listeners.
|
||||
//---------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when policy requests data upload.
|
||||
*/
|
||||
onRequestDataUpload: function (request) {
|
||||
if (!this.healthReporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
let os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
this.healthReporter.requestDataUpload(request);
|
||||
},
|
||||
|
||||
onNotifyDataPolicy: function (request) {
|
||||
Observers.notify("datareporting:notify-data-policy:request", request);
|
||||
},
|
||||
|
||||
onRequestRemoteDelete: function (request) {
|
||||
if (!this.healthReporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.healthReporter.deleteRemoteData(request);
|
||||
},
|
||||
|
||||
//---------------------------------------------
|
||||
// End of policy listeners.
|
||||
//---------------------------------------------
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "app-startup":
|
||||
os.addObserver(this, "sessionstore-windows-restored", true);
|
||||
this._os.addObserver(this, "profile-after-change", true);
|
||||
break;
|
||||
|
||||
case "profile-after-change":
|
||||
this._os.removeObserver(this, "profile-after-change");
|
||||
this._os.addObserver(this, "sessionstore-windows-restored", true);
|
||||
|
||||
// We can't interact with prefs until after the profile is present.
|
||||
let policyPrefs = new Preferences(POLICY_BRANCH);
|
||||
this._prefs = new Preferences(HEALTHREPORT_BRANCH);
|
||||
this.policy = new DataReportingPolicy(policyPrefs, this._prefs, this);
|
||||
break;
|
||||
|
||||
case "sessionstore-windows-restored":
|
||||
os.removeObserver(this, "sessionstore-windows-restored");
|
||||
this._os.removeObserver(this, "sessionstore-windows-restored");
|
||||
this._os.addObserver(this, "quit-application", false);
|
||||
|
||||
this.policy.startPolling();
|
||||
|
||||
// Don't initialize Firefox Health Reporter collection and submission
|
||||
// service unless it is enabled.
|
||||
if (!this._prefs.get("service.enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let delayInterval = this._prefs.get("service.loadDelayMsec") ||
|
||||
DEFAULT_LOAD_DELAY_MSEC;
|
||||
@ -86,12 +132,17 @@ HealthReportService.prototype = {
|
||||
notify: function notify() {
|
||||
// Side effect: instantiates the reporter instance if not already
|
||||
// accessed.
|
||||
let reporter = this.reporter;
|
||||
let reporter = this.healthReporter;
|
||||
delete this.timer;
|
||||
}.bind(this),
|
||||
}, delayInterval, this.timer.TYPE_ONE_SHOT);
|
||||
|
||||
break;
|
||||
|
||||
case "quit-application":
|
||||
this._os.removeObserver(this, "quit-application");
|
||||
this.policy.stopPolling();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -102,17 +153,29 @@ HealthReportService.prototype = {
|
||||
*
|
||||
* The obtained instance may not be fully initialized.
|
||||
*/
|
||||
get reporter() {
|
||||
get healthReporter() {
|
||||
if (!this._prefs.get("service.enabled", true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._reporter) {
|
||||
return this._reporter;
|
||||
if ("_healthReporter" in this) {
|
||||
return this._healthReporter;
|
||||
}
|
||||
|
||||
try {
|
||||
this._loadHealthReporter();
|
||||
} catch (ex) {
|
||||
dump("Error loading health reporter: " + ex);
|
||||
this._healthReporter = null;
|
||||
}
|
||||
|
||||
return this._healthReporter;
|
||||
},
|
||||
|
||||
_loadHealthReporter: function () {
|
||||
let ns = {};
|
||||
// Lazy import so application startup isn't adversely affected.
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm", ns);
|
||||
Cu.import("resource://gre/modules/services/healthreport/healthreporter.jsm", ns);
|
||||
Cu.import("resource://services-common/log4moz.js", ns);
|
||||
@ -120,15 +183,16 @@ HealthReportService.prototype = {
|
||||
// How many times will we rewrite this code before rolling it up into a
|
||||
// generic module? See also bug 451283.
|
||||
const LOGGERS = [
|
||||
"Services.DataReporting",
|
||||
"Services.HealthReport",
|
||||
"Services.Metrics",
|
||||
"Services.BagheeraClient",
|
||||
"Sqlite.Connection.healthreport",
|
||||
];
|
||||
|
||||
let prefs = new Preferences(BRANCH + "logging.");
|
||||
if (prefs.get("consoleEnabled", true)) {
|
||||
let level = prefs.get("consoleLevel", "Warn");
|
||||
let loggingPrefs = new Preferences(HEALTHREPORT_LOGGING_BRANCH);
|
||||
if (loggingPrefs.get("consoleEnabled", true)) {
|
||||
let level = loggingPrefs.get("consoleLevel", "Warn");
|
||||
let appender = new ns.Log4Moz.ConsoleAppender();
|
||||
appender.level = ns.Log4Moz.Level[level] || ns.Log4Moz.Level.Warn;
|
||||
|
||||
@ -139,13 +203,10 @@ HealthReportService.prototype = {
|
||||
}
|
||||
|
||||
// The reporter initializes in the background.
|
||||
this._reporter = new ns.HealthReporter(BRANCH);
|
||||
|
||||
return this._reporter;
|
||||
this._healthReporter = new ns.HealthReporter(HEALTHREPORT_BRANCH,
|
||||
this.policy);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
Object.freeze(HealthReportService.prototype);
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HealthReportService]);
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataReportingService]);
|
||||
|
26
services/datareporting/Makefile.in
Normal file
26
services/datareporting/Makefile.in
Normal file
@ -0,0 +1,26 @@
|
||||
# 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/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
TEST_DIRS += tests
|
||||
|
||||
MODULES_FILES := policy.jsm
|
||||
MODULES_DEST = $(FINAL_TARGET)/modules/services/datareporting
|
||||
INSTALL_TARGETS += MODULES
|
||||
|
||||
TESTING_JS_MODULES := $(addprefix modules-testing/,mocks.jsm)
|
||||
TESTING_JS_MODULE_DIR := services/datareporting
|
||||
|
||||
EXTRA_COMPONENTS := \
|
||||
DataReporting.manifest \
|
||||
DataReportingService.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
12
services/datareporting/datareporting-prefs.js
Normal file
12
services/datareporting/datareporting-prefs.js
Normal file
@ -0,0 +1,12 @@
|
||||
/* 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/. */
|
||||
|
||||
pref("datareporting.policy.dataSubmissionEnabled", true);
|
||||
pref("datareporting.policy.dataSubmissionPolicyAccepted", false);
|
||||
pref("datareporting.policy.dataSubmissionPolicyBypassAcceptance", false);
|
||||
pref("datareporting.policy.dataSubmissionPolicyNotifiedTime", "0");
|
||||
pref("datareporting.policy.dataSubmissionPolicyResponseType", "");
|
||||
pref("datareporting.policy.dataSubmissionPolicyResponseTime", "0");
|
||||
pref("datareporting.policy.firstRunTime", "0");
|
||||
|
@ -12,7 +12,7 @@ Cu.import("resource://services-common/log4moz.js");
|
||||
|
||||
|
||||
this.MockPolicyListener = function MockPolicyListener() {
|
||||
this._log = Log4Moz.repository.getLogger("HealthReport.Testing.MockPolicyListener");
|
||||
this._log = Log4Moz.repository.getLogger("Services.DataReporting.Testing.MockPolicyListener");
|
||||
this._log.level = Log4Moz.Level["Debug"];
|
||||
|
||||
this.requestDataUploadCount = 0;
|
||||
@ -44,3 +44,4 @@ MockPolicyListener.prototype = {
|
||||
this.lastNotifyRequest = request;
|
||||
},
|
||||
};
|
||||
|
@ -2,11 +2,22 @@
|
||||
* 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/. */
|
||||
|
||||
/**
|
||||
* This file is in transition. It was originally conceived to fulfill the
|
||||
* needs of only Firefox Health Report. It is slowly being morphed into
|
||||
* fulfilling the needs of all data reporting facilities in Gecko applications.
|
||||
* As a result, some things feel a bit weird.
|
||||
*
|
||||
* DataReportingPolicy is both a driver for data reporting notification
|
||||
* (a true policy) and the driver for FHR data submission. The latter should
|
||||
* eventually be split into its own type and module.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"DataSubmissionRequest", // For test use only.
|
||||
"HealthReportPolicy",
|
||||
"DataReportingPolicy",
|
||||
];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
@ -41,7 +52,7 @@ const OLDEST_ALLOWED_YEAR = 2012;
|
||||
* signaling explicit user acceptance or rejection of the policy. They do this
|
||||
* by calling `onUserAccept` or `onUserReject`, respectively. These functions
|
||||
* are essentially proxies to
|
||||
* HealthReportPolicy.{recordUserAcceptance,recordUserRejection}.
|
||||
* DataReportingPolicy.{recordUserAcceptance,recordUserRejection}.
|
||||
*
|
||||
* If the user never explicitly accepts or rejects the policy, it will be
|
||||
* implicitly accepted after a specified duration of time. The notice is
|
||||
@ -53,7 +64,7 @@ const OLDEST_ALLOWED_YEAR = 2012;
|
||||
* the exception of the on* functions.
|
||||
*
|
||||
* @param policy
|
||||
* (HealthReportPolicy) The policy instance this request came from.
|
||||
* (DataReportingPolicy) The policy instance this request came from.
|
||||
* @param promise
|
||||
* (deferred) The promise that will be fulfilled when display occurs.
|
||||
*/
|
||||
@ -235,15 +246,17 @@ Object.freeze(DataSubmissionRequest.prototype);
|
||||
* can have different mechanisms by which they notify the user of data
|
||||
* submission practices.
|
||||
*
|
||||
* @param prefs
|
||||
* @param policyPrefs
|
||||
* (Preferences) Handle on preferences branch on which state will be
|
||||
* queried and stored.
|
||||
* @param healthReportPrefs
|
||||
* (Preferences) Handle on preferences branch hold Health Report state.
|
||||
* @param listener
|
||||
* (object) Object with callbacks that will be invoked at certain key
|
||||
* events.
|
||||
*/
|
||||
this.HealthReportPolicy = function HealthReportPolicy(prefs, listener) {
|
||||
this._log = Log4Moz.repository.getLogger("Services.HealthReport.Policy");
|
||||
this.DataReportingPolicy = function (prefs, healthReportPrefs, listener) {
|
||||
this._log = Log4Moz.repository.getLogger("Services.DataReporting.Policy");
|
||||
this._log.level = Log4Moz.Level["Debug"];
|
||||
|
||||
for (let handler of this.REQUIRED_LISTENERS) {
|
||||
@ -254,6 +267,7 @@ this.HealthReportPolicy = function HealthReportPolicy(prefs, listener) {
|
||||
}
|
||||
|
||||
this._prefs = prefs;
|
||||
this._healthReportPrefs = healthReportPrefs;
|
||||
this._listener = listener;
|
||||
|
||||
// If we've never run before, record the current time.
|
||||
@ -276,7 +290,7 @@ this.HealthReportPolicy = function HealthReportPolicy(prefs, listener) {
|
||||
this._inProgressSubmissionRequest = null;
|
||||
}
|
||||
|
||||
HealthReportPolicy.prototype = {
|
||||
DataReportingPolicy.prototype = Object.freeze({
|
||||
/**
|
||||
* How long after first run we should notify about data submission.
|
||||
*/
|
||||
@ -444,22 +458,6 @@ HealthReportPolicy.prototype = {
|
||||
this._prefs.set("dataSubmissionEnabled", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether upload of data is allowed.
|
||||
*
|
||||
* This is a kill switch for upload. It is meant to reflect a system or
|
||||
* deployment policy decision. User intent should be reflected in the
|
||||
* "dataSubmissionPolicy" prefs.
|
||||
*/
|
||||
get dataUploadEnabled() {
|
||||
// Default is true because we are opt-out.
|
||||
return this._prefs.get("dataUploadEnabled", true);
|
||||
},
|
||||
|
||||
set dataUploadEnabled(value) {
|
||||
this._prefs.set("dataUploadEnabled", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether the user has accepted that data submission can occur.
|
||||
*
|
||||
@ -474,13 +472,17 @@ HealthReportPolicy.prototype = {
|
||||
this._prefs.set("dataSubmissionPolicyAccepted", !!value);
|
||||
},
|
||||
|
||||
set dataSubmissionPolicyAcceptedVersion(value) {
|
||||
this._prefs.set("dataSubmissionPolicyAcceptedVersion", value);
|
||||
},
|
||||
|
||||
/**
|
||||
* The state of user notification of the data policy.
|
||||
*
|
||||
* This must be HealthReportPolicy.STATE_NOTIFY_COMPLETE before data
|
||||
* This must be DataReportingPolicy.STATE_NOTIFY_COMPLETE before data
|
||||
* submission can occur.
|
||||
*
|
||||
* @return HealthReportPolicy.STATE_NOTIFY_* constant.
|
||||
* @return DataReportingPolicy.STATE_NOTIFY_* constant.
|
||||
*/
|
||||
get notifyState() {
|
||||
if (this.dataSubmissionPolicyResponseDate.getTime()) {
|
||||
@ -505,13 +507,14 @@ HealthReportPolicy.prototype = {
|
||||
* on scheduling or run-time behavior.
|
||||
*/
|
||||
get lastDataSubmissionRequestedDate() {
|
||||
return CommonUtils.getDatePref(this._prefs,
|
||||
return CommonUtils.getDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionRequestedTime", 0,
|
||||
this._log, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
set lastDataSubmissionRequestedDate(value) {
|
||||
CommonUtils.setDatePref(this._prefs, "lastDataSubmissionRequestedTime",
|
||||
CommonUtils.setDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionRequestedTime",
|
||||
value, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
@ -522,13 +525,14 @@ HealthReportPolicy.prototype = {
|
||||
* actual scheduling.
|
||||
*/
|
||||
get lastDataSubmissionSuccessfulDate() {
|
||||
return CommonUtils.getDatePref(this._prefs,
|
||||
return CommonUtils.getDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionSuccessfulTime", 0,
|
||||
this._log, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
set lastDataSubmissionSuccessfulDate(value) {
|
||||
CommonUtils.setDatePref(this._prefs, "lastDataSubmissionSuccessfulTime",
|
||||
CommonUtils.setDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionSuccessfulTime",
|
||||
value, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
@ -539,13 +543,15 @@ HealthReportPolicy.prototype = {
|
||||
* scheduling.
|
||||
*/
|
||||
get lastDataSubmissionFailureDate() {
|
||||
return CommonUtils.getDatePref(this._prefs, "lastDataSubmissionFailureTime",
|
||||
return CommonUtils.getDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionFailureTime",
|
||||
0, this._log, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
set lastDataSubmissionFailureDate(value) {
|
||||
CommonUtils.setDatePref(this._prefs, "lastDataSubmissionFailureTime", value,
|
||||
OLDEST_ALLOWED_YEAR);
|
||||
CommonUtils.setDatePref(this._healthReportPrefs,
|
||||
"lastDataSubmissionFailureTime",
|
||||
value, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -555,12 +561,14 @@ HealthReportPolicy.prototype = {
|
||||
* mutate this value.
|
||||
*/
|
||||
get nextDataSubmissionDate() {
|
||||
return CommonUtils.getDatePref(this._prefs, "nextDataSubmissionTime", 0,
|
||||
return CommonUtils.getDatePref(this._healthReportPrefs,
|
||||
"nextDataSubmissionTime", 0,
|
||||
this._log, OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
set nextDataSubmissionDate(value) {
|
||||
CommonUtils.setDatePref(this._prefs, "nextDataSubmissionTime", value,
|
||||
CommonUtils.setDatePref(this._healthReportPrefs,
|
||||
"nextDataSubmissionTime", value,
|
||||
OLDEST_ALLOWED_YEAR);
|
||||
},
|
||||
|
||||
@ -570,7 +578,7 @@ HealthReportPolicy.prototype = {
|
||||
* This is used to drive backoff and scheduling.
|
||||
*/
|
||||
get currentDaySubmissionFailureCount() {
|
||||
let v = this._prefs.get("currentDaySubmissionFailureCount", 0);
|
||||
let v = this._healthReportPrefs.get("currentDaySubmissionFailureCount", 0);
|
||||
|
||||
if (!Number.isInteger(v)) {
|
||||
v = 0;
|
||||
@ -584,7 +592,7 @@ HealthReportPolicy.prototype = {
|
||||
throw new Error("Value must be integer: " + value);
|
||||
}
|
||||
|
||||
this._prefs.set("currentDaySubmissionFailureCount", value);
|
||||
this._healthReportPrefs.set("currentDaySubmissionFailureCount", value);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -595,11 +603,22 @@ HealthReportPolicy.prototype = {
|
||||
* the remote deletion is fulfilled.
|
||||
*/
|
||||
get pendingDeleteRemoteData() {
|
||||
return !!this._prefs.get("pendingDeleteRemoteData", false);
|
||||
return !!this._healthReportPrefs.get("pendingDeleteRemoteData", false);
|
||||
},
|
||||
|
||||
set pendingDeleteRemoteData(value) {
|
||||
this._prefs.set("pendingDeleteRemoteData", !!value);
|
||||
this._healthReportPrefs.set("pendingDeleteRemoteData", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether upload of Firefox Health Report data is enabled.
|
||||
*/
|
||||
get healthReportUploadEnabled() {
|
||||
return !!this._healthReportPrefs.get("uploadEnabled", true);
|
||||
},
|
||||
|
||||
set healthReportUploadEnabled(value) {
|
||||
this._healthReportPrefs.set("uploadEnabled", !!value);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -620,6 +639,7 @@ HealthReportPolicy.prototype = {
|
||||
this.dataSubmissionPolicyResponseDate = this.now();
|
||||
this.dataSubmissionPolicyResponseType = "accepted-" + reason;
|
||||
this.dataSubmissionPolicyAccepted = true;
|
||||
this.dataSubmissionPolicyAcceptedVersion = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -753,7 +773,7 @@ HealthReportPolicy.prototype = {
|
||||
return this._dispatchSubmissionRequest("onRequestRemoteDelete", true);
|
||||
}
|
||||
|
||||
if (!this.dataUploadEnabled) {
|
||||
if (!this.healthReportUploadEnabled) {
|
||||
this._log.debug("Data upload is disabled. Doing nothing.");
|
||||
return;
|
||||
}
|
||||
@ -1003,7 +1023,5 @@ HealthReportPolicy.prototype = {
|
||||
_futureDate: function _futureDate(offset) {
|
||||
return new Date(this.now().getTime() + offset);
|
||||
},
|
||||
};
|
||||
|
||||
Object.freeze(HealthReportPolicy.prototype);
|
||||
});
|
||||
|
16
services/datareporting/tests/Makefile.in
Normal file
16
services/datareporting/tests/Makefile.in
Normal file
@ -0,0 +1,16 @@
|
||||
# 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/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
XPCSHELL_TESTS = xpcshell
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -6,15 +6,19 @@
|
||||
const {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
Cu.import("resource://gre/modules/services/healthreport/policy.jsm");
|
||||
Cu.import("resource://testing-common/services/healthreport/mocks.jsm");
|
||||
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
|
||||
Cu.import("resource://testing-common/services/datareporting/mocks.jsm");
|
||||
|
||||
|
||||
function getPolicy(name) {
|
||||
let prefs = new Preferences(name);
|
||||
let listener = new MockPolicyListener();
|
||||
let branch = "testing.datareporting." + name;
|
||||
let policyPrefs = new Preferences(branch + ".policy.");
|
||||
let healthReportPrefs = new Preferences(branch + ".healthreport.");
|
||||
|
||||
return [new HealthReportPolicy(prefs, listener), prefs, listener];
|
||||
let listener = new MockPolicyListener();
|
||||
let policy = new DataReportingPolicy(policyPrefs, healthReportPrefs, listener);
|
||||
|
||||
return [policy, policyPrefs, healthReportPrefs, listener];
|
||||
}
|
||||
|
||||
function defineNow(policy, now) {
|
||||
@ -32,14 +36,15 @@ function run_test() {
|
||||
}
|
||||
|
||||
add_test(function test_constructor() {
|
||||
let prefs = new Preferences("foo.bar");
|
||||
let policyPrefs = new Preferences("foo.bar.policy.");
|
||||
let hrPrefs = new Preferences("foo.bar.healthreport.");
|
||||
let listener = {
|
||||
onRequestDataUpload: function() {},
|
||||
onRequestRemoteDelete: function() {},
|
||||
onNotifyDataPolicy: function() {},
|
||||
};
|
||||
|
||||
let policy = new HealthReportPolicy(prefs, listener);
|
||||
let policy = new DataReportingPolicy(policyPrefs, hrPrefs, listener);
|
||||
do_check_true(Date.now() - policy.firstRunDate.getTime() < 1000);
|
||||
|
||||
let tomorrow = Date.now() + 24 * 60 * 60 * 1000;
|
||||
@ -51,68 +56,75 @@ add_test(function test_constructor() {
|
||||
});
|
||||
|
||||
add_test(function test_prefs() {
|
||||
let [policy, prefs, listener] = getPolicy("prefs");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("prefs");
|
||||
|
||||
let now = new Date();
|
||||
let nowT = now.getTime();
|
||||
|
||||
policy.firstRunDate = now;
|
||||
do_check_eq(prefs.get("firstRunTime"), nowT);
|
||||
do_check_eq(policyPrefs.get("firstRunTime"), nowT);
|
||||
do_check_eq(policy.firstRunDate.getTime(), nowT);
|
||||
|
||||
policy.dataSubmissionPolicyNotifiedDate= now;
|
||||
do_check_eq(prefs.get("dataSubmissionPolicyNotifiedTime"), nowT);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyNotifiedTime"), nowT);
|
||||
do_check_eq(policy.dataSubmissionPolicyNotifiedDate.getTime(), nowT);
|
||||
|
||||
policy.dataSubmissionPolicyResponseDate = now;
|
||||
do_check_eq(prefs.get("dataSubmissionPolicyResponseTime"), nowT);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyResponseTime"), nowT);
|
||||
do_check_eq(policy.dataSubmissionPolicyResponseDate.getTime(), nowT);
|
||||
|
||||
policy.dataSubmissionPolicyResponseType = "type-1";
|
||||
do_check_eq(prefs.get("dataSubmissionPolicyResponseType"), "type-1");
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyResponseType"), "type-1");
|
||||
do_check_eq(policy.dataSubmissionPolicyResponseType, "type-1");
|
||||
|
||||
policy.dataSubmissionEnabled = false;
|
||||
do_check_false(prefs.get("dataSubmissionEnabled", true));
|
||||
do_check_false(policyPrefs.get("dataSubmissionEnabled", true));
|
||||
do_check_false(policy.dataSubmissionEnabled);
|
||||
|
||||
policy.dataSubmissionPolicyAccepted = false;
|
||||
do_check_false(prefs.get("dataSubmissionPolicyAccepted", true));
|
||||
do_check_false(policyPrefs.get("dataSubmissionPolicyAccepted", true));
|
||||
do_check_false(policy.dataSubmissionPolicyAccepted);
|
||||
|
||||
policy.dataSubmissionPolicyAcceptedVersion = 2;
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"), 2);
|
||||
|
||||
do_check_false(policy.dataSubmissionPolicyBypassAcceptance);
|
||||
prefs.set("dataSubmissionPolicyBypassAcceptance", true);
|
||||
policyPrefs.set("dataSubmissionPolicyBypassAcceptance", true);
|
||||
do_check_true(policy.dataSubmissionPolicyBypassAcceptance);
|
||||
|
||||
policy.lastDataSubmissionRequestedDate = now;
|
||||
do_check_eq(prefs.get("lastDataSubmissionRequestedTime"), nowT);
|
||||
do_check_eq(hrPrefs.get("lastDataSubmissionRequestedTime"), nowT);
|
||||
do_check_eq(policy.lastDataSubmissionRequestedDate.getTime(), nowT);
|
||||
|
||||
policy.lastDataSubmissionSuccessfulDate = now;
|
||||
do_check_eq(prefs.get("lastDataSubmissionSuccessfulTime"), nowT);
|
||||
do_check_eq(hrPrefs.get("lastDataSubmissionSuccessfulTime"), nowT);
|
||||
do_check_eq(policy.lastDataSubmissionSuccessfulDate.getTime(), nowT);
|
||||
|
||||
policy.lastDataSubmissionFailureDate = now;
|
||||
do_check_eq(prefs.get("lastDataSubmissionFailureTime"), nowT);
|
||||
do_check_eq(hrPrefs.get("lastDataSubmissionFailureTime"), nowT);
|
||||
do_check_eq(policy.lastDataSubmissionFailureDate.getTime(), nowT);
|
||||
|
||||
policy.nextDataSubmissionDate = now;
|
||||
do_check_eq(prefs.get("nextDataSubmissionTime"), nowT);
|
||||
do_check_eq(hrPrefs.get("nextDataSubmissionTime"), nowT);
|
||||
do_check_eq(policy.nextDataSubmissionDate.getTime(), nowT);
|
||||
|
||||
policy.currentDaySubmissionFailureCount = 2;
|
||||
do_check_eq(prefs.get("currentDaySubmissionFailureCount", 0), 2);
|
||||
do_check_eq(hrPrefs.get("currentDaySubmissionFailureCount", 0), 2);
|
||||
do_check_eq(policy.currentDaySubmissionFailureCount, 2);
|
||||
|
||||
policy.pendingDeleteRemoteData = true;
|
||||
do_check_true(prefs.get("pendingDeleteRemoteData"));
|
||||
do_check_true(hrPrefs.get("pendingDeleteRemoteData"));
|
||||
do_check_true(policy.pendingDeleteRemoteData);
|
||||
|
||||
policy.healthReportUploadEnabled = false;
|
||||
do_check_false(hrPrefs.get("uploadEnabled"));
|
||||
do_check_false(policy.healthReportUploadEnabled);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_notify_state_prefs() {
|
||||
let [policy, prefs, listener] = getPolicy("notify_state_prefs");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notify_state_prefs");
|
||||
|
||||
do_check_eq(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED);
|
||||
|
||||
@ -127,7 +139,7 @@ add_test(function test_notify_state_prefs() {
|
||||
});
|
||||
|
||||
add_test(function test_initial_submission_notification() {
|
||||
let [policy, prefs, listener] = getPolicy("initial_submission_notification");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("initial_submission_notification");
|
||||
|
||||
do_check_eq(listener.notifyUserCount, 0);
|
||||
|
||||
@ -159,9 +171,9 @@ add_test(function test_initial_submission_notification() {
|
||||
});
|
||||
|
||||
add_test(function test_bypass_acceptance() {
|
||||
let [policy, prefs, listener] = getPolicy("bypass_acceptance");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("bypass_acceptance");
|
||||
|
||||
prefs.set("dataSubmissionPolicyBypassAcceptance", true);
|
||||
policyPrefs.set("dataSubmissionPolicyBypassAcceptance", true);
|
||||
do_check_false(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_true(policy.dataSubmissionPolicyBypassAcceptance);
|
||||
defineNow(policy, new Date(policy.nextDataSubmissionDate.getTime()));
|
||||
@ -172,7 +184,7 @@ add_test(function test_bypass_acceptance() {
|
||||
});
|
||||
|
||||
add_test(function test_notification_implicit_acceptance() {
|
||||
let [policy, prefs, listener] = getPolicy("notification_implicit_acceptance");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_implicit_acceptance");
|
||||
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime() -
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
|
||||
@ -202,7 +214,7 @@ add_test(function test_notification_implicit_acceptance() {
|
||||
|
||||
add_test(function test_notification_rejected() {
|
||||
// User notification failed. We should not record it as being presented.
|
||||
let [policy, prefs, listener] = getPolicy("notification_failed");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_failed");
|
||||
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime() -
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
|
||||
@ -218,7 +230,7 @@ add_test(function test_notification_rejected() {
|
||||
});
|
||||
|
||||
add_test(function test_notification_accepted() {
|
||||
let [policy, prefs, listener] = getPolicy("notification_accepted");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_accepted");
|
||||
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime() -
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
|
||||
@ -238,7 +250,7 @@ add_test(function test_notification_accepted() {
|
||||
});
|
||||
|
||||
add_test(function test_notification_rejected() {
|
||||
let [policy, prefs, listener] = getPolicy("notification_rejected");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("notification_rejected");
|
||||
|
||||
let now = new Date(policy.nextDataSubmissionDate.getTime() -
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC + 1);
|
||||
@ -261,11 +273,12 @@ add_test(function test_notification_rejected() {
|
||||
});
|
||||
|
||||
add_test(function test_submission_kill_switch() {
|
||||
let [policy, prefs, listener] = getPolicy("submission_kill_switch");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_kill_switch");
|
||||
|
||||
policy.firstRunDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
|
||||
policy.nextDataSubmissionDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.recordUserAcceptance("accept-old-ack");
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"), 1);
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
@ -279,16 +292,16 @@ add_test(function test_submission_kill_switch() {
|
||||
});
|
||||
|
||||
add_test(function test_upload_kill_switch() {
|
||||
let [policy, prefs, listener] = getPolicy("upload_kill_switch");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("upload_kill_switch");
|
||||
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
policy.recordUserAcceptance();
|
||||
defineNow(policy, policy.nextDataSubmissionDate);
|
||||
|
||||
policy.dataUploadEnabled = false;
|
||||
policy.healthReportUploadEnabled = false;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 0);
|
||||
policy.dataUploadEnabled = true;
|
||||
policy.healthReportUploadEnabled = true;
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.requestDataUploadCount, 1);
|
||||
|
||||
@ -296,7 +309,7 @@ add_test(function test_upload_kill_switch() {
|
||||
});
|
||||
|
||||
add_test(function test_data_submission_no_data() {
|
||||
let [policy, prefs, listener] = getPolicy("data_submission_no_data");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_no_data");
|
||||
|
||||
policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.dataSubmissionPolicyAccepted = true;
|
||||
@ -316,7 +329,7 @@ add_test(function test_data_submission_no_data() {
|
||||
});
|
||||
|
||||
add_test(function test_data_submission_submit_failure_hard() {
|
||||
let [policy, prefs, listener] = getPolicy("data_submission_submit_failure_hard");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_submit_failure_hard");
|
||||
|
||||
policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.dataSubmissionPolicyAccepted = true;
|
||||
@ -341,7 +354,7 @@ add_test(function test_data_submission_submit_failure_hard() {
|
||||
});
|
||||
|
||||
add_test(function test_data_submission_submit_try_again() {
|
||||
let [policy, prefs, listener] = getPolicy("data_submission_failure_soft");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("data_submission_failure_soft");
|
||||
|
||||
policy.recordUserAcceptance();
|
||||
let nextDataSubmissionDate = policy.nextDataSubmissionDate;
|
||||
@ -356,7 +369,7 @@ add_test(function test_data_submission_submit_try_again() {
|
||||
});
|
||||
|
||||
add_test(function test_submission_daily_scheduling() {
|
||||
let [policy, prefs, listener] = getPolicy("submission_daily_scheduling");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_daily_scheduling");
|
||||
|
||||
policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.dataSubmissionPolicyAccepted = true;
|
||||
@ -396,7 +409,7 @@ add_test(function test_submission_daily_scheduling() {
|
||||
});
|
||||
|
||||
add_test(function test_submission_far_future_scheduling() {
|
||||
let [policy, prefs, listener] = getPolicy("submission_far_future_scheduling");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_far_future_scheduling");
|
||||
|
||||
let now = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
defineNow(policy, now);
|
||||
@ -420,7 +433,7 @@ add_test(function test_submission_far_future_scheduling() {
|
||||
});
|
||||
|
||||
add_test(function test_submission_backoff() {
|
||||
let [policy, prefs, listener] = getPolicy("submission_backoff");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_backoff");
|
||||
|
||||
do_check_eq(policy.FAILURE_BACKOFF_INTERVALS.length, 2);
|
||||
|
||||
@ -483,7 +496,7 @@ add_test(function test_submission_backoff() {
|
||||
|
||||
// Ensure that only one submission request can be active at a time.
|
||||
add_test(function test_submission_expiring() {
|
||||
let [policy, prefs, listener] = getPolicy("submission_expiring");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("submission_expiring");
|
||||
|
||||
policy.dataSubmissionPolicyResponseDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
||||
policy.dataSubmissionPolicyAccepted = true;
|
||||
@ -506,7 +519,7 @@ add_test(function test_submission_expiring() {
|
||||
});
|
||||
|
||||
add_test(function test_delete_remote_data() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data");
|
||||
|
||||
do_check_false(policy.pendingDeleteRemoteData);
|
||||
let nextSubmissionDate = policy.nextDataSubmissionDate;
|
||||
@ -532,7 +545,7 @@ add_test(function test_delete_remote_data() {
|
||||
|
||||
// Ensure that deletion requests take priority over regular data submission.
|
||||
add_test(function test_delete_remote_data_priority() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_priority");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_priority");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
@ -553,7 +566,7 @@ add_test(function test_delete_remote_data_priority() {
|
||||
});
|
||||
|
||||
add_test(function test_delete_remote_data_backoff() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_backoff");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_backoff");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
@ -586,7 +599,7 @@ add_test(function test_delete_remote_data_backoff() {
|
||||
// If we request delete while an upload is in progress, delete should be
|
||||
// scheduled immediately after upload.
|
||||
add_test(function test_delete_remote_data_in_progress_upload() {
|
||||
let [policy, prefs, listener] = getPolicy("delete_remote_data_in_progress_upload");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("delete_remote_data_in_progress_upload");
|
||||
|
||||
let now = new Date();
|
||||
defineNow(policy, policy._futureDate(-24 * 60 * 60 * 1000));
|
||||
@ -616,7 +629,7 @@ add_test(function test_delete_remote_data_in_progress_upload() {
|
||||
});
|
||||
|
||||
add_test(function test_polling() {
|
||||
let [policy, prefs, listener] = getPolicy("polling");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("polling");
|
||||
|
||||
// Ensure checkStateAndTrigger is called at a regular interval.
|
||||
let now = new Date();
|
||||
@ -632,7 +645,7 @@ add_test(function test_polling() {
|
||||
|
||||
do_check_true(now2.getTime() - now.getTime() >= 500);
|
||||
now = now2;
|
||||
HealthReportPolicy.prototype.checkStateAndTrigger.call(policy);
|
||||
DataReportingPolicy.prototype.checkStateAndTrigger.call(policy);
|
||||
|
||||
if (count >= 2) {
|
||||
policy.stopPolling();
|
||||
@ -652,7 +665,7 @@ add_test(function test_polling() {
|
||||
// This is probably covered by other tests. But, it's best to have explicit
|
||||
// coverage from a higher-level.
|
||||
add_test(function test_polling_implicit_acceptance() {
|
||||
let [policy, prefs, listener] = getPolicy("polling_implicit_acceptance");
|
||||
let [policy, policyPrefs, hrPrefs, listener] = getPolicy("polling_implicit_acceptance");
|
||||
|
||||
// Redefine intervals with shorter, test-friendly values.
|
||||
Object.defineProperty(policy, "POLL_INTERVAL_MSEC", {
|
||||
@ -670,7 +683,7 @@ add_test(function test_polling_implicit_acceptance() {
|
||||
print("checkStateAndTrigger count: " + count);
|
||||
|
||||
// Account for some slack.
|
||||
HealthReportPolicy.prototype.checkStateAndTrigger.call(policy);
|
||||
DataReportingPolicy.prototype.checkStateAndTrigger.call(policy);
|
||||
|
||||
// What should happen on different invocations:
|
||||
//
|
5
services/datareporting/tests/xpcshell/xpcshell.ini
Normal file
5
services/datareporting/tests/xpcshell/xpcshell.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
|
||||
[test_policy.js]
|
@ -1,14 +1,4 @@
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
# suite (comm): {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}
|
||||
# metro browser: {99bceaaa-e3c6-48c1-b981-ef9b46b67d60}
|
||||
|
||||
component {e354c59b-b252-4040-b6dd-b71864e3e35c} HealthReportService.js
|
||||
contract @mozilla.org/healthreport/service;1 {e354c59b-b252-4040-b6dd-b71864e3e35c}
|
||||
category app-startup HealthReportService service,@mozilla.org/healthreport/service;1 application={3c2e2abc-06d4-11e1-ac3b-374f68613e61} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110} application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
|
||||
# Register Firefox Health Report providers.
|
||||
category healthreport-js-provider AddonsProvider resource://gre/modules/services/healthreport/providers.jsm
|
||||
category healthreport-js-provider AppInfoProvider resource://gre/modules/services/healthreport/providers.jsm
|
||||
category healthreport-js-provider CrashesProvider resource://gre/modules/services/healthreport/providers.jsm
|
||||
|
@ -11,13 +11,11 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
modules := \
|
||||
healthreporter.jsm \
|
||||
policy.jsm \
|
||||
profile.jsm \
|
||||
providers.jsm \
|
||||
$(NULL)
|
||||
|
||||
testing_modules := \
|
||||
mocks.jsm \
|
||||
utils.jsm \
|
||||
$(NULL)
|
||||
|
||||
@ -32,7 +30,6 @@ TESTING_JS_MODULE_DIR := services/healthreport
|
||||
|
||||
EXTRA_COMPONENTS := \
|
||||
HealthReportComponents.manifest \
|
||||
HealthReportService.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -2,23 +2,22 @@
|
||||
* 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/. */
|
||||
|
||||
pref("healthreport.documentServerURI", "https://data.mozilla.com/");
|
||||
pref("healthreport.documentServerNamespace", "metrics");
|
||||
pref("healthreport.logging.consoleEnabled", true);
|
||||
pref("healthreport.logging.consoleLevel", "Warn");
|
||||
pref("healthreport.policy.currentDaySubmissionFailureCount", 0);
|
||||
pref("healthreport.policy.dataSubmissionEnabled", true);
|
||||
pref("healthreport.policy.dataSubmissionPolicyAccepted", false);
|
||||
pref("healthreport.policy.dataSubmissionPolicyBypassAcceptance", false);
|
||||
pref("healthreport.policy.dataSubmissionPolicyNotifiedTime", "0");
|
||||
pref("healthreport.policy.dataSubmissionPolicyResponseType", "");
|
||||
pref("healthreport.policy.dataSubmissionPolicyResponseTime", "0");
|
||||
pref("healthreport.policy.firstRunTime", "0");
|
||||
pref("healthreport.policy.lastDataSubmissionFailureTime", "0");
|
||||
pref("healthreport.policy.lastDataSubmissionRequestedTime", "0");
|
||||
pref("healthreport.policy.lastDataSubmissionSuccessfulTime", "0");
|
||||
pref("healthreport.policy.nextDataSubmissionTime", "0");
|
||||
pref("healthreport.service.enabled", true);
|
||||
pref("healthreport.service.loadDelayMsec", 10000);
|
||||
pref("healthreport.service.providerCategories", "healthreport-js-provider");
|
||||
pref("healthreport.infoURL", "http://www.mozilla.org/legal/privacy/firefox.html#health-report");
|
||||
pref("datareporting.healthreport.currentDaySubmissionFailureCount", 0);
|
||||
pref("datareporting.healthreport.documentServerURI", "https://data.mozilla.com/");
|
||||
pref("datareporting.healthreport.documentServerNamespace", "metrics");
|
||||
pref("datareporting.healthreport.infoURL", "http://www.mozilla.org/legal/privacy/firefox.html#health-report");
|
||||
pref("datareporting.healthreport.logging.consoleEnabled", true);
|
||||
pref("datareporting.healthreport.logging.consoleLevel", "Warn");
|
||||
pref("datareporting.healthreport.lastDataSubmissionFailureTime", "0");
|
||||
pref("datareporting.healthreport.lastDataSubmissionRequestedTime", "0");
|
||||
pref("datareporting.healthreport.lastDataSubmissionSuccessfulTime", "0");
|
||||
pref("datareporting.healthreport.nextDataSubmissionTime", "0");
|
||||
pref("datareporting.healthreport.pendingDeleteRemoteData", false);
|
||||
|
||||
// Health Report is enabled by default on all channels.
|
||||
pref("datareporting.healthreport.uploadEnabled", true);
|
||||
|
||||
pref("datareporting.healthreport.service.enabled", true);
|
||||
pref("datareporting.healthreport.service.loadDelayMsec", 10000);
|
||||
pref("datareporting.healthreport.service.providerCategories", "healthreport-js-provider");
|
||||
|
||||
|
@ -11,7 +11,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
Cu.import("resource://services-common/async.js");
|
||||
Cu.import("resource://services-common/bagheeraclient.js");
|
||||
Cu.import("resource://services-common/log4moz.js");
|
||||
Cu.import("resource://services-common/observers.js");
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
Cu.import("resource://gre/modules/commonjs/promise/core.js");
|
||||
@ -20,7 +19,6 @@ Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/policy.jsm");
|
||||
|
||||
|
||||
// Oldest year to allow in date preferences. This module was implemented in
|
||||
@ -81,12 +79,19 @@ const DEFAULT_DATABASE_NAME = "healthreport.sqlite";
|
||||
* @param branch
|
||||
* (string) The preferences branch to use for state storage. The value
|
||||
* must end with a period (.).
|
||||
*
|
||||
* @param policy
|
||||
* (HealthReportPolicy) Policy driving execution of HealthReporter.
|
||||
*/
|
||||
function HealthReporter(branch) {
|
||||
function HealthReporter(branch, policy) {
|
||||
if (!branch.endsWith(".")) {
|
||||
throw new Error("Branch must end with a period (.): " + branch);
|
||||
}
|
||||
|
||||
if (!policy) {
|
||||
throw new Error("Must provide policy to HealthReporter constructor.");
|
||||
}
|
||||
|
||||
this._log = Log4Moz.repository.getLogger("Services.HealthReport.HealthReporter");
|
||||
this._log.info("Initializing health reporter instance against " + branch);
|
||||
|
||||
@ -100,10 +105,9 @@ function HealthReporter(branch) {
|
||||
throw new Error("No server namespace defined. Did you forget a pref?");
|
||||
}
|
||||
|
||||
this._dbName = this._prefs.get("dbName") || DEFAULT_DATABASE_NAME;
|
||||
this._policy = policy;
|
||||
|
||||
let policyBranch = new Preferences(branch + "policy.");
|
||||
this._policy = new HealthReportPolicy(policyBranch, this);
|
||||
this._dbName = this._prefs.get("dbName") || DEFAULT_DATABASE_NAME;
|
||||
|
||||
this._storage = null;
|
||||
this._storageInProgress = false;
|
||||
@ -210,6 +214,14 @@ HealthReporter.prototype = Object.freeze({
|
||||
this._prefs.set("lastSubmitID", value || "");
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether this instance will upload data to a server.
|
||||
*/
|
||||
get willUploadData() {
|
||||
return this._policy.dataSubmissionPolicyAccepted &&
|
||||
this._policy.healthReportUploadEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether remote data is currently stored.
|
||||
*
|
||||
@ -289,7 +301,6 @@ HealthReporter.prototype = Object.freeze({
|
||||
return;
|
||||
}
|
||||
|
||||
this._policy.startPolling();
|
||||
this._log.info("HealthReporter started.");
|
||||
this._initialized = true;
|
||||
Services.obs.addObserver(this, "idle-daily", false);
|
||||
@ -327,9 +338,6 @@ HealthReporter.prototype = Object.freeze({
|
||||
this._initialized = false;
|
||||
this._shutdownRequested = true;
|
||||
|
||||
// Safe to call multiple times.
|
||||
this._policy.stopPolling();
|
||||
|
||||
if (this._collectorInProgress) {
|
||||
this._log.warn("Collector is in progress of initializing. Waiting to finish.");
|
||||
return;
|
||||
@ -552,45 +560,14 @@ HealthReporter.prototype = Object.freeze({
|
||||
},
|
||||
|
||||
/**
|
||||
* Record the user's rejection of the data submission policy.
|
||||
* Called to initiate a data upload.
|
||||
*
|
||||
* This should be what everything uses to disable data submission.
|
||||
*
|
||||
* @param reason
|
||||
* (string) Why data submission is being disabled.
|
||||
* The passed argument is a `DataSubmissionRequest` from policy.jsm.
|
||||
*/
|
||||
recordPolicyRejection: function (reason) {
|
||||
this._policy.recordUserRejection(reason);
|
||||
},
|
||||
|
||||
/**
|
||||
* Record the user's acceptance of the data submission policy.
|
||||
*
|
||||
* This should be what everything uses to enable data submission.
|
||||
*
|
||||
* @param reason
|
||||
* (string) Why data submission is being enabled.
|
||||
*/
|
||||
recordPolicyAcceptance: function (reason) {
|
||||
this._policy.recordUserAcceptance(reason);
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether the data submission policy has been accepted.
|
||||
*
|
||||
* If this is true, health data will be submitted unless one of the kill
|
||||
* switches is active.
|
||||
*/
|
||||
get dataSubmissionPolicyAccepted() {
|
||||
return this._policy.dataSubmissionPolicyAccepted;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether this health reporter will upload data to a server.
|
||||
*/
|
||||
get willUploadData() {
|
||||
return this._policy.dataSubmissionPolicyAccepted &&
|
||||
this._policy.dataUploadEnabled;
|
||||
requestDataUpload: function (request) {
|
||||
this.collectMeasurements()
|
||||
.then(this._uploadData.bind(this, request),
|
||||
this._onSubmitDataRequestFailure.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -768,7 +745,7 @@ HealthReporter.prototype = Object.freeze({
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_deleteRemoteData: function (request) {
|
||||
deleteRemoteData: function (request) {
|
||||
if (!this.lastSubmitID) {
|
||||
this._log.info("Received request to delete remote data but no data stored.");
|
||||
request.onNoDataAvailable();
|
||||
@ -859,28 +836,5 @@ HealthReporter.prototype = Object.freeze({
|
||||
return new Date();
|
||||
},
|
||||
|
||||
//-----------------------------
|
||||
// HealthReportPolicy listeners
|
||||
//-----------------------------
|
||||
|
||||
onRequestDataUpload: function (request) {
|
||||
this.collectMeasurements()
|
||||
.then(this._uploadData.bind(this, request),
|
||||
this._onSubmitDataRequestFailure.bind(this));
|
||||
},
|
||||
|
||||
onNotifyDataPolicy: function (request) {
|
||||
// This isn't very loosely coupled. We may want to have this call
|
||||
// registered listeners instead.
|
||||
Observers.notify("healthreport:notify-data-policy:request", request);
|
||||
},
|
||||
|
||||
onRequestRemoteDelete: function (request) {
|
||||
this._deleteRemoteData(request);
|
||||
},
|
||||
|
||||
//------------------------------------
|
||||
// End of HealthReportPolicy listeners
|
||||
//------------------------------------
|
||||
});
|
||||
|
||||
|
@ -216,8 +216,8 @@ this.createFakeCrash = function (submitted=false, date=new Date()) {
|
||||
*
|
||||
* The purpose of this type is to aid testing of startup and shutdown.
|
||||
*/
|
||||
this.InspectedHealthReporter = function (branch) {
|
||||
HealthReporter.call(this, branch);
|
||||
this.InspectedHealthReporter = function (branch, policy) {
|
||||
HealthReporter.call(this, branch, policy);
|
||||
|
||||
this.onStorageCreated = null;
|
||||
this.onCollectorInitialized = null;
|
||||
|
@ -9,7 +9,7 @@ Cu.import("resource://services-common/observers.js");
|
||||
Cu.import("resource://services-common/preferences.js");
|
||||
Cu.import("resource://gre/modules/commonjs/promise/core.js");
|
||||
Cu.import("resource://gre/modules/services/healthreport/healthreporter.jsm");
|
||||
Cu.import("resource://gre/modules/services/healthreport/policy.jsm");
|
||||
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://testing-common/services-common/bagheeraserver.js");
|
||||
@ -36,12 +36,29 @@ function defineNow(policy, now) {
|
||||
function getJustReporter(name, uri=SERVER_URI, inspected=false) {
|
||||
let branch = "healthreport.testing. " + name + ".";
|
||||
|
||||
let prefs = new Preferences(branch);
|
||||
let prefs = new Preferences(branch + "healthreport.");
|
||||
prefs.set("documentServerURI", uri);
|
||||
prefs.set("dbName", name);
|
||||
|
||||
let reporter;
|
||||
|
||||
let policyPrefs = new Preferences(branch + "policy.");
|
||||
let policy = new DataReportingPolicy(policyPrefs, prefs, {
|
||||
onRequestDataUpload: function (request) {
|
||||
reporter.requestDataUpload(request);
|
||||
},
|
||||
|
||||
onNotifyDataPolicy: function (request) { },
|
||||
|
||||
onRequestRemoteDelete: function (request) {
|
||||
reporter.deleteRemoteData(request);
|
||||
},
|
||||
});
|
||||
|
||||
let type = inspected ? InspectedHealthReporter : HealthReporter;
|
||||
return new type(branch);
|
||||
reporter = new type(branch + "healthreport.", policy);
|
||||
|
||||
return reporter;
|
||||
}
|
||||
|
||||
function getReporter(name, uri, inspected) {
|
||||
@ -251,7 +268,7 @@ add_task(function test_data_submission_transport_failure() {
|
||||
|
||||
let deferred = Promise.defer();
|
||||
let request = new DataSubmissionRequest(deferred, new Date(Date.now + 30000));
|
||||
reporter.onRequestDataUpload(request);
|
||||
reporter.requestDataUpload(request);
|
||||
|
||||
yield deferred.promise;
|
||||
do_check_eq(request.state, request.SUBMISSION_FAILURE_SOFT);
|
||||
@ -268,7 +285,7 @@ add_task(function test_data_submission_success() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let request = new DataSubmissionRequest(deferred, new Date());
|
||||
reporter.onRequestDataUpload(request);
|
||||
reporter.requestDataUpload(request);
|
||||
yield deferred.promise;
|
||||
do_check_eq(request.state, request.SUBMISSION_SUCCESS);
|
||||
do_check_true(reporter.lastPingDate.getTime() > 0);
|
||||
@ -336,22 +353,23 @@ add_task(function test_request_remote_data_deletion() {
|
||||
add_task(function test_policy_accept_reject() {
|
||||
let [reporter, server] = yield getReporterAndServer("policy_accept_reject");
|
||||
|
||||
do_check_false(reporter.dataSubmissionPolicyAccepted);
|
||||
let policy = reporter._policy;
|
||||
|
||||
do_check_false(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_false(reporter.willUploadData);
|
||||
|
||||
reporter.recordPolicyAcceptance();
|
||||
do_check_true(reporter.dataSubmissionPolicyAccepted);
|
||||
policy.recordUserAcceptance();
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_true(reporter.willUploadData);
|
||||
|
||||
reporter.recordPolicyRejection();
|
||||
do_check_false(reporter.dataSubmissionPolicyAccepted);
|
||||
policy.recordUserRejection();
|
||||
do_check_false(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_false(reporter.willUploadData);
|
||||
|
||||
reporter._shutdown();
|
||||
yield shutdownServer(server);
|
||||
});
|
||||
|
||||
|
||||
add_task(function test_upload_save_payload() {
|
||||
let [reporter, server] = yield getReporterAndServer("upload_save_payload");
|
||||
|
||||
|
@ -5,24 +5,14 @@
|
||||
|
||||
const modules = [
|
||||
"healthreporter.jsm",
|
||||
"policy.jsm",
|
||||
"profile.jsm",
|
||||
"providers.jsm",
|
||||
];
|
||||
|
||||
const test_modules = [
|
||||
"mocks.jsm",
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
for (let m of modules) {
|
||||
let resource = "resource://gre/modules/services/healthreport/" + m;
|
||||
Components.utils.import(resource, {});
|
||||
}
|
||||
|
||||
for (let m of test_modules) {
|
||||
let resource = "resource://testing-common/services/healthreport/" + m;
|
||||
Components.utils.import(resource, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ tail =
|
||||
|
||||
[test_load_modules.js]
|
||||
[test_profile.js]
|
||||
[test_policy.js]
|
||||
[test_healthreporter.js]
|
||||
[test_provider_addons.js]
|
||||
[test_provider_appinfo.js]
|
||||
|
@ -9,6 +9,7 @@ add_makefiles "
|
||||
services/crypto/Makefile
|
||||
services/crypto/component/Makefile
|
||||
services/healthreport/Makefile
|
||||
services/datareporting/Makefile
|
||||
services/metrics/Makefile
|
||||
services/sync/Makefile
|
||||
services/sync/locales/Makefile
|
||||
@ -20,6 +21,7 @@ if [ "$ENABLE_TESTS" ]; then
|
||||
services/common/tests/Makefile
|
||||
services/crypto/tests/Makefile
|
||||
services/healthreport/tests/Makefile
|
||||
services/datareporting/tests/Makefile
|
||||
services/metrics/tests/Makefile
|
||||
services/sync/tests/Makefile
|
||||
"
|
||||
|
@ -88,6 +88,7 @@ skip-if = os == "android"
|
||||
[include:services/common/tests/unit/xpcshell.ini]
|
||||
[include:services/crypto/tests/unit/xpcshell.ini]
|
||||
[include:services/crypto/components/tests/unit/xpcshell.ini]
|
||||
[include:services/datareporting/tests/xpcshell/xpcshell.ini]
|
||||
[include:services/healthreport/tests/xpcshell/xpcshell.ini]
|
||||
[include:services/metrics/tests/xpcshell/xpcshell.ini]
|
||||
[include:services/sync/tests/unit/xpcshell.ini]
|
||||
|
Loading…
Reference in New Issue
Block a user