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 {interfaces: Ci, utils: Cu} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/Preferences.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "Experiments", michael@0: "resource:///modules/experiments/Experiments.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "OS", michael@0: "resource://gre/modules/osfile.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", michael@0: "resource://services-common/utils.js"); michael@0: michael@0: const PREF_EXPERIMENTS_ENABLED = "experiments.enabled"; michael@0: const PREF_ACTIVE_EXPERIMENT = "experiments.activeExperiment"; // whether we have an active experiment michael@0: const PREF_HEALTHREPORT_ENABLED = "datareporting.healthreport.service.enabled"; michael@0: const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled"; michael@0: const DELAY_INIT_MS = 30 * 1000; michael@0: michael@0: XPCOMUtils.defineLazyGetter( michael@0: this, "gPrefs", () => { michael@0: return new Preferences(); michael@0: }); michael@0: michael@0: XPCOMUtils.defineLazyGetter( michael@0: this, "gExperimentsEnabled", () => { michael@0: return gPrefs.get(PREF_EXPERIMENTS_ENABLED, false) && michael@0: gPrefs.get(PREF_TELEMETRY_ENABLED, false) && michael@0: gPrefs.get(PREF_HEALTHREPORT_ENABLED, false); michael@0: }); michael@0: michael@0: XPCOMUtils.defineLazyGetter( michael@0: this, "gActiveExperiment", () => { michael@0: return gPrefs.get(PREF_ACTIVE_EXPERIMENT); michael@0: }); michael@0: michael@0: function ExperimentsService() { michael@0: this._initialized = false; michael@0: this._delayedInitTimer = null; michael@0: } michael@0: michael@0: ExperimentsService.prototype = { michael@0: classID: Components.ID("{f7800463-3b97-47f9-9341-b7617e6d8d49}"), michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver]), michael@0: michael@0: notify: function (timer) { michael@0: if (!gExperimentsEnabled) { michael@0: return; michael@0: } michael@0: if (OS.Constants.Path.profileDir === undefined) { michael@0: throw Error("Update timer fired before profile was initialized?"); michael@0: } michael@0: Experiments.instance().updateManifest(); michael@0: }, michael@0: michael@0: _delayedInit: function () { michael@0: if (!this._initialized) { michael@0: this._initialized = true; michael@0: Experiments.instance(); // for side effects michael@0: } michael@0: }, michael@0: michael@0: observe: function (subject, topic, data) { michael@0: switch (topic) { michael@0: case "profile-after-change": michael@0: if (gExperimentsEnabled) { michael@0: Services.obs.addObserver(this, "quit-application", false); michael@0: Services.obs.addObserver(this, "sessionstore-state-finalized", false); michael@0: Services.obs.addObserver(this, "EM-loaded", false); michael@0: michael@0: if (gActiveExperiment) { michael@0: this._initialized = true; michael@0: Experiments.instance(); // for side effects michael@0: } michael@0: } michael@0: break; michael@0: case "sessionstore-state-finalized": michael@0: if (!this._initialized) { michael@0: CommonUtils.namedTimer(this._delayedInit, DELAY_INIT_MS, this, "_delayedInitTimer"); michael@0: } michael@0: break; michael@0: case "EM-loaded": michael@0: if (!this._initialized) { michael@0: Experiments.instance(); // for side effects michael@0: this._initialized = true; michael@0: michael@0: if (this._delayedInitTimer) { michael@0: this._delayedInitTimer.clear(); michael@0: } michael@0: } michael@0: break; michael@0: case "quit-application": michael@0: Services.obs.removeObserver(this, "quit-application"); michael@0: Services.obs.removeObserver(this, "sessionstore-state-finalized"); michael@0: Services.obs.removeObserver(this, "EM-loaded"); michael@0: if (this._delayedInitTimer) { michael@0: this._delayedInitTimer.clear(); michael@0: } michael@0: break; michael@0: } michael@0: }, michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ExperimentsService]);