blob: c6fcf0fbebe6ecf6fe59d2f05b1c019ec90df7a1 [file] [log] [blame]
Markus Liue3143912021-03-31 10:49:00 +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 re
Markus Liu481eccd2021-04-21 14:36:15 +080018import time
Markus Liue3143912021-03-31 10:49:00 +080019
Markus Liue3143912021-03-31 10:49:00 +080020from acts import signals
Markus Liufdef3062021-06-27 15:08:29 +080021from acts.utils import rand_ascii_str
Markus Liue3143912021-03-31 10:49:00 +080022from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
23from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
24from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
Markus Liufdef3062021-06-27 15:08:29 +080025from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
26from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
Markus Liu3bedf212021-06-16 17:39:07 +080027from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
Richard Chang8d40b882021-06-28 23:58:51 +080028from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
Markus Liufdef3062021-06-27 15:08:29 +080029from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
Markus Liue3143912021-03-31 10:49:00 +080030from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
Markus Liufdef3062021-06-27 15:08:29 +080031from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
Markus Liue3143912021-03-31 10:49:00 +080032from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
33from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
Markus Liufdef3062021-06-27 15:08:29 +080034from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
35from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
Markus Liue3143912021-03-31 10:49:00 +080036from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_0
37from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot_1
Markus Liufdef3062021-06-27 15:08:29 +080038from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
39from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
40from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id
Markus Liu481eccd2021-04-21 14:36:15 +080041from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
Markus Liu3bedf212021-06-16 17:39:07 +080042from acts_contrib.test_utils.tel.tel_test_utils import ensure_wifi_connected
Markus Liu481eccd2021-04-21 14:36:15 +080043from acts_contrib.test_utils.tel.tel_test_utils import erase_call_forwarding_by_mmi
44from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
Markus Liufdef3062021-06-27 15:08:29 +080045from acts_contrib.test_utils.tel.tel_test_utils import get_slot_index_from_subid
46from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
47from acts_contrib.test_utils.tel.tel_test_utils import initiate_call
48from acts_contrib.test_utils.tel.tel_test_utils import log_messaging_screen_shot
49from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
50from acts_contrib.test_utils.tel.tel_test_utils import mms_send_receive_verify
51from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
Markus Liu3bedf212021-06-16 17:39:07 +080052from acts_contrib.test_utils.tel.tel_test_utils import set_call_forwarding_by_mmi
Markus Liufdef3062021-06-27 15:08:29 +080053from acts_contrib.test_utils.tel.tel_test_utils import set_call_waiting
54from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription
55from acts_contrib.test_utils.tel.tel_test_utils import sms_send_receive_verify_for_subscription
Richard Chang8d40b882021-06-28 23:58:51 +080056from acts_contrib.test_utils.tel.tel_test_utils import start_youtube_video
Markus Liufdef3062021-06-27 15:08:29 +080057from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
58from acts_contrib.test_utils.tel.tel_test_utils import toggle_wfc_for_subscription
59from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
60from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
61from acts_contrib.test_utils.tel.tel_test_utils import wait_and_reject_call_for_subscription
62from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
Markus Liu3bedf212021-06-16 17:39:07 +080063from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
Markus Liue3143912021-03-31 10:49:00 +080064from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_on_rat
Markus Liufdef3062021-06-27 15:08:29 +080065from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
66from acts_contrib.test_utils.tel.tel_voice_utils import three_phone_call_forwarding_short_seq
67from acts_contrib.test_utils.tel.tel_voice_utils import three_phone_call_waiting_short_seq
Markus Liue3143912021-03-31 10:49:00 +080068from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot
Markus Liu481eccd2021-04-21 14:36:15 +080069from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant
70from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_wcdma_conference_merge_drop
Markus Liu3bedf212021-06-16 17:39:07 +080071from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mt
Markus Liue3143912021-03-31 10:49:00 +080072
73CallResult = TelephonyVoiceTestResult.CallResult.Value
74tel_logger = TelephonyMetricLogger.for_test_case()
75
76def dsds_voice_call_test(
77 log,
78 ads,
79 mo_slot,
80 mt_slot,
81 dds,
82 mo_rat=["", ""],
83 mt_rat=["", ""],
84 call_direction="mo"):
85 """Make MO/MT voice call at specific slot in specific RAT with DDS at
86 specific slot.
87
88 Test step:
89 1. Get sub IDs of specific slots of both MO and MT devices.
90 2. Switch DDS to specific slot.
91 3. Check HTTP connection after DDS switch.
92 4. Set up phones in desired RAT.
93 5. Make voice call.
94
95 Args:
96 log: logger object
97 ads: list of android devices
98 mo_slot: Slot making MO call (0 or 1)
99 mt_slot: Slot receiving MT call (0 or 1)
100 dds: Preferred data slot
101 mo_rat: RAT for both slots of MO device
102 mt_rat: RAT for both slots of MT device
103 call_direction: "mo" or "mt"
104
105 Returns:
106 TestFailure if failed.
107 """
108 if call_direction == "mo":
109 ad_mo = ads[0]
110 ad_mt = ads[1]
111 else:
112 ad_mo = ads[1]
113 ad_mt = ads[0]
114
115 if mo_slot is not None:
116 mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot)
117 if mo_sub_id == INVALID_SUB_ID:
118 ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
119 return False
120 mo_other_sub_id = get_subid_from_slot_index(
121 log, ad_mo, 1-mo_slot)
122 set_voice_sub_id(ad_mo, mo_sub_id)
123 else:
124 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
125 if mo_sub_id == INVALID_SUB_ID:
126 ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
127 return False
128 mo_slot = "auto"
129 set_voice_sub_id(ad_mo, mo_sub_id)
130 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s",
131 mo_slot, get_outgoing_voice_sub_id(ad_mo))
132
133 if mt_slot is not None:
134 mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot)
135 if mt_sub_id == INVALID_SUB_ID:
136 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
137 return False
138 mt_other_sub_id = get_subid_from_slot_index(
139 log, ad_mt, 1-mt_slot)
140 set_voice_sub_id(ad_mt, mt_sub_id)
141 else:
142 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
143 if mt_sub_id == INVALID_SUB_ID:
144 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
145 return False
146 mt_slot = "auto"
147 set_voice_sub_id(ad_mt, mt_sub_id)
148 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
149 get_incoming_voice_sub_id(ad_mt))
150
151 log.info("Step 1: Switch DDS.")
Markus Liufdef3062021-06-27 15:08:29 +0800152 if not set_dds_on_slot(ads[0], dds):
153 log.error(
154 "Failed to set DDS at slot %s on %s",(dds, ads[0].serial))
155 return False
Markus Liue3143912021-03-31 10:49:00 +0800156
157 log.info("Step 2: Check HTTP connection after DDS switch.")
Markus Liufdef3062021-06-27 15:08:29 +0800158 if not verify_http_connection(log, ads[0]):
Markus Liue3143912021-03-31 10:49:00 +0800159 log.error("Failed to verify http connection.")
160 return False
161 else:
162 log.info("Verify http connection successfully.")
163
164 if mo_slot == 0 or mo_slot == 1:
165 phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
166 mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
167 is_mo_in_call = is_phone_in_call_on_rat(
168 log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
169 else:
170 mo_phone_setup_func_argv = (log, ad_mo, 'general')
171 is_mo_in_call = is_phone_in_call_on_rat(
172 log, ad_mo, 'general', only_return_fn=True)
173
174 if mt_slot == 0 or mt_slot == 1:
175 phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
176 mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
177 is_mt_in_call = is_phone_in_call_on_rat(
178 log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
179 else:
180 mt_phone_setup_func_argv = (log, ad_mt, 'general')
181 is_mt_in_call = is_phone_in_call_on_rat(
182 log, ad_mt, 'general', only_return_fn=True)
183
184 log.info("Step 3: Set up phones in desired RAT.")
185 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
186 (phone_setup_on_rat, mt_phone_setup_func_argv)]
187 if not multithread_func(log, tasks):
188 log.error("Phone Failed to Set Up Properly.")
189 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
190 raise signals.TestFailure("Failed",
191 extras={"fail_reason": "Phone Failed to Set Up Properly."})
192
193 log.info("Step 4: Make voice call.")
194 result = two_phone_call_msim_for_slot(
195 log,
196 ad_mo,
197 get_slot_index_from_subid(log, ad_mo, mo_sub_id),
198 None,
199 is_mo_in_call,
200 ad_mt,
201 get_slot_index_from_subid(log, ad_mt, mt_sub_id),
202 None,
203 is_mt_in_call)
204
205 tel_logger.set_result(result.result_value)
206
207 if not result:
208 log.error(
209 "Failed to make MO call from %s slot %s to %s slot %s",
210 ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
211 raise signals.TestFailure("Failed",
Markus Liu481eccd2021-04-21 14:36:15 +0800212 extras={"fail_reason": str(result.result_value)})
213
Markus Liufdef3062021-06-27 15:08:29 +0800214def dsds_message_test(
215 log,
216 ads,
217 mo_slot,
218 mt_slot,
219 dds_slot,
220 msg="SMS",
221 mo_rat=["", ""],
222 mt_rat=["", ""],
223 direction="mo",
Richard Chang8d40b882021-06-28 23:58:51 +0800224 streaming=False,
Markus Liufdef3062021-06-27 15:08:29 +0800225 expected_result=True):
226 """Make MO/MT SMS/MMS at specific slot in specific RAT with DDS at
227 specific slot.
228
229 Test step:
230 1. Get sub IDs of specific slots of both MO and MT devices.
231 2. Switch DDS to specific slot.
232 3. Check HTTP connection after DDS switch.
233 4. Set up phones in desired RAT.
234 5. Send SMS/MMS.
235
236 Args:
237 mo_slot: Slot sending MO SMS (0 or 1)
238 mt_slot: Slot receiving MT SMS (0 or 1)
239 dds_slot: Preferred data slot
240 mo_rat: RAT for both slots of MO device
241 mt_rat: RAT for both slots of MT device
242 direction: "mo" or "mt"
Richard Chang8d40b882021-06-28 23:58:51 +0800243 streaming: True for playing Youtube before send/receive SMS/MMS and
244 False on the contrary.
245 expected_result: True or False
Markus Liufdef3062021-06-27 15:08:29 +0800246
247 Returns:
248 TestFailure if failed.
249 """
250 if direction == "mo":
251 ad_mo = ads[0]
252 ad_mt = ads[1]
253 else:
254 ad_mo = ads[1]
255 ad_mt = ads[0]
256
257 if mo_slot is not None:
258 mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot)
259 if mo_sub_id == INVALID_SUB_ID:
260 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
261 return False
262 mo_other_sub_id = get_subid_from_slot_index(
263 log, ad_mo, 1-mo_slot)
264 set_message_subid(ad_mo, mo_sub_id)
265 else:
266 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
267 ads, type="sms")
268 if mo_sub_id == INVALID_SUB_ID:
269 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
270 return False
271 mo_slot = "auto"
272 set_message_subid(ad_mo, mo_sub_id)
273 if msg == "MMS":
274 set_subid_for_data(ad_mo, mo_sub_id)
275 ad_mo.droid.telephonyToggleDataConnection(True)
276 ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot,
277 get_outgoing_message_sub_id(ad_mo))
278
279 if mt_slot is not None:
280 mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot)
281 if mt_sub_id == INVALID_SUB_ID:
282 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
283 return False
284 mt_other_sub_id = get_subid_from_slot_index(log, ad_mt, 1-mt_slot)
285 set_message_subid(ad_mt, mt_sub_id)
286 else:
287 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
288 ads, type="sms")
289 if mt_sub_id == INVALID_SUB_ID:
290 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
291 return False
292 mt_slot = "auto"
293 set_message_subid(ad_mt, mt_sub_id)
294 if msg == "MMS":
295 set_subid_for_data(ad_mt, mt_sub_id)
296 ad_mt.droid.telephonyToggleDataConnection(True)
297 ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot,
298 get_outgoing_message_sub_id(ad_mt))
299
300 log.info("Step 1: Switch DDS.")
301 if not set_dds_on_slot(ads[0], dds_slot):
302 log.error(
303 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
304 return False
305
306 log.info("Step 2: Check HTTP connection after DDS switch.")
307 if not verify_http_connection(log, ads[0]):
308 log.error("Failed to verify http connection.")
309 return False
310 else:
311 log.info("Verify http connection successfully.")
312
313 if mo_slot == 0 or mo_slot == 1:
314 phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
315 mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
316 else:
317 mo_phone_setup_func_argv = (log, ad_mo, 'general', mo_sub_id)
318
319 if mt_slot == 0 or mt_slot == 1:
320 phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
321 mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
322 else:
323 mt_phone_setup_func_argv = (log, ad_mt, 'general', mt_sub_id)
324
325 log.info("Step 3: Set up phones in desired RAT.")
326 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
327 (phone_setup_on_rat, mt_phone_setup_func_argv)]
328 if not multithread_func(log, tasks):
329 log.error("Phone Failed to Set Up Properly.")
330 return False
Markus Liufdef3062021-06-27 15:08:29 +0800331 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Markus Liufdef3062021-06-27 15:08:29 +0800332
Richard Chang8d40b882021-06-28 23:58:51 +0800333 if streaming:
334 log.info("Step 4: Start Youtube streaming.")
335 if not start_youtube_video(ads[0]):
336 log.warning("Fail to bring up youtube video")
337 time.sleep(10)
338 else:
339 log.info("Step 4: Skip Youtube streaming.")
340
341 log.info("Step 5: Send %s.", msg)
Markus Liufdef3062021-06-27 15:08:29 +0800342 if msg == "MMS":
343 for ad, current_data_sub_id, current_msg_sub_id in [
344 [ ads[0],
345 get_default_data_sub_id(ads[0]),
346 get_outgoing_message_sub_id(ads[0]) ],
347 [ ads[1],
348 get_default_data_sub_id(ads[1]),
349 get_outgoing_message_sub_id(ads[1]) ]]:
350 if current_data_sub_id != current_msg_sub_id:
351 ad.log.warning(
352 "Current data sub ID (%s) does not match message"
353 " sub ID (%s). MMS should NOT be sent.",
354 current_data_sub_id,
355 current_msg_sub_id)
356 expected_result = False
357
358 result = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id,
359 msg=msg, expected_result=expected_result)
360
361 if not result:
362 log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg)
363 log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg)
364
Richard Chang8d40b882021-06-28 23:58:51 +0800365 if streaming:
366 ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
Markus Liufdef3062021-06-27 15:08:29 +0800367 return result
368
Markus Liu481eccd2021-04-21 14:36:15 +0800369def erase_call_forwarding(log, ad):
370 slot0_sub_id = get_subid_from_slot_index(log, ad, 0)
371 slot1_sub_id = get_subid_from_slot_index(log, ad, 1)
372 current_voice_sub_id = get_incoming_voice_sub_id(ad)
373 for sub_id in (slot0_sub_id, slot1_sub_id):
374 set_voice_sub_id(ad, sub_id)
375 get_operator_name(log, ad, sub_id)
376 erase_call_forwarding_by_mmi(log, ad)
377 set_voice_sub_id(ad, current_voice_sub_id)
378
379def three_way_calling_mo_and_mt_with_hangup_once(
380 log,
381 ads,
382 phone_setups,
383 verify_funcs,
384 reject_once=False):
385 """Use 3 phones to make MO call and MT call.
386
387 Call from PhoneA to PhoneB, accept on PhoneB.
388 Call from PhoneC to PhoneA, accept on PhoneA.
389
390 Args:
391 ads: list of ad object.
392 The list should have three objects.
393 phone_setups: list of phone setup functions.
394 The list should have three objects.
395 verify_funcs: list of phone call verify functions.
396 The list should have three objects.
397
398 Returns:
399 If success, return 'call_AB' id in PhoneA.
400 if fail, return None.
401 """
402
403 class _CallException(Exception):
404 pass
405
406 try:
407 verify_func_a, verify_func_b, verify_func_c = verify_funcs
408 tasks = []
409 for ad, setup_func in zip(ads, phone_setups):
410 if setup_func is not None:
411 tasks.append((setup_func, (log, ad, get_incoming_voice_sub_id(ad))))
412 if tasks != [] and not multithread_func(log, tasks):
413 log.error("Phone Failed to Set Up Properly.")
414 raise _CallException("Setup failed.")
415 for ad in ads:
416 ad.droid.telecomCallClearCallList()
417 if num_active_calls(log, ad) != 0:
418 ad.log.error("Phone Call List is not empty.")
419 raise _CallException("Clear call list failed.")
420
421 log.info("Step1: Call From PhoneA to PhoneB.")
422 if not call_setup_teardown(
423 log,
424 ads[0],
425 ads[1],
426 ad_hangup=None,
427 verify_caller_func=verify_func_a,
428 verify_callee_func=verify_func_b):
429 raise _CallException("PhoneA call PhoneB failed.")
430
431 calls = ads[0].droid.telecomCallGetCallIds()
432 ads[0].log.info("Calls in PhoneA %s", calls)
433 if num_active_calls(log, ads[0]) != 1:
434 raise _CallException("Call list verify failed.")
435 call_ab_id = calls[0]
436
437 log.info("Step2: Call From PhoneC to PhoneA.")
438 if reject_once:
439 log.info("Step2-1: Reject incoming call once.")
440 if not initiate_call(
441 log,
442 ads[2],
443 ads[0].telephony['subscription'][get_incoming_voice_sub_id(
444 ads[0])]['phone_num']):
445 ads[2].log.error("Initiate call failed.")
446 raise _CallException("Failed to initiate call.")
447
448 if not wait_and_reject_call_for_subscription(
449 log,
450 ads[0],
451 get_incoming_voice_sub_id(ads[0]),
452 incoming_number= \
453 ads[2].telephony['subscription'][
454 get_incoming_voice_sub_id(
455 ads[2])]['phone_num']):
456 ads[0].log.error("Reject call fail.")
457 raise _CallException("Failed to reject call.")
458
459 hangup_call(log, ads[2])
460 time.sleep(15)
461
462 if not call_setup_teardown(
463 log,
464 ads[2],
465 ads[0],
466 ad_hangup=None,
467 verify_caller_func=verify_func_c,
468 verify_callee_func=verify_func_a):
469 raise _CallException("PhoneA call PhoneC failed.")
470 if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
471 True):
472 raise _CallException("Not All phones are in-call.")
473
474 except Exception as e:
475 setattr(ads[0], "exception", e)
476 return None
477
478 return call_ab_id
479
Markus Liufdef3062021-06-27 15:08:29 +0800480def msim_message_test(
481 log,
482 ad_mo,
483 ad_mt,
484 mo_sub_id,
485 mt_sub_id, msg="SMS",
486 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
487 expected_result=True):
488 """Make MO/MT SMS/MMS at specific slot.
489
490 Args:
491 ad_mo: Android object of the device sending SMS/MMS
492 ad_mt: Android object of the device receiving SMS/MMS
493 mo_sub_id: Sub ID of MO device
494 mt_sub_id: Sub ID of MT device
495 max_wait_time: Max wait time before SMS/MMS is received.
496 expected_result: True for successful sending/receiving and False on
497 the contrary
498
499 Returns:
500 True if the result matches expected_result and False on the
501 contrary.
502 """
503 message_lengths = (50, 160, 180)
504 if msg == "SMS":
505 for length in message_lengths:
506 message_array = [rand_ascii_str(length)]
507 if not sms_send_receive_verify_for_subscription(
508 log,
509 ad_mo,
510 ad_mt,
511 mo_sub_id,
512 mt_sub_id,
513 message_array,
514 max_wait_time):
515 ad_mo.log.warning(
516 "%s of length %s test failed", msg, length)
517 return False
518 else:
519 ad_mo.log.info(
520 "%s of length %s test succeeded", msg, length)
521 log.info("%s test of length %s characters succeeded.",
522 msg, message_lengths)
523
524 elif msg == "MMS":
525 for length in message_lengths:
526 message_array = [("Test Message", rand_ascii_str(length), None)]
527
528 if not mms_send_receive_verify(
529 log,
530 ad_mo,
531 ad_mt,
532 message_array,
533 max_wait_time,
534 expected_result):
535 log.warning("%s of body length %s test failed",
536 msg, length)
537 return False
538 else:
539 log.info(
540 "%s of body length %s test succeeded", msg, length)
541 log.info("%s test of body lengths %s succeeded",
542 msg, message_lengths)
543 return True
544
Markus Liu481eccd2021-04-21 14:36:15 +0800545def msim_call_forwarding(
546 log,
547 ads,
548 caller_slot,
549 callee_slot,
550 forwarded_callee_slot,
551 dds_slot,
552 caller_rat=["", ""],
553 callee_rat=["", ""],
554 forwarded_callee_rat=["", ""],
555 call_forwarding_type="unconditional"):
556 """Make MO voice call to the primary device at specific slot in specific
557 RAT with DDS at specific slot, and then forwarded to 3rd device with
558 specific call forwarding type.
559
560 Test step:
561 1. Get sub IDs of specific slots of both MO and MT devices.
562 2. Switch DDS to specific slot.
563 3. Check HTTP connection after DDS switch.
564 4. Set up phones in desired RAT.
565 5. Register and enable call forwarding with specifc type.
566 5. Make voice call to the primary device and wait for being forwarded
567 to 3rd device.
568
569 Args:
570 caller_slot: Slot of 2nd device making MO call (0 or 1)
571 callee_slot: Slot of primary device receiving and forwarding MT call
572 (0 or 1)
573 forwarded_callee_slot: Slot of 3rd device receiving forwarded call.
574 dds_slot: Preferred data slot
575 caller_rat: RAT for both slots of the 2nd device
576 callee_rat: RAT for both slots of the primary device
577 forwarded_callee_rat: RAT for both slots of the 3rd device
578 call_forwarding_type:
579 "unconditional"
580 "busy"
581 "not_answered"
582 "not_reachable"
583
584 Returns:
585 True or False
586 """
587 ad_caller = ads[1]
588 ad_callee = ads[0]
589 ad_forwarded_callee = ads[2]
590
591 if callee_slot is not None:
592 callee_sub_id = get_subid_from_slot_index(
593 log, ad_callee, callee_slot)
594 if callee_sub_id == INVALID_SUB_ID:
595 ad_callee.log.warning(
596 "Failed to get sub ID at slot %s.", callee_slot)
597 return False
598 callee_other_sub_id = get_subid_from_slot_index(
599 log, ad_callee, 1-callee_slot)
600 set_voice_sub_id(ad_callee, callee_sub_id)
601 else:
602 callee_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
603 if callee_sub_id == INVALID_SUB_ID:
604 ad_callee.log.warning(
605 "Failed to get sub ID at slot %s.", callee_slot)
606 return False
607 callee_slot = "auto"
608 set_voice_sub_id(ad_callee, callee_sub_id)
609 ad_callee.log.info(
610 "Sub ID for incoming call at slot %s: %s",
611 callee_slot, get_incoming_voice_sub_id(ad_callee))
612
613 if caller_slot is not None:
614 caller_sub_id = get_subid_from_slot_index(
615 log, ad_caller, caller_slot)
616 if caller_sub_id == INVALID_SUB_ID:
617 ad_caller.log.warning(
618 "Failed to get sub ID at slot %s.", caller_slot)
619 return False
620 caller_other_sub_id = get_subid_from_slot_index(
621 log, ad_caller, 1-caller_slot)
622 set_voice_sub_id(ad_caller, caller_sub_id)
623 else:
624 _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
625 if caller_sub_id == INVALID_SUB_ID:
626 ad_caller.log.warning(
627 "Failed to get sub ID at slot %s.", caller_slot)
628 return False
629 caller_slot = "auto"
630 set_voice_sub_id(ad_caller, caller_sub_id)
631 ad_caller.log.info(
632 "Sub ID for outgoing call at slot %s: %s",
633 caller_slot, get_outgoing_voice_sub_id(ad_caller))
634
635 if forwarded_callee_slot is not None:
636 forwarded_callee_sub_id = get_subid_from_slot_index(
637 log, ad_forwarded_callee, forwarded_callee_slot)
638 if forwarded_callee_sub_id == INVALID_SUB_ID:
639 ad_forwarded_callee.log.warning(
640 "Failed to get sub ID at slot %s.", forwarded_callee_slot)
641 return False
642 forwarded_callee_other_sub_id = get_subid_from_slot_index(
643 log, ad_forwarded_callee, 1-forwarded_callee_slot)
644 set_voice_sub_id(
645 ad_forwarded_callee, forwarded_callee_sub_id)
646 else:
647 _, _, forwarded_callee_sub_id = \
648 get_subid_on_same_network_of_host_ad(ads)
649 if forwarded_callee_sub_id == INVALID_SUB_ID:
650 ad_forwarded_callee.log.warning(
651 "Failed to get sub ID at slot %s.", forwarded_callee_slot)
652 return False
653 forwarded_callee_slot = "auto"
654 set_voice_sub_id(
655 ad_forwarded_callee, forwarded_callee_sub_id)
656 ad_forwarded_callee.log.info(
657 "Sub ID for incoming call at slot %s: %s",
658 forwarded_callee_slot,
659 get_incoming_voice_sub_id(ad_forwarded_callee))
660
661 log.info("Step 1: Switch DDS.")
Markus Liufdef3062021-06-27 15:08:29 +0800662 if not set_dds_on_slot(ads[0], dds_slot):
663 log.error(
664 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
665 return False
Markus Liu481eccd2021-04-21 14:36:15 +0800666
667 log.info("Step 2: Check HTTP connection after DDS switch.")
Markus Liufdef3062021-06-27 15:08:29 +0800668 if not verify_http_connection(log, ads[0]):
Markus Liu481eccd2021-04-21 14:36:15 +0800669 log.error("Failed to verify http connection.")
670 return False
671 else:
672 log.info("Verify http connection successfully.")
673
674 if caller_slot == 1:
675 phone_setup_on_rat(
676 log,
677 ad_caller,
678 caller_rat[0],
679 caller_other_sub_id)
680
681 elif caller_slot == 0:
682 phone_setup_on_rat(
683 log,
684 ad_caller,
685 caller_rat[1],
686 caller_other_sub_id)
687 else:
688 phone_setup_on_rat(
689 log,
690 ad_caller,
691 'general')
692
693 if callee_slot == 1:
694 phone_setup_on_rat(
695 log,
696 ad_callee,
697 callee_rat[0],
698 callee_other_sub_id)
699
700 elif callee_slot == 0:
701 phone_setup_on_rat(
702 log,
703 ad_callee,
704 callee_rat[1],
705 callee_other_sub_id)
706 else:
707 phone_setup_on_rat(
708 log,
709 ad_callee,
710 'general')
711
712 if forwarded_callee_slot == 1:
713 phone_setup_on_rat(
714 log,
715 ad_forwarded_callee,
716 forwarded_callee_rat[0],
717 forwarded_callee_other_sub_id)
718
719 elif forwarded_callee_slot == 0:
720 phone_setup_on_rat(
721 log,
722 ad_forwarded_callee,
723 forwarded_callee_rat[1],
724 forwarded_callee_other_sub_id)
725 else:
726 phone_setup_on_rat(
727 log,
728 ad_forwarded_callee,
729 'general')
730
731 if caller_slot == 0 or caller_slot == 1:
732 caller_phone_setup_func_argv = (log, ad_caller, caller_rat[caller_slot], caller_sub_id)
733 else:
734 caller_phone_setup_func_argv = (log, ad_caller, 'general')
735
736 callee_phone_setup_func_argv = (log, ad_callee, callee_rat[callee_slot], callee_sub_id)
737
738 if forwarded_callee_slot == 0 or forwarded_callee_slot == 1:
739 forwarded_callee_phone_setup_func_argv = (
740 log,
741 ad_forwarded_callee,
742 forwarded_callee_rat[forwarded_callee_slot],
743 forwarded_callee_sub_id)
744 else:
745 forwarded_callee_phone_setup_func_argv = (
746 log,
747 ad_forwarded_callee,
748 'general')
749
750 log.info("Step 3: Set up phones in desired RAT.")
751 tasks = [(phone_setup_on_rat, caller_phone_setup_func_argv),
752 (phone_setup_on_rat, callee_phone_setup_func_argv),
753 (phone_setup_on_rat,
754 forwarded_callee_phone_setup_func_argv)]
755 if not multithread_func(log, tasks):
756 log.error("Phone Failed to Set Up Properly.")
757 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
758 raise signals.TestFailure("Failed",
759 extras={"fail_reason": "Phone Failed to Set Up Properly."})
760
761 is_callee_in_call = is_phone_in_call_on_rat(
762 log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
763
764 is_call_waiting = re.search(
765 "call_waiting (True (\d)|False)", call_forwarding_type, re.I)
766 if is_call_waiting:
767 if is_call_waiting.group(1) == "False":
768 call_waiting = False
769 scenario = None
770 else:
771 call_waiting = True
772 scenario = int(is_call_waiting.group(2))
773
774 log.info(
775 "Step 4: Make voice call with call waiting enabled = %s.",
776 call_waiting)
777 result = three_phone_call_waiting_short_seq(
778 log,
779 ads[0],
780 None,
781 is_callee_in_call,
782 ads[1],
783 ads[2],
784 call_waiting=call_waiting, scenario=scenario)
785 else:
786 log.info(
787 "Step 4: Make voice call with call forwarding %s.",
788 call_forwarding_type)
789 result = three_phone_call_forwarding_short_seq(
790 log,
791 ads[0],
792 None,
793 is_callee_in_call,
794 ads[1],
795 ads[2],
796 call_forwarding_type=call_forwarding_type)
797
798 if not result:
799 if is_call_waiting:
800 pass
801 else:
802 log.error(
803 "Failed to make MO call from %s slot %s to %s slot %s"
804 " and forward to %s slot %s",
805 ad_caller.serial,
806 caller_slot,
807 ad_callee.serial,
808 callee_slot,
809 ad_forwarded_callee.serial,
810 forwarded_callee_slot)
811
812 return result
813
814def msim_call_voice_conf(
815 log,
816 ads,
817 host_slot,
818 p1_slot,
819 p2_slot,
820 dds_slot,
821 host_rat=["volte", "volte"],
822 p1_rat="",
823 p2_rat="",
824 merge=True,
825 disable_cw=False):
826 """Make a voice conference call at specific slot in specific RAT with
827 DDS at specific slot.
828
829 Test step:
830 1. Get sub IDs of specific slots of both MO and MT devices.
831 2. Switch DDS to specific slot.
832 3. Check HTTP connection after DDS switch.
833 4. Set up phones in desired RAT and make 3-way voice call.
834 5. Swap calls.
835 6. Merge calls.
836
837 Args:
838 host_slot: Slot on the primary device to host the comference call.
839 0 or 1 (0 for pSIM or 1 for eSIM)
840 p1_slot: Slot on the participant device for the call
841 p2_slot: Slot on another participant device for the call
842 dds_slot: Preferred data slot
843 host_rat: RAT for both slots of the primary device
844 p1_rat: RAT for both slots of the participant device
845 p2_rat: RAT for both slots of another participant device
846 merge: True for merging 2 calls into the conference call. False for
847 not merging 2 separated call.
848 disable_cw: True for disabling call waiting and False on the
849 contrary.
850
851 Returns:
Markus Liu3bedf212021-06-16 17:39:07 +0800852 True or False
Markus Liu481eccd2021-04-21 14:36:15 +0800853 """
854 ad_host = ads[0]
855 ad_p1 = ads[1]
856 ad_p2 = ads[2]
857
858 if host_slot is not None:
859 host_sub_id = get_subid_from_slot_index(
860 log, ad_host, host_slot)
861 if host_sub_id == INVALID_SUB_ID:
862 ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
863 return False
864 host_other_sub_id = get_subid_from_slot_index(
865 log, ad_host, 1-host_slot)
866 set_voice_sub_id(ad_host, host_sub_id)
867 else:
868 host_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
869 if host_sub_id == INVALID_SUB_ID:
870 ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
871 return False
872 host_slot = "auto"
873 set_voice_sub_id(ad_host, host_sub_id)
874
875 ad_host.log.info("Sub ID for outgoing call at slot %s: %s",
876 host_slot, get_outgoing_voice_sub_id(ad_host))
877
878 if p1_slot is not None:
879 p1_sub_id = get_subid_from_slot_index(log, ad_p1, p1_slot)
880 if p1_sub_id == INVALID_SUB_ID:
881 ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
882 return False
883 set_voice_sub_id(ad_p1, p1_sub_id)
884 else:
885 _, p1_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
886 if p1_sub_id == INVALID_SUB_ID:
887 ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
888 return False
889 p1_slot = "auto"
890 set_voice_sub_id(ad_p1, p1_sub_id)
891 ad_p1.log.info("Sub ID for incoming call at slot %s: %s",
892 p1_slot, get_incoming_voice_sub_id(ad_p1))
893
894 if p2_slot is not None:
895 p2_sub_id = get_subid_from_slot_index(log, ad_p2, p2_slot)
896 if p2_sub_id == INVALID_SUB_ID:
897 ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
898 return False
899 set_voice_sub_id(ad_p2, p2_sub_id)
900 else:
901 _, _, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
902 if p2_sub_id == INVALID_SUB_ID:
903 ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
904 return False
905 p2_slot = "auto"
906 set_voice_sub_id(ad_p2, p2_sub_id)
907 ad_p2.log.info("Sub ID for incoming call at slot %s: %s",
908 p2_slot, get_incoming_voice_sub_id(ad_p2))
909
910 log.info("Step 1: Switch DDS.")
Markus Liufdef3062021-06-27 15:08:29 +0800911 if not set_dds_on_slot(ads[0], dds_slot):
912 log.error(
913 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
914 return False
Markus Liu481eccd2021-04-21 14:36:15 +0800915
916 log.info("Step 2: Check HTTP connection after DDS switch.")
Markus Liufdef3062021-06-27 15:08:29 +0800917 if not verify_http_connection(log, ads[0]):
Markus Liu481eccd2021-04-21 14:36:15 +0800918 log.error("Failed to verify http connection.")
919 return False
920 else:
921 log.info("Verify http connection successfully.")
922
923 if disable_cw:
924 if not set_call_waiting(log, ad_host, enable=0):
925 return False
926 else:
927 if not set_call_waiting(log, ad_host, enable=1):
928 return False
929
930 if host_slot == 1:
931 phone_setup_on_rat(
932 log,
933 ad_host,
934 host_rat[0],
935 host_other_sub_id)
936
937 elif host_slot == 0:
938 phone_setup_on_rat(
939 log,
940 ad_host,
941 host_rat[1],
942 host_other_sub_id)
943
944 if host_slot == 0 or host_slot == 1:
945 host_phone_setup_func_argv = (log, ad_host, host_rat[host_slot], host_sub_id)
946 is_host_in_call = is_phone_in_call_on_rat(
947 log, ad_host, host_rat[host_slot], only_return_fn=True)
948 else:
949 host_phone_setup_func_argv = (log, ad_host, 'general')
950 is_host_in_call = is_phone_in_call_on_rat(
951 log, ad_host, 'general', only_return_fn=True)
952
953 if p1_rat:
954 p1_phone_setup_func_argv = (log, ad_p1, p1_rat, p1_sub_id)
955 is_p1_in_call = is_phone_in_call_on_rat(
956 log, ad_p1, p1_rat, only_return_fn=True)
957 else:
958 p1_phone_setup_func_argv = (log, ad_p1, 'general')
959 is_p1_in_call = is_phone_in_call_on_rat(
960 log, ad_p1, 'general', only_return_fn=True)
961
962 if p2_rat:
963 p2_phone_setup_func_argv = (log, ad_p2, p2_rat, p2_sub_id)
964 is_p2_in_call = is_phone_in_call_on_rat(
965 log, ad_p2, p2_rat, only_return_fn=True)
966 else:
967 p2_phone_setup_func_argv = (log, ad_p2, 'general')
968 is_p2_in_call = is_phone_in_call_on_rat(
969 log, ad_p2, 'general', only_return_fn=True)
970
971 log.info("Step 3: Set up phone in desired RAT and make 3-way"
972 " voice call.")
973
974 tasks = [(phone_setup_on_rat, host_phone_setup_func_argv),
975 (phone_setup_on_rat, p1_phone_setup_func_argv),
976 (phone_setup_on_rat, p2_phone_setup_func_argv)]
977 if not multithread_func(log, tasks):
978 log.error("Phone Failed to Set Up Properly.")
979 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
980 raise signals.TestFailure("Failed",
981 extras={"fail_reason": "Phone Failed to Set Up Properly."})
982
983 call_ab_id = three_way_calling_mo_and_mt_with_hangup_once(
984 log,
985 [ad_host, ad_p1, ad_p2],
986 [None, None, None], [
987 is_host_in_call, is_p1_in_call,
988 is_p2_in_call
989 ])
990
991 if call_ab_id is None:
992 if disable_cw:
993 set_call_waiting(log, ad_host, enable=1)
994 if str(getattr(ad_host, "exception", None)) == \
995 "PhoneA call PhoneC failed.":
996 ads[0].log.info("PhoneA failed to call PhoneC due to call"
997 " waiting being disabled.")
998 delattr(ad_host, "exception")
999 return True
1000 log.error("Failed to get call_ab_id")
1001 return False
1002 else:
1003 if disable_cw:
1004 return False
1005
1006 calls = ads[0].droid.telecomCallGetCallIds()
1007 ads[0].log.info("Calls in PhoneA %s", calls)
1008 if num_active_calls(log, ads[0]) != 2:
1009 return False
1010 if calls[0] == call_ab_id:
1011 call_ac_id = calls[1]
1012 else:
1013 call_ac_id = calls[0]
1014
1015 if call_ac_id is None:
1016 log.error("Failed to get call_ac_id")
1017 return False
1018
1019 num_swaps = 2
1020 log.info("Step 4: Begin Swap x%s test.", num_swaps)
1021 if not swap_calls(log, ads, call_ab_id, call_ac_id,
1022 num_swaps):
1023 log.error("Swap test failed.")
1024 return False
1025
1026 if not merge:
1027 result = True
1028 if not hangup_call(log, ads[1]):
1029 result = False
1030 if not hangup_call(log, ads[2]):
1031 result = False
1032 return result
1033 else:
1034 log.info("Step 5: Merge calls.")
1035 if host_rat[host_slot] == "volte":
1036 return _test_ims_conference_merge_drop_second_call_from_participant(
1037 log, ads, call_ab_id, call_ac_id)
1038 else:
1039 return _test_wcdma_conference_merge_drop(
Markus Liu3bedf212021-06-16 17:39:07 +08001040 log, ads, call_ab_id, call_ac_id)
1041
1042def msim_volte_wfc_call_forwarding(
1043 log,
1044 ads,
1045 callee_slot,
1046 dds_slot,
1047 callee_rat=["5g_wfc", "5g_wfc"],
1048 call_forwarding_type="unconditional",
1049 is_airplane_mode=False,
1050 is_wifi_connected=False,
1051 wfc_mode=[
1052 WFC_MODE_CELLULAR_PREFERRED,
1053 WFC_MODE_CELLULAR_PREFERRED],
1054 wifi_network_ssid=None,
1055 wifi_network_pass=None):
1056 """Make VoLTE/WFC call to the primary device at specific slot with DDS
1057 at specific slot, and then forwarded to 3rd device with specific call
1058 forwarding type.
1059
1060 Test step:
1061 1. Get sub IDs of specific slots of both MO and MT devices.
1062 2. Switch DDS to specific slot.
1063 3. Check HTTP connection after DDS switch.
1064 4. Set up phones in desired RAT.
1065 5. Register and enable call forwarding with specifc type.
1066 6. Make VoLTE/WFC call to the primary device and wait for being
1067 forwarded to 3rd device.
1068
1069 Args:
1070 callee_slot: Slot of primary device receiving and forwarding MT call
1071 (0 or 1)
1072 dds_slot: Preferred data slot
1073 callee_rat: RAT for both slots of the primary device
1074 call_forwarding_type:
1075 "unconditional"
1076 "busy"
1077 "not_answered"
1078 "not_reachable"
1079 is_airplane_mode: True or False for WFC setup
1080 wfc_mode: Cellular preferred or Wi-Fi preferred.
1081 wifi_network_ssid: SSID of Wi-Fi AP
1082 wifi_network_pass: Password of Wi-Fi AP SSID
1083
1084 Returns:
1085 True or False
1086 """
1087 ad_caller = ads[1]
1088 ad_callee = ads[0]
1089 ad_forwarded_callee = ads[2]
1090
1091 if not toggle_airplane_mode(log, ad_callee, False):
1092 ad_callee.log.error("Failed to disable airplane mode.")
1093 return False
1094
1095 # Set up callee (primary device)
1096 callee_sub_id = get_subid_from_slot_index(
1097 log, ad_callee, callee_slot)
1098 if callee_sub_id == INVALID_SUB_ID:
1099 log.warning(
1100 "Failed to get sub ID at slot %s.", callee_slot)
1101 return
1102 callee_other_sub_id = get_subid_from_slot_index(
1103 log, ad_callee, 1-callee_slot)
1104 set_voice_sub_id(ad_callee, callee_sub_id)
1105 ad_callee.log.info(
1106 "Sub ID for incoming call at slot %s: %s",
1107 callee_slot, get_incoming_voice_sub_id(ad_callee))
1108
1109 # Set up caller
1110 _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
1111 if caller_sub_id == INVALID_SUB_ID:
1112 ad_caller.log.warning("Failed to get proper sub ID of the caller")
1113 return
1114 set_voice_sub_id(ad_caller, caller_sub_id)
1115 ad_caller.log.info(
1116 "Sub ID for outgoing call of the caller: %s",
1117 get_outgoing_voice_sub_id(ad_caller))
1118
1119 # Set up forwarded callee
1120 _, _, forwarded_callee_sub_id = get_subid_on_same_network_of_host_ad(
1121 ads)
1122 if forwarded_callee_sub_id == INVALID_SUB_ID:
1123 ad_forwarded_callee.log.warning(
1124 "Failed to get proper sub ID of the forwarded callee.")
1125 return
1126 set_voice_sub_id(ad_forwarded_callee, forwarded_callee_sub_id)
1127 ad_forwarded_callee.log.info(
1128 "Sub ID for incoming call of the forwarded callee: %s",
1129 get_incoming_voice_sub_id(ad_forwarded_callee))
1130
Markus Liufdef3062021-06-27 15:08:29 +08001131 log.info("Step 1: Switch DDS.")
1132 if not set_dds_on_slot(ads[0], dds_slot):
1133 log.error(
1134 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
1135 return False
Markus Liu3bedf212021-06-16 17:39:07 +08001136
Markus Liufdef3062021-06-27 15:08:29 +08001137 log.info("Step 2: Check HTTP connection after DDS switch.")
Markus Liu3bedf212021-06-16 17:39:07 +08001138 if not verify_http_connection(log, ad_callee):
1139 ad_callee.log.error("Failed to verify http connection.")
1140 return False
1141 else:
1142 ad_callee.log.info("Verify http connection successfully.")
1143
1144 is_callee_in_call = is_phone_in_call_on_rat(
1145 log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
1146
1147 if is_airplane_mode:
1148 set_call_forwarding_by_mmi(log, ad_callee, ad_forwarded_callee)
1149
Markus Liufdef3062021-06-27 15:08:29 +08001150 log.info("Step 3: Set up phones in desired RAT.")
Markus Liu3bedf212021-06-16 17:39:07 +08001151 if callee_slot == 1:
1152 phone_setup_on_rat(
1153 log,
1154 ad_callee,
1155 callee_rat[0],
1156 callee_other_sub_id,
1157 is_airplane_mode,
1158 wfc_mode[0],
1159 wifi_network_ssid,
1160 wifi_network_pass)
1161
1162 elif callee_slot == 0:
1163 phone_setup_on_rat(
1164 log,
1165 ad_callee,
1166 callee_rat[1],
1167 callee_other_sub_id,
1168 is_airplane_mode,
1169 wfc_mode[1],
1170 wifi_network_ssid,
1171 wifi_network_pass)
1172
1173 argv = (
1174 log,
1175 ad_callee,
1176 callee_rat[callee_slot],
1177 callee_sub_id,
1178 is_airplane_mode,
1179 wfc_mode[callee_slot],
1180 wifi_network_ssid,
1181 wifi_network_pass)
1182
1183 tasks = [(phone_setup_voice_general, (log, ad_caller)),
1184 (phone_setup_on_rat, argv),
1185 (phone_setup_voice_general, (log, ad_forwarded_callee))]
1186
1187 if not multithread_func(log, tasks):
1188 log.error("Phone Failed to Set Up Properly.")
1189 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
1190 raise signals.TestFailure("Failed",
1191 extras={"fail_reason": "Phone Failed to Set Up Properly."})
1192
1193 if is_wifi_connected:
1194 if not ensure_wifi_connected(
1195 log,
1196 ad_callee,
1197 wifi_network_ssid,
1198 wifi_network_pass,
1199 apm=is_airplane_mode):
1200 return False
1201 time.sleep(5)
1202
1203 if "wfc" not in callee_rat[callee_slot]:
1204 if not toggle_wfc_for_subscription(
1205 log,
1206 ad_callee,
1207 new_state=True,
1208 sub_id=callee_sub_id):
1209 return False
1210 if not set_wfc_mode_for_subscription(
1211 ad_callee, wfc_mode[callee_slot], sub_id=callee_sub_id):
1212 return False
1213
1214 log.info(
1215 "Step 4: Make voice call with call forwarding %s.",
1216 call_forwarding_type)
1217 result = three_phone_call_forwarding_short_seq(
1218 log,
1219 ad_callee,
1220 None,
1221 is_callee_in_call,
1222 ad_caller,
1223 ad_forwarded_callee,
1224 call_forwarding_type=call_forwarding_type)
1225
1226 if not result:
1227 log.error(
1228 "Failed to make MO call from %s to %s slot %s and forward"
1229 " to %s.",
1230 ad_caller.serial,
1231 ad_callee.serial,
1232 callee_slot,
1233 ad_forwarded_callee.serial)
1234 return result
1235
1236def msim_volte_wfc_call_voice_conf(
1237 log,
1238 ads,
1239 host_slot,
1240 dds_slot,
1241 host_rat=["5g_wfc", "5g_wfc"],
1242 merge=True,
1243 disable_cw=False,
1244 is_airplane_mode=False,
1245 is_wifi_connected=False,
1246 wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
1247 reject_once=False,
1248 wifi_network_ssid=None,
1249 wifi_network_pass=None):
1250 """Make a VoLTE/WFC conference call at specific slot with DDS at
1251 specific slot.
1252
1253 Test step:
1254 1. Get sub IDs of specific slots of both MO and MT devices.
1255 2. Set up phones in desired RAT
1256 3. Enable VoLTE/WFC.
1257 4. Switch DDS to specific slot.
1258 5. Check HTTP connection after DDS switch.
1259 6. Make 3-way VoLTE/WFC call.
1260 7. Swap calls.
1261 8. Merge calls.
1262
1263 Args:
1264 host_slot: Slot on the primary device to host the comference call.
1265 0 or 1 (0 for pSIM or 1 for eSIM)call
1266 dds_slot: Preferred data slot
1267 host_rat: RAT for both slots of the primary devicevice
1268 merge: True for merging 2 calls into the conference call. False for
1269 not merging 2 separated call.
1270 disable_cw: True for disabling call waiting and False on the
1271 contrary.
1272 enable_volte: True for enabling and False for disabling VoLTE for
1273 each slot on the primary device
1274 enable_wfc: True for enabling and False for disabling WFC for
1275 each slot on the primary device
1276 is_airplane_mode: True or False for WFC setup
1277 wfc_mode: Cellular preferred or Wi-Fi preferred.
1278 reject_once: True for rejecting the 2nd call once from the 3rd
1279 device (Phone C) to the primary device (Phone A).
1280 wifi_network_ssid: SSID of Wi-Fi AP
1281 wifi_network_pass: Password of Wi-Fi AP SSID
1282
1283 Returns:
1284 True or False
1285 """
1286 ad_host = ads[0]
1287 ad_p1 = ads[1]
1288 ad_p2 = ads[2]
1289
1290 host_sub_id = get_subid_from_slot_index(log, ad_host, host_slot)
1291 if host_sub_id == INVALID_SUB_ID:
1292 ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
1293 return
1294 host_other_sub_id = get_subid_from_slot_index(
1295 log, ad_host, 1-host_slot)
1296 set_voice_sub_id(ad_host, host_sub_id)
1297 ad_host.log.info(
1298 "Sub ID for outgoing call at slot %s: %s",
1299 host_slot, get_outgoing_voice_sub_id(ad_host))
1300
1301 _, p1_sub_id, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
1302
1303 if p1_sub_id == INVALID_SUB_ID:
1304 ad_p1.log.warning("Failed to get proper sub ID.")
1305 return
1306 set_voice_sub_id(ad_p1, p1_sub_id)
1307 ad_p1.log.info(
1308 "Sub ID for incoming call: %s",
1309 get_incoming_voice_sub_id(ad_p1))
1310
1311 if p2_sub_id == INVALID_SUB_ID:
1312 ad_p2.log.warning("Failed to get proper sub ID.")
1313 return
1314 set_voice_sub_id(ad_p2, p2_sub_id)
1315 ad_p2.log.info(
1316 "Sub ID for incoming call: %s", get_incoming_voice_sub_id(ad_p2))
1317
Markus Liufdef3062021-06-27 15:08:29 +08001318 log.info("Step 1: Switch DDS.")
1319 if not set_dds_on_slot(ads[0], dds_slot):
1320 log.error(
1321 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
1322 return False
Markus Liu3bedf212021-06-16 17:39:07 +08001323
Markus Liufdef3062021-06-27 15:08:29 +08001324 log.info("Step 2: Check HTTP connection after DDS switch.")
Markus Liu3bedf212021-06-16 17:39:07 +08001325 if not verify_http_connection(log, ads[0]):
1326 ad_host.log.error("Failed to verify http connection.")
1327 return False
1328 else:
1329 ad_host.log.info("Verify http connection successfully.")
1330
1331 if disable_cw:
1332 if not set_call_waiting(log, ad_host, enable=0):
1333 return False
1334
Markus Liufdef3062021-06-27 15:08:29 +08001335 log.info("Step 3: Set up phones in desired RAT.")
Markus Liu3bedf212021-06-16 17:39:07 +08001336 if host_slot == 1:
1337 phone_setup_on_rat(
1338 log,
1339 ad_host,
1340 host_rat[0],
1341 host_other_sub_id,
1342 is_airplane_mode,
1343 wfc_mode[0],
1344 wifi_network_ssid,
1345 wifi_network_pass)
1346
1347 elif host_slot == 0:
1348 phone_setup_on_rat(
1349 log,
1350 ad_host,
1351 host_rat[1],
1352 host_other_sub_id,
1353 is_airplane_mode,
1354 wfc_mode[1],
1355 wifi_network_ssid,
1356 wifi_network_pass)
1357
1358 argv = (
1359 log,
1360 ad_host,
1361 host_rat[host_slot],
1362 host_sub_id,
1363 is_airplane_mode,
1364 wfc_mode[host_slot],
1365 wifi_network_ssid,
1366 wifi_network_pass)
1367
1368 tasks = [(phone_setup_voice_general, (log, ad_p1)),
1369 (phone_setup_on_rat, argv),
1370 (phone_setup_voice_general, (log, ad_p2))]
1371
1372 if not multithread_func(log, tasks):
1373 log.error("Phone Failed to Set Up Properly.")
1374 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
1375 raise signals.TestFailure("Failed",
1376 extras={"fail_reason": "Phone Failed to Set Up Properly."})
1377
1378 if is_wifi_connected:
1379 if not ensure_wifi_connected(
1380 log,
1381 ad_host,
1382 wifi_network_ssid,
1383 wifi_network_pass,
1384 apm=is_airplane_mode):
1385 return False
1386 time.sleep(5)
1387
1388 if "wfc" not in host_rat[host_slot]:
1389 if not toggle_wfc_for_subscription(
1390 log,
1391 ad_host,
1392 new_state=True,
1393 sub_id=host_sub_id):
1394 return False
1395 if not set_wfc_mode_for_subscription(
1396 ad_host, wfc_mode[host_slot], sub_id=host_sub_id):
1397 return False
1398
1399 log.info("Step 4: Make 3-way voice call.")
1400 is_host_in_call = is_phone_in_call_on_rat(
1401 log, ad_host, host_rat[host_slot], only_return_fn=True)
1402 call_ab_id = _three_phone_call_mo_add_mt(
1403 log,
1404 [ad_host, ad_p1, ad_p2],
1405 [None, None, None],
1406 [is_host_in_call, None, None],
1407 reject_once=reject_once)
1408
1409 if call_ab_id is None:
1410 if disable_cw:
1411 set_call_waiting(log, ad_host, enable=1)
1412 if str(getattr(ad_host, "exception", None)) == \
1413 "PhoneA call PhoneC failed.":
1414 ads[0].log.info("PhoneA failed to call PhoneC due to call"
1415 " waiting being disabled.")
1416 delattr(ad_host, "exception")
1417 return True
1418 log.error("Failed to get call_ab_id")
1419 return False
1420 else:
1421 if disable_cw:
1422 set_call_waiting(log, ad_host, enable=0)
1423 return False
1424
1425 calls = ads[0].droid.telecomCallGetCallIds()
1426 ads[0].log.info("Calls in PhoneA %s", calls)
1427 if num_active_calls(log, ads[0]) != 2:
1428 return False
1429 if calls[0] == call_ab_id:
1430 call_ac_id = calls[1]
1431 else:
1432 call_ac_id = calls[0]
1433
1434 if call_ac_id is None:
1435 log.error("Failed to get call_ac_id")
1436 return False
1437
1438 num_swaps = 2
Markus Liufdef3062021-06-27 15:08:29 +08001439 log.info("Step 5: Begin Swap x%s test.", num_swaps)
Markus Liu3bedf212021-06-16 17:39:07 +08001440 if not swap_calls(log, ads, call_ab_id, call_ac_id,
1441 num_swaps):
1442 ad_host.log.error("Swap test failed.")
1443 return False
1444
1445 if not merge:
1446 result = True
1447 if not hangup_call(log, ads[1]):
1448 result = False
1449 if not hangup_call(log, ads[2]):
1450 result = False
1451 return result
1452 else:
Markus Liufdef3062021-06-27 15:08:29 +08001453 log.info("Step 6: Merge calls.")
Markus Liu3bedf212021-06-16 17:39:07 +08001454
1455 if re.search('csfb|2g|3g', host_rat[host_slot].lower(), re.I):
1456 return _test_wcdma_conference_merge_drop(
1457 log, ads, call_ab_id, call_ac_id)
1458 else:
1459 return _test_ims_conference_merge_drop_second_call_from_participant(
Markus Liu481eccd2021-04-21 14:36:15 +08001460 log, ads, call_ab_id, call_ac_id)