|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 MARIONETTE_TIMEOUT = 60000; |
|
5 MARIONETTE_HEAD_JS = 'head.js'; |
|
6 |
|
7 let outNumber = "5555551111"; |
|
8 let inNumber = "5555552222"; |
|
9 let outgoingCall; |
|
10 let incomingCall; |
|
11 let gotOriginalConnected = false; |
|
12 let gotHeld = false; |
|
13 let gotConnected = false; |
|
14 |
|
15 function dial() { |
|
16 log("Make an outgoing call."); |
|
17 telephony.dial(outNumber).then(call => { |
|
18 outgoingCall = call; |
|
19 ok(outgoingCall); |
|
20 is(outgoingCall.number, outNumber); |
|
21 is(outgoingCall.state, "dialing"); |
|
22 |
|
23 outgoingCall.onalerting = function onalerting(event) { |
|
24 log("Received 'alerting' call event."); |
|
25 |
|
26 is(outgoingCall, event.call); |
|
27 is(outgoingCall.state, "alerting"); |
|
28 is(outgoingCall, telephony.active); |
|
29 is(telephony.calls.length, 1); |
|
30 is(telephony.calls[0], outgoingCall); |
|
31 |
|
32 emulator.run("gsm list", function(result) { |
|
33 log("Call list is now: " + result); |
|
34 is(result[0], "outbound to " + outNumber + " : ringing"); |
|
35 is(result[1], "OK"); |
|
36 answer(); |
|
37 }); |
|
38 }; |
|
39 }); |
|
40 } |
|
41 |
|
42 function answer() { |
|
43 log("Answering the outgoing call."); |
|
44 |
|
45 // We get no "connecting" event when the remote party answers the call. |
|
46 outgoingCall.onconnected = function onconnectedOut(event) { |
|
47 log("Received 'connected' call event for the original outgoing call."); |
|
48 |
|
49 is(outgoingCall, event.call); |
|
50 is(outgoingCall.state, "connected"); |
|
51 is(outgoingCall, telephony.active); |
|
52 |
|
53 emulator.run("gsm list", function(result) { |
|
54 log("Call list is now: " + result); |
|
55 is(result[0], "outbound to " + outNumber + " : active"); |
|
56 is(result[1], "OK"); |
|
57 |
|
58 if(!gotOriginalConnected){ |
|
59 gotOriginalConnected = true; |
|
60 holdCall(); |
|
61 } else { |
|
62 // Received connected event for original call multiple times (fail) |
|
63 ok(false, |
|
64 "Received 'connected' event for original call multiple times."); |
|
65 } |
|
66 }); |
|
67 }; |
|
68 emulator.run("gsm accept " + outNumber); |
|
69 } |
|
70 |
|
71 function holdCall() { |
|
72 log("Putting the original (outgoing) call on hold."); |
|
73 |
|
74 let gotHolding = false; |
|
75 outgoingCall.onholding = function onholding(event) { |
|
76 log("Received 'holding' call event"); |
|
77 is(outgoingCall, event.call); |
|
78 is(outgoingCall.state, "holding"); |
|
79 gotHolding = true; |
|
80 }; |
|
81 |
|
82 outgoingCall.onheld = function onheld(event) { |
|
83 log("Received 'held' call event"); |
|
84 is(outgoingCall, event.call); |
|
85 is(outgoingCall.state, "held"); |
|
86 ok(gotHolding); |
|
87 |
|
88 is(telephony.active, null); |
|
89 is(telephony.calls.length, 1); |
|
90 is(telephony.calls[0], outgoingCall); |
|
91 |
|
92 emulator.run("gsm list", function(result) { |
|
93 log("Call list is now: " + result); |
|
94 is(result[0], "outbound to " + outNumber + " : held"); |
|
95 is(result[1], "OK"); |
|
96 simulateIncoming(); |
|
97 }); |
|
98 }; |
|
99 outgoingCall.hold(); |
|
100 } |
|
101 |
|
102 // With one call on hold, simulate an incoming call |
|
103 function simulateIncoming() { |
|
104 log("Simulating an incoming call (with one call already held)."); |
|
105 |
|
106 telephony.onincoming = function onincoming(event) { |
|
107 log("Received 'incoming' call event."); |
|
108 incomingCall = event.call; |
|
109 ok(incomingCall); |
|
110 is(incomingCall.number, inNumber); |
|
111 is(incomingCall.state, "incoming"); |
|
112 |
|
113 // Should be two calls now |
|
114 is(telephony.calls.length, 2); |
|
115 is(telephony.calls[0], outgoingCall); |
|
116 is(telephony.calls[1], incomingCall); |
|
117 |
|
118 emulator.run("gsm list", function(result) { |
|
119 log("Call list is now: " + result); |
|
120 is(result[0], "outbound to " + outNumber + " : held"); |
|
121 is(result[1], "inbound from " + inNumber + " : incoming"); |
|
122 is(result[2], "OK"); |
|
123 answerIncoming(); |
|
124 }); |
|
125 }; |
|
126 emulator.run("gsm call " + inNumber); |
|
127 } |
|
128 |
|
129 // Answer incoming call; original outgoing call should be held |
|
130 function answerIncoming() { |
|
131 log("Answering the incoming call."); |
|
132 |
|
133 let gotConnecting = false; |
|
134 incomingCall.onconnecting = function onconnectingIn(event) { |
|
135 log("Received 'connecting' call event for incoming/2nd call."); |
|
136 is(incomingCall, event.call); |
|
137 is(incomingCall.state, "connecting"); |
|
138 gotConnecting = true; |
|
139 }; |
|
140 |
|
141 incomingCall.onconnected = function onconnectedIn(event) { |
|
142 log("Received 'connected' call event for incoming/2nd call."); |
|
143 is(incomingCall, event.call); |
|
144 ok(gotConnecting); |
|
145 |
|
146 is(incomingCall, telephony.active); |
|
147 |
|
148 // Original outbound call now held, incoming call active |
|
149 is(outgoingCall.state, "held"); |
|
150 is(incomingCall.state, "connected"); |
|
151 |
|
152 emulator.run("gsm list", function(result) { |
|
153 log("Call list is now: " + result); |
|
154 is(result[0], "outbound to " + outNumber + " : held"); |
|
155 is(result[1], "inbound from " + inNumber + " : active"); |
|
156 is(result[2], "OK"); |
|
157 swapCalls(); |
|
158 }); |
|
159 }; |
|
160 incomingCall.answer(); |
|
161 } |
|
162 |
|
163 // Now swap the held and active calls |
|
164 function swapCalls() { |
|
165 log("Swapping the held and active calls."); |
|
166 |
|
167 // Swap calls by resuming the held (outgoing) call. Will force active |
|
168 // (incoming) call to hold. |
|
169 |
|
170 incomingCall.onheld = function onheldIn(event) { |
|
171 log("Received 'held' call event for incoming call."); |
|
172 gotHeld = true; |
|
173 |
|
174 if (gotHeld && gotConnected) { verifySwap(); } |
|
175 }; |
|
176 |
|
177 let gotResuming = false; |
|
178 outgoingCall.onresuming = function onresuming(event) { |
|
179 log("Received 'resuming' call event for outbound call."); |
|
180 is(outgoingCall, event.call); |
|
181 is(outgoingCall.state, "resuming"); |
|
182 gotResuming = true; |
|
183 }; |
|
184 |
|
185 outgoingCall.onconnected = function onconnected(event) { |
|
186 log("Received 'connected' call event for outbound call."); |
|
187 is(outgoingCall, event.call); |
|
188 ok(gotResuming); |
|
189 |
|
190 is(outgoingCall, telephony.active); |
|
191 is(telephony.calls.length, 2); |
|
192 is(telephony.calls[0], outgoingCall); |
|
193 is(telephony.calls[1], incomingCall); |
|
194 gotConnected = true; |
|
195 |
|
196 if (gotHeld && gotConnected) { verifySwap(); } |
|
197 }; |
|
198 outgoingCall.resume(); |
|
199 } |
|
200 |
|
201 function verifySwap() { |
|
202 // Call status reflects swap |
|
203 is(outgoingCall.state, "connected"); |
|
204 is(incomingCall.state, "held"); |
|
205 |
|
206 emulator.run("gsm list", function(result) { |
|
207 log("Call list is now: " + result); |
|
208 is(result[0], "outbound to " + outNumber + " : active"); |
|
209 is(result[1], "inbound from " + inNumber + " : held"); |
|
210 |
|
211 // Begin hang-up |
|
212 hangUpOutgoing(); |
|
213 }); |
|
214 } |
|
215 |
|
216 // Hang-up original outgoing (now active) call |
|
217 function hangUpOutgoing() { |
|
218 log("Hanging up the original outgoing (now active) call."); |
|
219 |
|
220 let gotDisconnecting = false; |
|
221 outgoingCall.ondisconnecting = function ondisconnectingOut(event) { |
|
222 log("Received 'disconnecting' call event for original outgoing call."); |
|
223 is(outgoingCall, event.call); |
|
224 is(outgoingCall.state, "disconnecting"); |
|
225 gotDisconnecting = true; |
|
226 }; |
|
227 |
|
228 outgoingCall.ondisconnected = function ondisconnectedOut(event) { |
|
229 log("Received 'disconnected' call event for original outgoing call."); |
|
230 is(outgoingCall, event.call); |
|
231 is(outgoingCall.state, "disconnected"); |
|
232 ok(gotDisconnecting); |
|
233 |
|
234 // Back to one call now |
|
235 is(telephony.calls.length, 1); |
|
236 is(incomingCall.state, "held"); |
|
237 |
|
238 emulator.run("gsm list", function(result) { |
|
239 log("Call list is now: " + result); |
|
240 is(result[0], "inbound from " + inNumber + " : held"); |
|
241 is(result[1], "OK"); |
|
242 hangUpIncoming(); |
|
243 }); |
|
244 }; |
|
245 outgoingCall.hangUp(); |
|
246 } |
|
247 |
|
248 // Hang-up remaining (now held) call |
|
249 function hangUpIncoming() { |
|
250 log("Hanging up the remaining (now held) call."); |
|
251 |
|
252 let gotDisconnecting = false; |
|
253 incomingCall.ondisconnecting = function ondisconnectingIn(event) { |
|
254 log("Received 'disconnecting' call event for remaining (held) call."); |
|
255 is(incomingCall, event.call); |
|
256 is(incomingCall.state, "disconnecting"); |
|
257 gotDisconnecting = true; |
|
258 }; |
|
259 |
|
260 incomingCall.ondisconnected = function ondisconnectedIn(event) { |
|
261 log("Received 'disconnected' call event for remaining (incoming) call."); |
|
262 is(incomingCall, event.call); |
|
263 is(incomingCall.state, "disconnected"); |
|
264 ok(gotDisconnecting); |
|
265 |
|
266 // Zero calls left |
|
267 is(telephony.active, null); |
|
268 is(telephony.calls.length, 0); |
|
269 |
|
270 emulator.run("gsm list", function(result) { |
|
271 log("Call list is now: " + result); |
|
272 is(result[0], "OK"); |
|
273 cleanUp(); |
|
274 }); |
|
275 }; |
|
276 incomingCall.hangUp(); |
|
277 } |
|
278 |
|
279 function cleanUp() { |
|
280 telephony.onincoming = null; |
|
281 finish(); |
|
282 } |
|
283 |
|
284 startTest(function() { |
|
285 dial(); |
|
286 }); |