|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 MARIONETTE_TIMEOUT = 60000; |
|
5 |
|
6 const DATA_KEY = "ril.data.enabled"; |
|
7 const DATA_ROAMING_KEY = "ril.data.roaming_enabled"; |
|
8 const APN_KEY = "ril.data.apnSettings"; |
|
9 |
|
10 SpecialPowers.setBoolPref("dom.mozSettings.enabled", true); |
|
11 SpecialPowers.addPermission("mobileconnection", true, document); |
|
12 SpecialPowers.addPermission("settings-read", true, document); |
|
13 SpecialPowers.addPermission("settings-write", true, document); |
|
14 |
|
15 let settings = window.navigator.mozSettings; |
|
16 let connection = window.navigator.mozMobileConnections[0]; |
|
17 ok(connection instanceof MozMobileConnection, |
|
18 "connection is instanceof " + connection.constructor); |
|
19 |
|
20 |
|
21 let pendingEmulatorCmdCount = 0; |
|
22 function sendCmdToEmulator(cmd, callback) { |
|
23 ++pendingEmulatorCmdCount; |
|
24 |
|
25 runEmulatorCmd(cmd, function(result) { |
|
26 --pendingEmulatorCmdCount; |
|
27 |
|
28 is(result[0], "OK", "Emulator response"); |
|
29 |
|
30 if (callback) { |
|
31 callback(); |
|
32 } |
|
33 }); |
|
34 } |
|
35 |
|
36 let tasks = { |
|
37 // List of test fuctions. Each of them should call |tasks.next()| when |
|
38 // completed or |tasks.finish()| to jump to the last one. |
|
39 _tasks: [], |
|
40 _nextTaskIndex: 0, |
|
41 |
|
42 push: function(func) { |
|
43 this._tasks.push(func); |
|
44 }, |
|
45 |
|
46 next: function() { |
|
47 let index = this._nextTaskIndex++; |
|
48 let task = this._tasks[index]; |
|
49 try { |
|
50 task(); |
|
51 } catch (ex) { |
|
52 ok(false, "test task[" + index + "] throws: " + ex); |
|
53 // Run last task as clean up if possible. |
|
54 if (index != this._tasks.length - 1) { |
|
55 this.finish(); |
|
56 } |
|
57 } |
|
58 }, |
|
59 |
|
60 finish: function() { |
|
61 this._tasks[this._tasks.length - 1](); |
|
62 }, |
|
63 |
|
64 run: function() { |
|
65 this.next(); |
|
66 } |
|
67 }; |
|
68 |
|
69 function setSetting(key, value, callback) { |
|
70 let setLock = settings.createLock(); |
|
71 let obj = {}; |
|
72 obj[key] = value; |
|
73 |
|
74 let setReq = setLock.set(obj); |
|
75 setReq.addEventListener("success", function onSetSuccess() { |
|
76 ok(true, "set '" + key + "' to " + obj[key]); |
|
77 if (callback) { |
|
78 callback(); |
|
79 } |
|
80 }); |
|
81 setReq.addEventListener("error", function onSetError() { |
|
82 ok(false, "cannot set '" + key + "'"); |
|
83 tasks.finish(); |
|
84 }); |
|
85 } |
|
86 |
|
87 function getSetting(key, callback) { |
|
88 let getLock = settings.createLock(); |
|
89 |
|
90 let getReq = getLock.get(key); |
|
91 getReq.addEventListener("success", function onGetSuccess() { |
|
92 ok(true, "get " + key + " setting okay"); |
|
93 let value = getReq.result[key]; |
|
94 callback(value); |
|
95 }); |
|
96 getReq.addEventListener("error", function onGetError() { |
|
97 ok(false, "cannot get '" + key + "'"); |
|
98 tasks.finish(); |
|
99 }); |
|
100 } |
|
101 |
|
102 function setEmulatorAPN(callback) { |
|
103 let apn = |
|
104 [ |
|
105 [ |
|
106 {"carrier":"T-Mobile US", |
|
107 "apn":"epc.tmobile.com", |
|
108 "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", |
|
109 "types":["default","supl","mms"]} |
|
110 ] |
|
111 ]; |
|
112 setSetting(APN_KEY, apn, callback); |
|
113 } |
|
114 |
|
115 function setEmulatorRoaming(roaming, callback) { |
|
116 log("Setting emulator roaming state: " + roaming + "."); |
|
117 |
|
118 // Set voice registration state first and then data registration state. |
|
119 let cmd = "gsm voice " + (roaming ? "roaming" : "home"); |
|
120 sendCmdToEmulator(cmd, function() { |
|
121 |
|
122 connection.addEventListener("voicechange", function onvoicechange() { |
|
123 connection.removeEventListener("voicechange", onvoicechange); |
|
124 log("mobileConnection.voice.roaming is now '" |
|
125 + connection.voice.roaming + "'."); |
|
126 is(connection.voice.roaming, roaming, "voice.roaming"); |
|
127 |
|
128 let cmd = "gsm data " + (roaming ? "roaming" : "home"); |
|
129 sendCmdToEmulator(cmd, function() { |
|
130 |
|
131 connection.addEventListener("datachange", function ondatachange() { |
|
132 connection.removeEventListener("datachange", ondatachange); |
|
133 log("mobileConnection.data.roaming is now '" |
|
134 + connection.data.roaming + "'."); |
|
135 is(connection.data.roaming, roaming, "data.roaming"); |
|
136 if (callback) { |
|
137 callback(); |
|
138 } |
|
139 }); |
|
140 }); |
|
141 }); |
|
142 }); |
|
143 } |
|
144 |
|
145 function setEmulatorHome(callback) { |
|
146 let voiceRegistration = false; |
|
147 let dataRegistration = false; |
|
148 |
|
149 if (connection.voice.state != "registered") { |
|
150 sendCmdToEmulator("gsm voice home", function() { |
|
151 connection.addEventListener("voicechange", function onvoicechange() { |
|
152 connection.removeEventListener("voicechange", onvoicechange); |
|
153 log("mobileConnection.voice.state is now '" |
|
154 + connection.voice.state + "'."); |
|
155 is(connection.voice.state, "registered", "voice.state"); |
|
156 voiceRegistration = true; |
|
157 }); |
|
158 }); |
|
159 } else { |
|
160 voiceRegistration = true; |
|
161 } |
|
162 |
|
163 if (connection.data.state != "registered") { |
|
164 sendCmdToEmulator("gsm data home", function() { |
|
165 connection.addEventListener("datachange", function ondatachange() { |
|
166 connection.removeEventListener("datachange", ondatachange); |
|
167 log("mobileConnection.data.state is now '" |
|
168 + connection.data.state + "'."); |
|
169 is(connection.data.state, "registered", "data.state"); |
|
170 dataRegistration = true; |
|
171 }); |
|
172 }); |
|
173 } else { |
|
174 dataRegistration = true; |
|
175 } |
|
176 |
|
177 waitFor(callback, function() { |
|
178 return (voiceRegistration && dataRegistration); |
|
179 }); |
|
180 } |
|
181 |
|
182 |
|
183 tasks.push(function verifyInitialState() { |
|
184 log("Verifying initial state."); |
|
185 |
|
186 // Want to start test with mobileConnection.data.state 'registered', |
|
187 // This is the default state; if it is not currently this value then set it. |
|
188 setEmulatorHome(function() { |
|
189 // Want to start test with data off, |
|
190 // This is the default state; if it is not currently this value then set it. |
|
191 getSetting(DATA_KEY, function(result) { |
|
192 let value = result; |
|
193 log("Starting data enabled: " + value); |
|
194 if (value) { |
|
195 setSetting(DATA_KEY, false); |
|
196 |
|
197 connection.addEventListener("datachange", function ondatachange() { |
|
198 connection.removeEventListener("datachange", ondatachange); |
|
199 log("mobileConnection.data.connected is now '" |
|
200 + connection.data.connected + "'."); |
|
201 is(connection.data.connected, false, "data.connected"); |
|
202 setEmulatorAPN(function() { |
|
203 tasks.next(); |
|
204 }); |
|
205 }); |
|
206 } else { |
|
207 setEmulatorAPN(function() { |
|
208 tasks.next(); |
|
209 }); |
|
210 } |
|
211 }); |
|
212 }); |
|
213 }); |
|
214 |
|
215 tasks.push(function testEnableData() { |
|
216 log("Turn data on."); |
|
217 |
|
218 connection.addEventListener("datachange", function ondatachange() { |
|
219 connection.removeEventListener("datachange", ondatachange); |
|
220 log("mobileConnection.data.connected is now '" |
|
221 + connection.data.connected + "'."); |
|
222 is(connection.data.connected, true, "data.connected"); |
|
223 tasks.next(); |
|
224 }); |
|
225 |
|
226 setSetting(DATA_KEY, true); |
|
227 }); |
|
228 |
|
229 tasks.push(function testUnregisterDataWhileDataEnabled() { |
|
230 log("Set data registration unregistered while data enabled."); |
|
231 |
|
232 // When data registration is unregistered, all data calls |
|
233 // will be automatically deactivated. |
|
234 sendCmdToEmulator("gsm data unregistered", function() { |
|
235 connection.addEventListener("datachange", function ondatachange() { |
|
236 log("mobileConnection.data.state is now '" |
|
237 + connection.data.state + "'."); |
|
238 if (connection.data.state == "notSearching") { |
|
239 connection.removeEventListener("datachange", ondatachange); |
|
240 log("mobileConnection.data.connected is now '" |
|
241 + connection.data.connected + "'."); |
|
242 is(connection.data.connected, false, "data.connected"); |
|
243 tasks.next(); |
|
244 } |
|
245 }); |
|
246 }); |
|
247 }); |
|
248 |
|
249 tasks.push(function testRegisterDataWhileDataEnabled() { |
|
250 log("Set data registration home while data enabled."); |
|
251 |
|
252 // When data registration is registered, data call will be |
|
253 // (re)activated by gecko if ril.data.enabled is set to true. |
|
254 sendCmdToEmulator("gsm data home", function() { |
|
255 connection.addEventListener("datachange", function ondatachange() { |
|
256 connection.removeEventListener("datachange", ondatachange); |
|
257 log("mobileConnection.data.state is now '" |
|
258 + connection.data.state + "'."); |
|
259 is(connection.data.state, "registered", "data.state"); |
|
260 |
|
261 connection.addEventListener("datachange", function ondatachange() { |
|
262 connection.removeEventListener("datachange", ondatachange); |
|
263 log("mobileConnection.data.connected is now '" |
|
264 + connection.data.connected + "'."); |
|
265 is(connection.data.connected, true, "data.connected"); |
|
266 tasks.next(); |
|
267 }); |
|
268 }); |
|
269 }); |
|
270 }); |
|
271 |
|
272 tasks.push(function testDisableDataRoamingWhileRoaming() { |
|
273 log("Disable data roaming while roaming."); |
|
274 |
|
275 setSetting(DATA_ROAMING_KEY, false); |
|
276 |
|
277 // Wait for roaming state to change, then data connection should |
|
278 // be disconnected due to data roaming set to off. |
|
279 setEmulatorRoaming(true, function() { |
|
280 connection.addEventListener("datachange", function ondatachange() { |
|
281 connection.removeEventListener("datachange", ondatachange); |
|
282 log("mobileConnection.data.connected is now '" |
|
283 + connection.data.connected + "'."); |
|
284 is(connection.data.connected, false, "data.connected"); |
|
285 tasks.next(); |
|
286 }); |
|
287 }); |
|
288 }); |
|
289 |
|
290 tasks.push(function testEnableDataRoamingWhileRoaming() { |
|
291 log("Enable data roaming while roaming."); |
|
292 |
|
293 // Data should be re-connected as we enabled data roaming. |
|
294 connection.addEventListener("datachange", function ondatachange() { |
|
295 connection.removeEventListener("datachange", ondatachange); |
|
296 log("mobileConnection.data.connected is now '" |
|
297 + connection.data.connected + "'."); |
|
298 is(connection.data.connected, true, "data.connected"); |
|
299 tasks.next(); |
|
300 }); |
|
301 |
|
302 setSetting(DATA_ROAMING_KEY, true); |
|
303 }); |
|
304 |
|
305 tasks.push(function testDisableDataRoamingWhileNotRoaming() { |
|
306 log("Disable data roaming while not roaming."); |
|
307 |
|
308 // Wait for roaming state to change then set data roaming back |
|
309 // to off. |
|
310 setEmulatorRoaming(false, function() { |
|
311 setSetting(DATA_ROAMING_KEY, false); |
|
312 |
|
313 // No change event will be received cause data connection state |
|
314 // remains the same. |
|
315 window.setTimeout(function() { |
|
316 is(connection.data.connected, true, "data.connected"); |
|
317 tasks.next(); |
|
318 }, 1000); |
|
319 }); |
|
320 }); |
|
321 |
|
322 tasks.push(function testDisableData() { |
|
323 log("Turn data off."); |
|
324 |
|
325 connection.addEventListener("datachange", function ondatachange() { |
|
326 connection.removeEventListener("datachange", ondatachange); |
|
327 log("mobileConnection.data.connected is now '" |
|
328 + connection.data.connected + "'."); |
|
329 is(connection.data.connected, false, "data.connected"); |
|
330 tasks.next(); |
|
331 }); |
|
332 |
|
333 setSetting(DATA_KEY, false); |
|
334 }); |
|
335 |
|
336 // WARNING: All tasks should be pushed before this!!! |
|
337 tasks.push(function cleanUp() { |
|
338 if (pendingEmulatorCmdCount) { |
|
339 window.setTimeout(cleanUp, 100); |
|
340 return; |
|
341 } |
|
342 |
|
343 SpecialPowers.removePermission("mobileconnection", document); |
|
344 SpecialPowers.removePermission("settings-write", document); |
|
345 SpecialPowers.removePermission("settings-read", document); |
|
346 SpecialPowers.clearUserPref("dom.mozSettings.enabled"); |
|
347 finish(); |
|
348 }); |
|
349 |
|
350 tasks.run(); |
|
351 |