1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/* 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";
const { ClientEnvironmentBase } = ChromeUtils.import(
"resource://gre/modules/components-utils/ClientEnvironment.jsm"
);
const lazy = {};
ChromeUtils.defineModuleGetter(
lazy,
"NormandyApi",
"resource://normandy/lib/NormandyApi.jsm"
);
ChromeUtils.defineModuleGetter(
lazy,
"PreferenceExperiments",
"resource://normandy/lib/PreferenceExperiments.jsm"
);
ChromeUtils.defineModuleGetter(
lazy,
"PreferenceRollouts",
"resource://normandy/lib/PreferenceRollouts.jsm"
);
ChromeUtils.defineModuleGetter(
lazy,
"AddonStudies",
"resource://normandy/lib/AddonStudies.jsm"
);
ChromeUtils.defineModuleGetter(
lazy,
"AddonRollouts",
"resource://normandy/lib/AddonRollouts.jsm"
);
var EXPORTED_SYMBOLS = ["ClientEnvironment"];
// Cached API request for client attributes that are determined by the Normandy
// service.
let _classifyRequest = null;
class ClientEnvironment extends ClientEnvironmentBase {
/**
* Fetches information about the client that is calculated on the server,
* like geolocation and the current time.
*
* The server request is made lazily and is cached for the entire browser
* session.
*/
static async getClientClassification() {
if (!_classifyRequest) {
_classifyRequest = lazy.NormandyApi.classifyClient();
}
return _classifyRequest;
}
static clearClassifyCache() {
_classifyRequest = null;
}
/**
* Test wrapper that mocks the server request for classifying the client.
* @param {Object} data Fake server data to use
* @param {Function} testFunction Test function to execute while mock data is in effect.
*/
static withMockClassify(data, testFunction) {
return async function inner() {
const oldRequest = _classifyRequest;
_classifyRequest = Promise.resolve(data);
await testFunction();
_classifyRequest = oldRequest;
};
}
static get userId() {
return ClientEnvironment.randomizationId;
}
static get country() {
return (async () => {
const { country } = await ClientEnvironment.getClientClassification();
return country;
})();
}
static get request_time() {
return (async () => {
const {
request_time,
} = await ClientEnvironment.getClientClassification();
return request_time;
})();
}
static get experiments() {
return (async () => {
const names = { all: [], active: [], expired: [] };
for (const {
slug,
expired,
} of await lazy.PreferenceExperiments.getAll()) {
names.all.push(slug);
if (expired) {
names.expired.push(slug);
} else {
names.active.push(slug);
}
}
return names;
})();
}
static get studies() {
return (async () => {
const rv = { pref: {}, addon: {} };
for (const prefStudy of await lazy.PreferenceExperiments.getAll()) {
rv.pref[prefStudy.slug] = prefStudy;
}
for (const addonStudy of await lazy.AddonStudies.getAll()) {
rv.addon[addonStudy.slug] = addonStudy;
}
return rv;
})();
}
static get rollouts() {
return (async () => {
const rv = { pref: {}, addon: {} };
for (const prefRollout of await lazy.PreferenceRollouts.getAll()) {
rv.pref[prefRollout.slug] = prefRollout;
}
for (const addonRollout of await lazy.AddonRollouts.getAll()) {
rv.addon[addonRollout.slug] = addonRollout;
}
return rv;
})();
}
static get isFirstRun() {
return Services.prefs.getBoolPref("app.normandy.first_run", true);
}
}
|