1#!/usr/bin/env python3 2# 3# Copyright 2021 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import re 18import time 19from queue import Empty 20from acts import signals 21from acts.logger import epoch_to_log_line_timestamp 22from acts.utils import get_current_epoch_time 23from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult 24from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs 25from acts_contrib.test_utils.tel.tel_defines import CARRIER_NTT_DOCOMO, CARRIER_KDDI, CARRIER_RAKUTEN, CARRIER_SBM 26from acts_contrib.test_utils.tel.tel_defines import CALL_PROPERTY_HIGH_DEF_AUDIO 27from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_ACTIVE 28from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_HOLDING 29from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE 30from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC 31from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED 32from acts_contrib.test_utils.tel.tel_defines import GEN_2G 33from acts_contrib.test_utils.tel.tel_defines import GEN_3G 34from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND 35from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 36from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID 37from acts_contrib.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL 38from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT 39from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP 40from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT 41from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION 42from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING 43from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING 44from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT 45from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 46from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 47from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT 48from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN 49from acts_contrib.test_utils.tel.tel_defines import RAT_LTE 50from acts_contrib.test_utils.tel.tel_defines import RAT_UMTS 51from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN 52from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE 53from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK 54from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING 55from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 56from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL 57from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK 58from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 59from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL 60from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL 61from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE 62from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED 63from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged 64from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged 65from acts_contrib.test_utils.tel.tel_defines import CallStateContainer 66from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer 67from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled 68from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte 69from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc 70from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode 71from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_volte_enabled 72from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled 73from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled 74from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit 75from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle 76from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_rat 77from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phone_subscription 78from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_not_network_rat 79from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_voice_attach 80from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id 81from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id 82from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call 83from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index 84from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state 85from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_connected_by_adb 86from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_idle_by_adb 87from acts_contrib.test_utils.tel.tel_test_utils import check_phone_number_match 88from acts_contrib.test_utils.tel.tel_test_utils import check_voice_mail_count 89from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type 90from acts_contrib.test_utils.tel.tel_test_utils import get_call_uri 91from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time 92from acts_contrib.test_utils.tel.tel_test_utils import get_network_gen_for_subscription 93from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat 94from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription 95from acts_contrib.test_utils.tel.tel_test_utils import get_number_from_tel_uri 96from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name 97from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile 98from acts_contrib.test_utils.tel.tel_test_utils import get_voice_mail_number 99from acts_contrib.test_utils.tel.tel_test_utils import is_event_match 100from acts_contrib.test_utils.tel.tel_test_utils import is_event_match_for_list 101from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls 102from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper 103from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb 104from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state 105from acts_contrib.test_utils.tel.tel_test_utils import wait_for_state 106from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected 107from acts_contrib.test_utils.tel.tel_wifi_utils import wifi_toggle_state 108 109CallResult = TelephonyVoiceTestResult.CallResult.Value 110result_dict ={} 111voice_call_type = {} 112 113 114def check_call_status(ad, voice_type_init=None, voice_type_in_call=None): 115 """" 116 Args: 117 ad: Android device object 118 voice_type_init: Voice network type before initiate call 119 voice_type_in_call: Voice network type in call state 120 121 Return: 122 voice_call_type_dict: Voice call status 123 """ 124 dut = str(ad.serial) 125 network_type = voice_type_init + "_" + voice_type_in_call 126 if network_type == "NR_NR": 127 voice_call_type_dict = update_voice_call_type_dict(dut, "VoNR") 128 elif network_type == "NR_LTE": 129 voice_call_type_dict = update_voice_call_type_dict(dut, "EPSFB") 130 elif network_type == "LTE_LTE": 131 voice_call_type_dict = update_voice_call_type_dict(dut, "VoLTE") 132 elif (network_type == "LTE_WCDMA" or network_type == "LTE_EDGE" or 133 network_type == "LTE_GSM"): 134 voice_call_type_dict = update_voice_call_type_dict(dut, "CSFB") 135 elif network_type == "EDGE_EDGE": 136 voice_call_type_dict = update_voice_call_type_dict(dut, "EDGE") 137 elif network_type == "GSM_GSM": 138 voice_call_type_dict = update_voice_call_type_dict(dut, "GSM") 139 else: 140 voice_call_type_dict = update_voice_call_type_dict(dut, "UNKNOWN") 141 return voice_call_type_dict 142 143 144def update_voice_call_type_dict(dut, key): 145 """ 146 Args: 147 dut: Serial Number of android device object 148 key: Network subscription parameter (VoNR or EPSFB or VoLTE or CSFB or UNKNOWN) 149 Return: 150 voice_call_type: Voice call status 151 """ 152 if dut not in voice_call_type.keys(): 153 voice_call_type[dut] = {key:0} 154 if key not in voice_call_type[dut].keys(): 155 voice_call_type[dut].update({key:0}) 156 voice_call_type[dut][key] += 1 157 return voice_call_type 158 159 160def dial_phone_number(ad, callee_number): 161 for number in str(callee_number): 162 if number == "#": 163 ad.send_keycode("POUND") 164 elif number == "*": 165 ad.send_keycode("STAR") 166 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]: 167 ad.send_keycode("%s" % number) 168 169 170def disconnect_call_by_id(log, ad, call_id): 171 """Disconnect call by call id. 172 """ 173 ad.droid.telecomCallDisconnect(call_id) 174 return True 175 176 177def dumpsys_last_call_info(ad): 178 """ Get call information by dumpsys telecom. """ 179 num = dumpsys_last_call_number(ad) 180 output = ad.adb.shell("dumpsys telecom") 181 result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL) 182 call_info = {"TC": num} 183 if result: 184 result = result.group(1) 185 for attr in ("startTime", "endTime", "direction", "isInterrupted", 186 "callTechnologies", "callTerminationsReason", 187 "isVideoCall", "callProperties"): 188 match = re.search(r"%s: (.*)" % attr, result) 189 if match: 190 if attr in ("startTime", "endTime"): 191 call_info[attr] = epoch_to_log_line_timestamp( 192 int(match.group(1))) 193 else: 194 call_info[attr] = match.group(1) 195 ad.log.debug("call_info = %s", call_info) 196 return call_info 197 198 199def dumpsys_last_call_number(ad): 200 output = ad.adb.shell("dumpsys telecom") 201 call_nums = re.findall("Call TC@(\d+):", output) 202 if not call_nums: 203 return 0 204 else: 205 return int(call_nums[-1]) 206 207 208def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5): 209 for i in range(retries): 210 if dumpsys_last_call_number(ad) > last_tc_number: 211 call_info = dumpsys_last_call_info(ad) 212 ad.log.info("New call info = %s", sorted(call_info.items())) 213 return call_info 214 else: 215 time.sleep(interval) 216 ad.log.error("New call is not in sysdump telecom") 217 return {} 218 219 220def emergency_dialer_call_by_keyevent(ad, callee_number): 221 for i in range(3): 222 if "EmergencyDialer" in ad.get_my_current_focus_window(): 223 ad.log.info("EmergencyDialer is the current focus window") 224 break 225 elif i <= 2: 226 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 227 time.sleep(1) 228 else: 229 ad.log.error("Unable to bring up EmergencyDialer") 230 return False 231 ad.log.info("Make a phone call to %s", callee_number) 232 dial_phone_number(ad, callee_number) 233 ad.send_keycode("CALL") 234 235 236def get_current_voice_rat(log, ad): 237 """Return current Voice RAT 238 239 Args: 240 ad: Android device object. 241 """ 242 return get_current_voice_rat_for_subscription( 243 log, ad, get_outgoing_voice_sub_id(ad)) 244 245 246def get_current_voice_rat_for_subscription(log, ad, sub_id): 247 """Return current Voice RAT for subscription id. 248 249 Args: 250 ad: Android device object. 251 sub_id: subscription id. 252 """ 253 return get_network_rat_for_subscription(log, ad, sub_id, 254 NETWORK_SERVICE_VOICE) 255 256 257def hangup_call_by_adb(ad): 258 """Make emergency call by EmergencyDialer. 259 260 Args: 261 ad: Caller android device object. 262 callee_number: Callee phone number. 263 """ 264 ad.log.info("End call by adb") 265 ad.send_keycode("ENDCALL") 266 267 268def hangup_call(log, ad, is_emergency=False): 269 """Hang up ongoing active call. 270 271 Args: 272 log: log object. 273 ad: android device object. 274 275 Returns: 276 True: if all calls are cleared 277 False: for errors 278 """ 279 # short circuit in case no calls are active 280 if not ad.droid.telecomIsInCall(): 281 ad.log.warning("No active call exists.") 282 return True 283 ad.ed.clear_events(EventCallStateChanged) 284 ad.droid.telephonyStartTrackingCallState() 285 ad.log.info("Hangup call.") 286 if is_emergency: 287 for call in ad.droid.telecomCallGetCallIds(): 288 ad.droid.telecomCallDisconnect(call) 289 else: 290 ad.droid.telecomEndCall() 291 292 try: 293 ad.ed.wait_for_event( 294 EventCallStateChanged, 295 is_event_match, 296 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 297 field=CallStateContainer.CALL_STATE, 298 value=TELEPHONY_STATE_IDLE) 299 except Empty: 300 ad.log.warning("Call state IDLE event is not received after hang up.") 301 finally: 302 ad.droid.telephonyStopTrackingCallStateChange() 303 if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1): 304 ad.log.error("Telecom is in call, hangup call failed.") 305 return False 306 return True 307 308 309def initiate_emergency_dialer_call_by_adb( 310 log, 311 ad, 312 callee_number, 313 timeout=MAX_WAIT_TIME_CALL_INITIATION, 314 checking_interval=5): 315 """Make emergency call by EmergencyDialer. 316 317 Args: 318 ad: Caller android device object. 319 callee_number: Callee phone number. 320 emergency : specify the call is emergency. 321 Optional. Default value is False. 322 323 Returns: 324 result: if phone call is placed successfully. 325 """ 326 try: 327 # Make a Call 328 ad.wakeup_screen() 329 ad.send_keycode("MENU") 330 ad.log.info("Call %s", callee_number) 331 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 332 ad.adb.shell( 333 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" % 334 callee_number) 335 if not timeout: return True 336 ad.log.info("Check call state") 337 # Verify Call State 338 elapsed_time = 0 339 while elapsed_time < timeout: 340 time.sleep(checking_interval) 341 elapsed_time += checking_interval 342 if check_call_state_connected_by_adb(ad): 343 ad.log.info("Call to %s is connected", callee_number) 344 return True 345 if check_call_state_idle_by_adb(ad): 346 ad.log.info("Call to %s failed", callee_number) 347 return False 348 ad.log.info("Make call to %s failed", callee_number) 349 return False 350 except Exception as e: 351 ad.log.error("initiate emergency call failed with error %s", e) 352 353 354def initiate_call(log, 355 ad, 356 callee_number, 357 emergency=False, 358 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 359 video=False): 360 """Make phone call from caller to callee. 361 362 Args: 363 ad_caller: Caller android device object. 364 callee_number: Callee phone number. 365 emergency : specify the call is emergency. 366 Optional. Default value is False. 367 incall_ui_display: show the dialer UI foreground or backgroud 368 video: whether to initiate as video call 369 370 Returns: 371 result: if phone call is placed successfully. 372 """ 373 ad.ed.clear_events(EventCallStateChanged) 374 sub_id = get_outgoing_voice_sub_id(ad) 375 begin_time = get_device_epoch_time(ad) 376 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 377 try: 378 # Make a Call 379 ad.log.info("Make a phone call to %s", callee_number) 380 if emergency: 381 ad.droid.telecomCallEmergencyNumber(callee_number) 382 else: 383 ad.droid.telecomCallNumber(callee_number, video) 384 385 # Verify OFFHOOK state 386 if not wait_for_call_offhook_for_subscription( 387 log, ad, sub_id, event_tracking_started=True): 388 ad.log.info("sub_id %s not in call offhook state", sub_id) 389 last_call_drop_reason(ad, begin_time=begin_time) 390 return False 391 else: 392 return True 393 394 finally: 395 if hasattr(ad, "sdm_log") and getattr(ad, "sdm_log"): 396 ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True) 397 ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True) 398 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 399 400 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 401 ad.droid.telecomShowInCallScreen() 402 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 403 ad.droid.showHomeScreen() 404 405 406def last_call_drop_reason(ad, begin_time=None): 407 reasons = ad.search_logcat( 408 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time) 409 reason_string = "" 410 if reasons: 411 log_msg = "Logcat call drop reasons:" 412 for reason in reasons: 413 log_msg = "%s\n\t%s" % (log_msg, reason["log_message"]) 414 if "ril reason str" in reason["log_message"]: 415 reason_string = reason["log_message"].split(":")[-1].strip() 416 ad.log.info(log_msg) 417 reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION", 418 begin_time) 419 if reasons: 420 ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen") 421 ad.log.info("last call dumpsys: %s", 422 sorted(dumpsys_last_call_info(ad).items())) 423 return reason_string 424 425 426def call_reject(log, ad_caller, ad_callee, reject=True): 427 """Caller call Callee, then reject on callee. 428 429 430 """ 431 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId() 432 subid_callee = ad_callee.incoming_voice_sub_id 433 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller, 434 subid_callee) 435 return call_reject_for_subscription(log, ad_caller, ad_callee, 436 subid_caller, subid_callee, reject) 437 438 439def call_reject_for_subscription(log, 440 ad_caller, 441 ad_callee, 442 subid_caller, 443 subid_callee, 444 reject=True): 445 """ 446 """ 447 448 caller_number = ad_caller.telephony['subscription'][subid_caller][ 449 'phone_num'] 450 callee_number = ad_callee.telephony['subscription'][subid_callee][ 451 'phone_num'] 452 453 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 454 if not initiate_call(log, ad_caller, callee_number): 455 ad_caller.log.error("Initiate call failed") 456 return False 457 458 if not wait_and_reject_call_for_subscription( 459 log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL, 460 reject): 461 ad_callee.log.error("Reject call fail.") 462 return False 463 # Check if incoming call is cleared on callee or not. 464 if ad_callee.droid.telephonyGetCallStateForSubscription( 465 subid_callee) == TELEPHONY_STATE_RINGING: 466 ad_callee.log.error("Incoming call is not cleared") 467 return False 468 # Hangup on caller 469 hangup_call(log, ad_caller) 470 return True 471 472 473def call_reject_leave_message(log, 474 ad_caller, 475 ad_callee, 476 verify_caller_func=None, 477 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 478 """On default voice subscription, Call from caller to callee, 479 reject on callee, caller leave a voice mail. 480 481 1. Caller call Callee. 482 2. Callee reject incoming call. 483 3. Caller leave a voice mail. 484 4. Verify callee received the voice mail notification. 485 486 Args: 487 ad_caller: caller android device object. 488 ad_callee: callee android device object. 489 verify_caller_func: function to verify caller is in correct state while in-call. 490 This is optional, default is None. 491 wait_time_in_call: time to wait when leaving a voice mail. 492 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 493 494 Returns: 495 True: if voice message is received on callee successfully. 496 False: for errors 497 """ 498 subid_caller = get_outgoing_voice_sub_id(ad_caller) 499 subid_callee = get_incoming_voice_sub_id(ad_callee) 500 return call_reject_leave_message_for_subscription( 501 log, ad_caller, ad_callee, subid_caller, subid_callee, 502 verify_caller_func, wait_time_in_call) 503 504 505def check_reject_needed_for_voice_mail(log, ad_callee): 506 """Check if the carrier requires reject call to receive voice mail or just keep ringing 507 Requested in b//155935290 508 Four Japan carriers do not need to reject 509 SBM, KDDI, Ntt Docomo, Rakuten 510 Args: 511 log: log object 512 ad_callee: android device object 513 Returns: 514 True if callee's carrier is not one of the four Japan carriers 515 False if callee's carrier is one of the four Japan carriers 516 """ 517 518 operators_no_reject = [CARRIER_NTT_DOCOMO, 519 CARRIER_KDDI, 520 CARRIER_RAKUTEN, 521 CARRIER_SBM] 522 operator_name = get_operator_name(log, ad_callee) 523 524 return operator_name not in operators_no_reject 525 526 527def _is_on_message_waiting_event_true(event): 528 """Private function to return if the received EventMessageWaitingIndicatorChanged 529 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True. 530 """ 531 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING] 532 533 534def call_reject_leave_message_for_subscription( 535 log, 536 ad_caller, 537 ad_callee, 538 subid_caller, 539 subid_callee, 540 verify_caller_func=None, 541 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 542 """On specific voice subscription, Call from caller to callee, 543 reject on callee, caller leave a voice mail. 544 545 1. Caller call Callee. 546 2. Callee reject incoming call. 547 3. Caller leave a voice mail. 548 4. Verify callee received the voice mail notification. 549 550 Args: 551 ad_caller: caller android device object. 552 ad_callee: callee android device object. 553 subid_caller: caller's subscription id. 554 subid_callee: callee's subscription id. 555 verify_caller_func: function to verify caller is in correct state while in-call. 556 This is optional, default is None. 557 wait_time_in_call: time to wait when leaving a voice mail. 558 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 559 560 Returns: 561 True: if voice message is received on callee successfully. 562 False: for errors 563 """ 564 565 # Currently this test utility only works for TMO and ATT and SPT. 566 # It does not work for VZW (see b/21559800) 567 # "with VVM TelephonyManager APIs won't work for vm" 568 569 caller_number = ad_caller.telephony['subscription'][subid_caller][ 570 'phone_num'] 571 callee_number = ad_callee.telephony['subscription'][subid_callee][ 572 'phone_num'] 573 574 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 575 576 try: 577 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 578 subid_callee) 579 ad_callee.log.info("voice mail count is %s", voice_mail_count_before) 580 # -1 means there are unread voice mail, but the count is unknown 581 # 0 means either this API not working (VZW) or no unread voice mail. 582 if voice_mail_count_before != 0: 583 log.warning("--Pending new Voice Mail, please clear on phone.--") 584 585 if not initiate_call(log, ad_caller, callee_number): 586 ad_caller.log.error("Initiate call failed.") 587 return False 588 if check_reject_needed_for_voice_mail(log, ad_callee): 589 carrier_specific_delay_reject = 30 590 else: 591 carrier_specific_delay_reject = 2 592 carrier_reject_call = not check_reject_needed_for_voice_mail(log, ad_callee) 593 594 if not wait_and_reject_call_for_subscription( 595 log, ad_callee, subid_callee, incoming_number=caller_number, delay_reject=carrier_specific_delay_reject, 596 reject=carrier_reject_call): 597 ad_callee.log.error("Reject call fail.") 598 return False 599 600 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription( 601 subid_callee) 602 603 # ensure that all internal states are updated in telecom 604 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 605 ad_callee.ed.clear_events(EventCallStateChanged) 606 607 if verify_caller_func and not verify_caller_func(log, ad_caller): 608 ad_caller.log.error("Caller not in correct state!") 609 return False 610 611 # TODO: b/26293512 Need to play some sound to leave message. 612 # Otherwise carrier voice mail server may drop this voice mail. 613 time.sleep(wait_time_in_call) 614 615 if not verify_caller_func: 616 caller_state_result = ad_caller.droid.telecomIsInCall() 617 else: 618 caller_state_result = verify_caller_func(log, ad_caller) 619 if not caller_state_result: 620 ad_caller.log.error("Caller not in correct state after %s seconds", 621 wait_time_in_call) 622 623 if not hangup_call(log, ad_caller): 624 ad_caller.log.error("Error in Hanging-Up Call") 625 return False 626 627 ad_callee.log.info("Wait for voice mail indicator on callee.") 628 try: 629 event = ad_callee.ed.wait_for_event( 630 EventMessageWaitingIndicatorChanged, 631 _is_on_message_waiting_event_true) 632 ad_callee.log.info("Got event %s", event) 633 except Empty: 634 ad_callee.log.warning("No expected event %s", 635 EventMessageWaitingIndicatorChanged) 636 return False 637 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 638 subid_callee) 639 ad_callee.log.info( 640 "telephonyGetVoiceMailCount output - before: %s, after: %s", 641 voice_mail_count_before, voice_mail_count_after) 642 643 # voice_mail_count_after should: 644 # either equals to (voice_mail_count_before + 1) [For ATT and SPT] 645 # or equals to -1 [For TMO] 646 # -1 means there are unread voice mail, but the count is unknown 647 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before, 648 voice_mail_count_after): 649 log.error("before and after voice mail count is not incorrect.") 650 return False 651 finally: 652 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription( 653 subid_callee) 654 return True 655 656 657def call_voicemail_erase_all_pending_voicemail(log, ad): 658 """Script for phone to erase all pending voice mail. 659 This script only works for TMO and ATT and SPT currently. 660 This script only works if phone have already set up voice mail options, 661 and phone should disable password protection for voice mail. 662 663 1. If phone don't have pending voice message, return True. 664 2. Dial voice mail number. 665 For TMO, the number is '123' 666 For ATT, the number is phone's number 667 For SPT, the number is phone's number 668 3. Wait for voice mail connection setup. 669 4. Wait for voice mail play pending voice message. 670 5. Send DTMF to delete one message. 671 The digit is '7'. 672 6. Repeat steps 4 and 5 until voice mail server drop this call. 673 (No pending message) 674 6. Check telephonyGetVoiceMailCount result. it should be 0. 675 676 Args: 677 log: log object 678 ad: android device object 679 Returns: 680 False if error happens. True is succeed. 681 """ 682 log.info("Erase all pending voice mail.") 683 count = ad.droid.telephonyGetVoiceMailCount() 684 if count == 0: 685 ad.log.info("No Pending voice mail.") 686 return True 687 if count == -1: 688 ad.log.info("There is pending voice mail, but the count is unknown") 689 count = MAX_SAVED_VOICE_MAIL 690 else: 691 ad.log.info("There are %s voicemails", count) 692 693 voice_mail_number = get_voice_mail_number(log, ad) 694 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad)) 695 if not initiate_call(log, ad, voice_mail_number): 696 log.error("Initiate call to voice mail failed.") 697 return False 698 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 699 callId = ad.droid.telecomCallGetCallIds()[0] 700 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 701 while (is_phone_in_call(log, ad) and (count > 0)): 702 ad.log.info("Press %s to delete voice mail.", delete_digit) 703 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit) 704 ad.droid.telecomCallStopDtmfTone(callId) 705 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 706 count -= 1 707 if is_phone_in_call(log, ad): 708 hangup_call(log, ad) 709 710 # wait for telephonyGetVoiceMailCount to update correct result 711 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT 712 while ((remaining_time > 0) 713 and (ad.droid.telephonyGetVoiceMailCount() != 0)): 714 time.sleep(1) 715 remaining_time -= 1 716 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount() 717 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count) 718 return (current_voice_mail_count == 0) 719 720 721def call_setup_teardown(log, 722 ad_caller, 723 ad_callee, 724 ad_hangup=None, 725 verify_caller_func=None, 726 verify_callee_func=None, 727 wait_time_in_call=WAIT_TIME_IN_CALL, 728 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 729 dialing_number_length=None, 730 video_state=None, 731 slot_id_callee=None, 732 voice_type_init=None, 733 call_stats_check=False, 734 result_info=result_dict): 735 """ Call process, including make a phone call from caller, 736 accept from callee, and hang up. The call is on default voice subscription 737 738 In call process, call from <droid_caller> to <droid_callee>, 739 accept the call, (optional)then hang up from <droid_hangup>. 740 741 Args: 742 ad_caller: Caller Android Device Object. 743 ad_callee: Callee Android Device Object. 744 ad_hangup: Android Device Object end the phone call. 745 Optional. Default value is None, and phone call will continue. 746 verify_call_mode_caller: func_ptr to verify caller in correct mode 747 Optional. Default is None 748 verify_call_mode_caller: func_ptr to verify caller in correct mode 749 Optional. Default is None 750 incall_ui_display: after answer the call, bring in-call UI to foreground or 751 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 752 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 753 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 754 else, do nothing. 755 dialing_number_length: the number of digits used for dialing 756 slot_id_callee : the slot if of the callee to call to 757 758 Returns: 759 True if call process without any error. 760 False if error happened. 761 762 """ 763 subid_caller = get_outgoing_voice_sub_id(ad_caller) 764 if slot_id_callee is None: 765 subid_callee = get_incoming_voice_sub_id(ad_callee) 766 else: 767 subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee) 768 769 return call_setup_teardown_for_subscription( 770 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup, 771 verify_caller_func, verify_callee_func, wait_time_in_call, 772 incall_ui_display, dialing_number_length, video_state, 773 voice_type_init, call_stats_check, result_info) 774 775 776def call_setup_teardown_for_subscription( 777 log, 778 ad_caller, 779 ad_callee, 780 subid_caller, 781 subid_callee, 782 ad_hangup=None, 783 verify_caller_func=None, 784 verify_callee_func=None, 785 wait_time_in_call=WAIT_TIME_IN_CALL, 786 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 787 dialing_number_length=None, 788 video_state=None, 789 voice_type_init=None, 790 call_stats_check=False, 791 result_info=result_dict): 792 """ Call process, including make a phone call from caller, 793 accept from callee, and hang up. The call is on specified subscription 794 795 In call process, call from <droid_caller> to <droid_callee>, 796 accept the call, (optional)then hang up from <droid_hangup>. 797 798 Args: 799 ad_caller: Caller Android Device Object. 800 ad_callee: Callee Android Device Object. 801 subid_caller: Caller subscription ID 802 subid_callee: Callee subscription ID 803 ad_hangup: Android Device Object end the phone call. 804 Optional. Default value is None, and phone call will continue. 805 verify_call_mode_caller: func_ptr to verify caller in correct mode 806 Optional. Default is None 807 verify_call_mode_caller: func_ptr to verify caller in correct mode 808 Optional. Default is None 809 incall_ui_display: after answer the call, bring in-call UI to foreground or 810 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 811 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 812 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 813 else, do nothing. 814 815 Returns: 816 TelResultWrapper which will evaluate as False if error. 817 818 """ 819 CHECK_INTERVAL = 5 820 begin_time = get_current_epoch_time() 821 if not verify_caller_func: 822 verify_caller_func = is_phone_in_call 823 if not verify_callee_func: 824 verify_callee_func = is_phone_in_call 825 826 caller_number = ad_caller.telephony['subscription'][subid_caller][ 827 'phone_num'] 828 callee_number = ad_callee.telephony['subscription'][subid_callee][ 829 'phone_num'] 830 831 callee_number = truncate_phone_number( 832 log, 833 caller_number, 834 callee_number, 835 dialing_number_length) 836 837 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS')) 838 msg = "Call from %s to %s" % (caller_number, callee_number) 839 if video_state: 840 msg = "Video %s" % msg 841 video = True 842 else: 843 video = False 844 if ad_hangup: 845 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call) 846 ad_caller.log.info(msg) 847 848 for ad in (ad_caller, ad_callee): 849 call_ids = ad.droid.telecomCallGetCallIds() 850 setattr(ad, "call_ids", call_ids) 851 if call_ids: 852 ad.log.info("Pre-exist CallId %s before making call", call_ids) 853 854 if not initiate_call( 855 log, 856 ad_caller, 857 callee_number, 858 incall_ui_display=incall_ui_display, 859 video=video): 860 ad_caller.log.error("Initiate call failed.") 861 tel_result_wrapper.result_value = CallResult('INITIATE_FAILED') 862 return tel_result_wrapper 863 else: 864 ad_caller.log.info("Caller initate call successfully") 865 if not wait_and_answer_call_for_subscription( 866 log, 867 ad_callee, 868 subid_callee, 869 incoming_number=caller_number, 870 caller=ad_caller, 871 incall_ui_display=incall_ui_display, 872 video_state=video_state): 873 ad_callee.log.error("Answer call fail.") 874 tel_result_wrapper.result_value = CallResult( 875 'NO_RING_EVENT_OR_ANSWER_FAILED') 876 return tel_result_wrapper 877 else: 878 ad_callee.log.info("Callee answered the call successfully") 879 880 for ad, call_func in zip([ad_caller, ad_callee], 881 [verify_caller_func, verify_callee_func]): 882 call_ids = ad.droid.telecomCallGetCallIds() 883 new_call_ids = set(call_ids) - set(ad.call_ids) 884 if not new_call_ids: 885 ad.log.error( 886 "No new call ids are found after call establishment") 887 ad.log.error("telecomCallGetCallIds returns %s", 888 ad.droid.telecomCallGetCallIds()) 889 tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND') 890 for new_call_id in new_call_ids: 891 if not wait_for_in_call_active(ad, call_id=new_call_id): 892 tel_result_wrapper.result_value = CallResult( 893 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT') 894 else: 895 ad.log.info("callProperties = %s", 896 ad.droid.telecomCallGetProperties(new_call_id)) 897 898 if not ad.droid.telecomCallGetAudioState(): 899 ad.log.error("Audio is not in call state") 900 tel_result_wrapper.result_value = CallResult( 901 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT') 902 903 if call_func(log, ad): 904 ad.log.info("Call is in %s state", call_func.__name__) 905 else: 906 ad.log.error("Call is not in %s state, voice in RAT %s", 907 call_func.__name__, 908 ad.droid.telephonyGetCurrentVoiceNetworkType()) 909 tel_result_wrapper.result_value = CallResult( 910 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT') 911 if not tel_result_wrapper: 912 return tel_result_wrapper 913 914 if call_stats_check: 915 voice_type_in_call = check_voice_network_type([ad_caller, ad_callee], voice_init=False) 916 phone_a_call_type = check_call_status(ad_caller, 917 voice_type_init[0], 918 voice_type_in_call[0]) 919 result_info["Call Stats"] = phone_a_call_type 920 ad_caller.log.debug("Voice Call Type: %s", phone_a_call_type) 921 phone_b_call_type = check_call_status(ad_callee, 922 voice_type_init[1], 923 voice_type_in_call[1]) 924 result_info["Call Stats"] = phone_b_call_type 925 ad_callee.log.debug("Voice Call Type: %s", phone_b_call_type) 926 927 return wait_for_call_end( 928 log, 929 ad_caller, 930 ad_callee, 931 ad_hangup, 932 verify_caller_func, 933 verify_callee_func, 934 begin_time, 935 check_interval=CHECK_INTERVAL, 936 tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')), 937 wait_time_in_call=wait_time_in_call) 938 939 940def two_phone_call_leave_voice_mail( 941 log, 942 caller, 943 caller_idle_func, 944 caller_in_call_check_func, 945 callee, 946 callee_idle_func, 947 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 948 """Call from caller to callee, reject on callee, caller leave a voice mail. 949 950 1. Caller call Callee. 951 2. Callee reject incoming call. 952 3. Caller leave a voice mail. 953 4. Verify callee received the voice mail notification. 954 955 Args: 956 caller: caller android device object. 957 caller_idle_func: function to check caller's idle state. 958 caller_in_call_check_func: function to check caller's in-call state. 959 callee: callee android device object. 960 callee_idle_func: function to check callee's idle state. 961 wait_time_in_call: time to wait when leaving a voice mail. 962 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 963 964 Returns: 965 True: if voice message is received on callee successfully. 966 False: for errors 967 """ 968 969 ads = [caller, callee] 970 971 # Make sure phones are idle. 972 ensure_phones_idle(log, ads) 973 if caller_idle_func and not caller_idle_func(log, caller): 974 caller.log.error("Caller Failed to Reselect") 975 return False 976 if callee_idle_func and not callee_idle_func(log, callee): 977 callee.log.error("Callee Failed to Reselect") 978 return False 979 980 # TODO: b/26337871 Need to use proper API to check phone registered. 981 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 982 983 # Make call and leave a message. 984 if not call_reject_leave_message( 985 log, caller, callee, caller_in_call_check_func, wait_time_in_call): 986 log.error("make a call and leave a message failed.") 987 return False 988 return True 989 990 991def two_phone_call_short_seq(log, 992 phone_a, 993 phone_a_idle_func, 994 phone_a_in_call_check_func, 995 phone_b, 996 phone_b_idle_func, 997 phone_b_in_call_check_func, 998 call_sequence_func=None, 999 wait_time_in_call=WAIT_TIME_IN_CALL, 1000 call_params=None): 1001 """Call process short sequence. 1002 1. Ensure phone idle and in idle_func check return True. 1003 2. Call from PhoneA to PhoneB, accept on PhoneB. 1004 3. Check phone state, hangup on PhoneA. 1005 4. Ensure phone idle and in idle_func check return True. 1006 5. Call from PhoneA to PhoneB, accept on PhoneB. 1007 6. Check phone state, hangup on PhoneB. 1008 1009 Args: 1010 phone_a: PhoneA's android device object. 1011 phone_a_idle_func: function to check PhoneA's idle state. 1012 phone_a_in_call_check_func: function to check PhoneA's in-call state. 1013 phone_b: PhoneB's android device object. 1014 phone_b_idle_func: function to check PhoneB's idle state. 1015 phone_b_in_call_check_func: function to check PhoneB's in-call state. 1016 call_sequence_func: default parameter, not implemented. 1017 wait_time_in_call: time to wait in call. 1018 This is optional, default is WAIT_TIME_IN_CALL 1019 call_params: list of call parameters for both MO/MT devices, including: 1020 - MO device object 1021 - MT device object 1022 - Device object hanging up the call 1023 - Function to check the in-call state of MO device 1024 - Function to check the in-call state of MT device 1025 1026 and the format should be: 1027 [(Args for the 1st call), (Args for the 2nd call), ......] 1028 1029 The format of args for each call should be: 1030 (mo_device_obj, mt_device_obj, device_obj_hanging_up, 1031 mo_in_call_check_func, mt_in_call_check_func) 1032 1033 Example of a call, which will not be hung up: 1034 1035 call_params = [ 1036 (ads[0], ads[1], None, mo_in_call_check_func, 1037 mt_in_call_check_func) 1038 ] 1039 1040 Returns: 1041 TelResultWrapper which will evaluate as False if error. 1042 """ 1043 ads = [phone_a, phone_b] 1044 1045 if not call_params: 1046 call_params = [ 1047 (ads[0], ads[1], ads[0], phone_a_in_call_check_func, 1048 phone_b_in_call_check_func), 1049 (ads[0], ads[1], ads[1], phone_a_in_call_check_func, 1050 phone_b_in_call_check_func), 1051 ] 1052 1053 tel_result = TelResultWrapper(CallResult('SUCCESS')) 1054 for param in call_params: 1055 # Make sure phones are idle. 1056 ensure_phones_idle(log, ads) 1057 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1058 phone_a.log.error("Phone A Failed to Reselect") 1059 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1060 if phone_b_idle_func and not phone_b_idle_func(log, phone_b): 1061 phone_b.log.error("Phone B Failed to Reselect") 1062 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1063 1064 # TODO: b/26337871 Need to use proper API to check phone registered. 1065 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1066 1067 # Make call. 1068 log.info("---> Call test: %s to %s <---", param[0].serial, 1069 param[1].serial) 1070 tel_result = call_setup_teardown( 1071 log, *param, wait_time_in_call=wait_time_in_call) 1072 if not tel_result: 1073 log.error("Call Iteration Failed") 1074 break 1075 1076 return tel_result 1077 1078def two_phone_call_msim_short_seq(log, 1079 phone_a, 1080 phone_a_idle_func, 1081 phone_a_in_call_check_func, 1082 phone_b, 1083 phone_b_idle_func, 1084 phone_b_in_call_check_func, 1085 call_sequence_func=None, 1086 wait_time_in_call=WAIT_TIME_IN_CALL): 1087 """Call process short sequence. 1088 1. Ensure phone idle and in idle_func check return True. 1089 2. Call from PhoneA to PhoneB, accept on PhoneB. 1090 3. Check phone state, hangup on PhoneA. 1091 4. Ensure phone idle and in idle_func check return True. 1092 5. Call from PhoneA to PhoneB, accept on PhoneB. 1093 6. Check phone state, hangup on PhoneB. 1094 Args: 1095 phone_a: PhoneA's android device object. 1096 phone_a_idle_func: function to check PhoneA's idle state. 1097 phone_a_in_call_check_func: function to check PhoneA's in-call state. 1098 phone_b: PhoneB's android device object. 1099 phone_b_idle_func: function to check PhoneB's idle state. 1100 phone_b_in_call_check_func: function to check PhoneB's in-call state. 1101 call_sequence_func: default parameter, not implemented. 1102 wait_time_in_call: time to wait in call. 1103 This is optional, default is WAIT_TIME_IN_CALL 1104 Returns: 1105 True: if call sequence succeed. 1106 False: for errors 1107 """ 1108 ads = [phone_a, phone_b] 1109 call_params = [ 1110 (ads[0], ads[1], ads[0], phone_a_in_call_check_func, 1111 phone_b_in_call_check_func), 1112 (ads[0], ads[1], ads[1], phone_a_in_call_check_func, 1113 phone_b_in_call_check_func), 1114 ] 1115 for param in call_params: 1116 # Make sure phones are idle. 1117 ensure_phones_idle(log, ads) 1118 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1119 phone_a.log.error("Phone A Failed to Reselect") 1120 return False 1121 if phone_b_idle_func and not phone_b_idle_func(log, phone_b): 1122 phone_b.log.error("Phone B Failed to Reselect") 1123 return False 1124 # TODO: b/26337871 Need to use proper API to check phone registered. 1125 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1126 # Make call. 1127 log.info("--> Call test: %s to %s <--", phone_a.serial, phone_b.serial) 1128 slots = 2 1129 for slot in range(slots): 1130 set_subid_for_outgoing_call( 1131 ads[0], get_subid_from_slot_index(log,ads[0],slot)) 1132 set_subid_for_outgoing_call( 1133 ads[1], get_subid_from_slot_index(log,ads[1],slot)) 1134 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1135 if not call_setup_teardown(log, *param,slot_id_callee = slot, 1136 wait_time_in_call=wait_time_in_call): 1137 log.error("Call Iteration Failed") 1138 return False 1139 if not call_setup_teardown(log, *param,slot_id_callee = 1-slot, 1140 wait_time_in_call=wait_time_in_call): 1141 log.error("Call Iteration Failed") 1142 return False 1143 return True 1144 1145def two_phone_call_long_seq(log, 1146 phone_a, 1147 phone_a_idle_func, 1148 phone_a_in_call_check_func, 1149 phone_b, 1150 phone_b_idle_func, 1151 phone_b_in_call_check_func, 1152 call_sequence_func=None, 1153 wait_time_in_call=WAIT_TIME_IN_CALL): 1154 """Call process long sequence. 1155 1. Ensure phone idle and in idle_func check return True. 1156 2. Call from PhoneA to PhoneB, accept on PhoneB. 1157 3. Check phone state, hangup on PhoneA. 1158 4. Ensure phone idle and in idle_func check return True. 1159 5. Call from PhoneA to PhoneB, accept on PhoneB. 1160 6. Check phone state, hangup on PhoneB. 1161 7. Ensure phone idle and in idle_func check return True. 1162 8. Call from PhoneB to PhoneA, accept on PhoneA. 1163 9. Check phone state, hangup on PhoneA. 1164 10. Ensure phone idle and in idle_func check return True. 1165 11. Call from PhoneB to PhoneA, accept on PhoneA. 1166 12. Check phone state, hangup on PhoneB. 1167 1168 Args: 1169 phone_a: PhoneA's android device object. 1170 phone_a_idle_func: function to check PhoneA's idle state. 1171 phone_a_in_call_check_func: function to check PhoneA's in-call state. 1172 phone_b: PhoneB's android device object. 1173 phone_b_idle_func: function to check PhoneB's idle state. 1174 phone_b_in_call_check_func: function to check PhoneB's in-call state. 1175 call_sequence_func: default parameter, not implemented. 1176 wait_time_in_call: time to wait in call. 1177 This is optional, default is WAIT_TIME_IN_CALL 1178 1179 Returns: 1180 TelResultWrapper which will evaluate as False if error. 1181 1182 """ 1183 ads = [phone_a, phone_b] 1184 1185 call_params = [ 1186 (ads[0], ads[1], ads[0], phone_a_in_call_check_func, 1187 phone_b_in_call_check_func), 1188 (ads[0], ads[1], ads[1], phone_a_in_call_check_func, 1189 phone_b_in_call_check_func), 1190 (ads[1], ads[0], ads[0], phone_b_in_call_check_func, 1191 phone_a_in_call_check_func), 1192 (ads[1], ads[0], ads[1], phone_b_in_call_check_func, 1193 phone_a_in_call_check_func), 1194 ] 1195 1196 tel_result = TelResultWrapper(CallResult('SUCCESS')) 1197 for param in call_params: 1198 # Make sure phones are idle. 1199 ensure_phones_idle(log, ads) 1200 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1201 phone_a.log.error("Phone A Failed to Reselect") 1202 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1203 if phone_b_idle_func and not phone_b_idle_func(log, phone_b): 1204 phone_b.log.error("Phone B Failed to Reselect") 1205 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1206 1207 # TODO: b/26337871 Need to use proper API to check phone registered. 1208 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1209 1210 # Make call. 1211 log.info("---> Call test: %s to %s <---", param[0].serial, 1212 param[1].serial) 1213 tel_result = call_setup_teardown( 1214 log, *param, wait_time_in_call=wait_time_in_call) 1215 if not tel_result: 1216 log.error("Call Iteration Failed") 1217 break 1218 1219 return tel_result 1220 1221def two_phone_call_msim_for_slot(log, 1222 phone_a, 1223 phone_a_slot, 1224 phone_a_idle_func, 1225 phone_a_in_call_check_func, 1226 phone_b, 1227 phone_b_slot, 1228 phone_b_idle_func, 1229 phone_b_in_call_check_func, 1230 call_sequence_func=None, 1231 wait_time_in_call=WAIT_TIME_IN_CALL, 1232 retry=2): 1233 """Call process between 2 phones with specific slot. 1234 1. Ensure phone idle and in idle_func check return True. 1235 2. Call from PhoneA to PhoneB, accept on PhoneB. 1236 3. Check phone state, hangup on PhoneA. 1237 4. Ensure phone idle and in idle_func check return True. 1238 5. Call from PhoneA to PhoneB, accept on PhoneB. 1239 6. Check phone state, hangup on PhoneB. 1240 1241 Args: 1242 phone_a: PhoneA's android device object. 1243 phone_a_slot: 0 or 1 (pSIM or eSIM) 1244 phone_a_idle_func: function to check PhoneA's idle state. 1245 phone_a_in_call_check_func: function to check PhoneA's in-call state. 1246 phone_b: PhoneB's android device object. 1247 phone_b_slot: 0 or 1 (pSIM or eSIM) 1248 phone_b_idle_func: function to check PhoneB's idle state. 1249 phone_b_in_call_check_func: function to check PhoneB's in-call state. 1250 call_sequence_func: default parameter, not implemented. 1251 wait_time_in_call: time to wait in call. 1252 This is optional, default is WAIT_TIME_IN_CALL 1253 retry: times of retry if call_setup_teardown failed. 1254 1255 Returns: 1256 True: if call sequence succeed. 1257 False: for errors 1258 """ 1259 ads = [phone_a, phone_b] 1260 1261 call_params = [ 1262 (ads[0], ads[1], ads[0], phone_a_in_call_check_func, 1263 phone_b_in_call_check_func), 1264 (ads[0], ads[1], ads[1], phone_a_in_call_check_func, 1265 phone_b_in_call_check_func), 1266 ] 1267 1268 tel_result = TelResultWrapper(CallResult('SUCCESS')) 1269 for param in call_params: 1270 # Make sure phones are idle. 1271 ensure_phones_idle(log, ads) 1272 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1273 phone_a.log.error("Phone A Failed to Reselect") 1274 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1275 if phone_b_idle_func and not phone_b_idle_func(log, phone_b): 1276 phone_b.log.error("Phone B Failed to Reselect") 1277 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1278 1279 # TODO: b/26337871 Need to use proper API to check phone registered. 1280 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1281 1282 # Make call. 1283 log.info("--> Call test: %s slot %s to %s slot %s <--", phone_a.serial, 1284 phone_a_slot, phone_b.serial, phone_b_slot) 1285 1286 mo_default_voice_subid = get_subid_from_slot_index(log,ads[0], 1287 phone_a_slot) 1288 if mo_default_voice_subid == INVALID_SUB_ID: 1289 log.warning("Sub ID of MO (%s) slot %s is invalid.", phone_a.serial, 1290 phone_a_slot) 1291 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1292 set_subid_for_outgoing_call( 1293 ads[0], mo_default_voice_subid) 1294 1295 mt_default_voice_subid = get_subid_from_slot_index(log,ads[1], 1296 phone_b_slot) 1297 if mt_default_voice_subid == INVALID_SUB_ID: 1298 log.warning("Sub ID of MT (%s) slot %s is invalid.", phone_b.serial, 1299 phone_b_slot) 1300 return TelResultWrapper(CallResult('CALL_SETUP_FAILURE')) 1301 1302 tel_result = call_setup_teardown( 1303 log, 1304 *param, 1305 slot_id_callee=phone_b_slot, 1306 wait_time_in_call=wait_time_in_call) 1307 1308 while not tel_result: 1309 if retry <= 0: 1310 log.error("Call Iteration failed.") 1311 break 1312 else: 1313 log.info("RERUN call_setup_teardown.") 1314 tel_result = call_setup_teardown( 1315 log, 1316 *param, 1317 slot_id_callee=phone_b_slot, 1318 wait_time_in_call=wait_time_in_call) 1319 1320 retry = retry - 1 1321 1322 return tel_result 1323 1324 1325def is_phone_in_call(log, ad): 1326 """Return True if phone in call. 1327 1328 Args: 1329 log: log object. 1330 ad: android device. 1331 """ 1332 try: 1333 return ad.droid.telecomIsInCall() 1334 except: 1335 return "mCallState=2" in ad.adb.shell( 1336 "dumpsys telephony.registry | grep mCallState") 1337 1338 1339def is_phone_in_call_active(ad, call_id=None): 1340 """Return True if phone in active call. 1341 1342 Args: 1343 log: log object. 1344 ad: android device. 1345 call_id: the call id 1346 """ 1347 if ad.droid.telecomIsInCall(): 1348 if not call_id: 1349 call_id = ad.droid.telecomCallGetCallIds()[0] 1350 call_state = ad.droid.telecomCallGetCallState(call_id) 1351 ad.log.info("%s state is %s", call_id, call_state) 1352 return call_state == "ACTIVE" 1353 else: 1354 ad.log.info("Not in telecomIsInCall") 1355 return False 1356 1357 1358def is_phone_in_call_volte(log, ad): 1359 """Return if phone is in VoLTE call. 1360 1361 Args: 1362 ad: Android device object. 1363 """ 1364 return is_phone_in_call_volte_for_subscription( 1365 log, ad, get_outgoing_voice_sub_id(ad)) 1366 1367 1368def is_phone_in_call_volte_for_subscription(log, ad, sub_id): 1369 """Return if phone is in VoLTE call for subscription id. 1370 1371 Args: 1372 ad: Android device object. 1373 sub_id: subscription id. 1374 """ 1375 if not ad.droid.telecomIsInCall(): 1376 ad.log.error("Not in call.") 1377 return False 1378 nw_type = get_network_rat_for_subscription(log, ad, sub_id, 1379 NETWORK_SERVICE_VOICE) 1380 if nw_type != RAT_LTE: 1381 ad.log.error("Voice rat on: %s. Expected: LTE", nw_type) 1382 return False 1383 return True 1384 1385 1386def is_phone_in_call_csfb(log, ad): 1387 """Return if phone is in CSFB call. 1388 1389 Args: 1390 ad: Android device object. 1391 """ 1392 return is_phone_in_call_csfb_for_subscription( 1393 log, ad, get_outgoing_voice_sub_id(ad)) 1394 1395 1396def is_phone_in_call_csfb_for_subscription(log, ad, sub_id): 1397 """Return if phone is in CSFB call for subscription id. 1398 1399 Args: 1400 ad: Android device object. 1401 sub_id: subscription id. 1402 """ 1403 if not ad.droid.telecomIsInCall(): 1404 ad.log.error("Not in call.") 1405 return False 1406 nw_type = get_network_rat_for_subscription(log, ad, sub_id, 1407 NETWORK_SERVICE_VOICE) 1408 if nw_type == RAT_LTE: 1409 ad.log.error("Voice rat on: %s. Expected: not LTE", nw_type) 1410 return False 1411 return True 1412 1413 1414def is_phone_in_call_3g(log, ad): 1415 """Return if phone is in 3G call. 1416 1417 Args: 1418 ad: Android device object. 1419 """ 1420 return is_phone_in_call_3g_for_subscription(log, ad, 1421 get_outgoing_voice_sub_id(ad)) 1422 1423 1424def is_phone_in_call_3g_for_subscription(log, ad, sub_id): 1425 """Return if phone is in 3G call for subscription id. 1426 1427 Args: 1428 ad: Android device object. 1429 sub_id: subscription id. 1430 """ 1431 if not ad.droid.telecomIsInCall(): 1432 ad.log.error("Not in call.") 1433 return False 1434 nw_gen = get_network_gen_for_subscription(log, ad, sub_id, 1435 NETWORK_SERVICE_VOICE) 1436 if nw_gen != GEN_3G: 1437 ad.log.error("Voice rat on: %s. Expected: 3g", nw_gen) 1438 return False 1439 return True 1440 1441 1442def is_phone_in_call_2g(log, ad): 1443 """Return if phone is in 2G call. 1444 1445 Args: 1446 ad: Android device object. 1447 """ 1448 return is_phone_in_call_2g_for_subscription(log, ad, 1449 get_outgoing_voice_sub_id(ad)) 1450 1451 1452def is_phone_in_call_2g_for_subscription(log, ad, sub_id): 1453 """Return if phone is in 2G call for subscription id. 1454 1455 Args: 1456 ad: Android device object. 1457 sub_id: subscription id. 1458 """ 1459 if not ad.droid.telecomIsInCall(): 1460 ad.log.error("Not in call.") 1461 return False 1462 nw_gen = get_network_gen_for_subscription(log, ad, sub_id, 1463 NETWORK_SERVICE_VOICE) 1464 if nw_gen != GEN_2G: 1465 ad.log.error("Voice rat on: %s. Expected: 2g", nw_gen) 1466 return False 1467 return True 1468 1469 1470def is_phone_in_call_1x(log, ad): 1471 """Return if phone is in 1x call. 1472 1473 Args: 1474 ad: Android device object. 1475 """ 1476 return is_phone_in_call_1x_for_subscription(log, ad, 1477 get_outgoing_voice_sub_id(ad)) 1478 1479 1480def is_phone_in_call_1x_for_subscription(log, ad, sub_id): 1481 """Return if phone is in 1x call for subscription id. 1482 1483 Args: 1484 ad: Android device object. 1485 sub_id: subscription id. 1486 """ 1487 if not ad.droid.telecomIsInCall(): 1488 ad.log.error("Not in call.") 1489 return False 1490 nw_type = get_network_rat_for_subscription(log, ad, sub_id, 1491 NETWORK_SERVICE_VOICE) 1492 if nw_type != RAT_1XRTT: 1493 ad.log.error("Voice rat on: %s. Expected: 1xrtt", nw_type) 1494 return False 1495 return True 1496 1497 1498def is_phone_in_call_wcdma(log, ad): 1499 """Return if phone is in WCDMA call. 1500 1501 Args: 1502 ad: Android device object. 1503 """ 1504 return is_phone_in_call_wcdma_for_subscription( 1505 log, ad, get_outgoing_voice_sub_id(ad)) 1506 1507 1508def is_phone_in_call_wcdma_for_subscription(log, ad, sub_id): 1509 """Return if phone is in WCDMA call for subscription id. 1510 1511 Args: 1512 ad: Android device object. 1513 sub_id: subscription id. 1514 """ 1515 # Currently checking 'umts'. 1516 # Changes may needed in the future. 1517 if not ad.droid.telecomIsInCall(): 1518 ad.log.error("Not in call.") 1519 return False 1520 nw_type = get_network_rat_for_subscription(log, ad, sub_id, 1521 NETWORK_SERVICE_VOICE) 1522 if nw_type != RAT_UMTS: 1523 ad.log.error("%s voice rat on: %s. Expected: umts", nw_type) 1524 return False 1525 return True 1526 1527 1528def is_phone_in_call_iwlan(log, ad, call_id=None): 1529 """Return if phone is in WiFi call. 1530 1531 Args: 1532 ad: Android device object. 1533 """ 1534 if not ad.droid.telecomIsInCall(): 1535 ad.log.error("Not in call.") 1536 return False 1537 if not ad.droid.telephonyIsImsRegistered(): 1538 ad.log.info("IMS is not registered.") 1539 return False 1540 if not ad.droid.telephonyIsWifiCallingAvailable(): 1541 ad.log.info("IsWifiCallingAvailable is False") 1542 return False 1543 if not call_id: 1544 call_ids = ad.droid.telecomCallGetCallIds() 1545 if call_ids: 1546 call_id = call_ids[-1] 1547 if not call_id: 1548 ad.log.error("Failed to get call id") 1549 return False 1550 else: 1551 call_prop = ad.droid.telecomCallGetProperties(call_id) 1552 if "WIFI" not in call_prop: 1553 ad.log.info("callProperties = %s, expecting WIFI", call_prop) 1554 return False 1555 nw_type = get_network_rat(log, ad, NETWORK_SERVICE_DATA) 1556 if nw_type != RAT_IWLAN: 1557 ad.log.warning("Data rat on: %s. Expected: iwlan", nw_type) 1558 return True 1559 1560 1561def is_phone_in_call_not_iwlan(log, ad): 1562 """Return if phone is in WiFi call for subscription id. 1563 1564 Args: 1565 ad: Android device object. 1566 sub_id: subscription id. 1567 """ 1568 if not ad.droid.telecomIsInCall(): 1569 ad.log.error("Not in call.") 1570 return False 1571 nw_type = get_network_rat(log, ad, NETWORK_SERVICE_DATA) 1572 if nw_type == RAT_IWLAN: 1573 ad.log.error("Data rat on: %s. Expected: not iwlan", nw_type) 1574 return False 1575 if is_wfc_enabled(log, ad): 1576 ad.log.error("WiFi Calling feature bit is True.") 1577 return False 1578 return True 1579 1580 1581def swap_calls(log, 1582 ads, 1583 call_hold_id, 1584 call_active_id, 1585 num_swaps=1, 1586 check_call_status=True): 1587 """PhoneA in call with B and C. Swap active/holding call on PhoneA. 1588 1589 Swap call and check status on PhoneA. 1590 (This step may have multiple times according to 'num_swaps'.) 1591 Check if all 3 phones are 'in-call'. 1592 1593 Args: 1594 ads: list of ad object, at least three need to pass in. 1595 Swap operation will happen on ads[0]. 1596 ads[1] and ads[2] are call participants. 1597 call_hold_id: id for the holding call in ads[0]. 1598 call_hold_id should be 'STATE_HOLDING' when calling this function. 1599 call_active_id: id for the active call in ads[0]. 1600 call_active_id should be 'STATE_ACTIVE' when calling this function. 1601 num_swaps: how many swap/check operations will be done before return. 1602 check_call_status: This is optional. Default value is True. 1603 If this value is True, then call status (active/hold) will be 1604 be checked after each swap operation. 1605 1606 Returns: 1607 If no error happened, return True, otherwise, return False. 1608 """ 1609 if check_call_status: 1610 # Check status before swap. 1611 if ads[0].droid.telecomCallGetCallState( 1612 call_active_id) != CALL_STATE_ACTIVE: 1613 ads[0].log.error( 1614 "Call_id:%s, state:%s, expected: STATE_ACTIVE", call_active_id, 1615 ads[0].droid.telecomCallGetCallState(call_active_id)) 1616 return False 1617 if ads[0].droid.telecomCallGetCallState( 1618 call_hold_id) != CALL_STATE_HOLDING: 1619 ads[0].log.error( 1620 "Call_id:%s, state:%s, expected: STATE_HOLDING", call_hold_id, 1621 ads[0].droid.telecomCallGetCallState(call_hold_id)) 1622 return False 1623 1624 i = 1 1625 while (i <= num_swaps): 1626 ads[0].log.info("swap_test %s: swap and check call status.", i) 1627 ads[0].droid.telecomCallHold(call_active_id) 1628 time.sleep(WAIT_TIME_IN_CALL) 1629 # Swap object reference 1630 call_active_id, call_hold_id = call_hold_id, call_active_id 1631 if check_call_status: 1632 # Check status 1633 if ads[0].droid.telecomCallGetCallState( 1634 call_active_id) != CALL_STATE_ACTIVE: 1635 ads[0].log.error( 1636 "Call_id:%s, state:%s, expected: STATE_ACTIVE", 1637 call_active_id, 1638 ads[0].droid.telecomCallGetCallState(call_active_id)) 1639 return False 1640 if ads[0].droid.telecomCallGetCallState( 1641 call_hold_id) != CALL_STATE_HOLDING: 1642 ads[0].log.error( 1643 "Call_id:%s, state:%s, expected: STATE_HOLDING", 1644 call_hold_id, 1645 ads[0].droid.telecomCallGetCallState(call_hold_id)) 1646 return False 1647 # TODO: b/26296375 add voice check. 1648 1649 i += 1 1650 1651 #In the end, check all three phones are 'in-call'. 1652 if not verify_incall_state(log, [ads[0], ads[1], ads[2]], True): 1653 return False 1654 1655 return True 1656 1657 1658def get_audio_route(log, ad): 1659 """Gets the audio route for the active call 1660 1661 Args: 1662 log: logger object 1663 ad: android_device object 1664 1665 Returns: 1666 Audio route string ["BLUETOOTH", "EARPIECE", "SPEAKER", "WIRED_HEADSET" 1667 "WIRED_OR_EARPIECE"] 1668 """ 1669 1670 audio_state = ad.droid.telecomCallGetAudioState() 1671 return audio_state["AudioRoute"] 1672 1673 1674def set_audio_route(log, ad, route): 1675 """Sets the audio route for the active call 1676 1677 Args: 1678 log: logger object 1679 ad: android_device object 1680 route: string ["BLUETOOTH", "EARPIECE", "SPEAKER", "WIRED_HEADSET" 1681 "WIRED_OR_EARPIECE"] 1682 1683 Returns: 1684 If no error happened, return True, otherwise, return False. 1685 """ 1686 ad.droid.telecomCallSetAudioRoute(route) 1687 return True 1688 1689 1690def is_property_in_call_properties(log, ad, call_id, expected_property): 1691 """Return if the call_id has the expected property 1692 1693 Args: 1694 log: logger object 1695 ad: android_device object 1696 call_id: call id. 1697 expected_property: expected property. 1698 1699 Returns: 1700 True if call_id has expected_property. False if not. 1701 """ 1702 properties = ad.droid.telecomCallGetProperties(call_id) 1703 return (expected_property in properties) 1704 1705 1706def is_call_hd(log, ad, call_id): 1707 """Return if the call_id is HD call. 1708 1709 Args: 1710 log: logger object 1711 ad: android_device object 1712 call_id: call id. 1713 1714 Returns: 1715 True if call_id is HD call. False if not. 1716 """ 1717 return is_property_in_call_properties(log, ad, call_id, 1718 CALL_PROPERTY_HIGH_DEF_AUDIO) 1719 1720 1721def get_cep_conference_call_id(ad): 1722 """Get CEP conference call id if there is an ongoing CEP conference call. 1723 1724 Args: 1725 ad: android device object. 1726 1727 Returns: 1728 call id for CEP conference call if there is an ongoing CEP conference call. 1729 None otherwise. 1730 """ 1731 for call in ad.droid.telecomCallGetCallIds(): 1732 if len(ad.droid.telecomCallGetCallChildren(call)) != 0: 1733 return call 1734 return None 1735 1736 1737def is_phone_in_call_on_rat(log, ad, rat='volte', only_return_fn=None): 1738 if rat.lower() == 'volte' or rat.lower() == '5g_volte': 1739 if only_return_fn: 1740 return is_phone_in_call_volte 1741 else: 1742 return is_phone_in_call_volte(log, ad) 1743 1744 elif rat.lower() == 'csfb' or rat.lower() == '5g_csfb': 1745 if only_return_fn: 1746 return is_phone_in_call_csfb 1747 else: 1748 return is_phone_in_call_csfb(log, ad) 1749 1750 elif rat.lower() == '3g': 1751 if only_return_fn: 1752 return is_phone_in_call_3g 1753 else: 1754 return is_phone_in_call_3g(log, ad) 1755 1756 elif rat.lower() == '2g': 1757 if only_return_fn: 1758 return is_phone_in_call_2g 1759 else: 1760 return is_phone_in_call_2g(log, ad) 1761 1762 elif rat.lower() == 'wfc' or rat.lower() == '5g_wfc': 1763 if only_return_fn: 1764 return is_phone_in_call_iwlan 1765 else: 1766 return is_phone_in_call_iwlan(log, ad) 1767 else: 1768 return None 1769 1770 1771def hold_unhold_test(log, ads): 1772 """ Test hold/unhold functionality. 1773 1774 PhoneA is in call with PhoneB. The call on PhoneA is active. 1775 Get call list on PhoneA. 1776 Hold call_id on PhoneA. 1777 Check call_id state. 1778 Unhold call_id on PhoneA. 1779 Check call_id state. 1780 1781 Args: 1782 log: log object 1783 ads: List of android objects. 1784 This list should contain 2 android objects. 1785 ads[0] is the ad to do hold/unhold operation. 1786 1787 Returns: 1788 List of test result and call states. 1789 The first element of the list is always the test result. 1790 True if pass; False if fail. 1791 The rest of the list contains call states. 1792 """ 1793 call_list = ads[0].droid.telecomCallGetCallIds() 1794 log.info("Calls in PhoneA %s", call_list) 1795 if num_active_calls(ads[0].log, ads[0]) != 1: 1796 log.error("No voice call or too many voice calls in PhoneA!") 1797 call_state_list = [ads[0].droid.telecomCallGetCallState(call_id) for call_id in call_list] 1798 return [False] + call_state_list 1799 call_id = call_list[0] 1800 1801 call_state = ads[0].droid.telecomCallGetCallState(call_id) 1802 if call_state != CALL_STATE_ACTIVE: 1803 log.error("Call_id:%s, state:%s, expected: STATE_ACTIVE", 1804 call_id, 1805 ads[0].droid.telecomCallGetCallState(call_id)) 1806 return [False, call_state] 1807 # TODO: b/26296375 add voice check. 1808 1809 log.info("Hold call_id %s on PhoneA", call_id) 1810 ads[0].droid.telecomCallHold(call_id) 1811 time.sleep(WAIT_TIME_IN_CALL) 1812 1813 call_state = ads[0].droid.telecomCallGetCallState(call_id) 1814 if call_state != CALL_STATE_HOLDING: 1815 ads[0].log.error("Call_id:%s, state:%s, expected: STATE_HOLDING", 1816 call_id, 1817 ads[0].droid.telecomCallGetCallState(call_id)) 1818 return [False, call_state] 1819 # TODO: b/26296375 add voice check. 1820 1821 log.info("Unhold call_id %s on PhoneA", call_id) 1822 ads[0].droid.telecomCallUnhold(call_id) 1823 time.sleep(WAIT_TIME_IN_CALL) 1824 1825 call_state = ads[0].droid.telecomCallGetCallState(call_id) 1826 if call_state != CALL_STATE_ACTIVE: 1827 log.error("Call_id:%s, state:%s, expected: STATE_ACTIVE", 1828 call_id, 1829 call_state) 1830 return [False, call_state] 1831 # TODO: b/26296375 add voice check. 1832 1833 return [True, call_state] 1834 1835 1836def phone_setup_call_hold_unhold_test(log, 1837 ads, 1838 call_direction=DIRECTION_MOBILE_ORIGINATED, 1839 caller_func=None, 1840 callee_func=None): 1841 """Test hold and unhold in voice call. 1842 1843 1. Clear call list. 1844 2. Set up MO/MT call. 1845 3. Test hold and unhold in call. 1846 4. hangup call. 1847 1848 Args: 1849 log: log object 1850 ads: list of android objects, this list should have two ad. 1851 call_direction: MO(DIRECTION_MOBILE_ORIGINATED) or MT(DIRECTION_MOBILE_TERMINATED) call. 1852 caller_func: function to verify caller is in correct state while in-call. 1853 callee_func: function to verify callee is in correct state while in-call. 1854 1855 Returns: 1856 True if pass; False if fail. 1857 """ 1858 1859 ads[0].droid.telecomCallClearCallList() 1860 if num_active_calls(log, ads[0]) != 0: 1861 ads[0].log.error("call list is not empty") 1862 return False 1863 log.info("begin hold/unhold test") 1864 1865 ad_caller = ads[0] 1866 ad_callee = ads[1] 1867 1868 if call_direction != DIRECTION_MOBILE_ORIGINATED: 1869 ad_caller = ads[1] 1870 ad_callee = ads[0] 1871 1872 if not call_setup_teardown( 1873 log, 1874 ad_caller, 1875 ad_callee, 1876 ad_hangup=None, 1877 verify_caller_func=caller_func, 1878 verify_callee_func=callee_func): 1879 return False 1880 1881 if not hold_unhold_test(ads[0].log, ads)[0]: 1882 log.error("hold/unhold test fail.") 1883 # hangup call in case voice call is still active. 1884 hangup_call(log, ads[0]) 1885 return False 1886 1887 if not hangup_call(log, ads[0]): 1888 log.error("call hangup failed") 1889 return False 1890 return True 1891 1892 1893def _test_call_long_duration(log, ads, dut_incall_check_func, total_duration): 1894 1895 log.info("Long Duration Call Test. Total duration = %s", 1896 total_duration) 1897 return call_setup_teardown( 1898 log, 1899 ads[0], 1900 ads[1], 1901 ads[0], 1902 verify_caller_func=dut_incall_check_func, 1903 wait_time_in_call=total_duration) 1904 1905 1906def _wait_for_ringing_event(log, ad, wait_time): 1907 """Wait for ringing event. 1908 1909 Args: 1910 log: log object. 1911 ad: android device object. 1912 wait_time: max time to wait for ringing event. 1913 1914 Returns: 1915 event_ringing if received ringing event. 1916 otherwise return None. 1917 """ 1918 event_ringing = None 1919 1920 try: 1921 event_ringing = ad.ed.wait_for_event( 1922 EventCallStateChanged, 1923 is_event_match, 1924 timeout=wait_time, 1925 field=CallStateContainer.CALL_STATE, 1926 value=TELEPHONY_STATE_RINGING) 1927 ad.log.info("Receive ringing event") 1928 except Empty: 1929 ad.log.info("No Ringing Event") 1930 finally: 1931 return event_ringing 1932 1933 1934def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING): 1935 """Wait for android to be in telecom ringing state. 1936 1937 Args: 1938 log: log object. 1939 ad: android device. 1940 max_time: maximal wait time. This is optional. 1941 Default Value is MAX_WAIT_TIME_TELECOM_RINGING. 1942 1943 Returns: 1944 If phone become in telecom ringing state within max_time, return True. 1945 Return False if timeout. 1946 """ 1947 return _wait_for_droid_in_state( 1948 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging()) 1949 1950 1951def wait_for_ringing_call(log, ad, incoming_number=None): 1952 """Wait for an incoming call on default voice subscription and 1953 accepts the call. 1954 1955 Args: 1956 log: log object. 1957 ad: android device object. 1958 incoming_number: Expected incoming number. 1959 Optional. Default is None 1960 1961 Returns: 1962 True: if incoming call is received and answered successfully. 1963 False: for errors 1964 """ 1965 return wait_for_ringing_call_for_subscription( 1966 log, ad, get_incoming_voice_sub_id(ad), incoming_number) 1967 1968 1969def wait_for_ringing_call_for_subscription( 1970 log, 1971 ad, 1972 sub_id, 1973 incoming_number=None, 1974 caller=None, 1975 event_tracking_started=False, 1976 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 1977 interval=WAIT_TIME_BETWEEN_STATE_CHECK): 1978 """Wait for an incoming call on specified subscription. 1979 1980 Args: 1981 log: log object. 1982 ad: android device object. 1983 sub_id: subscription ID 1984 incoming_number: Expected incoming number. Default is None 1985 event_tracking_started: True if event tracking already state outside 1986 timeout: time to wait for ring 1987 interval: checking interval 1988 1989 Returns: 1990 True: if incoming call is received and answered successfully. 1991 False: for errors 1992 """ 1993 if not event_tracking_started: 1994 ad.ed.clear_events(EventCallStateChanged) 1995 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1996 ring_event_received = False 1997 end_time = time.time() + timeout 1998 try: 1999 while time.time() < end_time: 2000 if not ring_event_received: 2001 event_ringing = _wait_for_ringing_event(log, ad, interval) 2002 if event_ringing: 2003 if incoming_number and not check_phone_number_match( 2004 event_ringing['data'] 2005 [CallStateContainer.INCOMING_NUMBER], incoming_number): 2006 ad.log.error( 2007 "Incoming Number not match. Expected number:%s, actual number:%s", 2008 incoming_number, event_ringing['data'][ 2009 CallStateContainer.INCOMING_NUMBER]) 2010 return False 2011 ring_event_received = True 2012 telephony_state = ad.droid.telephonyGetCallStateForSubscription( 2013 sub_id) 2014 telecom_state = ad.droid.telecomGetCallState() 2015 if telephony_state == TELEPHONY_STATE_RINGING and ( 2016 telecom_state == TELEPHONY_STATE_RINGING): 2017 ad.log.info("callee is in telephony and telecom RINGING state") 2018 if caller: 2019 if caller.droid.telecomIsInCall(): 2020 caller.log.info("Caller telecom is in call state") 2021 return True 2022 else: 2023 caller.log.info("Caller telecom is NOT in call state") 2024 else: 2025 return True 2026 else: 2027 ad.log.info( 2028 "telephony in %s, telecom in %s, expecting RINGING state", 2029 telephony_state, telecom_state) 2030 time.sleep(interval) 2031 finally: 2032 if not event_tracking_started: 2033 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 2034 sub_id) 2035 2036 2037def wait_for_call_offhook_for_subscription( 2038 log, 2039 ad, 2040 sub_id, 2041 event_tracking_started=False, 2042 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT, 2043 interval=WAIT_TIME_BETWEEN_STATE_CHECK): 2044 """Wait for an incoming call on specified subscription. 2045 2046 Args: 2047 log: log object. 2048 ad: android device object. 2049 sub_id: subscription ID 2050 timeout: time to wait for ring 2051 interval: checking interval 2052 2053 Returns: 2054 True: if incoming call is received and answered successfully. 2055 False: for errors 2056 """ 2057 if not event_tracking_started: 2058 ad.ed.clear_events(EventCallStateChanged) 2059 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 2060 offhook_event_received = False 2061 end_time = time.time() + timeout 2062 try: 2063 while time.time() < end_time: 2064 if not offhook_event_received: 2065 if wait_for_call_offhook_event(log, ad, sub_id, True, 2066 interval): 2067 offhook_event_received = True 2068 telephony_state = ad.droid.telephonyGetCallStateForSubscription( 2069 sub_id) 2070 telecom_state = ad.droid.telecomGetCallState() 2071 if telephony_state == TELEPHONY_STATE_OFFHOOK and ( 2072 telecom_state == TELEPHONY_STATE_OFFHOOK): 2073 ad.log.info("telephony and telecom are in OFFHOOK state") 2074 return True 2075 else: 2076 ad.log.info( 2077 "telephony in %s, telecom in %s, expecting OFFHOOK state", 2078 telephony_state, telecom_state) 2079 if offhook_event_received: 2080 time.sleep(interval) 2081 finally: 2082 if not event_tracking_started: 2083 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 2084 sub_id) 2085 2086 2087def wait_for_call_offhook_event( 2088 log, 2089 ad, 2090 sub_id, 2091 event_tracking_started=False, 2092 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT): 2093 """Wait for an incoming call on specified subscription. 2094 2095 Args: 2096 log: log object. 2097 ad: android device object. 2098 event_tracking_started: True if event tracking already state outside 2099 timeout: time to wait for event 2100 2101 Returns: 2102 True: if call offhook event is received. 2103 False: if call offhook event is not received. 2104 """ 2105 if not event_tracking_started: 2106 ad.ed.clear_events(EventCallStateChanged) 2107 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 2108 try: 2109 ad.ed.wait_for_event( 2110 EventCallStateChanged, 2111 is_event_match, 2112 timeout=timeout, 2113 field=CallStateContainer.CALL_STATE, 2114 value=TELEPHONY_STATE_OFFHOOK) 2115 ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK) 2116 except Empty: 2117 ad.log.info("No event for call state change to OFFHOOK") 2118 return False 2119 finally: 2120 if not event_tracking_started: 2121 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 2122 sub_id) 2123 return True 2124 2125 2126def wait_and_answer_call_for_subscription( 2127 log, 2128 ad, 2129 sub_id, 2130 incoming_number=None, 2131 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 2132 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 2133 caller=None, 2134 video_state=None): 2135 """Wait for an incoming call on specified subscription and 2136 accepts the call. 2137 2138 Args: 2139 log: log object. 2140 ad: android device object. 2141 sub_id: subscription ID 2142 incoming_number: Expected incoming number. 2143 Optional. Default is None 2144 incall_ui_display: after answer the call, bring in-call UI to foreground or 2145 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 2146 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 2147 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 2148 else, do nothing. 2149 2150 Returns: 2151 True: if incoming call is received and answered successfully. 2152 False: for errors 2153 """ 2154 ad.ed.clear_events(EventCallStateChanged) 2155 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 2156 try: 2157 if not wait_for_ringing_call_for_subscription( 2158 log, 2159 ad, 2160 sub_id, 2161 incoming_number=incoming_number, 2162 caller=caller, 2163 event_tracking_started=True, 2164 timeout=timeout): 2165 ad.log.info("Incoming call ringing check failed.") 2166 return False 2167 ad.log.info("Accept the ring call") 2168 ad.droid.telecomAcceptRingingCall(video_state) 2169 2170 if wait_for_call_offhook_for_subscription( 2171 log, ad, sub_id, event_tracking_started=True): 2172 return True 2173 else: 2174 ad.log.error("Could not answer the call.") 2175 return False 2176 except Exception as e: 2177 log.error(e) 2178 return False 2179 finally: 2180 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 2181 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 2182 ad.droid.telecomShowInCallScreen() 2183 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 2184 ad.droid.showHomeScreen() 2185 2186 2187def wait_and_reject_call(log, 2188 ad, 2189 incoming_number=None, 2190 delay_reject=WAIT_TIME_REJECT_CALL, 2191 reject=True): 2192 """Wait for an incoming call on default voice subscription and 2193 reject the call. 2194 2195 Args: 2196 log: log object. 2197 ad: android device object. 2198 incoming_number: Expected incoming number. 2199 Optional. Default is None 2200 delay_reject: time to wait before rejecting the call 2201 Optional. Default is WAIT_TIME_REJECT_CALL 2202 2203 Returns: 2204 True: if incoming call is received and reject successfully. 2205 False: for errors 2206 """ 2207 return wait_and_reject_call_for_subscription(log, ad, 2208 get_incoming_voice_sub_id(ad), 2209 incoming_number, delay_reject, 2210 reject) 2211 2212 2213def wait_and_reject_call_for_subscription(log, 2214 ad, 2215 sub_id, 2216 incoming_number=None, 2217 delay_reject=WAIT_TIME_REJECT_CALL, 2218 reject=True): 2219 """Wait for an incoming call on specific subscription and 2220 reject the call. 2221 2222 Args: 2223 log: log object. 2224 ad: android device object. 2225 sub_id: subscription ID 2226 incoming_number: Expected incoming number. 2227 Optional. Default is None 2228 delay_reject: time to wait before rejecting the call 2229 Optional. Default is WAIT_TIME_REJECT_CALL 2230 2231 Returns: 2232 True: if incoming call is received and reject successfully. 2233 False: for errors 2234 """ 2235 2236 if not wait_for_ringing_call_for_subscription(log, ad, sub_id, 2237 incoming_number): 2238 ad.log.error( 2239 "Could not reject a call: incoming call in ringing check failed.") 2240 return False 2241 2242 ad.ed.clear_events(EventCallStateChanged) 2243 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 2244 if reject is True: 2245 # Delay between ringing and reject. 2246 time.sleep(delay_reject) 2247 is_find = False 2248 # Loop the call list and find the matched one to disconnect. 2249 for call in ad.droid.telecomCallGetCallIds(): 2250 if check_phone_number_match( 2251 get_number_from_tel_uri(get_call_uri(ad, call)), 2252 incoming_number): 2253 ad.droid.telecomCallDisconnect(call) 2254 ad.log.info("Callee reject the call") 2255 is_find = True 2256 if is_find is False: 2257 ad.log.error("Callee did not find matching call to reject.") 2258 return False 2259 else: 2260 # don't reject on callee. Just ignore the incoming call. 2261 ad.log.info("Callee received incoming call. Ignore it.") 2262 try: 2263 ad.ed.wait_for_event( 2264 EventCallStateChanged, 2265 is_event_match_for_list, 2266 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 2267 field=CallStateContainer.CALL_STATE, 2268 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK]) 2269 except Empty: 2270 ad.log.error("No onCallStateChangedIdle event received.") 2271 return False 2272 finally: 2273 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 2274 return True 2275 2276 2277def wait_and_answer_call(log, 2278 ad, 2279 incoming_number=None, 2280 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 2281 caller=None, 2282 video_state=None): 2283 """Wait for an incoming call on default voice subscription and 2284 accepts the call. 2285 2286 Args: 2287 ad: android device object. 2288 incoming_number: Expected incoming number. 2289 Optional. Default is None 2290 incall_ui_display: after answer the call, bring in-call UI to foreground or 2291 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 2292 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 2293 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 2294 else, do nothing. 2295 2296 Returns: 2297 True: if incoming call is received and answered successfully. 2298 False: for errors 2299 """ 2300 return wait_and_answer_call_for_subscription( 2301 log, 2302 ad, 2303 get_incoming_voice_sub_id(ad), 2304 incoming_number, 2305 incall_ui_display=incall_ui_display, 2306 caller=caller, 2307 video_state=video_state) 2308 2309 2310def wait_for_in_call_active(ad, 2311 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT, 2312 interval=WAIT_TIME_BETWEEN_STATE_CHECK, 2313 call_id=None): 2314 """Wait for call reach active state. 2315 2316 Args: 2317 log: log object. 2318 ad: android device. 2319 call_id: the call id 2320 """ 2321 if not call_id: 2322 call_id = ad.droid.telecomCallGetCallIds()[0] 2323 args = [ad, call_id] 2324 if not wait_for_state(is_phone_in_call_active, True, timeout, interval, 2325 *args): 2326 ad.log.error("Call did not reach ACTIVE state") 2327 return False 2328 else: 2329 return True 2330 2331 2332def wait_for_droid_in_call(log, ad, max_time): 2333 """Wait for android to be in call state. 2334 2335 Args: 2336 log: log object. 2337 ad: android device. 2338 max_time: maximal wait time. 2339 2340 Returns: 2341 If phone become in call state within max_time, return True. 2342 Return False if timeout. 2343 """ 2344 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call) 2345 2346 2347def wait_for_call_id_clearing(ad, 2348 previous_ids, 2349 timeout=MAX_WAIT_TIME_CALL_DROP): 2350 while timeout > 0: 2351 new_call_ids = ad.droid.telecomCallGetCallIds() 2352 if len(new_call_ids) <= len(previous_ids): 2353 return True 2354 time.sleep(5) 2355 timeout = timeout - 5 2356 ad.log.error("Call id clearing failed. Before: %s; After: %s", 2357 previous_ids, new_call_ids) 2358 return False 2359 2360 2361def wait_for_call_end( 2362 log, 2363 ad_caller, 2364 ad_callee, 2365 ad_hangup, 2366 verify_caller_func, 2367 verify_callee_func, 2368 call_begin_time, 2369 check_interval=5, 2370 tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')), 2371 wait_time_in_call=WAIT_TIME_IN_CALL): 2372 elapsed_time = 0 2373 while (elapsed_time < wait_time_in_call): 2374 check_interval = min(check_interval, wait_time_in_call - elapsed_time) 2375 time.sleep(check_interval) 2376 elapsed_time += check_interval 2377 time_message = "at <%s>/<%s> second." % (elapsed_time, wait_time_in_call) 2378 for ad, call_func in [(ad_caller, verify_caller_func), 2379 (ad_callee, verify_callee_func)]: 2380 if not call_func(log, ad): 2381 ad.log.error( 2382 "NOT in correct %s state at %s, voice in RAT %s", 2383 call_func.__name__, 2384 time_message, 2385 ad.droid.telephonyGetCurrentVoiceNetworkType()) 2386 tel_result_wrapper.result_value = CallResult( 2387 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED') 2388 else: 2389 ad.log.info("In correct %s state at %s", 2390 call_func.__name__, time_message) 2391 if not ad.droid.telecomCallGetAudioState(): 2392 ad.log.error("Audio is not in call state at %s", time_message) 2393 tel_result_wrapper.result_value = CallResult( 2394 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED') 2395 2396 if not tel_result_wrapper: 2397 break 2398 2399 if not tel_result_wrapper: 2400 for ad in (ad_caller, ad_callee): 2401 last_call_drop_reason(ad, call_begin_time) 2402 try: 2403 if ad.droid.telecomIsInCall(): 2404 ad.log.info("In call. End now.") 2405 ad.droid.telecomEndCall() 2406 except Exception as e: 2407 log.error(str(e)) 2408 else: 2409 if ad_hangup: 2410 if not hangup_call(log, ad_hangup): 2411 ad_hangup.log.info("Failed to hang up the call") 2412 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL') 2413 2414 if ad_hangup or not tel_result_wrapper: 2415 for ad in (ad_caller, ad_callee): 2416 if not wait_for_call_id_clearing(ad, getattr(ad, "caller_ids", [])): 2417 tel_result_wrapper.result_value = CallResult( 2418 'CALL_ID_CLEANUP_FAIL') 2419 2420 return tel_result_wrapper 2421 2422 2423def check_call(log, dut, dut_client): 2424 result = True 2425 if not call_setup_teardown(log, dut_client, dut, 2426 dut): 2427 if not call_setup_teardown(log, dut_client, 2428 dut, dut): 2429 dut.log.error("MT call failed") 2430 result = False 2431 if not call_setup_teardown(log, dut, dut_client, 2432 dut): 2433 dut.log.error("MO call failed") 2434 result = False 2435 return result 2436 2437 2438def check_call_in_wfc(log, dut, dut_client): 2439 result = True 2440 if not call_setup_teardown(log, dut_client, dut, 2441 dut, None, is_phone_in_call_iwlan): 2442 if not call_setup_teardown(log, dut_client, 2443 dut, dut, None, 2444 is_phone_in_call_iwlan): 2445 dut.log.error("MT WFC call failed") 2446 result = False 2447 if not call_setup_teardown(log, dut, dut_client, 2448 dut, is_phone_in_call_iwlan): 2449 dut.log.error("MO WFC call failed") 2450 result = False 2451 return result 2452 2453 2454def check_call_in_volte(log, dut, dut_client): 2455 result = True 2456 if not call_setup_teardown(log, dut_client, dut, 2457 dut, None, is_phone_in_call_volte): 2458 if not call_setup_teardown(log, dut_client, 2459 dut, dut, None, 2460 is_phone_in_call_volte): 2461 dut.log.error("MT VoLTE call failed") 2462 result = False 2463 if not call_setup_teardown(log, dut, dut_client, 2464 dut, is_phone_in_call_volte): 2465 dut.log.error("MO VoLTE call failed") 2466 result = False 2467 return result 2468 2469 2470def change_ims_setting(log, 2471 ad, 2472 dut_client, 2473 wifi_network_ssid, 2474 wifi_network_pass, 2475 subid, 2476 dut_capabilities, 2477 airplane_mode, 2478 wifi_enabled, 2479 volte_enabled, 2480 wfc_enabled, 2481 nw_gen=RAT_LTE, 2482 wfc_mode=None): 2483 result = True 2484 ad.log.info( 2485 "Setting APM %s, WIFI %s, VoLTE %s, WFC %s, WFC mode %s", 2486 airplane_mode, wifi_enabled, volte_enabled, wfc_enabled, wfc_mode) 2487 2488 toggle_airplane_mode_by_adb(log, ad, airplane_mode) 2489 if wifi_enabled: 2490 if not ensure_wifi_connected(log, ad, 2491 wifi_network_ssid, 2492 wifi_network_pass, 2493 apm=airplane_mode): 2494 ad.log.error("Fail to connected to WiFi") 2495 result = False 2496 else: 2497 if not wifi_toggle_state(log, ad, False): 2498 ad.log.error("Failed to turn off WiFi.") 2499 result = False 2500 toggle_volte(log, ad, volte_enabled) 2501 toggle_wfc(log, ad, wfc_enabled) 2502 if wfc_mode: 2503 set_wfc_mode(log, ad, wfc_mode) 2504 wfc_mode = ad.droid.imsGetWfcMode() 2505 if wifi_enabled or not airplane_mode: 2506 if not ensure_phone_subscription(log, ad): 2507 ad.log.error("Failed to find valid subscription") 2508 result = False 2509 if airplane_mode: 2510 if (CAPABILITY_WFC in dut_capabilities) and (wifi_enabled 2511 and wfc_enabled): 2512 if not wait_for_wfc_enabled(log, ad): 2513 result = False 2514 elif not check_call_in_wfc(log, ad, dut_client): 2515 result = False 2516 else: 2517 if not wait_for_state( 2518 ad.droid.telephonyGetCurrentVoiceNetworkType, 2519 RAT_UNKNOWN): 2520 ad.log.error( 2521 "Voice RAT is %s not UNKNOWN", 2522 ad.droid.telephonyGetCurrentVoiceNetworkType()) 2523 result = False 2524 else: 2525 ad.log.info("Voice RAT is in UNKKNOWN") 2526 else: 2527 if (wifi_enabled and wfc_enabled) and ( 2528 wfc_mode == WFC_MODE_WIFI_PREFERRED) and ( 2529 CAPABILITY_WFC in dut_capabilities): 2530 if not wait_for_wfc_enabled(log, ad): 2531 result = False 2532 if not wait_for_state( 2533 ad.droid.telephonyGetCurrentVoiceNetworkType, 2534 RAT_UNKNOWN): 2535 ad.log.error( 2536 "Voice RAT is %s, not UNKNOWN", 2537 ad.droid.telephonyGetCurrentVoiceNetworkType()) 2538 if not check_call_in_wfc(log, ad, dut_client): 2539 result = False 2540 else: 2541 if not wait_for_wfc_disabled(log, ad): 2542 ad.log.error("WFC is not disabled") 2543 result = False 2544 if volte_enabled and CAPABILITY_VOLTE in dut_capabilities: 2545 if not wait_for_volte_enabled(log, ad): 2546 result = False 2547 if not check_call_in_volte(log, ad, dut_client): 2548 result = False 2549 else: 2550 if not wait_for_not_network_rat( 2551 log, 2552 ad, 2553 nw_gen, 2554 voice_or_data=NETWORK_SERVICE_VOICE): 2555 ad.log.error( 2556 "Voice RAT is %s", 2557 ad.droid.telephonyGetCurrentVoiceNetworkType( 2558 )) 2559 result = False 2560 if not wait_for_voice_attach(log, ad): 2561 result = False 2562 if not check_call(log, ad, dut_client): 2563 result = False 2564 user_config_profile = get_user_config_profile(ad) 2565 ad.log.info("user_config_profile: %s ", 2566 sorted(user_config_profile.items())) 2567 return result 2568 2569 2570def verify_default_ims_setting(log, 2571 ad, 2572 dut_client, 2573 carrier_configs, 2574 default_wfc_enabled, 2575 default_volte, 2576 wfc_mode=None): 2577 result = True 2578 airplane_mode = ad.droid.connectivityCheckAirplaneMode() 2579 default_wfc_mode = carrier_configs.get( 2580 CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, wfc_mode) 2581 if default_wfc_enabled: 2582 wait_for_wfc_enabled(log, ad) 2583 else: 2584 wait_for_wfc_disabled(log, ad) 2585 if airplane_mode: 2586 wait_for_network_rat( 2587 log, 2588 ad, 2589 RAT_UNKNOWN, 2590 voice_or_data=NETWORK_SERVICE_VOICE) 2591 else: 2592 if default_volte: 2593 wait_for_volte_enabled(log, ad) 2594 else: 2595 wait_for_not_network_rat( 2596 log, 2597 ad, 2598 RAT_UNKNOWN, 2599 voice_or_data=NETWORK_SERVICE_VOICE) 2600 2601 if not ensure_phone_subscription(log, ad): 2602 ad.log.error("Failed to find valid subscription") 2603 result = False 2604 user_config_profile = get_user_config_profile(ad) 2605 ad.log.info("user_config_profile = %s ", 2606 sorted(user_config_profile.items())) 2607 if user_config_profile["VoLTE Enabled"] != default_volte: 2608 ad.log.error("VoLTE mode is not %s", default_volte) 2609 result = False 2610 else: 2611 ad.log.info("VoLTE mode is %s as expected", 2612 default_volte) 2613 if user_config_profile["WFC Enabled"] != default_wfc_enabled: 2614 ad.log.error("WFC enabled is not %s", default_wfc_enabled) 2615 if user_config_profile["WFC Enabled"]: 2616 if user_config_profile["WFC Mode"] != default_wfc_mode: 2617 ad.log.error( 2618 "WFC mode is not %s after IMS factory reset", 2619 default_wfc_mode) 2620 result = False 2621 else: 2622 ad.log.info("WFC mode is %s as expected", 2623 default_wfc_mode) 2624 if default_wfc_enabled and \ 2625 default_wfc_mode == WFC_MODE_WIFI_PREFERRED: 2626 if not check_call_in_wfc(log, ad, dut_client): 2627 result = False 2628 elif not airplane_mode: 2629 if default_volte: 2630 if not check_call_in_volte(log, ad, dut_client): 2631 result = False 2632 else: 2633 if not check_call(log, ad, dut_client): 2634 result = False 2635 if result == False: 2636 user_config_profile = get_user_config_profile(ad) 2637 ad.log.info("user_config_profile = %s ", 2638 sorted(user_config_profile.items())) 2639 return result 2640 2641 2642def truncate_phone_number( 2643 log, 2644 caller_number, 2645 callee_number, 2646 dialing_number_length, 2647 skip_inter_area_call=False): 2648 """This function truncates the phone number of the caller/callee to test 2649 7/10/11/12 digit dialing for North American numbering plan, and distinguish 2650 if this is an inter-area call by comparing the area code. 2651 2652 Args: 2653 log: logger object 2654 caller_number: phone number of the caller 2655 callee_number: phone number of the callee 2656 dialing_number_length: the length of phone number (usually 7/10/11/12) 2657 skip_inter_area_call: True to raise a TestSkip exception to skip dialing 2658 the inter-area call. Otherwise False. 2659 2660 Returns: 2661 The truncated phone number of the callee 2662 """ 2663 2664 if not dialing_number_length: 2665 return callee_number 2666 2667 trunc_position = 0 - int(dialing_number_length) 2668 try: 2669 caller_area_code = caller_number[:trunc_position] 2670 callee_area_code = callee_number[:trunc_position] 2671 callee_dial_number = callee_number[trunc_position:] 2672 2673 if caller_area_code != callee_area_code: 2674 skip_inter_area_call = True 2675 2676 except: 2677 skip_inter_area_call = True 2678 2679 if skip_inter_area_call: 2680 msg = "Cannot make call from %s to %s by %s digits since inter-area \ 2681 call is not allowed" % ( 2682 caller_number, callee_number, dialing_number_length) 2683 log.info(msg) 2684 raise signals.TestSkip(msg) 2685 else: 2686 callee_number = callee_dial_number 2687 2688 return callee_number 2689 2690