blob: 75ff64b96d9e9904d58e3eb7db1ef6eda56e9ff9 [file] [log] [blame]
Pratik Sheth59913862021-02-26 12:30:25 -08001#!/usr/bin/env python3
2#
3# Copyright 2021 - Google
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import time
18
19from acts import signals
20from acts_contrib.test_utils.tel.tel_defines import CALL_CAPABILITY_MANAGE_CONFERENCE
21from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_CONFERENCE
22from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE
Pratik Sheth07796402021-03-03 17:44:48 -080023from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING
Pratik Sheth59913862021-02-26 12:30:25 -080024from acts_contrib.test_utils.tel.tel_defines import PHONE_TYPE_GSM
25from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
26from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
27from acts_contrib.test_utils.tel.tel_test_utils import get_call_uri
28from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
29from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
30from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
31from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
32from acts_contrib.test_utils.tel.tel_voice_utils import get_cep_conference_call_id
33from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
34from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_wcdma
35from acts_contrib.test_utils.tel.tel_test_utils import is_uri_equivalent
36from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
37from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
38from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
39from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
40
41
42def _three_phone_call_mo_add_mo(log, ads, phone_setups, verify_funcs):
43 """Use 3 phones to make MO calls.
44
45 Call from PhoneA to PhoneB, accept on PhoneB.
46 Call from PhoneA to PhoneC, accept on PhoneC.
47
48 Args:
49 ads: list of ad object.
50 The list should have three objects.
51 phone_setups: list of phone setup functions.
52 The list should have three objects.
53 verify_funcs: list of phone call verify functions.
54 The list should have three objects.
55
56 Returns:
57 If success, return 'call_AB' id in PhoneA.
58 if fail, return None.
59 """
60
61 class _CallException(Exception):
62 pass
63
64 try:
65 verify_func_a, verify_func_b, verify_func_c = verify_funcs
66 tasks = []
67 for ad, setup_func in zip(ads, phone_setups):
68 if setup_func is not None:
69 tasks.append((setup_func, (log, ad)))
70 if tasks != [] and not multithread_func(log, tasks):
71 log.error("Phone Failed to Set Up Properly.")
72 raise _CallException("Setup failed.")
73 for ad in ads:
74 ad.droid.telecomCallClearCallList()
75 if num_active_calls(log, ad) != 0:
76 ad.log.error("Phone Call List is not empty.")
77 raise _CallException("Clear call list failed.")
78
79 log.info("Step1: Call From PhoneA to PhoneB.")
80 if not call_setup_teardown(
81 log,
82 ads[0],
83 ads[1],
84 ad_hangup=None,
85 verify_caller_func=verify_func_a,
86 verify_callee_func=verify_func_b):
87 raise _CallException("PhoneA call PhoneB failed.")
88
89 calls = ads[0].droid.telecomCallGetCallIds()
90 ads[0].log.info("Calls in PhoneA %s", calls)
91 if num_active_calls(log, ads[0]) != 1:
92 raise _CallException("Call list verify failed.")
93 call_ab_id = calls[0]
94
95 log.info("Step2: Call From PhoneA to PhoneC.")
96 if not call_setup_teardown(
97 log,
98 ads[0],
99 ads[2],
100 ad_hangup=None,
101 verify_caller_func=verify_func_a,
102 verify_callee_func=verify_func_c):
103 raise _CallException("PhoneA call PhoneC failed.")
104 if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
105 True):
106 raise _CallException("Not All phones are in-call.")
107
108 except _CallException:
109 return None
110
111 return call_ab_id
112
113
114def _test_call_mo_mo_add_swap_x(log,
115 ads,
116 num_swaps,
117 phone_setup_a=None,
118 phone_setup_b=None,
119 phone_setup_c=None,
120 verify_phone_a_network_subscription=None,
121 verify_phone_b_network_subscription=None,
122 verify_phone_c_network_subscription=None):
123 """Test swap feature in VoLTE call.
124
125 PhoneA call PhoneB , accept on PhoneB.
126 PhoneA call PhoneC , accept on PhoneC.
127 Swap active call on PhoneA.(N times)
128
129 Args:
130 num_swaps: do swap for 'num_swaps' times.
131 This value can be 0 (no swap operation).
132
133 Returns:
134 call_ab_id, call_ac_id if succeed;
135 None, None if failed.
136
137 """
138 if ((phone_setup_a == phone_setup_voice_3g) or (phone_setup_a == phone_setup_voice_2g)):
139 # make sure PhoneA is GSM phone before proceed.
140 if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
141 raise signals.TestSkip("not GSM phone, abort swap test.")
142
143 if (((phone_setup_b == phone_setup_voice_3g)
144 and (phone_setup_c == phone_setup_voice_3g)) or
145 ((phone_setup_b == phone_setup_voice_2g)
146 and (phone_setup_c == phone_setup_voice_2g))):
147 # make sure PhoneB and PhoneC are GSM phone before proceed.
148 for ad in [ads[1], ads[2]]:
149 if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
150 raise signals.TestSkip("not GSM phone, abort swap test.")
151
152 call_ab_id = _three_phone_call_mo_add_mo(log,
153 [ads[0], ads[1], ads[2]],
154 [phone_setup_a, phone_setup_b, phone_setup_c], [
155 verify_phone_a_network_subscription, verify_phone_b_network_subscription,
156 verify_phone_c_network_subscription
157 ])
158 if call_ab_id is None:
159 log.error("Failed to get call_ab_id")
160 return None, None
161
162 calls = ads[0].droid.telecomCallGetCallIds()
163 ads[0].log.info("Calls in PhoneA %s", calls)
164 if num_active_calls(log, ads[0]) != 2:
165 return None, None
166 if calls[0] == call_ab_id:
167 call_ac_id = calls[1]
168 else:
169 call_ac_id = calls[0]
170
171 if num_swaps > 0:
172 log.info("Step3: Begin Swap x%s test.", num_swaps)
173 if not swap_calls(log, ads, call_ab_id, call_ac_id,
174 num_swaps):
175 log.error("Swap test failed.")
176 return None, None
177
178 return call_ab_id, call_ac_id
179
180
181def _merge_ims_conference_call(log, ads, call_ab_id, call_ac_id):
182 """Merge IMS conference call for both cases of CEP enabled and disabled.
183
184 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
185 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
186 Merge calls to conference on PhoneA.
187
188 Args:
189 call_ab_id: call id for call_AB on PhoneA.
190 call_ac_id: call id for call_AC on PhoneA.
191
192 Returns:
193 call_id for conference
194 """
195
196 log.info("Step4: Merge to Conf Call and verify Conf Call.")
197 ads[0].droid.telecomCallJoinCallsInConf(call_ab_id, call_ac_id)
198 time.sleep(WAIT_TIME_IN_CALL)
199 calls = ads[0].droid.telecomCallGetCallIds()
200 ads[0].log.info("Calls in PhoneA %s", calls)
201
202 call_conf_id = None
203 if num_active_calls(log, ads[0]) != 1:
204 ads[0].log.info("Total number of call ids is not 1.")
205 call_conf_id = get_cep_conference_call_id(ads[0])
206 if call_conf_id is not None:
207 log.info("New conference call id is found. CEP enabled.")
208 calls.remove(call_conf_id)
209 if (set(ads[0].droid.telecomCallGetCallChildren(
210 call_conf_id)) != set(calls)):
211 ads[0].log.error(
212 "Children list %s for conference call is not correct.",
213 ads[0].droid.telecomCallGetCallChildren(call_conf_id))
214 return None
215
216 if (CALL_PROPERTY_CONFERENCE not in ads[0]
217 .droid.telecomCallGetProperties(call_conf_id)):
218 ads[0].log.error("Conf call id % properties wrong: %s", call_conf_id,
219 ads[0].droid.telecomCallGetProperties(call_conf_id))
220 return None
221
222 if (CALL_CAPABILITY_MANAGE_CONFERENCE not in ads[0]
223 .droid.telecomCallGetCapabilities(call_conf_id)):
224 ads[0].log.error(
225 "Conf call id %s capabilities wrong: %s", call_conf_id,
226 ads[0].droid.telecomCallGetCapabilities(call_conf_id))
227 return None
228
229 if (call_ab_id in calls) or (call_ac_id in calls):
230 log.error("Previous call ids should not in new call"
231 " list after merge.")
232 return None
233 else:
234 for call_id in calls:
235 if call_id != call_ab_id and call_id != call_ac_id:
236 call_conf_id = call_id
237 log.info("CEP not enabled.")
238
239 if not call_conf_id:
240 log.error("Merge call fail, no new conference call id.")
241 raise signals.TestFailure(
242 "Calls were not merged. Failed to merge calls.",
243 extras={"fail_reason": "Calls were not merged."
244 " Failed to merge calls."})
245 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], True):
246 return False
247
248 # Check if Conf Call is currently active
249 if ads[0].droid.telecomCallGetCallState(
250 call_conf_id) != CALL_STATE_ACTIVE:
251 ads[0].log.error(
252 "Call_ID: %s, state: %s, expected: STATE_ACTIVE", call_conf_id,
253 ads[0].droid.telecomCallGetCallState(call_conf_id))
254 return None
255
256 return call_conf_id
257
258
259def _hangup_call(log, ad, device_description='Device'):
260 if not hangup_call(log, ad):
261 ad.log.error("Failed to hang up on %s", device_description)
262 return False
263 return True
264
265
266def _test_ims_conference_merge_drop_second_call_from_participant(
267 log, ads, call_ab_id, call_ac_id):
268 """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
269 (CEP enabled).
270
271 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
272 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
273 Merge calls to conference on PhoneA (CEP enabled IMS conference).
274 Hangup on PhoneC, check call continues between AB.
275 Hangup on PhoneB, check A ends.
276
277 Args:
278 call_ab_id: call id for call_AB on PhoneA.
279 call_ac_id: call id for call_AC on PhoneA.
280
281 Returns:
282 True if succeed;
283 False if failed.
284 """
285
286 call_conf_id = _merge_ims_conference_call(log, ads, call_ab_id, call_ac_id)
287 if call_conf_id is None:
288 return False
289
290 log.info("Step5: End call on PhoneC and verify call continues.")
291 if not _hangup_call(log, ads[2], "PhoneC"):
292 return False
293 time.sleep(WAIT_TIME_IN_CALL)
294 calls = ads[0].droid.telecomCallGetCallIds()
295 ads[0].log.info("Calls in PhoneA %s", calls)
296 if not verify_incall_state(log, [ads[0], ads[1]], True):
297 return False
298 if not verify_incall_state(log, [ads[2]], False):
299 return False
300
301 log.info("Step6: End call on PhoneB and verify PhoneA end.")
302 if not _hangup_call(log, ads[1], "PhoneB"):
303 return False
304 time.sleep(WAIT_TIME_IN_CALL)
305 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], False):
306 return False
307 return True
308
309
310def _test_ims_conference_merge_drop_second_call_from_host(
311 log, ads, call_ab_id, call_ac_id):
312 """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
313 (CEP enabled).
314
315 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
316 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
317 Merge calls to conference on PhoneA (CEP enabled IMS conference).
318 On PhoneA, disconnect call between A-C, verify PhoneA PhoneB still in call.
319 On PhoneA, disconnect call between A-B, verify PhoneA PhoneB disconnected.
320
321 Args:
322 call_ab_id: call id for call_AB on PhoneA.
323 call_ac_id: call id for call_AC on PhoneA.
324
325 Returns:
326 True if succeed;
327 False if failed.
328 """
329 call_ab_uri = get_call_uri(ads[0], call_ab_id)
330 call_ac_uri = get_call_uri(ads[0], call_ac_id)
331
332 call_conf_id = _merge_ims_conference_call(log, ads, call_ab_id, call_ac_id)
333 if call_conf_id is None:
334 return False
335
336 calls = ads[0].droid.telecomCallGetCallIds()
337 calls.remove(call_conf_id)
338
339 log.info("Step5: Disconnect call A-C and verify call continues.")
340 call_to_disconnect = None
341 for call in calls:
342 if is_uri_equivalent(call_ac_uri, get_call_uri(ads[0], call)):
343 call_to_disconnect = call
344 calls.remove(call_to_disconnect)
345 break
346 if call_to_disconnect is None:
347 log.error("Can NOT find call on host represents A-C.")
348 return False
349 else:
350 ads[0].droid.telecomCallDisconnect(call_to_disconnect)
351 time.sleep(WAIT_TIME_IN_CALL)
352 if not verify_incall_state(log, [ads[0], ads[1]], True):
353 return False
354 if not verify_incall_state(log, [ads[2]], False):
355 return False
356
357 log.info(
358 "Step6: Disconnect call A-B and verify PhoneA PhoneB end.")
359 calls = ads[0].droid.telecomCallGetCallIds()
360 call_to_disconnect = None
361 for call in calls:
362 if is_uri_equivalent(call_ab_uri, get_call_uri(ads[0], call)):
363 call_to_disconnect = call
364 calls.remove(call_to_disconnect)
365 break
366 if call_to_disconnect is None:
367 log.error("Can NOT find call on host represents A-B.")
368 return False
369 else:
370 ads[0].droid.telecomCallDisconnect(call_to_disconnect)
371 time.sleep(WAIT_TIME_IN_CALL)
372 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], False):
373 return False
374 return True
375
376
377def _test_ims_conference_merge_drop_first_call_from_participant(
378 log, ads, call_ab_id, call_ac_id):
379 """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
380 (CEP enabled).
381
382 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
383 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
384 Merge calls to conference on PhoneA (CEP enabled IMS conference).
385 Hangup on PhoneB, check call continues between AC.
386 Hangup on PhoneC, check A ends.
387
388 Args:
389 call_ab_id: call id for call_AB on PhoneA.
390 call_ac_id: call id for call_AC on PhoneA.
391
392 Returns:
393 True if succeed;
394 False if failed.
395 """
396 call_conf_id = _merge_ims_conference_call(log, ads, call_ab_id, call_ac_id)
397 if call_conf_id is None:
398 return False
399
400 log.info("Step5: End call on PhoneB and verify call continues.")
401 if not _hangup_call(log, ads[1], "PhoneB"):
402 return False
403 time.sleep(WAIT_TIME_IN_CALL)
404 if not verify_incall_state(log, [ads[0], ads[2]], True):
405 return False
406 if not verify_incall_state(log, [ads[1]], False):
407 return False
408
409 log.info("Step6: End call on PhoneC and verify PhoneA end.")
410 if not _hangup_call(log, ads[2], "PhoneC"):
411 return False
412 time.sleep(WAIT_TIME_IN_CALL)
413 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], False):
414 return False
415 return True
416
417
418def _test_ims_conference_merge_drop_first_call_from_host(
419 log, ads, call_ab_id, call_ac_id):
420 """Test conference merge and drop in IMS (VoLTE or WiFi Calling) call.
421 (CEP enabled).
422
423 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneB.
424 PhoneA in IMS (VoLTE or WiFi Calling) call with PhoneC.
425 Merge calls to conference on PhoneA (CEP enabled IMS conference).
426 On PhoneA, disconnect call between A-B, verify PhoneA PhoneC still in call.
427 On PhoneA, disconnect call between A-C, verify PhoneA PhoneC disconnected.
428
429 Args:
430 call_ab_id: call id for call_AB on PhoneA.
431 call_ac_id: call id for call_AC on PhoneA.
432
433 Returns:
434 True if succeed;
435 False if failed.
436 """
437 call_ab_uri = get_call_uri(ads[0], call_ab_id)
438 call_ac_uri = get_call_uri(ads[0], call_ac_id)
439
440 call_conf_id = _merge_ims_conference_call(log, ads, call_ab_id, call_ac_id)
441 if call_conf_id is None:
442 return False
443
444 calls = ads[0].droid.telecomCallGetCallIds()
445 calls.remove(call_conf_id)
446
447 log.info("Step5: Disconnect call A-B and verify call continues.")
448 call_to_disconnect = None
449 for call in calls:
450 if is_uri_equivalent(call_ab_uri, get_call_uri(ads[0], call)):
451 call_to_disconnect = call
452 calls.remove(call_to_disconnect)
453 break
454 if call_to_disconnect is None:
455 log.error("Can NOT find call on host represents A-B.")
456 return False
457 else:
458 ads[0].droid.telecomCallDisconnect(call_to_disconnect)
459 time.sleep(WAIT_TIME_IN_CALL)
460 if not verify_incall_state(log, [ads[0], ads[2]], True):
461 return False
462 if not verify_incall_state(log, [ads[1]], False):
463 return False
464
465 log.info(
466 "Step6: Disconnect call A-C and verify PhoneA PhoneC end.")
467 calls = ads[0].droid.telecomCallGetCallIds()
468 call_to_disconnect = None
469 for call in calls:
470 if is_uri_equivalent(call_ac_uri, get_call_uri(ads[0], call)):
471 call_to_disconnect = call
472 calls.remove(call_to_disconnect)
473 break
474 if call_to_disconnect is None:
475 log.error("Can NOT find call on host represents A-C.")
476 return False
477 else:
478 ads[0].droid.telecomCallDisconnect(call_to_disconnect)
479 time.sleep(WAIT_TIME_IN_CALL)
480 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], False):
481 return False
482 return True
483
484
485def _three_phone_call_mo_add_mt(log, ads, phone_setups, verify_funcs):
486 """Use 3 phones to make MO call and MT call.
487
488 Call from PhoneA to PhoneB, accept on PhoneB.
489 Call from PhoneC to PhoneA, accept on PhoneA.
490
491 Args:
492 ads: list of ad object.
493 The list should have three objects.
494 phone_setups: list of phone setup functions.
495 The list should have three objects.
496 verify_funcs: list of phone call verify functions.
497 The list should have three objects.
498
499 Returns:
500 If success, return 'call_AB' id in PhoneA.
501 if fail, return None.
502 """
503
504 class _CallException(Exception):
505 pass
506
507 try:
508 verify_func_a, verify_func_b, verify_func_c = verify_funcs
509 tasks = []
510 for ad, setup_func in zip(ads, phone_setups):
511 if setup_func is not None:
512 tasks.append((setup_func, (log, ad)))
513 if tasks != [] and not multithread_func(log, tasks):
514 log.error("Phone Failed to Set Up Properly.")
515 raise _CallException("Setup failed.")
516 for ad in ads:
517 ad.droid.telecomCallClearCallList()
518 if num_active_calls(log, ad) != 0:
519 ad.log.error("Phone Call List is not empty.")
520 raise _CallException("Clear call list failed.")
521
522 log.info("Step1: Call From PhoneA to PhoneB.")
523 if not call_setup_teardown(
524 log,
525 ads[0],
526 ads[1],
527 ad_hangup=None,
528 verify_caller_func=verify_func_a,
529 verify_callee_func=verify_func_b):
530 raise _CallException("PhoneA call PhoneB failed.")
531
532 calls = ads[0].droid.telecomCallGetCallIds()
533 ads[0].log.info("Calls in PhoneA %s", calls)
534 if num_active_calls(log, ads[0]) != 1:
535 raise _CallException("Call list verify failed.")
536 call_ab_id = calls[0]
537
538 log.info("Step2: Call From PhoneC to PhoneA.")
539 if not call_setup_teardown(
540 log,
541 ads[2],
542 ads[0],
543 ad_hangup=None,
544 verify_caller_func=verify_func_c,
545 verify_callee_func=verify_func_a):
546 raise _CallException("PhoneA call PhoneC failed.")
547 if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
548 True):
549 raise _CallException("Not All phones are in-call.")
550
551 except _CallException:
552 return None
553 return call_ab_id
554
555
556def _test_call_mo_mt_add_swap_x(log,
557 ads,
558 num_swaps,
559 phone_setup_a=None,
560 phone_setup_b=None,
561 phone_setup_c=None,
562 verify_phone_a_network_subscription=None,
563 verify_phone_b_network_subscription=None,
564 verify_phone_c_network_subscription=None):
565 """Test swap feature in VoLTE call.
566
567 PhoneA call PhoneB, accept on PhoneB.
568 PhoneC call PhoneA, accept on PhoneA.
569 Swap active call on PhoneA. (N times)
570
571 Args:
572 num_swaps: do swap for 'num_swaps' times.
573 This value can be 0 (no swap operation).
574
575 Returns:
576 call_ab_id, call_ac_id if succeed;
577 None, None if failed.
578
579 """
580 if ((phone_setup_a == phone_setup_voice_3g) or (phone_setup_a == phone_setup_voice_2g)):
581 # make sure PhoneA is GSM phone before proceed.
582 if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
583 raise signals.TestSkip("not GSM phone, abort swap test.")
584
585 if (((phone_setup_b == phone_setup_voice_3g)
586 and (phone_setup_c == phone_setup_voice_3g)) or
587 ((phone_setup_b == phone_setup_voice_2g)
588 and (phone_setup_c == phone_setup_voice_2g))):
589 # make sure PhoneB and PhoneC are GSM phone before proceed.
590 for ad in [ads[1], ads[2]]:
591 if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
592 raise signals.TestSkip("not GSM phone, abort swap test.")
593
594 call_ab_id = _three_phone_call_mo_add_mt(log,
595 [ads[0], ads[1], ads[2]],
596 [phone_setup_a, phone_setup_b, phone_setup_c], [
597 verify_phone_a_network_subscription, verify_phone_b_network_subscription,
598 verify_phone_c_network_subscription
599 ])
600 if call_ab_id is None:
601 log.error("Failed to get call_ab_id")
602 return None, None
603
604 calls = ads[0].droid.telecomCallGetCallIds()
605 ads[0].log.info("Calls in PhoneA %s", calls)
606 if num_active_calls(log, ads[0]) != 2:
607 return None, None
608 if calls[0] == call_ab_id:
609 call_ac_id = calls[1]
610 else:
611 call_ac_id = calls[0]
612
613 if num_swaps > 0:
614 log.info("Step3: Begin Swap x%s test.", num_swaps)
615 if not swap_calls(log, ads, call_ab_id, call_ac_id,
616 num_swaps):
617 log.error("Swap test failed.")
618 return None, None
619
620 return call_ab_id, call_ac_id
621
622
623def _three_phone_call_mt_add_mt(log, ads, phone_setups, verify_funcs):
624 """Use 3 phones to make MT call and MT call.
625
626 Call from PhoneB to PhoneA, accept on PhoneA.
627 Call from PhoneC to PhoneA, accept on PhoneA.
628
629 Args:
630 ads: list of ad object.
631 The list should have three objects.
632 phone_setups: list of phone setup functions.
633 The list should have three objects.
634 verify_funcs: list of phone call verify functions.
635 The list should have three objects.
636
637 Returns:
638 If success, return 'call_AB' id in PhoneA.
639 if fail, return None.
640 """
641
642 class _CallException(Exception):
643 pass
644
645 try:
646 verify_func_a, verify_func_b, verify_func_c = verify_funcs
647 tasks = []
648 for ad, setup_func in zip(ads, phone_setups):
649 if setup_func is not None:
650 tasks.append((setup_func, (log, ad)))
651 if tasks != [] and not multithread_func(log, tasks):
652 log.error("Phone Failed to Set Up Properly.")
653 raise _CallException("Setup failed.")
654 for ad in ads:
655 ad.droid.telecomCallClearCallList()
656 if num_active_calls(log, ad) != 0:
657 ad.log.error("Phone Call List is not empty.")
658 raise _CallException("Clear call list failed.")
659
660 log.info("Step1: Call From PhoneB to PhoneA.")
661 if not call_setup_teardown(
662 log,
663 ads[1],
664 ads[0],
665 ad_hangup=None,
666 verify_caller_func=verify_func_b,
667 verify_callee_func=verify_func_a):
668 raise _CallException("PhoneB call PhoneA failed.")
669
670 calls = ads[0].droid.telecomCallGetCallIds()
671 ads[0].log.info("Calls in PhoneA %s", calls)
672 if num_active_calls(log, ads[0]) != 1:
673 raise _CallException("Call list verify failed.")
674 call_ab_id = calls[0]
675
676 log.info("Step2: Call From PhoneC to PhoneA.")
677 if not call_setup_teardown(
678 log,
679 ads[2],
680 ads[0],
681 ad_hangup=None,
682 verify_caller_func=verify_func_c,
683 verify_callee_func=verify_func_a):
684 raise _CallException("PhoneA call PhoneC failed.")
685 if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
686 True):
687 raise _CallException("Not All phones are in-call.")
688
689 except _CallException:
690 return None
691
692 return call_ab_id
693
694
695def _test_call_mt_mt_add_swap_x(log,
696 ads,
697 num_swaps,
698 phone_setup_a=None,
699 phone_setup_b=None,
700 phone_setup_c=None,
701 verify_phone_a_network_subscription=None,
702 verify_phone_b_network_subscription=None,
703 verify_phone_c_network_subscription=None):
704 """Test swap feature in VoLTE call.
705
706 PhoneB call PhoneA, accept on PhoneA.
707 PhoneC call PhoneA, accept on PhoneA.
708 Swap active call on PhoneA. (N times)
709
710 Args:
711 num_swaps: do swap for 'num_swaps' times.
712 This value can be 0 (no swap operation).
713
714 Returns:
715 call_ab_id, call_ac_id if succeed;
716 None, None if failed.
717
718 """
719 if ((phone_setup_a == phone_setup_voice_3g) or (phone_setup_a == phone_setup_voice_2g)):
720 # make sure PhoneA is GSM phone before proceeSSd.
721 if (ads[0].droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
722 raise signals.TestSkip("not GSM phone, abort swap test.")
723
724 if (((phone_setup_b == phone_setup_voice_3g)
725 and (phone_setup_c == phone_setup_voice_3g)) or
726 ((phone_setup_b == phone_setup_voice_2g)
727 and (phone_setup_c == phone_setup_voice_2g))):
728 # make sure PhoneB and PhoneC are GSM phone before proceed.
729 for ad in [ads[1], ads[2]]:
730 if (ad.droid.telephonyGetPhoneType() != PHONE_TYPE_GSM):
731 raise signals.TestSkip("not GSM phone, abort swap test.")
732
733 call_ab_id = _three_phone_call_mt_add_mt(log,
734 [ads[0], ads[1], ads[2]],
735 [phone_setup_a, phone_setup_b, phone_setup_c], [
736 verify_phone_a_network_subscription, verify_phone_b_network_subscription,
737 verify_phone_c_network_subscription
738 ])
739 if call_ab_id is None:
740 log.error("Failed to get call_ab_id")
741 return None, None
742
743 calls = ads[0].droid.telecomCallGetCallIds()
744 ads[0].log.info("Calls in PhoneA %s", calls)
745 if num_active_calls(log, ads[0]) != 2:
746 return None, None
747 if calls[0] == call_ab_id:
748 call_ac_id = calls[1]
749 else:
750 call_ac_id = calls[0]
751
752 if num_swaps > 0:
753 log.info("Step3: Begin Swap x%s test.", num_swaps)
754 if not swap_calls(log, ads, call_ab_id, call_ac_id,
755 num_swaps):
756 log.error("Swap test failed.")
757 return None, None
758
759 return call_ab_id, call_ac_id
760
761
Pratik Sheth07796402021-03-03 17:44:48 -0800762def _three_phone_hangup_call_verify_call_state(
763 log, ad_hangup, ad_verify, call_id, call_state, ads_active):
764 """Private Test utility for swap test.
765
766 Hangup on 'ad_hangup'.
767 Verify 'call_id' on 'ad_verify' is in expected 'call_state'
768 Verify each ad in ads_active are 'in-call'.
769
770 Args:
771 ad_hangup: android object to hangup call.
772 ad_verify: android object to verify call id state.
773 call_id: call id in 'ad_verify'.
774 call_state: expected state for 'call_id'.
775 'call_state' is either CALL_STATE_HOLDING or CALL_STATE_ACTIVE.
776 ads_active: list of android object.
777 Each one of them should be 'in-call' after 'hangup' operation.
778
779 Returns:
780 True if no error happened. Otherwise False.
781
782 """
783
784 ad_hangup.log.info("Hangup, verify call continues.")
785 if not _hangup_call(log, ad_hangup):
786 ad_hangup.log.error("Phone fails to hang up")
787 return False
788 time.sleep(WAIT_TIME_IN_CALL)
789
790 if ad_verify.droid.telecomCallGetCallState(call_id) != call_state:
791 ad_verify.log.error(
792 "Call_id: %s, state: %s, expected: %s", call_id,
793 ad_verify.droid.telecomCallGetCallState(call_id), call_state)
794 return False
795 ad_verify.log.info("Call in expected %s state", call_state)
796
797 if not verify_incall_state(log, ads_active, True):
798 ads_active.log.error("Phone not in call state")
799 return False
800 if not verify_incall_state(log, [ad_hangup], False):
801 ad_hangup.log.error("Phone not in hangup state")
802 return False
803
804 return True
805
806
807def _get_expected_call_state(ad):
808 if "vzw" in [
809 sub["operator"]
810 for sub in ad.telephony["subscription"].values()
811 ]:
812 return CALL_STATE_ACTIVE
813 return CALL_STATE_HOLDING
814
815