1#!/usr/bin/env python3 2# 3# Copyright 2022 - 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 17from datetime import datetime, timedelta 18import re 19import time 20from typing import Optional, Sequence 21 22from acts import signals 23from acts import tracelogger 24from acts.controllers.android_device import AndroidDevice 25from acts.utils import rand_ascii_str 26from acts.libs.proc.job import TimeoutError 27from acts.libs.utils.multithread import multithread_func 28from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult 29from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger 30from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID 31from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE 32from acts_contrib.test_utils.tel.tel_defines import SimSlotInfo 33from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 34from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 35from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED 36from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME 37from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test 38from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video 39from acts_contrib.test_utils.tel.tel_message_utils import log_messaging_screen_shot 40from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify 41from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify_for_subscription 42from acts_contrib.test_utils.tel.tel_ss_utils import erase_call_forwarding_by_mmi 43from acts_contrib.test_utils.tel.tel_ss_utils import set_call_forwarding_by_mmi 44from acts_contrib.test_utils.tel.tel_ss_utils import set_call_waiting 45from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc_for_subscription 46from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription 47from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general 48from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat 49from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_idle 50from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_forwarding_short_seq 51from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_waiting_short_seq 52from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id 53from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id 54from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id 55from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id 56from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid 57from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index 58from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad 59from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot 60from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid 61from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data 62from acts_contrib.test_utils.tel.tel_subscription_utils import set_voice_sub_id 63from acts_contrib.test_utils.tel.tel_test_utils import change_slot 64from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name 65from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls 66from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim 67from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim 68from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode 69from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state 70from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection 71from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant 72from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_wcdma_conference_merge_drop 73from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mt 74from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown 75from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call 76from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call 77from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat 78from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls 79from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot 80from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_reject_call_for_subscription 81from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected 82from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state 83 84CallResult = TelephonyVoiceTestResult.CallResult.Value 85 86 87def dsds_dds_swap_message_streaming_test( 88 log: tracelogger.TraceLogger, 89 ads: Sequence[AndroidDevice], 90 sim_slot: Sequence[SimSlotInfo], 91 test_rat: Sequence[str], 92 test_slot: Sequence[SimSlotInfo] = [ 93 SimSlotInfo.SLOT_0, 94 SimSlotInfo.SLOT_1, 95 SimSlotInfo.SLOT_0], 96 init_dds: int = 0, 97 msg_type: str = "SMS", 98 direction: str = "mt", 99 streaming: bool = True, 100 expected_result: bool = True) -> bool: 101 """Make MO/MT message at specific slot in specific RAT with DDS at 102 specific slot and do the same steps after dds swap. 103 104 Args: 105 log: Logger object. 106 ads: A list of Android device objects. 107 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 108 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 109 test_rat: RAT for both slots of primary device. 110 test_slot: The slot which make/receive MO/MT SMS/MMS of primary device. 111 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1, SimSlotInfo.SLOT_0] 112 dds_slot: Preferred data slot of primary device. 113 msg_type: SMS or MMS to send. 114 direction: The direction of message("mo" or "mt") at first. 115 streaming: True for playing Youtube before send/receive SMS/MMS and 116 False on the contrary. 117 expected_result: True or False 118 119 Returns: 120 TestFailure if failed. 121 """ 122 result = True 123 to_change_slot = True 124 dds_slot = [sim.value[0] for sim in sim_slot] 125 if init_dds != dds_slot[0]: 126 dds_slot = dds_slot[::-1] 127 dds_slot.append(dds_slot[0]) 128 else: 129 dds_slot.append(init_dds) 130 131 for test_slot, dds_slot in zip(test_slot, dds_slot): 132 ads[0].log.info("test_slot: %d, dds_slot: %d", test_slot, dds_slot) 133 result = result and dsds_message_streaming_test( 134 log=log, 135 ads=ads, 136 sim_slot=sim_slot, 137 test_rat=test_rat, 138 test_slot=test_slot, 139 dds_slot=dds_slot, 140 msg_type=msg_type, 141 direction=direction, 142 to_change_slot=to_change_slot, 143 streaming=streaming, 144 expected_result=expected_result 145 ) 146 to_change_slot = False 147 if not result: 148 return result 149 150 return result 151 152 153def dsds_dds_swap_call_streaming_test( 154 log: tracelogger.TraceLogger, 155 tel_logger: TelephonyMetricLogger.for_test_case, 156 ads: Sequence[AndroidDevice], 157 sim_slot: Sequence[SimSlotInfo], 158 test_rat: Sequence[str], 159 init_dds: int = 0, 160 test_slot: Sequence[SimSlotInfo] = [ 161 SimSlotInfo.SLOT_0, 162 SimSlotInfo.SLOT_1, 163 SimSlotInfo.SLOT_0], 164 direction: Optional[str] = None, 165 duration: int = WAIT_TIME_IN_CALL, 166 streaming: bool = True, 167 is_airplane_mode: bool = False, 168 wfc_mode: Sequence[str] = [ 169 WFC_MODE_CELLULAR_PREFERRED, 170 WFC_MODE_CELLULAR_PREFERRED], 171 wifi_network_ssid: Optional[str] = None, 172 wifi_network_pass: Optional[str] = None, 173 turn_off_wifi_in_the_end: bool = False, 174 turn_off_airplane_mode_in_the_end: bool = False) -> bool: 175 """Make MO/MT call at specific slot in specific RAT with DDS at specific 176 slot and do the same steps after dds swap. 177 178 Args: 179 log: Logger object. 180 tel_logger: Logger object for telephony proto. 181 ads: A list of Android device objects. 182 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 183 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 184 test_rat: RAT for both slots of primary device. 185 init_dds: Initial preferred data slot of primary device. 186 test_slot: The slot which make/receive MO/MT call of primary device. 187 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1, SimSlotInfo.SLOT_0] 188 direction: The direction of call("mo" or "mt"). 189 duration: In call time of voice call. 190 streaming: True for playing Youtube and False on the contrary. 191 is_airplane_mode: True or False for WFC setup 192 wfc_mode: Cellular preferred or Wi-Fi preferred. 193 wifi_network_ssid: SSID of Wi-Fi AP. 194 wifi_network_pass: Password of Wi-Fi AP SSID. 195 turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn 196 off Wi-Fi in the end of the function. 197 turn_off_airplane_mode_in_the_end: True to turn off airplane mode and 198 False not to turn off airplane mode in the end of the function. 199 200 Returns: 201 TestFailure if failed. 202 """ 203 result = True 204 to_change_slot = True 205 dds_slot = [sim.value[0] for sim in sim_slot] 206 if init_dds != dds_slot[0]: 207 dds_slot = dds_slot[::-1] 208 dds_slot.append(dds_slot[0]) 209 else: 210 dds_slot.append(init_dds) 211 212 for test_slot, dds_slot in zip(test_slot, dds_slot): 213 ads[0].log.info("test_slot: %d, dds_slot: %d", test_slot, dds_slot) 214 result = result and dsds_call_streaming_test( 215 log=log, 216 tel_logger=tel_logger, 217 ads=ads, 218 sim_slot=sim_slot, 219 test_rat=test_rat, 220 dds_slot=dds_slot, 221 test_slot=test_slot, 222 direction=direction, 223 duration=duration, 224 to_change_slot=to_change_slot, 225 streaming=streaming, 226 is_airplane_mode=is_airplane_mode, 227 wfc_mode=wfc_mode, 228 wifi_network_ssid=wifi_network_ssid, 229 wifi_network_pass=wifi_network_pass, 230 turn_off_wifi_in_the_end=turn_off_wifi_in_the_end, 231 turn_off_airplane_mode_in_the_end=turn_off_airplane_mode_in_the_end 232 ) 233 to_change_slot = False 234 if not result: 235 return result 236 237 return result 238 239 240def dsds_call_streaming_test( 241 log: tracelogger.TraceLogger, 242 tel_logger: TelephonyMetricLogger.for_test_case, 243 ads: Sequence[AndroidDevice], 244 sim_slot: Sequence[SimSlotInfo], 245 test_rat: Sequence[str], 246 dds_slot: int, 247 test_slot: Optional[SimSlotInfo] = None, 248 direction: Optional[str] = None, 249 duration: int = WAIT_TIME_IN_CALL, 250 to_change_slot: bool = True, 251 streaming: bool = True, 252 is_airplane_mode: bool = False, 253 wfc_mode: Sequence[str] = [ 254 WFC_MODE_CELLULAR_PREFERRED, 255 WFC_MODE_CELLULAR_PREFERRED], 256 wifi_network_ssid: Optional[str] = None, 257 wifi_network_pass: Optional[str] = None, 258 turn_off_wifi_in_the_end: bool = False, 259 turn_off_airplane_mode_in_the_end: bool = False) -> bool: 260 """Make MO/MT call at specific slot in specific RAT with DDS at specific 261 slot for the given time. 262 263 Args: 264 log: Logger object. 265 tel_logger: Logger object for telephony proto. 266 ads: A list of Android device objects. 267 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 268 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 269 test_rat: RAT for both slots of primary device. 270 e.g. ["5g_volte", "5g_volte"] 271 dds_slot: Preferred data slot of primary device. 272 0 for pSIM, 273 1 for eSIM port 0, 274 2 for eSIM port 1. 275 test_slot: The slot which make/receive MO/MT call of primary device. 276 e.g. SimSlotInfo.SLOT_0 for pSIM 277 SimSlotInfo.SLOT_1 for eSIM port 0 278 SimSlotInfo.SLOT_2 for eSIM port 1 279 direction: The direction of call("mo" or "mt"). 280 duration: In call time of voice call. 281 to_change_slot: True to change slot, False otherwise. 282 streaming: True for playing Youtube and False on the contrary. 283 is_airplane_mode: True or False for WFC setup 284 wfc_mode: Cellular preferred or Wi-Fi preferred. 285 wifi_network_ssid: SSID of Wi-Fi AP. 286 wifi_network_pass: Password of Wi-Fi AP SSID. 287 turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn 288 off Wi-Fi in the end of the function. 289 turn_off_airplane_mode_in_the_end: True to turn off airplane mode and 290 False not to turn off airplane mode in the end of the function. 291 292 Returns: 293 TestFailure if failed. 294 """ 295 rat_dict = dict((x, y) for x, y in list(zip(sim_slot, test_rat))) 296 wfc_mode_dict = dict((x, y) for x, y in list(zip(sim_slot, wfc_mode))) 297 298 if to_change_slot: 299 log.info("Step 0: Switch to specific SIM slot combination.") 300 try: 301 change_slot(ads[0], sim_slot) 302 except TimeoutError: 303 ads[0].log.warning("Device not support MEP.") 304 305 log.info("Step 1: Switch DDS.") 306 if not set_dds_on_slot(ads[0], dds_slot): 307 ads[0].log.error( 308 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 309 return False 310 311 log.info("Step 2: Check HTTP connection after DDS switch.") 312 if not verify_http_connection(log, ads[0]): 313 ads[0].log.error("Failed to verify http connection.") 314 return False 315 else: 316 ads[0].log.info("Verify http connection successfully.") 317 318 log.info("Step 3: Set up phones in desired RAT.") 319 if test_slot: 320 non_test_slot = list(set(sim_slot) - set([test_slot]))[0] 321 if direction == "mo": 322 # setup voice subid on primary device. 323 ad_mo = ads[0] 324 mo_sub_id = get_subid_from_slot_index(log, ad_mo, test_slot.value[0]) 325 if mo_sub_id == INVALID_SUB_ID: 326 ad_mo.log.warning("Failed to get sub ID at slot %s.", test_slot.value[0]) 327 return False 328 mo_other_sub_id = get_subid_from_slot_index( 329 log, ad_mo, non_test_slot.value[0]) 330 sub_id_list = [mo_sub_id, mo_other_sub_id] 331 set_voice_sub_id(ad_mo, mo_sub_id) 332 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", test_slot.value[0], 333 get_outgoing_voice_sub_id(ad_mo)) 334 335 # setup voice subid on secondary device. 336 ad_mt = ads[1] 337 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 338 if mt_sub_id == INVALID_SUB_ID: 339 ad_mt.log.warning("Failed to get sub ID at default voice slot.") 340 return False 341 mo_slot = test_slot.value[0] 342 mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id) 343 set_voice_sub_id(ad_mt, mt_sub_id) 344 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot, 345 get_outgoing_voice_sub_id(ad_mt)) 346 347 # setup the rat on non-test slot(primary device). 348 phone_setup_on_rat( 349 log, 350 ad_mo, 351 rat_dict[non_test_slot], 352 mo_other_sub_id, 353 is_airplane_mode, 354 wfc_mode_dict[non_test_slot], 355 wifi_network_ssid, 356 wifi_network_pass) 357 # assign phone setup argv for test slot. 358 mo_phone_setup_func_argv = ( 359 log, 360 ad_mo, 361 rat_dict[test_slot], 362 mo_sub_id, 363 is_airplane_mode, 364 wfc_mode_dict[test_slot], 365 wifi_network_ssid, 366 wifi_network_pass) 367 verify_caller_func = is_phone_in_call_on_rat( 368 log, ad_mo, rat_dict[test_slot], only_return_fn=True) 369 mt_phone_setup_func_argv = (log, ad_mt, 'general') 370 verify_callee_func = is_phone_in_call_on_rat( 371 log, ad_mt, 'general', only_return_fn=True) 372 elif direction == "mt": 373 # setup voice subid on primary device. 374 ad_mt = ads[0] 375 mt_sub_id = get_subid_from_slot_index(log, ad_mt, test_slot.value[0]) 376 if mt_sub_id == INVALID_SUB_ID: 377 ad_mt.log.warning("Failed to get sub ID at slot %s.", test_slot.value[0]) 378 return False 379 mt_other_sub_id = get_subid_from_slot_index( 380 log, ad_mt, non_test_slot.value[0]) 381 sub_id_list = [mt_sub_id, mt_other_sub_id] 382 set_voice_sub_id(ad_mt, mt_sub_id) 383 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", test_slot.value[0], 384 get_outgoing_voice_sub_id(ad_mt)) 385 386 # setup voice subid on secondary device. 387 ad_mo = ads[1] 388 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 389 if mo_sub_id == INVALID_SUB_ID: 390 ad_mo.log.warning("Failed to get sub ID at default voice slot.") 391 return False 392 mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id) 393 mt_slot = test_slot.value[0] 394 set_voice_sub_id(ad_mo, mo_sub_id) 395 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot, 396 get_outgoing_voice_sub_id(ad_mo)) 397 398 # setup the rat on non-test slot(primary device). 399 phone_setup_on_rat( 400 log, 401 ad_mt, 402 rat_dict[non_test_slot], 403 mt_other_sub_id, 404 is_airplane_mode, 405 wfc_mode_dict[non_test_slot], 406 wifi_network_ssid, 407 wifi_network_pass) 408 # assign phone setup argv for test slot. 409 mt_phone_setup_func_argv = ( 410 log, 411 ad_mt, 412 rat_dict[test_slot], 413 mt_sub_id, 414 is_airplane_mode, 415 wfc_mode_dict[test_slot], 416 wifi_network_ssid, 417 wifi_network_pass) 418 verify_callee_func = is_phone_in_call_on_rat( 419 log, ad_mt, rat_dict[test_slot], only_return_fn=True) 420 mo_phone_setup_func_argv = (log, ad_mo, 'general') 421 verify_caller_func = is_phone_in_call_on_rat( 422 log, ad_mo, 'general', only_return_fn=True) 423 else: 424 return True 425 426 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv), 427 (phone_setup_on_rat, mt_phone_setup_func_argv)] 428 if not multithread_func(log, tasks): 429 log.error("Phone Failed to Set Up Properly.") 430 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 431 raise signals.TestFailure("Failed", 432 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 433 if streaming: 434 log.info("Step 4-0: Start Youtube streaming.") 435 if not start_youtube_video(ads[0]): 436 raise signals.TestFailure("Failed", 437 extras={"fail_reason": "Fail to bring up youtube video."}) 438 time.sleep(10) 439 440 log.info("Step 4: Make voice call.") 441 result = call_setup_teardown(log, 442 ad_mo, 443 ad_mt, 444 ad_hangup=ad_mo, 445 verify_caller_func=verify_caller_func, 446 verify_callee_func=verify_callee_func, 447 wait_time_in_call=duration) 448 tel_logger.set_result(result.result_value) 449 450 if not result: 451 log.error( 452 "Failed to make %s call from %s slot %s to %s slot %s", 453 direction, ad_mo.serial, mo_slot, ad_mt.serial, mt_slot) 454 raise signals.TestFailure("Failed", 455 extras={"fail_reason": str(result.result_value)}) 456 457 log.info("Step 5: Verify RAT and HTTP connection.") 458 # For the tese cases related to WFC in which airplane mode will be turned 459 # off in the end. 460 if turn_off_airplane_mode_in_the_end: 461 log.info("Step 5-1: Turning off airplane mode......") 462 if not toggle_airplane_mode(log, ads[0], False): 463 ads[0].log.error('Failed to toggle off airplane mode.') 464 465 # For the tese cases related to WFC in which Wi-Fi will be turned off in the 466 # end. 467 rat_list = [rat_dict[test_slot], rat_dict[non_test_slot]] 468 469 if turn_off_wifi_in_the_end: 470 log.info("Step 5-2: Turning off Wi-Fi......") 471 if not wifi_toggle_state(log, ads[0], False): 472 ads[0].log.error('Failed to toggle off Wi-Fi.') 473 return False 474 475 for index, value in enumerate(rat_list): 476 if value == '5g_wfc': 477 rat_list[index] = '5g' 478 elif value == 'wfc': 479 rat_list[index] = '4g' 480 481 for rat, sub_id in zip(rat_list, sub_id_list): 482 if not wait_for_network_idle(log, ads[0], rat, sub_id): 483 raise signals.TestFailure( 484 "Failed", 485 extras={ 486 "fail_reason": "Idle state of sub ID %s does not match the " 487 "given RAT %s." % (sub_id, rat)}) 488 489 if not verify_http_connection(log, ads[0]): 490 ads[0].log.error("Failed to verify http connection.") 491 return False 492 else: 493 ads[0].log.info("Verify http connection successfully.") 494 495 if streaming: 496 ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME) 497 498 return True 499 500 501def dsds_voice_call_test( 502 log, 503 tel_logger, 504 ads, 505 mo_slot, 506 mt_slot, 507 dds, 508 mo_rat=["", ""], 509 mt_rat=["", ""], 510 call_direction="mo", 511 is_airplane_mode=False, 512 wfc_mode=[ 513 WFC_MODE_CELLULAR_PREFERRED, 514 WFC_MODE_CELLULAR_PREFERRED], 515 wifi_network_ssid=None, 516 wifi_network_pass=None, 517 turn_off_wifi_in_the_end=False, 518 turn_off_airplane_mode_in_the_end=False): 519 """Make MO/MT voice call at specific slot in specific RAT with DDS at 520 specific slot. 521 522 Test step: 523 1. Get sub IDs of specific slots of both MO and MT devices. 524 2. Switch DDS to specific slot. 525 3. Check HTTP connection after DDS switch. 526 4. Set up phones in desired RAT. 527 5. Make voice call. 528 6. Turn off airplane mode if necessary. 529 7. Turn off Wi-Fi if necessary. 530 8. Verify RAT and HTTP connection. 531 532 Args: 533 log: logger object 534 tel_logger: logger object for telephony proto 535 ads: list of android devices 536 mo_slot: Slot making MO call (0 or 1) 537 mt_slot: Slot receiving MT call (0 or 1) 538 dds: Preferred data slot 539 mo_rat: RAT for both slots of MO device 540 mt_rat: RAT for both slots of MT device 541 call_direction: "mo" or "mt" 542 is_airplane_mode: True or False for WFC setup 543 wfc_mode: Cellular preferred or Wi-Fi preferred. 544 wifi_network_ssid: SSID of Wi-Fi AP 545 wifi_network_pass: Password of Wi-Fi AP SSID 546 turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn 547 off Wi-Fi in the end of the function. 548 turn_off_airplane_mode_in_the_end: True to turn off airplane mode and 549 False not to turn off airplane mode in the end of the function. 550 551 Returns: 552 TestFailure if failed. 553 """ 554 if not toggle_airplane_mode(log, ads[0], False): 555 ads[0].log.error("Failed to disable airplane mode.") 556 return False 557 558 if call_direction == "mo": 559 ad_mo = ads[0] 560 ad_mt = ads[1] 561 else: 562 ad_mo = ads[1] 563 ad_mt = ads[0] 564 565 if mo_slot is not None: 566 mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot) 567 if mo_sub_id == INVALID_SUB_ID: 568 ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot) 569 return False 570 mo_other_sub_id = get_subid_from_slot_index( 571 log, ad_mo, 1-mo_slot) 572 set_voice_sub_id(ad_mo, mo_sub_id) 573 else: 574 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 575 if mo_sub_id == INVALID_SUB_ID: 576 ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot) 577 return False 578 mo_slot = "auto" 579 set_voice_sub_id(ad_mo, mo_sub_id) 580 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", 581 mo_slot, get_outgoing_voice_sub_id(ad_mo)) 582 583 if mt_slot is not None: 584 mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot) 585 if mt_sub_id == INVALID_SUB_ID: 586 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 587 return False 588 mt_other_sub_id = get_subid_from_slot_index( 589 log, ad_mt, 1-mt_slot) 590 set_voice_sub_id(ad_mt, mt_sub_id) 591 else: 592 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 593 if mt_sub_id == INVALID_SUB_ID: 594 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 595 return False 596 mt_slot = "auto" 597 set_voice_sub_id(ad_mt, mt_sub_id) 598 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot, 599 get_incoming_voice_sub_id(ad_mt)) 600 601 log.info("Step 1: Switch DDS.") 602 if not set_dds_on_slot(ads[0], dds): 603 log.error( 604 "Failed to set DDS at slot %s on %s",(dds, ads[0].serial)) 605 return False 606 607 log.info("Step 2: Check HTTP connection after DDS switch.") 608 if not verify_http_connection(log, ads[0]): 609 log.error("Failed to verify http connection.") 610 return False 611 else: 612 log.info("Verify http connection successfully.") 613 614 log.info("Step 3: Set up phones in desired RAT.") 615 if mo_slot == 0 or mo_slot == 1: 616 phone_setup_on_rat( 617 log, 618 ad_mo, 619 mo_rat[1-mo_slot], 620 mo_other_sub_id, 621 is_airplane_mode, 622 wfc_mode[1-mo_slot], 623 wifi_network_ssid, 624 wifi_network_pass) 625 626 mo_phone_setup_func_argv = ( 627 log, 628 ad_mo, 629 mo_rat[mo_slot], 630 mo_sub_id, 631 is_airplane_mode, 632 wfc_mode[mo_slot], 633 wifi_network_ssid, 634 wifi_network_pass) 635 636 is_mo_in_call = is_phone_in_call_on_rat( 637 log, ad_mo, mo_rat[mo_slot], only_return_fn=True) 638 else: 639 mo_phone_setup_func_argv = (log, ad_mo, 'general') 640 is_mo_in_call = is_phone_in_call_on_rat( 641 log, ad_mo, 'general', only_return_fn=True) 642 643 if mt_slot == 0 or mt_slot == 1: 644 phone_setup_on_rat( 645 log, 646 ad_mt, 647 mt_rat[1-mt_slot], 648 mt_other_sub_id, 649 is_airplane_mode, 650 wfc_mode[1-mt_slot], 651 wifi_network_ssid, 652 wifi_network_pass) 653 654 mt_phone_setup_func_argv = ( 655 log, 656 ad_mt, 657 mt_rat[mt_slot], 658 mt_sub_id, 659 is_airplane_mode, 660 wfc_mode[mt_slot], 661 wifi_network_ssid, 662 wifi_network_pass) 663 664 is_mt_in_call = is_phone_in_call_on_rat( 665 log, ad_mt, mt_rat[mt_slot], only_return_fn=True) 666 else: 667 mt_phone_setup_func_argv = (log, ad_mt, 'general') 668 is_mt_in_call = is_phone_in_call_on_rat( 669 log, ad_mt, 'general', only_return_fn=True) 670 671 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv), 672 (phone_setup_on_rat, mt_phone_setup_func_argv)] 673 if not multithread_func(log, tasks): 674 log.error("Phone Failed to Set Up Properly.") 675 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 676 raise signals.TestFailure("Failed", 677 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 678 679 log.info("Step 4: Make voice call.") 680 result = two_phone_call_msim_for_slot( 681 log, 682 ad_mo, 683 get_slot_index_from_subid(ad_mo, mo_sub_id), 684 None, 685 is_mo_in_call, 686 ad_mt, 687 get_slot_index_from_subid(ad_mt, mt_sub_id), 688 None, 689 is_mt_in_call) 690 691 tel_logger.set_result(result.result_value) 692 693 if not result: 694 log.error( 695 "Failed to make MO call from %s slot %s to %s slot %s", 696 ad_mo.serial, mo_slot, ad_mt.serial, mt_slot) 697 raise signals.TestFailure("Failed", 698 extras={"fail_reason": str(result.result_value)}) 699 700 log.info("Step 5: Verify RAT and HTTP connection.") 701 if call_direction == "mo": 702 rat_list = [mo_rat[mo_slot], mo_rat[1-mo_slot]] 703 sub_id_list = [mo_sub_id, mo_other_sub_id] 704 else: 705 rat_list = [mt_rat[mt_slot], mt_rat[1-mt_slot]] 706 sub_id_list = [mt_sub_id, mt_other_sub_id] 707 708 # For the tese cases related to WFC in which airplane mode will be turned 709 # off in the end. 710 if turn_off_airplane_mode_in_the_end: 711 log.info("Step 5-1: Turning off airplane mode......") 712 if not toggle_airplane_mode(log, ads[0], False): 713 ads[0].log.error('Failed to toggle off airplane mode.') 714 715 # For the tese cases related to WFC in which Wi-Fi will be turned off in the 716 # end. 717 if turn_off_wifi_in_the_end: 718 log.info("Step 5-2: Turning off Wi-Fi......") 719 if not wifi_toggle_state(log, ads[0], False): 720 ads[0].log.error('Failed to toggle off Wi-Fi.') 721 return False 722 723 for index, value in enumerate(rat_list): 724 if value == '5g_wfc': 725 rat_list[index] = '5g' 726 elif value == 'wfc': 727 rat_list[index] = '4g' 728 729 for rat, sub_id in zip(rat_list, sub_id_list): 730 if not wait_for_network_idle(log, ads[0], rat, sub_id): 731 raise signals.TestFailure( 732 "Failed", 733 extras={ 734 "fail_reason": "Idle state of sub ID %s does not match the " 735 "given RAT %s." % (sub_id, rat)}) 736 737 738def dsds_message_streaming_test( 739 log: tracelogger.TraceLogger, 740 ads: Sequence[AndroidDevice], 741 sim_slot: Sequence[SimSlotInfo], 742 test_rat: Sequence[str], 743 test_slot: SimSlotInfo, 744 dds_slot: int, 745 msg_type: str = "SMS", 746 direction: str = "mt", 747 to_change_slot: bool = True, 748 streaming: bool = True, 749 expected_result: bool = True) -> bool: 750 """Make MO or MT SMS/MMS at specific slot in specific RAT with DDS at 751 specific slot. 752 753 Test step: 754 1. Get sub IDs of specific slots of both MO and MT devices. 755 2. Switch DDS to specific slot. 756 3. Check HTTP connection after DDS switch. 757 4. Set up phones in desired RAT. 758 5. Receive and Send SMS/MMS. 759 760 Args: 761 log: Logger object. 762 ads: A list of Android device objects. 763 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 764 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 765 test_rat: RAT for both slots of primary device. 766 e.g. ["5g_volte", "5g_volte"] 767 test_slot: The slot which make/receive MO/MT call of primary device. 768 e.g. SimSlotInfo.SLOT_0 for pSIM 769 SimSlotInfo.SLOT_1 for eSIM port 0 770 SimSlotInfo.SLOT_2 for eSIM port 1 771 dds_slot: Preferred data slot of primary device. 772 0 for pSIM, 773 1 for eSIM port 0, 774 2 for eSIM port 1. 775 msg_type: SMS or MMS to send. 776 direction: The direction of message("mo" or "mt") at first. 777 to_change_slot: True to change slot, False otherwise. 778 streaming: True for playing Youtube before send/receive SMS/MMS and 779 False on the contrary. 780 expected_result: True or False 781 782 Returns: 783 TestFailure if failed. 784 """ 785 rat_dict = dict((x, y) for x, y in list(zip(sim_slot, test_rat))) 786 787 if to_change_slot: 788 log.info("Step 0: Switch to specific SIM slot combination.") 789 try: 790 change_slot(ads[0], sim_slot) 791 except TimeoutError: 792 ads[0].log.warning("Device not support MEP.") 793 794 log.info("Step 1: Switch DDS.") 795 if not set_dds_on_slot(ads[0], dds_slot): 796 ads[0].log.error( 797 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 798 return False 799 800 log.info("Step 2: Check HTTP connection after DDS switch.") 801 if not verify_http_connection(log, ads[0]): 802 ads[0].log.error("Failed to verify http connection.") 803 return False 804 else: 805 ads[0].log.info("Verify http connection successfully.") 806 807 log.info("Step 3: Set up phones in desired RAT.") 808 non_test_slot = list(set(sim_slot) - set([test_slot]))[0] 809 if direction == "mo": 810 # setup message subid on primary device. 811 ad_mo = ads[0] 812 mo_sub_id = get_subid_from_slot_index(log, ad_mo, test_slot.value[0]) 813 if mo_sub_id == INVALID_SUB_ID: 814 ad_mo.log.warning("Failed to get sub ID at slot %s.", test_slot.value[0]) 815 return False 816 mo_other_sub_id = get_subid_from_slot_index( 817 log, ad_mo, non_test_slot.value[0]) 818 sub_id_list = [mo_sub_id, mo_other_sub_id] 819 set_message_subid(ad_mo, mo_sub_id) 820 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", test_slot.value[0], 821 get_outgoing_message_sub_id(ad_mo)) 822 823 # setup message subid on secondary device. 824 ad_mt = ads[1] 825 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads, type="sms") 826 if mt_sub_id == INVALID_SUB_ID: 827 ad_mt.log.warning("Failed to get sub ID at default voice slot.") 828 return False 829 mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id) 830 set_message_subid(ad_mt, mt_sub_id) 831 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot, 832 get_outgoing_message_sub_id(ad_mt)) 833 834 # setup the rat on non-test slot(primary device). 835 phone_setup_on_rat( 836 log, 837 ad_mo, 838 rat_dict[non_test_slot], 839 mo_other_sub_id) 840 # assign phone setup argv for test slot. 841 mo_phone_setup_func_argv = ( 842 log, 843 ad_mo, 844 rat_dict[test_slot], 845 mo_sub_id) 846 mt_phone_setup_func_argv = (log, ad_mt, 'general') 847 else: 848 # setup message subid on primary device. 849 ad_mt = ads[0] 850 mt_sub_id = get_subid_from_slot_index(log, ad_mt, test_slot.value[0]) 851 if mt_sub_id == INVALID_SUB_ID: 852 ad_mt.log.warning("Failed to get sub ID at slot %s.", test_slot.value[0]) 853 return False 854 mt_other_sub_id = get_subid_from_slot_index( 855 log, ad_mt, non_test_slot.value[0]) 856 sub_id_list = [mt_sub_id, mt_other_sub_id] 857 set_message_subid(ad_mt, mt_sub_id) 858 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", test_slot.value[0], 859 get_outgoing_message_sub_id(ad_mt)) 860 861 # setup message subid on secondary device. 862 ad_mo = ads[1] 863 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads, type="sms") 864 if mo_sub_id == INVALID_SUB_ID: 865 ad_mo.log.warning("Failed to get sub ID at default voice slot.") 866 return False 867 mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id) 868 set_message_subid(ad_mo, mo_sub_id) 869 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot, 870 get_outgoing_message_sub_id(ad_mo)) 871 872 # setup the rat on non-test slot(primary device). 873 phone_setup_on_rat( 874 log, 875 ad_mt, 876 rat_dict[non_test_slot], 877 mt_other_sub_id) 878 # assign phone setup argv for test slot. 879 mt_phone_setup_func_argv = ( 880 log, 881 ad_mt, 882 rat_dict[test_slot], 883 mt_sub_id) 884 mo_phone_setup_func_argv = (log, ad_mo, 'general') 885 886 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv), 887 (phone_setup_on_rat, mt_phone_setup_func_argv)] 888 if not multithread_func(log, tasks): 889 log.error("Phone Failed to Set Up Properly.") 890 raise signals.TestFailure("Failed", 891 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 892 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 893 894 if streaming: 895 log.info("Step 4-0: Start Youtube streaming.") 896 if not start_youtube_video(ads[0]): 897 raise signals.TestFailure("Failed", 898 extras={"fail_reason": "Fail to bring up youtube video."}) 899 time.sleep(10) 900 901 log.info("Step 4: Send %s.", msg_type) 902 if msg_type == "MMS": 903 for ad, current_data_sub_id, current_msg_sub_id in [ 904 [ ads[0], 905 get_default_data_sub_id(ads[0]), 906 get_outgoing_message_sub_id(ads[0]) ], 907 [ ads[1], 908 get_default_data_sub_id(ads[1]), 909 get_outgoing_message_sub_id(ads[1]) ]]: 910 if current_data_sub_id != current_msg_sub_id: 911 ad.log.warning( 912 "Current data sub ID (%s) does not match message" 913 " sub ID (%s). MMS should NOT be sent.", 914 current_data_sub_id, 915 current_msg_sub_id) 916 expected_result = False 917 918 result = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id, 919 msg=msg_type, expected_result=expected_result) 920 921 if not result: 922 log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg_type) 923 log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg_type) 924 925 log.info("Step 5: Verify RAT and HTTP connection.") 926 rat_list = [rat_dict[test_slot], rat_dict[non_test_slot]] 927 for rat, sub_id in zip(rat_list, sub_id_list): 928 if not wait_for_network_idle(log, ads[0], rat, sub_id): 929 raise signals.TestFailure( 930 "Failed", 931 extras={ 932 "fail_reason": "Idle state of sub ID %s does not match the " 933 "given RAT %s." % (sub_id, rat)}) 934 935 if streaming: 936 ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME) 937 938 return result 939 940 941def dsds_message_test( 942 log, 943 ads, 944 mo_slot, 945 mt_slot, 946 dds_slot, 947 msg="SMS", 948 mo_rat=["", ""], 949 mt_rat=["", ""], 950 direction="mo", 951 streaming=False, 952 expected_result=True): 953 """Make MO/MT SMS/MMS at specific slot in specific RAT with DDS at 954 specific slot. 955 956 Test step: 957 1. Get sub IDs of specific slots of both MO and MT devices. 958 2. Switch DDS to specific slot. 959 3. Check HTTP connection after DDS switch. 960 4. Set up phones in desired RAT. 961 5. Send SMS/MMS. 962 963 Args: 964 mo_slot: Slot sending MO SMS (0 or 1) 965 mt_slot: Slot receiving MT SMS (0 or 1) 966 dds_slot: Preferred data slot 967 mo_rat: RAT for both slots of MO device 968 mt_rat: RAT for both slots of MT device 969 direction: "mo" or "mt" 970 streaming: True for playing Youtube before send/receive SMS/MMS and 971 False on the contrary. 972 expected_result: True or False 973 974 Returns: 975 TestFailure if failed. 976 """ 977 if direction == "mo": 978 ad_mo = ads[0] 979 ad_mt = ads[1] 980 else: 981 ad_mo = ads[1] 982 ad_mt = ads[0] 983 984 if mo_slot is not None: 985 mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot) 986 if mo_sub_id == INVALID_SUB_ID: 987 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot) 988 return False 989 mo_other_sub_id = get_subid_from_slot_index( 990 log, ad_mo, 1-mo_slot) 991 set_message_subid(ad_mo, mo_sub_id) 992 else: 993 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad( 994 ads, type="sms") 995 if mo_sub_id == INVALID_SUB_ID: 996 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot) 997 return False 998 mo_slot = "auto" 999 set_message_subid(ad_mo, mo_sub_id) 1000 if msg == "MMS": 1001 set_subid_for_data(ad_mo, mo_sub_id) 1002 ad_mo.droid.telephonyToggleDataConnection(True) 1003 ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot, 1004 get_outgoing_message_sub_id(ad_mo)) 1005 1006 if mt_slot is not None: 1007 mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot) 1008 if mt_sub_id == INVALID_SUB_ID: 1009 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 1010 return False 1011 mt_other_sub_id = get_subid_from_slot_index(log, ad_mt, 1-mt_slot) 1012 set_message_subid(ad_mt, mt_sub_id) 1013 else: 1014 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 1015 ads, type="sms") 1016 if mt_sub_id == INVALID_SUB_ID: 1017 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 1018 return False 1019 mt_slot = "auto" 1020 set_message_subid(ad_mt, mt_sub_id) 1021 if msg == "MMS": 1022 set_subid_for_data(ad_mt, mt_sub_id) 1023 ad_mt.droid.telephonyToggleDataConnection(True) 1024 ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot, 1025 get_outgoing_message_sub_id(ad_mt)) 1026 1027 log.info("Step 1: Switch DDS.") 1028 if not set_dds_on_slot(ads[0], dds_slot): 1029 log.error( 1030 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 1031 return False 1032 1033 log.info("Step 2: Check HTTP connection after DDS switch.") 1034 if not verify_http_connection(log, ads[0]): 1035 log.error("Failed to verify http connection.") 1036 return False 1037 else: 1038 log.info("Verify http connection successfully.") 1039 1040 if mo_slot == 0 or mo_slot == 1: 1041 phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id) 1042 mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id) 1043 else: 1044 mo_phone_setup_func_argv = (log, ad_mo, 'general', mo_sub_id) 1045 1046 if mt_slot == 0 or mt_slot == 1: 1047 phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id) 1048 mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id) 1049 else: 1050 mt_phone_setup_func_argv = (log, ad_mt, 'general', mt_sub_id) 1051 1052 log.info("Step 3: Set up phones in desired RAT.") 1053 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv), 1054 (phone_setup_on_rat, mt_phone_setup_func_argv)] 1055 if not multithread_func(log, tasks): 1056 log.error("Phone Failed to Set Up Properly.") 1057 return False 1058 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 1059 1060 if streaming: 1061 log.info("Step 4: Start Youtube streaming.") 1062 if not start_youtube_video(ads[0]): 1063 log.warning("Fail to bring up youtube video") 1064 time.sleep(10) 1065 else: 1066 log.info("Step 4: Skip Youtube streaming.") 1067 1068 log.info("Step 5: Send %s.", msg) 1069 if msg == "MMS": 1070 for ad, current_data_sub_id, current_msg_sub_id in [ 1071 [ ads[0], 1072 get_default_data_sub_id(ads[0]), 1073 get_outgoing_message_sub_id(ads[0]) ], 1074 [ ads[1], 1075 get_default_data_sub_id(ads[1]), 1076 get_outgoing_message_sub_id(ads[1]) ]]: 1077 if current_data_sub_id != current_msg_sub_id: 1078 ad.log.warning( 1079 "Current data sub ID (%s) does not match message" 1080 " sub ID (%s). MMS should NOT be sent.", 1081 current_data_sub_id, 1082 current_msg_sub_id) 1083 expected_result = False 1084 1085 result = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id, 1086 msg=msg, expected_result=expected_result) 1087 1088 if not result: 1089 log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg) 1090 log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg) 1091 1092 if streaming: 1093 ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME) 1094 return result 1095 1096 1097def dds_switch_during_data_transfer_test( 1098 log, 1099 tel_logger, 1100 ads, 1101 nw_rat=["volte", "volte"], 1102 call_slot=0, 1103 call_direction=None, 1104 call_or_sms_or_mms="call", 1105 streaming=True, 1106 is_airplane_mode=False, 1107 wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED], 1108 wifi_network_ssid=None, 1109 wifi_network_pass=None): 1110 """Switch DDS and make voice call(VoLTE/WFC/CS call)/SMS/MMS together with 1111 Youtube playing after each DDS switch at specific slot in specific RAT. 1112 1113 Test step: 1114 1. Get sub ID of each slot of the primary device. 1115 2. Set up phones in desired RAT. 1116 3. Switch DDS to slot 0. 1117 4. Check HTTP connection after DDS switch. 1118 5. Play Youtube. 1119 6. Make voice call (VoLTE/WFC/CS call)/SMS/MMS 1120 7. Switch DDS to slot 1 and repeat step 4-6. 1121 8. Switch DDS to slot 0 again and repeat step 4-6. 1122 1123 Args: 1124 log: logger object 1125 tel_logger: logger object for telephony proto 1126 ads: list of android devices 1127 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 1128 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 1129 nw_rat: RAT for both slots of the primary device 1130 call_slot: Slot for making voice call 1131 call_direction: "mo" or "mt" or None to stoping making call. 1132 call_or_sms_or_mms: Voice call or SMS or MMS 1133 streaming: True for playing Youtube after DDS switch and False on the contrary. 1134 is_airplane_mode: True or False for WFC setup 1135 wfc_mode: Cellular preferred or Wi-Fi preferred. 1136 wifi_network_ssid: SSID of Wi-Fi AP 1137 wifi_network_pass: Password of Wi-Fi AP SSID 1138 1139 Returns: 1140 TestFailure if failed. 1141 """ 1142 ad = ads[0] 1143 slot_0_subid = get_subid_from_slot_index(log, ad, 0) 1144 slot_1_subid = get_subid_from_slot_index(log, ad, 1) 1145 1146 if slot_0_subid == INVALID_SUB_ID or slot_1_subid == INVALID_SUB_ID: 1147 ad.log.error("Not all slots have valid sub ID.") 1148 raise signals.TestFailure("Failed", 1149 extras={"fail_reason": "Not all slots have valid sub ID"}) 1150 1151 ad.log.info( 1152 "Step 0: Set up phone in desired RAT (slot 0: %s, slot 1: %s)", 1153 nw_rat[0], nw_rat[1]) 1154 1155 if not phone_setup_on_rat( 1156 log, 1157 ad, 1158 nw_rat[0], 1159 slot_0_subid, 1160 is_airplane_mode, 1161 wfc_mode[0], 1162 wifi_network_ssid, 1163 wifi_network_pass): 1164 log.error("Phone Failed to Set Up Properly.") 1165 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 1166 raise signals.TestFailure("Failed", 1167 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 1168 1169 if not phone_setup_on_rat( 1170 log, 1171 ad, 1172 nw_rat[1], 1173 slot_1_subid, 1174 is_airplane_mode, 1175 wfc_mode[1], 1176 wifi_network_ssid, 1177 wifi_network_pass): 1178 log.error("Phone Failed to Set Up Properly.") 1179 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 1180 raise signals.TestFailure("Failed", 1181 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 1182 1183 is_slot0_in_call = is_phone_in_call_on_rat( 1184 log, ad, nw_rat[0], True) 1185 is_slot1_in_call = is_phone_in_call_on_rat( 1186 log, ad, nw_rat[1], True) 1187 1188 for attempt in range(3): 1189 if attempt != 0: 1190 ad.log.info("Repeat step 1 to 4.") 1191 1192 ad.log.info("Step 1: Switch DDS.") 1193 if attempt % 2 == 0: 1194 set_dds_on_slot(ad, 0) 1195 else: 1196 set_dds_on_slot(ad, 1) 1197 1198 ad.log.info("Step 2: Check HTTP connection after DDS switch.") 1199 if not verify_http_connection(log, ad): 1200 ad.log.error("Failed to verify http connection.") 1201 return False 1202 else: 1203 ad.log.info("Verify http connection successfully.") 1204 1205 if streaming: 1206 ad.log.info("Step 3: Start Youtube streaming.") 1207 if not start_youtube_video(ad): 1208 ad.log.warning("Fail to bring up youtube video") 1209 time.sleep(10) 1210 else: 1211 ad.log.info("Step 3: Skip Youtube streaming.") 1212 1213 if not call_direction: 1214 return True 1215 else: 1216 expected_result = True 1217 if call_direction == "mo": 1218 ad_mo = ads[0] 1219 ad_mt = ads[1] 1220 phone_setup_on_rat(log, ad_mt, 'general') 1221 mo_sub_id = get_subid_from_slot_index(log, ad, call_slot) 1222 if call_or_sms_or_mms == "call": 1223 set_voice_sub_id(ad_mo, mo_sub_id) 1224 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 1225 ads) 1226 1227 if call_slot == 0: 1228 is_mo_in_call = is_slot0_in_call 1229 elif call_slot == 1: 1230 is_mo_in_call = is_slot1_in_call 1231 is_mt_in_call = None 1232 1233 elif call_or_sms_or_mms == "sms": 1234 set_message_subid(ad_mo, mo_sub_id) 1235 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 1236 ads, type="sms") 1237 set_message_subid(ad_mt, mt_sub_id) 1238 1239 elif call_or_sms_or_mms == "mms": 1240 current_data_sub_id = get_default_data_sub_id(ad_mo) 1241 if mo_sub_id != current_data_sub_id: 1242 ad_mo.log.warning( 1243 "Current data sub ID (%s) does not match" 1244 " message sub ID (%s). MMS should NOT be sent.", 1245 current_data_sub_id, mo_sub_id) 1246 expected_result = False 1247 set_message_subid(ad_mo, mo_sub_id) 1248 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad( 1249 ads, type="sms") 1250 set_message_subid(ad_mt, mt_sub_id) 1251 set_subid_for_data(ad_mt, mt_sub_id) 1252 ad_mt.droid.telephonyToggleDataConnection(True) 1253 1254 elif call_direction == "mt": 1255 ad_mo = ads[1] 1256 ad_mt = ads[0] 1257 phone_setup_on_rat(log, ad_mo, 'general') 1258 mt_sub_id = get_subid_from_slot_index(log, ad, call_slot) 1259 if call_or_sms_or_mms == "call": 1260 set_voice_sub_id(ad_mt, mt_sub_id) 1261 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad( 1262 ads) 1263 1264 if call_slot == 0: 1265 is_mt_in_call = is_slot0_in_call 1266 elif call_slot == 1: 1267 is_mt_in_call = is_slot1_in_call 1268 is_mo_in_call = None 1269 1270 elif call_or_sms_or_mms == "sms": 1271 set_message_subid(ad_mt, mt_sub_id) 1272 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad( 1273 ads, type="sms") 1274 set_message_subid(ad_mo, mo_sub_id) 1275 1276 elif call_or_sms_or_mms == "mms": 1277 current_data_sub_id = get_default_data_sub_id(ad_mt) 1278 if mt_sub_id != current_data_sub_id: 1279 ad_mt.log.warning( 1280 "Current data sub ID (%s) does not match" 1281 " message sub ID (%s). MMS should NOT be" 1282 " received.", current_data_sub_id, mt_sub_id) 1283 expected_result = False 1284 set_message_subid(ad_mt, mt_sub_id) 1285 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad( 1286 ads, type="sms") 1287 set_message_subid(ad_mo, mo_sub_id) 1288 set_subid_for_data(ad_mo, mo_sub_id) 1289 ad_mo.droid.telephonyToggleDataConnection(True) 1290 1291 if call_or_sms_or_mms == "call": 1292 log.info("Step 4: Make voice call.") 1293 mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id) 1294 mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id) 1295 result = two_phone_call_msim_for_slot( 1296 log, 1297 ad_mo, 1298 mo_slot, 1299 None, 1300 is_mo_in_call, 1301 ad_mt, 1302 mt_slot, 1303 None, 1304 is_mt_in_call) 1305 tel_logger.set_result(result.result_value) 1306 1307 if not result: 1308 log.error( 1309 "Failed to make MO call from %s slot %s to %s" 1310 " slot %s", ad_mo.serial, mo_slot, ad_mt.serial, 1311 mt_slot) 1312 raise signals.TestFailure("Failed", 1313 extras={"fail_reason": str(result.result_value)}) 1314 else: 1315 log.info("Step 4: Send %s.", call_or_sms_or_mms) 1316 if call_or_sms_or_mms == "sms": 1317 result = msim_message_test( 1318 ad_mo, 1319 ad_mt, 1320 mo_sub_id, 1321 mt_sub_id, 1322 msg=call_or_sms_or_mms.upper()) 1323 elif call_or_sms_or_mms == "mms": 1324 result = msim_message_test( 1325 ad_mo, 1326 ad_mt, 1327 mo_sub_id, 1328 mt_sub_id, 1329 msg=call_or_sms_or_mms.upper(), 1330 expected_result=expected_result) 1331 if not result: 1332 log_messaging_screen_shot( 1333 ad_mo, test_name="%s_tx" % call_or_sms_or_mms) 1334 log_messaging_screen_shot( 1335 ad_mt, test_name="%s_rx" % call_or_sms_or_mms) 1336 return False 1337 if streaming: 1338 ad.force_stop_apk(YOUTUBE_PACKAGE_NAME) 1339 return True 1340 1341 1342def enable_slot_after_voice_call_test( 1343 log, 1344 tel_logger, 1345 ads, 1346 mo_slot, 1347 mt_slot, 1348 disabled_slot, 1349 mo_rat=["", ""], 1350 mt_rat=["", ""], 1351 call_direction="mo"): 1352 """Disable/enable pSIM or eSIM with voice call 1353 1354 Test step: 1355 1. Get sub IDs of specific slots of both MO and MT devices. 1356 2. Set up phones in desired RAT. 1357 3. Disable assigned slot. 1358 4. Switch DDS to the other slot. 1359 5. Verify RAT and HTTP connection after DDS switch. 1360 6. Make voice call. 1361 7. Enable assigned slot. 1362 8. Switch DDS to the assigned slot. 1363 9. Verify RAT and HTTP connection after DDS switch. 1364 1365 Args: 1366 log: logger object 1367 tel_logger: logger object for telephony proto 1368 ads: list of android devices 1369 mo_slot: Slot making MO call (0 or 1) 1370 mt_slot: Slot receiving MT call (0 or 1) 1371 disabled_slot: slot to be disabled/enabled 1372 mo_rat: RAT for both slots of MO device 1373 mt_rat: RAT for both slots of MT device 1374 call_direction: "mo" or "mt" 1375 1376 Returns: 1377 TestFailure if failed. 1378 """ 1379 if call_direction == "mo": 1380 ad_mo = ads[0] 1381 ad_mt = ads[1] 1382 else: 1383 ad_mo = ads[1] 1384 ad_mt = ads[0] 1385 1386 if mo_slot is not None: 1387 mo_sub_id = get_subid_from_slot_index(log, ad_mo, mo_slot) 1388 if mo_sub_id == INVALID_SUB_ID: 1389 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot) 1390 raise signals.TestFailure( 1391 "Failed", 1392 extras={ 1393 "fail_reason": "Failed to get sub ID at slot %s." % mo_slot}) 1394 mo_other_sub_id = get_subid_from_slot_index( 1395 log, ad_mo, 1-mo_slot) 1396 set_voice_sub_id(ad_mo, mo_sub_id) 1397 else: 1398 _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 1399 if mo_sub_id == INVALID_SUB_ID: 1400 ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot) 1401 raise signals.TestFailure( 1402 "Failed", 1403 extras={ 1404 "fail_reason": "Failed to get sub ID at slot %s." % mo_slot}) 1405 mo_slot = "auto" 1406 set_voice_sub_id(ad_mo, mo_sub_id) 1407 ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", 1408 mo_slot, get_outgoing_voice_sub_id(ad_mo)) 1409 1410 if mt_slot is not None: 1411 mt_sub_id = get_subid_from_slot_index(log, ad_mt, mt_slot) 1412 if mt_sub_id == INVALID_SUB_ID: 1413 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 1414 raise signals.TestFailure( 1415 "Failed", 1416 extras={ 1417 "fail_reason": "Failed to get sub ID at slot %s." % mt_slot}) 1418 mt_other_sub_id = get_subid_from_slot_index( 1419 log, ad_mt, 1-mt_slot) 1420 set_voice_sub_id(ad_mt, mt_sub_id) 1421 else: 1422 _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 1423 if mt_sub_id == INVALID_SUB_ID: 1424 ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot) 1425 raise signals.TestFailure( 1426 "Failed", 1427 extras={ 1428 "fail_reason": "Failed to get sub ID at slot %s." % mt_slot}) 1429 mt_slot = "auto" 1430 set_voice_sub_id(ad_mt, mt_sub_id) 1431 ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot, 1432 get_incoming_voice_sub_id(ad_mt)) 1433 1434 if mo_slot == 0 or mo_slot == 1: 1435 phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id) 1436 mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id) 1437 is_mo_in_call = is_phone_in_call_on_rat( 1438 log, ad_mo, mo_rat[mo_slot], only_return_fn=True) 1439 else: 1440 mo_phone_setup_func_argv = (log, ad_mo, 'general') 1441 is_mo_in_call = is_phone_in_call_on_rat( 1442 log, ad_mo, 'general', only_return_fn=True) 1443 1444 if mt_slot == 0 or mt_slot == 1: 1445 phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id) 1446 mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id) 1447 is_mt_in_call = is_phone_in_call_on_rat( 1448 log, ad_mt, mt_rat[mt_slot], only_return_fn=True) 1449 else: 1450 mt_phone_setup_func_argv = (log, ad_mt, 'general') 1451 is_mt_in_call = is_phone_in_call_on_rat( 1452 log, ad_mt, 'general', only_return_fn=True) 1453 1454 log.info("Step 1: Set up phones in desired RAT.") 1455 tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv), 1456 (phone_setup_on_rat, mt_phone_setup_func_argv)] 1457 if not multithread_func(log, tasks): 1458 log.error("Phone Failed to Set Up Properly.") 1459 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 1460 raise signals.TestFailure( 1461 "Failed", 1462 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 1463 1464 log.info("Step 2: Disable slot %s.", disabled_slot) 1465 if not power_off_sim(ads[0], disabled_slot): 1466 raise signals.TestFailure( 1467 "Failed", 1468 extras={ 1469 "fail_reason": "Failed to disable slot %s." % disabled_slot}) 1470 1471 log.info("Step 3: Switch DDS.") 1472 if not set_dds_on_slot(ads[0], 1-disabled_slot): 1473 log.error( 1474 "Failed to set DDS at slot %s on %s.", 1475 (1-disabled_slot, ads[0].serial)) 1476 raise signals.TestFailure( 1477 "Failed", 1478 extras={"fail_reason": "Failed to set DDS at slot %s on %s." % ( 1479 1-disabled_slot, ads[0].serial)}) 1480 1481 log.info("Step 4: Verify RAT and HTTP connection after DDS switch.") 1482 if mo_slot == 0 or mo_slot == 1: 1483 if not wait_for_network_idle( 1484 log, ad_mo, mo_rat[1-disabled_slot], mo_sub_id): 1485 raise signals.TestFailure( 1486 "Failed", 1487 extras={ 1488 "fail_reason": "Idle state does not match the given " 1489 "RAT %s." % mo_rat[1-disabled_slot]}) 1490 1491 if mt_slot == 0 or mt_slot == 1: 1492 if not wait_for_network_idle( 1493 log, ad_mt, mt_rat[1-disabled_slot], mt_sub_id): 1494 raise signals.TestFailure( 1495 "Failed", 1496 extras={ 1497 "fail_reason": "Idle state does not match the given " 1498 "RAT %s." % mt_rat[1-disabled_slot]}) 1499 1500 if not verify_http_connection(log, ads[0]): 1501 log.error("Failed to verify http connection.") 1502 raise signals.TestFailure( 1503 "Failed", 1504 extras={"fail_reason": "Failed to verify http connection."}) 1505 else: 1506 log.info("Verify http connection successfully.") 1507 1508 log.info("Step 5: Make voice call.") 1509 result = two_phone_call_msim_for_slot( 1510 log, 1511 ad_mo, 1512 get_slot_index_from_subid(ad_mo, mo_sub_id), 1513 None, 1514 is_mo_in_call, 1515 ad_mt, 1516 get_slot_index_from_subid(ad_mt, mt_sub_id), 1517 None, 1518 is_mt_in_call) 1519 1520 tel_logger.set_result(result.result_value) 1521 1522 if not result: 1523 log.error( 1524 "Failed to make MO call from %s slot %s to %s slot %s", 1525 ad_mo.serial, mo_slot, ad_mt.serial, mt_slot) 1526 raise signals.TestFailure("Failed", 1527 extras={"fail_reason": str(result.result_value)}) 1528 1529 log.info("Step 6: Enable slot %s.", disabled_slot) 1530 if not power_on_sim(ads[0], disabled_slot): 1531 raise signals.TestFailure( 1532 "Failed", 1533 extras={"fail_reason": "Failed to enable slot %s." % disabled_slot}) 1534 1535 log.info("Step 7: Switch DDS to slot %s.", disabled_slot) 1536 if not set_dds_on_slot(ads[0], disabled_slot): 1537 log.error( 1538 "Failed to set DDS at slot %s on %s.",(disabled_slot, ads[0].serial)) 1539 raise signals.TestFailure( 1540 "Failed", 1541 extras={"fail_reason": "Failed to set DDS at slot %s on %s." % ( 1542 disabled_slot, ads[0].serial)}) 1543 1544 log.info("Step 8: Verify RAT and HTTP connection after DDS switch.") 1545 if mo_slot == 0 or mo_slot == 1: 1546 if not wait_for_network_idle( 1547 log, ad_mo, mo_rat[disabled_slot], mo_other_sub_id): 1548 raise signals.TestFailure( 1549 "Failed", 1550 extras={ 1551 "fail_reason": "Idle state does not match the given " 1552 "RAT %s." % mo_rat[mo_slot]}) 1553 1554 if mt_slot == 0 or mt_slot == 1: 1555 if not wait_for_network_idle( 1556 log, ad_mt, mt_rat[disabled_slot], mt_other_sub_id): 1557 raise signals.TestFailure( 1558 "Failed", 1559 extras={"fail_reason": "Idle state does not match the given " 1560 "RAT %s." % mt_rat[mt_slot]}) 1561 1562 if not verify_http_connection(log, ads[0]): 1563 log.error("Failed to verify http connection.") 1564 raise signals.TestFailure( 1565 "Failed", 1566 extras={"fail_reason": "Failed to verify http connection."}) 1567 else: 1568 log.info("Verify http connection successfully.") 1569 1570 1571def enable_slot_after_data_call_test( 1572 log, 1573 ad, 1574 disabled_slot, 1575 rat=["", ""]): 1576 """Disable/enable pSIM or eSIM with data call 1577 1578 Test step: 1579 1. Get sub IDs of specific slots of both MO and MT devices. 1580 2. Set up phones in desired RAT. 1581 3. Disable assigned slot. 1582 4. Switch DDS to the other slot. 1583 5. Verify RAT and HTTP connection after DDS switch. 1584 6. Make a data call by http download. 1585 7. Enable assigned slot. 1586 8. Switch DDS to the assigned slot. 1587 9. Verify RAT and HTTP connection after DDS switch. 1588 1589 Args: 1590 log: logger object 1591 ads: list of android devices 1592 disabled_slot: slot to be disabled/enabled 1593 mo_rat: RAT for both slots of MO device 1594 mt_rat: RAT for both slots of MT device 1595 1596 Returns: 1597 TestFailure if failed. 1598 """ 1599 data_sub_id = get_subid_from_slot_index(log, ad, 1-disabled_slot) 1600 if data_sub_id == INVALID_SUB_ID: 1601 ad.log.warning("Failed to get sub ID at slot %s.", 1-disabled_slot) 1602 raise signals.TestFailure( 1603 "Failed", 1604 extras={ 1605 "fail_reason": "Failed to get sub ID at slot %s." % ( 1606 1-disabled_slot)}) 1607 other_sub_id = get_subid_from_slot_index(log, ad, disabled_slot) 1608 1609 log.info("Step 1: Set up phones in desired RAT.") 1610 if not phone_setup_on_rat(log, ad, rat[1-disabled_slot], data_sub_id): 1611 raise signals.TestFailure( 1612 "Failed", 1613 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 1614 1615 if not phone_setup_on_rat(log, ad, rat[disabled_slot], other_sub_id): 1616 raise signals.TestFailure( 1617 "Failed", 1618 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 1619 1620 log.info("Step 2: Disable slot %s.", disabled_slot) 1621 if not power_off_sim(ad, disabled_slot): 1622 raise signals.TestFailure( 1623 "Failed", 1624 extras={"fail_reason": "Failed to disable slot %s." % disabled_slot}) 1625 1626 log.info("Step 3: Switch DDS.") 1627 if not set_dds_on_slot(ad, 1-disabled_slot): 1628 log.error( 1629 "Failed to set DDS at slot %s on %s.",(1-disabled_slot, ad.serial)) 1630 raise signals.TestFailure( 1631 "Failed", 1632 extras={"fail_reason": "Failed to set DDS at slot %s on %s." % ( 1633 1-disabled_slot, ad.serial)}) 1634 1635 log.info("Step 4: Verify RAT and HTTP connection after DDS switch.") 1636 if not wait_for_network_idle(log, ad, rat[1-disabled_slot], data_sub_id): 1637 raise signals.TestFailure( 1638 "Failed", 1639 extras={ 1640 "fail_reason": "Idle state does not match the given " 1641 "RAT %s." % rat[1-disabled_slot]}) 1642 1643 if not verify_http_connection(log, ad): 1644 log.error("Failed to verify http connection.") 1645 raise signals.TestFailure("Failed", 1646 extras={"fail_reason": "Failed to verify http connection."}) 1647 else: 1648 log.info("Verify http connection successfully.") 1649 1650 duration = 30 1651 start_time = datetime.now() 1652 while datetime.now() - start_time <= timedelta(seconds=duration): 1653 if not active_file_download_test( 1654 log, ad, file_name='20MB', method='sl4a'): 1655 raise signals.TestFailure( 1656 "Failed", 1657 extras={"fail_reason": "Failed to download by sl4a."}) 1658 1659 log.info("Step 6: Enable slot %s.", disabled_slot) 1660 if not power_on_sim(ad, disabled_slot): 1661 raise signals.TestFailure( 1662 "Failed", 1663 extras={"fail_reason": "Failed to enable slot %s." % disabled_slot}) 1664 1665 log.info("Step 7: Switch DDS to slot %s.", disabled_slot) 1666 if not set_dds_on_slot(ad, disabled_slot): 1667 log.error( 1668 "Failed to set DDS at slot %s on %s.",(disabled_slot, ad.serial)) 1669 raise signals.TestFailure( 1670 "Failed", 1671 extras={"fail_reason": "Failed to set DDS at slot %s on %s." % ( 1672 disabled_slot, ad.serial)}) 1673 1674 log.info("Step 8: Verify RAT and HTTP connection after DDS switch.") 1675 if not wait_for_network_idle(log, ad, rat[disabled_slot], other_sub_id): 1676 raise signals.TestFailure( 1677 "Failed", 1678 extras={ 1679 "fail_reason": "Idle state does not match the given " 1680 "RAT %s." % rat[disabled_slot]}) 1681 1682 if not verify_http_connection(log, ad): 1683 log.error("Failed to verify http connection.") 1684 raise signals.TestFailure( 1685 "Failed", 1686 extras={"fail_reason": "Failed to verify http connection."}) 1687 else: 1688 log.info("Verify http connection successfully.") 1689 1690 1691def erase_call_forwarding(log, ad): 1692 slot0_sub_id = get_subid_from_slot_index(log, ad, 0) 1693 slot1_sub_id = get_subid_from_slot_index(log, ad, 1) 1694 current_voice_sub_id = get_incoming_voice_sub_id(ad) 1695 for sub_id in (slot0_sub_id, slot1_sub_id): 1696 set_voice_sub_id(ad, sub_id) 1697 get_operator_name(log, ad, sub_id) 1698 erase_call_forwarding_by_mmi(log, ad) 1699 set_voice_sub_id(ad, current_voice_sub_id) 1700 1701 1702def three_way_calling_mo_and_mt_with_hangup_once( 1703 log, 1704 ads, 1705 phone_setups, 1706 verify_funcs, 1707 reject_once=False): 1708 """Use 3 phones to make MO call and MT call. 1709 1710 Call from PhoneA to PhoneB, accept on PhoneB. 1711 Call from PhoneC to PhoneA, accept on PhoneA. 1712 1713 Args: 1714 ads: list of ad object. 1715 The list should have three objects. 1716 phone_setups: list of phone setup functions. 1717 The list should have three objects. 1718 verify_funcs: list of phone call verify functions. 1719 The list should have three objects. 1720 1721 Returns: 1722 If success, return 'call_AB' id in PhoneA. 1723 if fail, return None. 1724 """ 1725 1726 class _CallException(Exception): 1727 pass 1728 1729 try: 1730 verify_func_a, verify_func_b, verify_func_c = verify_funcs 1731 tasks = [] 1732 for ad, setup_func in zip(ads, phone_setups): 1733 if setup_func is not None: 1734 tasks.append((setup_func, (log, ad, get_incoming_voice_sub_id(ad)))) 1735 if tasks != [] and not multithread_func(log, tasks): 1736 log.error("Phone Failed to Set Up Properly.") 1737 raise _CallException("Setup failed.") 1738 for ad in ads: 1739 ad.droid.telecomCallClearCallList() 1740 if num_active_calls(log, ad) != 0: 1741 ad.log.error("Phone Call List is not empty.") 1742 raise _CallException("Clear call list failed.") 1743 1744 log.info("Step1: Call From PhoneA to PhoneB.") 1745 if not call_setup_teardown( 1746 log, 1747 ads[0], 1748 ads[1], 1749 ad_hangup=None, 1750 verify_caller_func=verify_func_a, 1751 verify_callee_func=verify_func_b): 1752 raise _CallException("PhoneA call PhoneB failed.") 1753 1754 calls = ads[0].droid.telecomCallGetCallIds() 1755 ads[0].log.info("Calls in PhoneA %s", calls) 1756 if num_active_calls(log, ads[0]) != 1: 1757 raise _CallException("Call list verify failed.") 1758 call_ab_id = calls[0] 1759 1760 log.info("Step2: Call From PhoneC to PhoneA.") 1761 if reject_once: 1762 log.info("Step2-1: Reject incoming call once.") 1763 if not initiate_call( 1764 log, 1765 ads[2], 1766 ads[0].telephony['subscription'][get_incoming_voice_sub_id( 1767 ads[0])]['phone_num']): 1768 ads[2].log.error("Initiate call failed.") 1769 raise _CallException("Failed to initiate call.") 1770 1771 if not wait_and_reject_call_for_subscription( 1772 log, 1773 ads[0], 1774 get_incoming_voice_sub_id(ads[0]), 1775 incoming_number= \ 1776 ads[2].telephony['subscription'][ 1777 get_incoming_voice_sub_id( 1778 ads[2])]['phone_num']): 1779 ads[0].log.error("Reject call fail.") 1780 raise _CallException("Failed to reject call.") 1781 1782 hangup_call(log, ads[2]) 1783 time.sleep(15) 1784 1785 if not call_setup_teardown( 1786 log, 1787 ads[2], 1788 ads[0], 1789 ad_hangup=None, 1790 verify_caller_func=verify_func_c, 1791 verify_callee_func=verify_func_a): 1792 raise _CallException("PhoneA call PhoneC failed.") 1793 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], 1794 True): 1795 raise _CallException("Not All phones are in-call.") 1796 1797 except Exception as e: 1798 setattr(ads[0], "exception", e) 1799 return None 1800 1801 return call_ab_id 1802 1803 1804def msim_message_test( 1805 log, 1806 ad_mo, 1807 ad_mt, 1808 mo_sub_id, 1809 mt_sub_id, msg="SMS", 1810 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE, 1811 expected_result=True): 1812 """Make MO/MT SMS/MMS at specific slot. 1813 1814 Args: 1815 ad_mo: Android object of the device sending SMS/MMS 1816 ad_mt: Android object of the device receiving SMS/MMS 1817 mo_sub_id: Sub ID of MO device 1818 mt_sub_id: Sub ID of MT device 1819 max_wait_time: Max wait time before SMS/MMS is received. 1820 expected_result: True for successful sending/receiving and False on 1821 the contrary 1822 1823 Returns: 1824 True if the result matches expected_result and False on the 1825 contrary. 1826 """ 1827 message_lengths = (50, 160, 180) 1828 if msg == "SMS": 1829 for length in message_lengths: 1830 message_array = [rand_ascii_str(length)] 1831 if not sms_send_receive_verify_for_subscription( 1832 log, 1833 ad_mo, 1834 ad_mt, 1835 mo_sub_id, 1836 mt_sub_id, 1837 message_array, 1838 max_wait_time): 1839 ad_mo.log.warning( 1840 "%s of length %s test failed", msg, length) 1841 return False 1842 else: 1843 ad_mo.log.info( 1844 "%s of length %s test succeeded", msg, length) 1845 log.info("%s test of length %s characters succeeded.", 1846 msg, message_lengths) 1847 1848 elif msg == "MMS": 1849 for length in message_lengths: 1850 message_array = [("Test Message", rand_ascii_str(length), None)] 1851 1852 if not mms_send_receive_verify( 1853 log, 1854 ad_mo, 1855 ad_mt, 1856 message_array, 1857 max_wait_time, 1858 expected_result): 1859 log.warning("%s of body length %s test failed", 1860 msg, length) 1861 return False 1862 else: 1863 log.info( 1864 "%s of body length %s test succeeded", msg, length) 1865 log.info("%s test of body lengths %s succeeded", 1866 msg, message_lengths) 1867 return True 1868 1869 1870def msim_call_forwarding( 1871 log, 1872 tel_logger, 1873 ads, 1874 caller_slot, 1875 callee_slot, 1876 forwarded_callee_slot, 1877 dds_slot, 1878 sim_slot=[SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1], 1879 caller_rat=["", ""], 1880 callee_rat=["", ""], 1881 forwarded_callee_rat=["", ""], 1882 call_forwarding_type="unconditional"): 1883 """Make MO voice call to the primary device at specific slot in specific 1884 RAT with DDS at specific slot, and then forwarded to 3rd device with 1885 specific call forwarding type. 1886 1887 Test step: 1888 1. Get sub IDs of specific slots of both MO and MT devices. 1889 2. Switch DDS to specific slot. 1890 3. Check HTTP connection after DDS switch. 1891 4. Set up phones in desired RAT. 1892 5. Register and enable call forwarding with specifc type. 1893 5. Make voice call to the primary device and wait for being forwarded 1894 to 3rd device. 1895 1896 Args: 1897 log: logger object 1898 tel_logger: logger object for telephony proto 1899 ads: list of android devices 1900 caller_slot: Slot of 2nd device making MO call (0 or 1) 1901 callee_slot: Slot of primary device receiving and forwarding MT call 1902 (0 or 1) 1903 forwarded_callee_slot: Slot of 3rd device receiving forwarded call. 1904 dds_slot: Preferred data slot 1905 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 1906 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 1907 caller_rat: RAT for both slots of the 2nd device 1908 callee_rat: RAT for both slots of the primary device 1909 forwarded_callee_rat: RAT for both slots of the 3rd device 1910 call_forwarding_type: 1911 "unconditional" 1912 "busy" 1913 "not_answered" 1914 "not_reachable" 1915 1916 Returns: 1917 True or False 1918 """ 1919 ad_caller = ads[1] 1920 ad_callee = ads[0] 1921 ad_forwarded_callee = ads[2] 1922 1923 log.info("Step 0: Switch to specific SIM slot combination.") 1924 try: 1925 change_slot(ad_callee, sim_slot) 1926 except TimeoutError: 1927 ad_callee.log.warning("Device not support MEP.") 1928 1929 if callee_slot is not None: 1930 callee_sub_id = get_subid_from_slot_index( 1931 log, ad_callee, callee_slot) 1932 if callee_sub_id == INVALID_SUB_ID: 1933 ad_callee.log.warning( 1934 "Failed to get sub ID at slot %s.", callee_slot) 1935 return False 1936 callee_other_sub_id = get_subid_from_slot_index( 1937 log, ad_callee, 1-callee_slot) 1938 set_voice_sub_id(ad_callee, callee_sub_id) 1939 else: 1940 callee_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads) 1941 if callee_sub_id == INVALID_SUB_ID: 1942 ad_callee.log.warning( 1943 "Failed to get sub ID at slot %s.", callee_slot) 1944 return False 1945 callee_slot = "auto" 1946 set_voice_sub_id(ad_callee, callee_sub_id) 1947 ad_callee.log.info( 1948 "Sub ID for incoming call at slot %s: %s", 1949 callee_slot, get_incoming_voice_sub_id(ad_callee)) 1950 1951 if caller_slot is not None: 1952 caller_sub_id = get_subid_from_slot_index( 1953 log, ad_caller, caller_slot) 1954 if caller_sub_id == INVALID_SUB_ID: 1955 ad_caller.log.warning( 1956 "Failed to get sub ID at slot %s.", caller_slot) 1957 return False 1958 caller_other_sub_id = get_subid_from_slot_index( 1959 log, ad_caller, 1-caller_slot) 1960 set_voice_sub_id(ad_caller, caller_sub_id) 1961 else: 1962 _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 1963 if caller_sub_id == INVALID_SUB_ID: 1964 ad_caller.log.warning( 1965 "Failed to get sub ID at slot %s.", caller_slot) 1966 return False 1967 caller_slot = "auto" 1968 set_voice_sub_id(ad_caller, caller_sub_id) 1969 ad_caller.log.info( 1970 "Sub ID for outgoing call at slot %s: %s", 1971 caller_slot, get_outgoing_voice_sub_id(ad_caller)) 1972 1973 if forwarded_callee_slot is not None: 1974 forwarded_callee_sub_id = get_subid_from_slot_index( 1975 log, ad_forwarded_callee, forwarded_callee_slot) 1976 if forwarded_callee_sub_id == INVALID_SUB_ID: 1977 ad_forwarded_callee.log.warning( 1978 "Failed to get sub ID at slot %s.", forwarded_callee_slot) 1979 return False 1980 forwarded_callee_other_sub_id = get_subid_from_slot_index( 1981 log, ad_forwarded_callee, 1-forwarded_callee_slot) 1982 set_voice_sub_id( 1983 ad_forwarded_callee, forwarded_callee_sub_id) 1984 else: 1985 _, _, forwarded_callee_sub_id = \ 1986 get_subid_on_same_network_of_host_ad(ads) 1987 if forwarded_callee_sub_id == INVALID_SUB_ID: 1988 ad_forwarded_callee.log.warning( 1989 "Failed to get sub ID at slot %s.", forwarded_callee_slot) 1990 return False 1991 forwarded_callee_slot = "auto" 1992 set_voice_sub_id( 1993 ad_forwarded_callee, forwarded_callee_sub_id) 1994 ad_forwarded_callee.log.info( 1995 "Sub ID for incoming call at slot %s: %s", 1996 forwarded_callee_slot, 1997 get_incoming_voice_sub_id(ad_forwarded_callee)) 1998 1999 log.info("Step 1: Switch DDS.") 2000 if not set_dds_on_slot(ads[0], dds_slot): 2001 log.error( 2002 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 2003 return False 2004 2005 log.info("Step 2: Check HTTP connection after DDS switch.") 2006 if not verify_http_connection(log, ads[0]): 2007 log.error("Failed to verify http connection.") 2008 return False 2009 else: 2010 log.info("Verify http connection successfully.") 2011 2012 if caller_slot == 1: 2013 phone_setup_on_rat( 2014 log, 2015 ad_caller, 2016 caller_rat[0], 2017 caller_other_sub_id) 2018 2019 elif caller_slot == 0: 2020 phone_setup_on_rat( 2021 log, 2022 ad_caller, 2023 caller_rat[1], 2024 caller_other_sub_id) 2025 else: 2026 phone_setup_on_rat( 2027 log, 2028 ad_caller, 2029 'general') 2030 2031 if callee_slot == 1: 2032 phone_setup_on_rat( 2033 log, 2034 ad_callee, 2035 callee_rat[0], 2036 callee_other_sub_id) 2037 2038 elif callee_slot == 0: 2039 phone_setup_on_rat( 2040 log, 2041 ad_callee, 2042 callee_rat[1], 2043 callee_other_sub_id) 2044 else: 2045 phone_setup_on_rat( 2046 log, 2047 ad_callee, 2048 'general') 2049 2050 if forwarded_callee_slot == 1: 2051 phone_setup_on_rat( 2052 log, 2053 ad_forwarded_callee, 2054 forwarded_callee_rat[0], 2055 forwarded_callee_other_sub_id) 2056 2057 elif forwarded_callee_slot == 0: 2058 phone_setup_on_rat( 2059 log, 2060 ad_forwarded_callee, 2061 forwarded_callee_rat[1], 2062 forwarded_callee_other_sub_id) 2063 else: 2064 phone_setup_on_rat( 2065 log, 2066 ad_forwarded_callee, 2067 'general') 2068 2069 if caller_slot == 0 or caller_slot == 1: 2070 caller_phone_setup_func_argv = (log, ad_caller, caller_rat[caller_slot], caller_sub_id) 2071 else: 2072 caller_phone_setup_func_argv = (log, ad_caller, 'general') 2073 2074 callee_phone_setup_func_argv = (log, ad_callee, callee_rat[callee_slot], callee_sub_id) 2075 2076 if forwarded_callee_slot == 0 or forwarded_callee_slot == 1: 2077 forwarded_callee_phone_setup_func_argv = ( 2078 log, 2079 ad_forwarded_callee, 2080 forwarded_callee_rat[forwarded_callee_slot], 2081 forwarded_callee_sub_id) 2082 else: 2083 forwarded_callee_phone_setup_func_argv = ( 2084 log, 2085 ad_forwarded_callee, 2086 'general') 2087 2088 log.info("Step 3: Set up phones in desired RAT.") 2089 tasks = [(phone_setup_on_rat, caller_phone_setup_func_argv), 2090 (phone_setup_on_rat, callee_phone_setup_func_argv), 2091 (phone_setup_on_rat, 2092 forwarded_callee_phone_setup_func_argv)] 2093 if not multithread_func(log, tasks): 2094 log.error("Phone Failed to Set Up Properly.") 2095 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 2096 raise signals.TestFailure("Failed", 2097 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 2098 2099 is_callee_in_call = is_phone_in_call_on_rat( 2100 log, ad_callee, callee_rat[callee_slot], only_return_fn=True) 2101 2102 is_call_waiting = re.search( 2103 "call_waiting (True (\d)|False)", call_forwarding_type, re.I) 2104 if is_call_waiting: 2105 if is_call_waiting.group(1) == "False": 2106 call_waiting = False 2107 scenario = None 2108 else: 2109 call_waiting = True 2110 scenario = int(is_call_waiting.group(2)) 2111 2112 log.info( 2113 "Step 4: Make voice call with call waiting enabled = %s.", 2114 call_waiting) 2115 result = three_phone_call_waiting_short_seq( 2116 log, 2117 ads[0], 2118 None, 2119 is_callee_in_call, 2120 ads[1], 2121 ads[2], 2122 call_waiting=call_waiting, scenario=scenario) 2123 else: 2124 log.info( 2125 "Step 4: Make voice call with call forwarding %s.", 2126 call_forwarding_type) 2127 result = three_phone_call_forwarding_short_seq( 2128 log, 2129 ads[0], 2130 None, 2131 is_callee_in_call, 2132 ads[1], 2133 ads[2], 2134 call_forwarding_type=call_forwarding_type) 2135 2136 if not result: 2137 if is_call_waiting: 2138 pass 2139 else: 2140 log.error( 2141 "Failed to make MO call from %s slot %s to %s slot %s" 2142 " and forward to %s slot %s", 2143 ad_caller.serial, 2144 caller_slot, 2145 ad_callee.serial, 2146 callee_slot, 2147 ad_forwarded_callee.serial, 2148 forwarded_callee_slot) 2149 2150 return result 2151 2152 2153def msim_call_voice_conf( 2154 log, 2155 tel_logger, 2156 ads, 2157 host_slot, 2158 p1_slot, 2159 p2_slot, 2160 dds_slot, 2161 sim_slot=[SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1], 2162 host_rat=["volte", "volte"], 2163 p1_rat="", 2164 p2_rat="", 2165 merge=True, 2166 disable_cw=False): 2167 """Make a voice conference call at specific slot in specific RAT with 2168 DDS at specific slot. 2169 2170 Test step: 2171 1. Get sub IDs of specific slots of both MO and MT devices. 2172 2. Switch DDS to specific slot. 2173 3. Check HTTP connection after DDS switch. 2174 4. Set up phones in desired RAT and make 3-way voice call. 2175 5. Swap calls. 2176 6. Merge calls. 2177 2178 Args: 2179 log: logger object 2180 tel_logger: logger object for telephony proto 2181 ads: list of android devices 2182 host_slot: Slot on the primary device to host the comference call. 2183 0 or 1 (0 for pSIM or 1 for eSIM) 2184 p1_slot: Slot on the participant device for the call 2185 p2_slot: Slot on another participant device for the call 2186 dds_slot: Preferred data slot 2187 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 2188 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 2189 host_rat: RAT for both slots of the primary device 2190 p1_rat: RAT for both slots of the participant device 2191 p2_rat: RAT for both slots of another participant device 2192 merge: True for merging 2 calls into the conference call. False for 2193 not merging 2 separated call. 2194 disable_cw: True for disabling call waiting and False on the 2195 contrary. 2196 2197 Returns: 2198 True or False 2199 """ 2200 ad_host = ads[0] 2201 ad_p1 = ads[1] 2202 ad_p2 = ads[2] 2203 2204 log.info("Step 0: Switch to specific SIM slot combination.") 2205 try: 2206 change_slot(ad_host, sim_slot) 2207 except TimeoutError: 2208 ad_host.log.warning("Device not support MEP.") 2209 2210 if host_slot is not None: 2211 host_sub_id = get_subid_from_slot_index( 2212 log, ad_host, host_slot) 2213 if host_sub_id == INVALID_SUB_ID: 2214 ad_host.log.warning("Failed to get sub ID at slot.", host_slot) 2215 return False 2216 host_other_sub_id = get_subid_from_slot_index( 2217 log, ad_host, 1-host_slot) 2218 set_voice_sub_id(ad_host, host_sub_id) 2219 else: 2220 host_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads) 2221 if host_sub_id == INVALID_SUB_ID: 2222 ad_host.log.warning("Failed to get sub ID at slot.", host_slot) 2223 return False 2224 host_slot = "auto" 2225 set_voice_sub_id(ad_host, host_sub_id) 2226 2227 ad_host.log.info("Sub ID for outgoing call at slot %s: %s", 2228 host_slot, get_outgoing_voice_sub_id(ad_host)) 2229 2230 if p1_slot is not None: 2231 p1_sub_id = get_subid_from_slot_index(log, ad_p1, p1_slot) 2232 if p1_sub_id == INVALID_SUB_ID: 2233 ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot) 2234 return False 2235 set_voice_sub_id(ad_p1, p1_sub_id) 2236 else: 2237 _, p1_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 2238 if p1_sub_id == INVALID_SUB_ID: 2239 ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot) 2240 return False 2241 p1_slot = "auto" 2242 set_voice_sub_id(ad_p1, p1_sub_id) 2243 ad_p1.log.info("Sub ID for incoming call at slot %s: %s", 2244 p1_slot, get_incoming_voice_sub_id(ad_p1)) 2245 2246 if p2_slot is not None: 2247 p2_sub_id = get_subid_from_slot_index(log, ad_p2, p2_slot) 2248 if p2_sub_id == INVALID_SUB_ID: 2249 ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot) 2250 return False 2251 set_voice_sub_id(ad_p2, p2_sub_id) 2252 else: 2253 _, _, p2_sub_id = get_subid_on_same_network_of_host_ad(ads) 2254 if p2_sub_id == INVALID_SUB_ID: 2255 ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot) 2256 return False 2257 p2_slot = "auto" 2258 set_voice_sub_id(ad_p2, p2_sub_id) 2259 ad_p2.log.info("Sub ID for incoming call at slot %s: %s", 2260 p2_slot, get_incoming_voice_sub_id(ad_p2)) 2261 2262 log.info("Step 1: Switch DDS.") 2263 if not set_dds_on_slot(ads[0], dds_slot): 2264 log.error( 2265 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 2266 return False 2267 2268 log.info("Step 2: Check HTTP connection after DDS switch.") 2269 if not verify_http_connection(log, ads[0]): 2270 log.error("Failed to verify http connection.") 2271 return False 2272 else: 2273 log.info("Verify http connection successfully.") 2274 2275 if disable_cw: 2276 if not set_call_waiting(log, ad_host, enable=0): 2277 return False 2278 else: 2279 if not set_call_waiting(log, ad_host, enable=1): 2280 return False 2281 2282 if host_slot == 1: 2283 phone_setup_on_rat( 2284 log, 2285 ad_host, 2286 host_rat[0], 2287 host_other_sub_id) 2288 2289 elif host_slot == 0: 2290 phone_setup_on_rat( 2291 log, 2292 ad_host, 2293 host_rat[1], 2294 host_other_sub_id) 2295 2296 if host_slot == 0 or host_slot == 1: 2297 host_phone_setup_func_argv = (log, ad_host, host_rat[host_slot], host_sub_id) 2298 is_host_in_call = is_phone_in_call_on_rat( 2299 log, ad_host, host_rat[host_slot], only_return_fn=True) 2300 else: 2301 host_phone_setup_func_argv = (log, ad_host, 'general') 2302 is_host_in_call = is_phone_in_call_on_rat( 2303 log, ad_host, 'general', only_return_fn=True) 2304 2305 if p1_rat: 2306 p1_phone_setup_func_argv = (log, ad_p1, p1_rat, p1_sub_id) 2307 is_p1_in_call = is_phone_in_call_on_rat( 2308 log, ad_p1, p1_rat, only_return_fn=True) 2309 else: 2310 p1_phone_setup_func_argv = (log, ad_p1, 'general') 2311 is_p1_in_call = is_phone_in_call_on_rat( 2312 log, ad_p1, 'general', only_return_fn=True) 2313 2314 if p2_rat: 2315 p2_phone_setup_func_argv = (log, ad_p2, p2_rat, p2_sub_id) 2316 is_p2_in_call = is_phone_in_call_on_rat( 2317 log, ad_p2, p2_rat, only_return_fn=True) 2318 else: 2319 p2_phone_setup_func_argv = (log, ad_p2, 'general') 2320 is_p2_in_call = is_phone_in_call_on_rat( 2321 log, ad_p2, 'general', only_return_fn=True) 2322 2323 log.info("Step 3: Set up phone in desired RAT and make 3-way" 2324 " voice call.") 2325 2326 tasks = [(phone_setup_on_rat, host_phone_setup_func_argv), 2327 (phone_setup_on_rat, p1_phone_setup_func_argv), 2328 (phone_setup_on_rat, p2_phone_setup_func_argv)] 2329 if not multithread_func(log, tasks): 2330 log.error("Phone Failed to Set Up Properly.") 2331 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 2332 raise signals.TestFailure("Failed", 2333 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 2334 2335 call_ab_id = three_way_calling_mo_and_mt_with_hangup_once( 2336 log, 2337 [ad_host, ad_p1, ad_p2], 2338 [None, None, None], [ 2339 is_host_in_call, is_p1_in_call, 2340 is_p2_in_call 2341 ]) 2342 2343 if call_ab_id is None: 2344 if disable_cw: 2345 set_call_waiting(log, ad_host, enable=1) 2346 if str(getattr(ad_host, "exception", None)) == \ 2347 "PhoneA call PhoneC failed.": 2348 ads[0].log.info("PhoneA failed to call PhoneC due to call" 2349 " waiting being disabled.") 2350 delattr(ad_host, "exception") 2351 return True 2352 log.error("Failed to get call_ab_id") 2353 return False 2354 else: 2355 if disable_cw: 2356 return False 2357 2358 calls = ads[0].droid.telecomCallGetCallIds() 2359 ads[0].log.info("Calls in PhoneA %s", calls) 2360 if num_active_calls(log, ads[0]) != 2: 2361 return False 2362 if calls[0] == call_ab_id: 2363 call_ac_id = calls[1] 2364 else: 2365 call_ac_id = calls[0] 2366 2367 if call_ac_id is None: 2368 log.error("Failed to get call_ac_id") 2369 return False 2370 2371 num_swaps = 2 2372 log.info("Step 4: Begin Swap x%s test.", num_swaps) 2373 if not swap_calls(log, ads, call_ab_id, call_ac_id, 2374 num_swaps): 2375 log.error("Swap test failed.") 2376 return False 2377 2378 if not merge: 2379 result = True 2380 if not hangup_call(log, ads[1]): 2381 result = False 2382 if not hangup_call(log, ads[2]): 2383 result = False 2384 return result 2385 else: 2386 log.info("Step 5: Merge calls.") 2387 if host_rat[host_slot] == "volte": 2388 return _test_ims_conference_merge_drop_second_call_from_participant( 2389 log, ads, call_ab_id, call_ac_id) 2390 else: 2391 return _test_wcdma_conference_merge_drop( 2392 log, ads, call_ab_id, call_ac_id) 2393 2394 2395def msim_volte_wfc_call_forwarding( 2396 log, 2397 tel_logger, 2398 ads, 2399 callee_slot, 2400 dds_slot, 2401 callee_rat=["5g_wfc", "5g_wfc"], 2402 call_forwarding_type="unconditional", 2403 is_airplane_mode=False, 2404 is_wifi_connected=False, 2405 wfc_mode=[ 2406 WFC_MODE_CELLULAR_PREFERRED, 2407 WFC_MODE_CELLULAR_PREFERRED], 2408 wifi_network_ssid=None, 2409 wifi_network_pass=None): 2410 """Make VoLTE/WFC call to the primary device at specific slot with DDS 2411 at specific slot, and then forwarded to 3rd device with specific call 2412 forwarding type. 2413 2414 Test step: 2415 1. Get sub IDs of specific slots of both MO and MT devices. 2416 2. Switch DDS to specific slot. 2417 3. Check HTTP connection after DDS switch. 2418 4. Set up phones in desired RAT. 2419 5. Register and enable call forwarding with specifc type. 2420 6. Make VoLTE/WFC call to the primary device and wait for being 2421 forwarded to 3rd device. 2422 2423 Args: 2424 log: logger object 2425 tel_logger: logger object for telephony proto 2426 ads: list of android devices 2427 callee_slot: Slot of primary device receiving and forwarding MT call 2428 (0 or 1) 2429 dds_slot: Preferred data slot 2430 callee_rat: RAT for both slots of the primary device 2431 call_forwarding_type: 2432 "unconditional" 2433 "busy" 2434 "not_answered" 2435 "not_reachable" 2436 is_airplane_mode: True or False for WFC setup 2437 wfc_mode: Cellular preferred or Wi-Fi preferred. 2438 wifi_network_ssid: SSID of Wi-Fi AP 2439 wifi_network_pass: Password of Wi-Fi AP SSID 2440 2441 Returns: 2442 True or False 2443 """ 2444 ad_caller = ads[1] 2445 ad_callee = ads[0] 2446 ad_forwarded_callee = ads[2] 2447 2448 if not toggle_airplane_mode(log, ad_callee, False): 2449 ad_callee.log.error("Failed to disable airplane mode.") 2450 return False 2451 2452 # Set up callee (primary device) 2453 callee_sub_id = get_subid_from_slot_index( 2454 log, ad_callee, callee_slot) 2455 if callee_sub_id == INVALID_SUB_ID: 2456 log.warning( 2457 "Failed to get sub ID at slot %s.", callee_slot) 2458 return 2459 callee_other_sub_id = get_subid_from_slot_index( 2460 log, ad_callee, 1-callee_slot) 2461 set_voice_sub_id(ad_callee, callee_sub_id) 2462 ad_callee.log.info( 2463 "Sub ID for incoming call at slot %s: %s", 2464 callee_slot, get_incoming_voice_sub_id(ad_callee)) 2465 2466 # Set up caller 2467 _, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads) 2468 if caller_sub_id == INVALID_SUB_ID: 2469 ad_caller.log.warning("Failed to get proper sub ID of the caller") 2470 return 2471 set_voice_sub_id(ad_caller, caller_sub_id) 2472 ad_caller.log.info( 2473 "Sub ID for outgoing call of the caller: %s", 2474 get_outgoing_voice_sub_id(ad_caller)) 2475 2476 # Set up forwarded callee 2477 _, _, forwarded_callee_sub_id = get_subid_on_same_network_of_host_ad( 2478 ads) 2479 if forwarded_callee_sub_id == INVALID_SUB_ID: 2480 ad_forwarded_callee.log.warning( 2481 "Failed to get proper sub ID of the forwarded callee.") 2482 return 2483 set_voice_sub_id(ad_forwarded_callee, forwarded_callee_sub_id) 2484 ad_forwarded_callee.log.info( 2485 "Sub ID for incoming call of the forwarded callee: %s", 2486 get_incoming_voice_sub_id(ad_forwarded_callee)) 2487 2488 log.info("Step 1: Switch DDS.") 2489 if not set_dds_on_slot(ads[0], dds_slot): 2490 log.error( 2491 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 2492 return False 2493 2494 log.info("Step 2: Check HTTP connection after DDS switch.") 2495 if not verify_http_connection(log, ad_callee): 2496 ad_callee.log.error("Failed to verify http connection.") 2497 return False 2498 else: 2499 ad_callee.log.info("Verify http connection successfully.") 2500 2501 is_callee_in_call = is_phone_in_call_on_rat( 2502 log, ad_callee, callee_rat[callee_slot], only_return_fn=True) 2503 2504 if is_airplane_mode: 2505 set_call_forwarding_by_mmi(log, ad_callee, ad_forwarded_callee) 2506 2507 log.info("Step 3: Set up phones in desired RAT.") 2508 if callee_slot == 1: 2509 phone_setup_on_rat( 2510 log, 2511 ad_callee, 2512 callee_rat[0], 2513 callee_other_sub_id, 2514 is_airplane_mode, 2515 wfc_mode[0], 2516 wifi_network_ssid, 2517 wifi_network_pass) 2518 2519 elif callee_slot == 0: 2520 phone_setup_on_rat( 2521 log, 2522 ad_callee, 2523 callee_rat[1], 2524 callee_other_sub_id, 2525 is_airplane_mode, 2526 wfc_mode[1], 2527 wifi_network_ssid, 2528 wifi_network_pass) 2529 2530 argv = ( 2531 log, 2532 ad_callee, 2533 callee_rat[callee_slot], 2534 callee_sub_id, 2535 is_airplane_mode, 2536 wfc_mode[callee_slot], 2537 wifi_network_ssid, 2538 wifi_network_pass) 2539 2540 tasks = [(phone_setup_voice_general, (log, ad_caller)), 2541 (phone_setup_on_rat, argv), 2542 (phone_setup_voice_general, (log, ad_forwarded_callee))] 2543 2544 if not multithread_func(log, tasks): 2545 log.error("Phone Failed to Set Up Properly.") 2546 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 2547 raise signals.TestFailure("Failed", 2548 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 2549 2550 if is_wifi_connected: 2551 if not ensure_wifi_connected( 2552 log, 2553 ad_callee, 2554 wifi_network_ssid, 2555 wifi_network_pass, 2556 apm=is_airplane_mode): 2557 return False 2558 time.sleep(5) 2559 2560 if "wfc" not in callee_rat[callee_slot]: 2561 if not toggle_wfc_for_subscription( 2562 log, 2563 ad_callee, 2564 new_state=True, 2565 sub_id=callee_sub_id): 2566 return False 2567 if not set_wfc_mode_for_subscription( 2568 ad_callee, wfc_mode[callee_slot], sub_id=callee_sub_id): 2569 return False 2570 2571 log.info( 2572 "Step 4: Make voice call with call forwarding %s.", 2573 call_forwarding_type) 2574 result = three_phone_call_forwarding_short_seq( 2575 log, 2576 ad_callee, 2577 None, 2578 is_callee_in_call, 2579 ad_caller, 2580 ad_forwarded_callee, 2581 call_forwarding_type=call_forwarding_type) 2582 2583 if not result: 2584 log.error( 2585 "Failed to make MO call from %s to %s slot %s and forward" 2586 " to %s.", 2587 ad_caller.serial, 2588 ad_callee.serial, 2589 callee_slot, 2590 ad_forwarded_callee.serial) 2591 return result 2592 2593 2594def msim_volte_wfc_call_voice_conf( 2595 log, 2596 tel_logger, 2597 ads, 2598 host_slot, 2599 dds_slot, 2600 sim_slot=[SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1], 2601 host_rat=["5g_wfc", "5g_wfc"], 2602 merge=True, 2603 disable_cw=False, 2604 is_airplane_mode=False, 2605 is_wifi_connected=False, 2606 wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED], 2607 reject_once=False, 2608 wifi_network_ssid=None, 2609 wifi_network_pass=None): 2610 """Make a VoLTE/WFC conference call at specific slot with DDS at 2611 specific slot. 2612 2613 Test step: 2614 1. Get sub IDs of specific slots of both MO and MT devices. 2615 2. Set up phones in desired RAT 2616 3. Enable VoLTE/WFC. 2617 4. Switch DDS to specific slot. 2618 5. Check HTTP connection after DDS switch. 2619 6. Make 3-way VoLTE/WFC call. 2620 7. Swap calls. 2621 8. Merge calls. 2622 2623 Args: 2624 log: logger object 2625 tel_logger: logger object for telephony proto 2626 ads: list of android devices 2627 host_slot: Slot on the primary device to host the comference call. 2628 0 or 1 (0 for pSIM or 1 for eSIM)call 2629 dds_slot: Preferred data slot 2630 sim_slot: a list which contains 2 slots for logical slot 0 and 1. 2631 e.g. [SimSlotInfo.SLOT_0, SimSlotInfo.SLOT_1] 2632 host_rat: RAT for both slots of the primary devicevice 2633 merge: True for merging 2 calls into the conference call. False for 2634 not merging 2 separated call. 2635 disable_cw: True for disabling call waiting and False on the 2636 contrary. 2637 enable_volte: True for enabling and False for disabling VoLTE for 2638 each slot on the primary device 2639 enable_wfc: True for enabling and False for disabling WFC for 2640 each slot on the primary device 2641 is_airplane_mode: True or False for WFC setup 2642 wfc_mode: Cellular preferred or Wi-Fi preferred. 2643 reject_once: True for rejecting the 2nd call once from the 3rd 2644 device (Phone C) to the primary device (Phone A). 2645 wifi_network_ssid: SSID of Wi-Fi AP 2646 wifi_network_pass: Password of Wi-Fi AP SSID 2647 2648 Returns: 2649 True or False 2650 """ 2651 ad_host = ads[0] 2652 ad_p1 = ads[1] 2653 ad_p2 = ads[2] 2654 2655 log.info("Step 0: Switch to specific SIM slot combination.") 2656 try: 2657 change_slot(ad_host, sim_slot) 2658 except TimeoutError: 2659 ad_host.log.warning("Device not support MEP.") 2660 2661 host_sub_id = get_subid_from_slot_index(log, ad_host, host_slot) 2662 if host_sub_id == INVALID_SUB_ID: 2663 ad_host.log.warning("Failed to get sub ID at slot.", host_slot) 2664 return 2665 host_other_sub_id = get_subid_from_slot_index( 2666 log, ad_host, 1-host_slot) 2667 set_voice_sub_id(ad_host, host_sub_id) 2668 ad_host.log.info( 2669 "Sub ID for outgoing call at slot %s: %s", 2670 host_slot, get_outgoing_voice_sub_id(ad_host)) 2671 2672 _, p1_sub_id, p2_sub_id = get_subid_on_same_network_of_host_ad(ads) 2673 2674 if p1_sub_id == INVALID_SUB_ID: 2675 ad_p1.log.warning("Failed to get proper sub ID.") 2676 return 2677 set_voice_sub_id(ad_p1, p1_sub_id) 2678 ad_p1.log.info( 2679 "Sub ID for incoming call: %s", 2680 get_incoming_voice_sub_id(ad_p1)) 2681 2682 if p2_sub_id == INVALID_SUB_ID: 2683 ad_p2.log.warning("Failed to get proper sub ID.") 2684 return 2685 set_voice_sub_id(ad_p2, p2_sub_id) 2686 ad_p2.log.info( 2687 "Sub ID for incoming call: %s", get_incoming_voice_sub_id(ad_p2)) 2688 2689 log.info("Step 1: Switch DDS.") 2690 if not set_dds_on_slot(ads[0], dds_slot): 2691 log.error( 2692 "Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial)) 2693 return False 2694 2695 log.info("Step 2: Check HTTP connection after DDS switch.") 2696 if not verify_http_connection(log, ads[0]): 2697 ad_host.log.error("Failed to verify http connection.") 2698 return False 2699 else: 2700 ad_host.log.info("Verify http connection successfully.") 2701 2702 if disable_cw: 2703 if not set_call_waiting(log, ad_host, enable=0): 2704 return False 2705 2706 log.info("Step 3: Set up phones in desired RAT.") 2707 if host_slot == 1: 2708 phone_setup_on_rat( 2709 log, 2710 ad_host, 2711 host_rat[0], 2712 host_other_sub_id, 2713 is_airplane_mode, 2714 wfc_mode[0], 2715 wifi_network_ssid, 2716 wifi_network_pass) 2717 2718 elif host_slot == 0: 2719 phone_setup_on_rat( 2720 log, 2721 ad_host, 2722 host_rat[1], 2723 host_other_sub_id, 2724 is_airplane_mode, 2725 wfc_mode[1], 2726 wifi_network_ssid, 2727 wifi_network_pass) 2728 2729 argv = ( 2730 log, 2731 ad_host, 2732 host_rat[host_slot], 2733 host_sub_id, 2734 is_airplane_mode, 2735 wfc_mode[host_slot], 2736 wifi_network_ssid, 2737 wifi_network_pass) 2738 2739 tasks = [(phone_setup_voice_general, (log, ad_p1)), 2740 (phone_setup_on_rat, argv), 2741 (phone_setup_voice_general, (log, ad_p2))] 2742 2743 if not multithread_func(log, tasks): 2744 log.error("Phone Failed to Set Up Properly.") 2745 tel_logger.set_result(CallResult("CALL_SETUP_FAILURE")) 2746 raise signals.TestFailure("Failed", 2747 extras={"fail_reason": "Phone Failed to Set Up Properly."}) 2748 2749 if is_wifi_connected: 2750 if not ensure_wifi_connected( 2751 log, 2752 ad_host, 2753 wifi_network_ssid, 2754 wifi_network_pass, 2755 apm=is_airplane_mode): 2756 return False 2757 time.sleep(5) 2758 2759 if "wfc" not in host_rat[host_slot]: 2760 if not toggle_wfc_for_subscription( 2761 log, 2762 ad_host, 2763 new_state=True, 2764 sub_id=host_sub_id): 2765 return False 2766 if not set_wfc_mode_for_subscription( 2767 ad_host, wfc_mode[host_slot], sub_id=host_sub_id): 2768 return False 2769 2770 log.info("Step 4: Make 3-way voice call.") 2771 is_host_in_call = is_phone_in_call_on_rat( 2772 log, ad_host, host_rat[host_slot], only_return_fn=True) 2773 call_ab_id = _three_phone_call_mo_add_mt( 2774 log, 2775 [ad_host, ad_p1, ad_p2], 2776 [None, None, None], 2777 [is_host_in_call, None, None], 2778 reject_once=reject_once) 2779 2780 if call_ab_id is None: 2781 if disable_cw: 2782 set_call_waiting(log, ad_host, enable=1) 2783 if str(getattr(ad_host, "exception", None)) == \ 2784 "PhoneA call PhoneC failed.": 2785 ads[0].log.info("PhoneA failed to call PhoneC due to call" 2786 " waiting being disabled.") 2787 delattr(ad_host, "exception") 2788 return True 2789 log.error("Failed to get call_ab_id") 2790 return False 2791 else: 2792 if disable_cw: 2793 set_call_waiting(log, ad_host, enable=0) 2794 return False 2795 2796 calls = ads[0].droid.telecomCallGetCallIds() 2797 ads[0].log.info("Calls in PhoneA %s", calls) 2798 if num_active_calls(log, ads[0]) != 2: 2799 return False 2800 if calls[0] == call_ab_id: 2801 call_ac_id = calls[1] 2802 else: 2803 call_ac_id = calls[0] 2804 2805 if call_ac_id is None: 2806 log.error("Failed to get call_ac_id") 2807 return False 2808 2809 num_swaps = 2 2810 log.info("Step 5: Begin Swap x%s test.", num_swaps) 2811 if not swap_calls(log, ads, call_ab_id, call_ac_id, 2812 num_swaps): 2813 ad_host.log.error("Swap test failed.") 2814 return False 2815 2816 if not merge: 2817 result = True 2818 if not hangup_call(log, ads[1]): 2819 result = False 2820 if not hangup_call(log, ads[2]): 2821 result = False 2822 return result 2823 else: 2824 log.info("Step 6: Merge calls.") 2825 2826 if re.search('csfb|2g|3g', host_rat[host_slot].lower(), re.I): 2827 return _test_wcdma_conference_merge_drop( 2828 log, ads, call_ab_id, call_ac_id) 2829 else: 2830 return _test_ims_conference_merge_drop_second_call_from_participant( 2831 log, ads, call_ab_id, call_ac_id)