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 17from acts import signals 18import re 19import time 20 21from acts.utils import get_current_epoch_time 22from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 23from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED 24from acts_contrib.test_utils.tel.tel_defines import NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST 25from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_REG_AND_CALL 26from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 27from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled 28from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle 29from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id 30from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id 31from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid 32from acts_contrib.test_utils.tel.tel_test_utils import _phone_number_remove_prefix 33from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_ring_by_adb 34from acts_contrib.test_utils.tel.tel_test_utils import check_call_state_idle_by_adb 35from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name 36from acts_contrib.test_utils.tel.tel_test_utils import get_user_config_profile 37from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode 38from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_msim 39from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown_for_subscription 40from acts_contrib.test_utils.tel.tel_voice_utils import dial_phone_number 41from acts_contrib.test_utils.tel.tel_voice_utils import disconnect_call_by_id 42from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call 43from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call 44from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call 45from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason 46from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call_for_subscription 47from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_id_clearing 48from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_offhook_for_subscription 49from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active 50from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_ringing_call_for_subscription 51 52 53def call_setup_teardown_for_call_forwarding( 54 log, 55 ad_caller, 56 ad_callee, 57 forwarded_callee, 58 ad_hangup=None, 59 verify_callee_func=None, 60 verify_after_cf_disabled=None, 61 wait_time_in_call=WAIT_TIME_IN_CALL, 62 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 63 dialing_number_length=None, 64 video_state=None, 65 call_forwarding_type="unconditional"): 66 """ Call process for call forwarding, including make a phone call from 67 caller, forward from callee, accept from the forwarded callee and hang up. 68 The call is on default voice subscription 69 70 In call process, call from <ad_caller> to <ad_callee>, forwarded to 71 <forwarded_callee>, accept the call, (optional) and then hang up from 72 <ad_hangup>. 73 74 Args: 75 ad_caller: Caller Android Device Object. 76 ad_callee: Callee Android Device Object which forwards the call. 77 forwarded_callee: Callee Android Device Object which answers the call. 78 ad_hangup: Android Device Object end the phone call. 79 Optional. Default value is None, and phone call will continue. 80 verify_callee_func: func_ptr to verify callee in correct mode 81 Optional. Default is None 82 verify_after_cf_disabled: If True the test of disabling call forwarding 83 will be appended. 84 wait_time_in_call: the call duration of a connected call 85 incall_ui_display: after answer the call, bring in-call UI to foreground 86 or background. 87 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 88 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 89 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 90 else, do nothing. 91 dialing_number_length: the number of digits used for dialing 92 video_state: video call or voice call. Default is voice call. 93 call_forwarding_type: type of call forwarding listed below: 94 - unconditional 95 - busy 96 - not_answered 97 - not_reachable 98 99 Returns: 100 True if call process without any error. 101 False if error happened. 102 103 """ 104 subid_caller = get_outgoing_voice_sub_id(ad_caller) 105 subid_callee = get_incoming_voice_sub_id(ad_callee) 106 subid_forwarded_callee = get_incoming_voice_sub_id(forwarded_callee) 107 return call_setup_teardown_for_call_forwarding_for_subscription( 108 log, 109 ad_caller, 110 ad_callee, 111 forwarded_callee, 112 subid_caller, 113 subid_callee, 114 subid_forwarded_callee, 115 ad_hangup, 116 verify_callee_func, 117 wait_time_in_call, 118 incall_ui_display, 119 dialing_number_length, 120 video_state, 121 call_forwarding_type, 122 verify_after_cf_disabled) 123 124 125def call_setup_teardown_for_call_forwarding_for_subscription( 126 log, 127 ad_caller, 128 ad_callee, 129 forwarded_callee, 130 subid_caller, 131 subid_callee, 132 subid_forwarded_callee, 133 ad_hangup=None, 134 verify_callee_func=None, 135 wait_time_in_call=WAIT_TIME_IN_CALL, 136 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 137 dialing_number_length=None, 138 video_state=None, 139 call_forwarding_type="unconditional", 140 verify_after_cf_disabled=None): 141 """ Call process for call forwarding, including make a phone call from caller, 142 forward from callee, accept from the forwarded callee and hang up. 143 The call is on specified subscription 144 145 In call process, call from <ad_caller> to <ad_callee>, forwarded to 146 <forwarded_callee>, accept the call, (optional) and then hang up from 147 <ad_hangup>. 148 149 Args: 150 ad_caller: Caller Android Device Object. 151 ad_callee: Callee Android Device Object which forwards the call. 152 forwarded_callee: Callee Android Device Object which answers the call. 153 subid_caller: Caller subscription ID 154 subid_callee: Callee subscription ID 155 subid_forwarded_callee: Forwarded callee subscription ID 156 ad_hangup: Android Device Object end the phone call. 157 Optional. Default value is None, and phone call will continue. 158 verify_callee_func: func_ptr to verify callee in correct mode 159 Optional. Default is None 160 wait_time_in_call: the call duration of a connected call 161 incall_ui_display: after answer the call, bring in-call UI to foreground 162 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 163 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 164 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 165 else, do nothing. 166 dialing_number_length: the number of digits used for dialing 167 video_state: video call or voice call. Default is voice call. 168 call_forwarding_type: type of call forwarding listed below: 169 - unconditional 170 - busy 171 - not_answered 172 - not_reachable 173 verify_after_cf_disabled: If True the call forwarding will not be 174 enabled. This argument is used to verify if the call can be received 175 successfully after call forwarding was disabled. 176 177 Returns: 178 True if call process without any error. 179 False if error happened. 180 181 """ 182 CHECK_INTERVAL = 5 183 begin_time = get_current_epoch_time() 184 verify_caller_func = is_phone_in_call 185 if not verify_callee_func: 186 verify_callee_func = is_phone_in_call 187 verify_forwarded_callee_func = is_phone_in_call 188 189 caller_number = ad_caller.telephony['subscription'][subid_caller][ 190 'phone_num'] 191 callee_number = ad_callee.telephony['subscription'][subid_callee][ 192 'phone_num'] 193 forwarded_callee_number = forwarded_callee.telephony['subscription'][ 194 subid_forwarded_callee]['phone_num'] 195 196 if dialing_number_length: 197 skip_test = False 198 trunc_position = 0 - int(dialing_number_length) 199 try: 200 caller_area_code = caller_number[:trunc_position] 201 callee_area_code = callee_number[:trunc_position] 202 callee_dial_number = callee_number[trunc_position:] 203 except: 204 skip_test = True 205 if caller_area_code != callee_area_code: 206 skip_test = True 207 if skip_test: 208 msg = "Cannot make call from %s to %s by %s digits" % ( 209 caller_number, callee_number, dialing_number_length) 210 ad_caller.log.info(msg) 211 raise signals.TestSkip(msg) 212 else: 213 callee_number = callee_dial_number 214 215 result = True 216 msg = "Call from %s to %s (forwarded to %s)" % ( 217 caller_number, callee_number, forwarded_callee_number) 218 if video_state: 219 msg = "Video %s" % msg 220 video = True 221 else: 222 video = False 223 if ad_hangup: 224 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call) 225 ad_caller.log.info(msg) 226 227 for ad in (ad_caller, forwarded_callee): 228 call_ids = ad.droid.telecomCallGetCallIds() 229 setattr(ad, "call_ids", call_ids) 230 if call_ids: 231 ad.log.info("Pre-exist CallId %s before making call", call_ids) 232 233 if not verify_after_cf_disabled: 234 if not set_call_forwarding_by_mmi( 235 log, 236 ad_callee, 237 forwarded_callee, 238 call_forwarding_type=call_forwarding_type): 239 raise signals.TestFailure( 240 "Failed to register or activate call forwarding.", 241 extras={"fail_reason": "Failed to register or activate call" 242 " forwarding."}) 243 244 if call_forwarding_type == "not_reachable": 245 if not toggle_airplane_mode_msim( 246 log, 247 ad_callee, 248 new_state=True, 249 strict_checking=True): 250 return False 251 252 if call_forwarding_type == "busy": 253 ad_callee.log.info("Callee is making a phone call to 0000000000 to make" 254 " itself busy.") 255 ad_callee.droid.telecomCallNumber("0000000000", False) 256 time.sleep(2) 257 258 if check_call_state_idle_by_adb(ad_callee): 259 ad_callee.log.error("Call state of the callee is idle.") 260 if not verify_after_cf_disabled: 261 erase_call_forwarding_by_mmi( 262 log, 263 ad_callee, 264 call_forwarding_type=call_forwarding_type) 265 return False 266 267 try: 268 if not initiate_call( 269 log, 270 ad_caller, 271 callee_number, 272 incall_ui_display=incall_ui_display, 273 video=video): 274 275 ad_caller.log.error("Caller failed to initiate the call.") 276 result = False 277 278 if call_forwarding_type == "not_reachable": 279 if toggle_airplane_mode_msim( 280 log, 281 ad_callee, 282 new_state=False, 283 strict_checking=True): 284 time.sleep(10) 285 elif call_forwarding_type == "busy": 286 hangup_call(log, ad_callee) 287 288 if not verify_after_cf_disabled: 289 erase_call_forwarding_by_mmi( 290 log, 291 ad_callee, 292 call_forwarding_type=call_forwarding_type) 293 return False 294 else: 295 ad_caller.log.info("Caller initated the call successfully.") 296 297 if call_forwarding_type == "not_answered": 298 if not wait_for_ringing_call_for_subscription( 299 log, 300 ad_callee, 301 subid_callee, 302 incoming_number=caller_number, 303 caller=ad_caller, 304 event_tracking_started=True): 305 ad.log.info("Incoming call ringing check failed.") 306 return False 307 308 _timeout = 30 309 while check_call_state_ring_by_adb(ad_callee) == 1 and _timeout >= 0: 310 time.sleep(1) 311 _timeout = _timeout - 1 312 313 if not wait_and_answer_call_for_subscription( 314 log, 315 forwarded_callee, 316 subid_forwarded_callee, 317 incoming_number=caller_number, 318 caller=ad_caller, 319 incall_ui_display=incall_ui_display, 320 video_state=video_state): 321 322 if not verify_after_cf_disabled: 323 forwarded_callee.log.error("Forwarded callee failed to receive" 324 "or answer the call.") 325 result = False 326 else: 327 forwarded_callee.log.info("Forwarded callee did not receive or" 328 " answer the call.") 329 330 if call_forwarding_type == "not_reachable": 331 if toggle_airplane_mode_msim( 332 log, 333 ad_callee, 334 new_state=False, 335 strict_checking=True): 336 time.sleep(10) 337 elif call_forwarding_type == "busy": 338 hangup_call(log, ad_callee) 339 340 if not verify_after_cf_disabled: 341 erase_call_forwarding_by_mmi( 342 log, 343 ad_callee, 344 call_forwarding_type=call_forwarding_type) 345 return False 346 347 else: 348 if not verify_after_cf_disabled: 349 forwarded_callee.log.info("Forwarded callee answered the call" 350 " successfully.") 351 else: 352 forwarded_callee.log.error("Forwarded callee should not be able" 353 " to answer the call.") 354 hangup_call(log, ad_caller) 355 result = False 356 357 for ad, subid, call_func in zip( 358 [ad_caller, forwarded_callee], 359 [subid_caller, subid_forwarded_callee], 360 [verify_caller_func, verify_forwarded_callee_func]): 361 call_ids = ad.droid.telecomCallGetCallIds() 362 new_call_ids = set(call_ids) - set(ad.call_ids) 363 if not new_call_ids: 364 if not verify_after_cf_disabled: 365 ad.log.error( 366 "No new call ids are found after call establishment") 367 ad.log.error("telecomCallGetCallIds returns %s", 368 ad.droid.telecomCallGetCallIds()) 369 result = False 370 for new_call_id in new_call_ids: 371 if not verify_after_cf_disabled: 372 if not wait_for_in_call_active(ad, call_id=new_call_id): 373 result = False 374 else: 375 ad.log.info("callProperties = %s", 376 ad.droid.telecomCallGetProperties(new_call_id)) 377 else: 378 ad.log.error("No new call id should be found.") 379 380 if not ad.droid.telecomCallGetAudioState(): 381 if not verify_after_cf_disabled: 382 ad.log.error("Audio is not in call state") 383 result = False 384 385 if call_func(log, ad): 386 if not verify_after_cf_disabled: 387 ad.log.info("Call is in %s state", call_func.__name__) 388 else: 389 ad.log.error("Call is in %s state", call_func.__name__) 390 else: 391 if not verify_after_cf_disabled: 392 ad.log.error( 393 "Call is not in %s state, voice in RAT %s", 394 call_func.__name__, 395 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 396 result = False 397 398 if not result: 399 if call_forwarding_type == "not_reachable": 400 if toggle_airplane_mode_msim( 401 log, 402 ad_callee, 403 new_state=False, 404 strict_checking=True): 405 time.sleep(10) 406 elif call_forwarding_type == "busy": 407 hangup_call(log, ad_callee) 408 409 if not verify_after_cf_disabled: 410 erase_call_forwarding_by_mmi( 411 log, 412 ad_callee, 413 call_forwarding_type=call_forwarding_type) 414 return False 415 416 elapsed_time = 0 417 while (elapsed_time < wait_time_in_call): 418 CHECK_INTERVAL = min(CHECK_INTERVAL, 419 wait_time_in_call - elapsed_time) 420 time.sleep(CHECK_INTERVAL) 421 elapsed_time += CHECK_INTERVAL 422 time_message = "at <%s>/<%s> second." % (elapsed_time, 423 wait_time_in_call) 424 for ad, subid, call_func in [ 425 (ad_caller, subid_caller, verify_caller_func), 426 (forwarded_callee, subid_forwarded_callee, 427 verify_forwarded_callee_func)]: 428 if not call_func(log, ad): 429 if not verify_after_cf_disabled: 430 ad.log.error( 431 "NOT in correct %s state at %s, voice in RAT %s", 432 call_func.__name__, time_message, 433 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 434 result = False 435 else: 436 if not verify_after_cf_disabled: 437 ad.log.info("In correct %s state at %s", 438 call_func.__name__, time_message) 439 else: 440 ad.log.error("In correct %s state at %s", 441 call_func.__name__, time_message) 442 443 if not ad.droid.telecomCallGetAudioState(): 444 if not verify_after_cf_disabled: 445 ad.log.error("Audio is not in call state at %s", 446 time_message) 447 result = False 448 449 if not result: 450 if call_forwarding_type == "not_reachable": 451 if toggle_airplane_mode_msim( 452 log, 453 ad_callee, 454 new_state=False, 455 strict_checking=True): 456 time.sleep(10) 457 elif call_forwarding_type == "busy": 458 hangup_call(log, ad_callee) 459 460 if not verify_after_cf_disabled: 461 erase_call_forwarding_by_mmi( 462 log, 463 ad_callee, 464 call_forwarding_type=call_forwarding_type) 465 return False 466 467 if ad_hangup: 468 if not hangup_call(log, ad_hangup): 469 ad_hangup.log.info("Failed to hang up the call") 470 result = False 471 if call_forwarding_type == "not_reachable": 472 if toggle_airplane_mode_msim( 473 log, 474 ad_callee, 475 new_state=False, 476 strict_checking=True): 477 time.sleep(10) 478 elif call_forwarding_type == "busy": 479 hangup_call(log, ad_callee) 480 481 if not verify_after_cf_disabled: 482 erase_call_forwarding_by_mmi( 483 log, 484 ad_callee, 485 call_forwarding_type=call_forwarding_type) 486 return False 487 finally: 488 if not result: 489 if verify_after_cf_disabled: 490 result = True 491 else: 492 for ad in (ad_caller, forwarded_callee): 493 last_call_drop_reason(ad, begin_time) 494 try: 495 if ad.droid.telecomIsInCall(): 496 ad.log.info("In call. End now.") 497 ad.droid.telecomEndCall() 498 except Exception as e: 499 log.error(str(e)) 500 501 if ad_hangup or not result: 502 for ad in (ad_caller, forwarded_callee): 503 if not wait_for_call_id_clearing( 504 ad, getattr(ad, "caller_ids", [])): 505 result = False 506 507 if call_forwarding_type == "not_reachable": 508 if toggle_airplane_mode_msim( 509 log, 510 ad_callee, 511 new_state=False, 512 strict_checking=True): 513 time.sleep(10) 514 elif call_forwarding_type == "busy": 515 hangup_call(log, ad_callee) 516 517 if not verify_after_cf_disabled: 518 erase_call_forwarding_by_mmi( 519 log, 520 ad_callee, 521 call_forwarding_type=call_forwarding_type) 522 523 if not result: 524 return result 525 526 ad_caller.log.info( 527 "Make a normal call to callee to ensure the call can be connected after" 528 " call forwarding was disabled") 529 return call_setup_teardown_for_subscription( 530 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_caller, 531 verify_caller_func, verify_callee_func, wait_time_in_call, 532 incall_ui_display, dialing_number_length, video_state) 533 534 535def get_call_forwarding_by_adb(log, ad, call_forwarding_type="unconditional"): 536 """ Get call forwarding status by adb shell command 537 'dumpsys telephony.registry'. 538 539 Args: 540 log: log object 541 ad: android object 542 call_forwarding_type: 543 - "unconditional" 544 - "busy" (todo) 545 - "not_answered" (todo) 546 - "not_reachable" (todo) 547 Returns: 548 - "true": if call forwarding unconditional is enabled. 549 - "false": if call forwarding unconditional is disabled. 550 - "unknown": if the type is other than 'unconditional'. 551 - False: any case other than above 3 cases. 552 """ 553 if call_forwarding_type != "unconditional": 554 return "unknown" 555 556 slot_index_of_default_voice_subid = get_slot_index_from_subid(ad, 557 get_incoming_voice_sub_id(ad)) 558 output = ad.adb.shell("dumpsys telephony.registry | grep mCallForwarding") 559 if "mCallForwarding" in output: 560 result_list = re.findall(r"mCallForwarding=(true|false)", output) 561 if result_list: 562 result = result_list[slot_index_of_default_voice_subid] 563 ad.log.info("mCallForwarding is %s", result) 564 565 if re.search("false", result, re.I): 566 return "false" 567 elif re.search("true", result, re.I): 568 return "true" 569 else: 570 return False 571 else: 572 return False 573 else: 574 ad.log.error("'mCallForwarding' cannot be found in dumpsys.") 575 return False 576 577 578def erase_call_forwarding_by_mmi( 579 log, 580 ad, 581 retry=2, 582 call_forwarding_type="unconditional"): 583 """ Erase setting of call forwarding (erase the number and disable call 584 forwarding) by MMI code. 585 586 Args: 587 log: log object 588 ad: android object 589 retry: times of retry if the erasure failed. 590 call_forwarding_type: 591 - "unconditional" 592 - "busy" 593 - "not_answered" 594 - "not_reachable" 595 Returns: 596 True by successful erasure. Otherwise False. 597 """ 598 operator_name = get_operator_name(log, ad) 599 600 run_get_call_forwarding_by_adb = 1 601 if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST: 602 run_get_call_forwarding_by_adb = 0 603 604 if run_get_call_forwarding_by_adb: 605 res = get_call_forwarding_by_adb(log, ad, 606 call_forwarding_type=call_forwarding_type) 607 if res == "false": 608 return True 609 610 user_config_profile = get_user_config_profile(ad) 611 is_airplane_mode = user_config_profile["Airplane Mode"] 612 is_wfc_enabled = user_config_profile["WFC Enabled"] 613 wfc_mode = user_config_profile["WFC Mode"] 614 is_wifi_on = user_config_profile["WiFi State"] 615 616 if is_airplane_mode: 617 if not toggle_airplane_mode(log, ad, False): 618 ad.log.error("Failed to disable airplane mode.") 619 return False 620 621 code_dict = { 622 "Verizon": { 623 "unconditional": "73", 624 "busy": "73", 625 "not_answered": "73", 626 "not_reachable": "73", 627 "mmi": "*%s" 628 }, 629 "Sprint": { 630 "unconditional": "720", 631 "busy": "740", 632 "not_answered": "730", 633 "not_reachable": "720", 634 "mmi": "*%s" 635 }, 636 "Far EasTone": { 637 "unconditional": "142", 638 "busy": "143", 639 "not_answered": "144", 640 "not_reachable": "144", 641 "mmi": "*%s*2" 642 }, 643 'Generic': { 644 "unconditional": "21", 645 "busy": "67", 646 "not_answered": "61", 647 "not_reachable": "62", 648 "mmi": "##%s#" 649 } 650 } 651 652 if operator_name in code_dict: 653 code = code_dict[operator_name][call_forwarding_type] 654 mmi = code_dict[operator_name]["mmi"] 655 else: 656 code = code_dict['Generic'][call_forwarding_type] 657 mmi = code_dict['Generic']["mmi"] 658 659 result = False 660 while retry >= 0: 661 if run_get_call_forwarding_by_adb: 662 res = get_call_forwarding_by_adb( 663 log, ad, call_forwarding_type=call_forwarding_type) 664 if res == "false": 665 ad.log.info("Call forwarding is already disabled.") 666 result = True 667 break 668 669 ad.log.info("Erasing and deactivating call forwarding %s..." % 670 call_forwarding_type) 671 672 ad.droid.telecomDialNumber(mmi % code) 673 674 time.sleep(3) 675 ad.send_keycode("ENTER") 676 time.sleep(15) 677 678 # To dismiss the pop-out dialog 679 ad.send_keycode("BACK") 680 time.sleep(5) 681 ad.send_keycode("BACK") 682 683 if run_get_call_forwarding_by_adb: 684 res = get_call_forwarding_by_adb( 685 log, ad, call_forwarding_type=call_forwarding_type) 686 if res == "false" or res == "unknown": 687 result = True 688 break 689 else: 690 ad.log.error("Failed to erase and deactivate call forwarding by " 691 "MMI code ##%s#." % code) 692 retry = retry - 1 693 time.sleep(30) 694 else: 695 result = True 696 break 697 698 if is_airplane_mode: 699 if not toggle_airplane_mode(log, ad, True): 700 ad.log.error("Failed to enable airplane mode again.") 701 else: 702 if is_wifi_on: 703 ad.droid.wifiToggleState(True) 704 if is_wfc_enabled: 705 if not wait_for_wfc_enabled( 706 log, ad,max_time=MAX_WAIT_TIME_WFC_ENABLED): 707 ad.log.error("WFC is not enabled") 708 709 return result 710 711def set_call_forwarding_by_mmi( 712 log, 713 ad, 714 ad_forwarded, 715 call_forwarding_type="unconditional", 716 retry=2): 717 """ Set up the forwarded number and enable call forwarding by MMI code. 718 719 Args: 720 log: log object 721 ad: android object of the device forwarding the call (primary device) 722 ad_forwarded: android object of the device receiving forwarded call. 723 retry: times of retry if the erasure failed. 724 call_forwarding_type: 725 - "unconditional" 726 - "busy" 727 - "not_answered" 728 - "not_reachable" 729 Returns: 730 True by successful erasure. Otherwise False. 731 """ 732 733 res = get_call_forwarding_by_adb(log, ad, 734 call_forwarding_type=call_forwarding_type) 735 if res == "true": 736 return True 737 738 if ad.droid.connectivityCheckAirplaneMode(): 739 ad.log.warning("%s is now in airplane mode.", ad.serial) 740 return True 741 742 operator_name = get_operator_name(log, ad) 743 744 code_dict = { 745 "Verizon": { 746 "unconditional": "72", 747 "busy": "71", 748 "not_answered": "71", 749 "not_reachable": "72", 750 "mmi": "*%s%s" 751 }, 752 "Sprint": { 753 "unconditional": "72", 754 "busy": "74", 755 "not_answered": "73", 756 "not_reachable": "72", 757 "mmi": "*%s%s" 758 }, 759 "Far EasTone": { 760 "unconditional": "142", 761 "busy": "143", 762 "not_answered": "144", 763 "not_reachable": "144", 764 "mmi": "*%s*%s" 765 }, 766 'Generic': { 767 "unconditional": "21", 768 "busy": "67", 769 "not_answered": "61", 770 "not_reachable": "62", 771 "mmi": "*%s*%s#", 772 "mmi_for_plus_sign": "*%s*" 773 } 774 } 775 776 if operator_name in code_dict: 777 code = code_dict[operator_name][call_forwarding_type] 778 mmi = code_dict[operator_name]["mmi"] 779 if "mmi_for_plus_sign" in code_dict[operator_name]: 780 mmi_for_plus_sign = code_dict[operator_name]["mmi_for_plus_sign"] 781 else: 782 code = code_dict['Generic'][call_forwarding_type] 783 mmi = code_dict['Generic']["mmi"] 784 mmi_for_plus_sign = code_dict['Generic']["mmi_for_plus_sign"] 785 786 while retry >= 0: 787 if not erase_call_forwarding_by_mmi( 788 log, ad, call_forwarding_type=call_forwarding_type): 789 retry = retry - 1 790 continue 791 792 forwarded_number = ad_forwarded.telephony['subscription'][ 793 ad_forwarded.droid.subscriptionGetDefaultVoiceSubId()][ 794 'phone_num'] 795 ad.log.info("Registering and activating call forwarding %s to %s..." % 796 (call_forwarding_type, forwarded_number)) 797 798 (forwarded_number_no_prefix, _) = _phone_number_remove_prefix( 799 forwarded_number) 800 801 if operator_name == "Far EasTone": 802 forwarded_number_no_prefix = "0" + forwarded_number_no_prefix 803 804 run_get_call_forwarding_by_adb = 1 805 if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST: 806 run_get_call_forwarding_by_adb = 0 807 808 _found_plus_sign = 0 809 if re.search("^\+", forwarded_number): 810 _found_plus_sign = 1 811 forwarded_number.replace("+", "") 812 813 if operator_name in code_dict: 814 ad.droid.telecomDialNumber(mmi % (code, forwarded_number_no_prefix)) 815 else: 816 if _found_plus_sign == 0: 817 ad.droid.telecomDialNumber(mmi % (code, forwarded_number)) 818 else: 819 ad.droid.telecomDialNumber(mmi_for_plus_sign % code) 820 ad.send_keycode("PLUS") 821 822 if "#" in mmi: 823 dial_phone_number(ad, forwarded_number + "#") 824 else: 825 dial_phone_number(ad, forwarded_number) 826 827 time.sleep(3) 828 ad.send_keycode("ENTER") 829 time.sleep(15) 830 831 # To dismiss the pop-out dialog 832 ad.send_keycode("BACK") 833 time.sleep(5) 834 ad.send_keycode("BACK") 835 836 if not run_get_call_forwarding_by_adb: 837 return True 838 839 result = get_call_forwarding_by_adb( 840 log, ad, call_forwarding_type=call_forwarding_type) 841 if result == "false": 842 retry = retry - 1 843 elif result == "true": 844 return True 845 elif result == "unknown": 846 return True 847 else: 848 retry = retry - 1 849 850 if retry >= 0: 851 ad.log.warning("Failed to register or activate call forwarding %s " 852 "to %s. Retry after 15 seconds." % (call_forwarding_type, 853 forwarded_number)) 854 time.sleep(15) 855 856 ad.log.error("Failed to register or activate call forwarding %s to %s." % 857 (call_forwarding_type, forwarded_number)) 858 return False 859 860 861def call_setup_teardown_for_call_waiting(log, 862 ad_caller, 863 ad_callee, 864 ad_caller2, 865 ad_hangup=None, 866 ad_hangup2=None, 867 verify_callee_func=None, 868 end_first_call_before_answering_second_call=True, 869 wait_time_in_call=WAIT_TIME_IN_CALL, 870 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 871 dialing_number_length=None, 872 video_state=None, 873 call_waiting=True): 874 """ Call process for call waiting, including make the 1st phone call from 875 caller, answer the call by the callee, and receive the 2nd call from the 876 caller2. The call is on default voice subscription 877 878 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from 879 <ad_caller2> to <ad_callee>, hang up the existing call or reject the 880 incoming call according to the test scenario. 881 882 Args: 883 ad_caller: Caller Android Device Object. 884 ad_callee: Callee Android Device Object. 885 ad_caller2: Caller2 Android Device Object. 886 ad_hangup: Android Device Object end the 1st phone call. 887 Optional. Default value is None, and phone call will continue. 888 ad_hangup2: Android Device Object end the 2nd phone call. 889 Optional. Default value is None, and phone call will continue. 890 verify_callee_func: func_ptr to verify callee in correct mode 891 Optional. Default is None 892 end_first_call_before_answering_second_call: If True the 2nd call will 893 be rejected on the ringing stage. 894 wait_time_in_call: the call duration of a connected call 895 incall_ui_display: after answer the call, bring in-call UI to foreground 896 or background. 897 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 898 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 899 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 900 else, do nothing. 901 dialing_number_length: the number of digits used for dialing 902 video_state: video call or voice call. Default is voice call. 903 call_waiting: True to enable call waiting and False to disable. 904 905 Returns: 906 True if call process without any error. 907 False if error happened. 908 909 """ 910 subid_caller = get_outgoing_voice_sub_id(ad_caller) 911 subid_callee = get_incoming_voice_sub_id(ad_callee) 912 subid_caller2 = get_incoming_voice_sub_id(ad_caller2) 913 return call_setup_teardown_for_call_waiting_for_subscription( 914 log, 915 ad_caller, 916 ad_callee, 917 ad_caller2, 918 subid_caller, 919 subid_callee, 920 subid_caller2, 921 ad_hangup, ad_hangup2, 922 verify_callee_func, 923 end_first_call_before_answering_second_call, 924 wait_time_in_call, 925 incall_ui_display, 926 dialing_number_length, 927 video_state, 928 call_waiting) 929 930 931def call_setup_teardown_for_call_waiting_for_subscription( 932 log, 933 ad_caller, 934 ad_callee, 935 ad_caller2, 936 subid_caller, 937 subid_callee, 938 subid_caller2, 939 ad_hangup=None, 940 ad_hangup2=None, 941 verify_callee_func=None, 942 end_first_call_before_answering_second_call=True, 943 wait_time_in_call=WAIT_TIME_IN_CALL, 944 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 945 dialing_number_length=None, 946 video_state=None, 947 call_waiting=True): 948 """ Call process for call waiting, including make the 1st phone call from 949 caller, answer the call by the callee, and receive the 2nd call from the 950 caller2. The call is on specified subscription. 951 952 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from 953 <ad_caller2> to <ad_callee>, hang up the existing call or reject the 954 incoming call according to the test scenario. 955 956 Args: 957 ad_caller: Caller Android Device Object. 958 ad_callee: Callee Android Device Object. 959 ad_caller2: Caller2 Android Device Object. 960 subid_caller: Caller subscription ID. 961 subid_callee: Callee subscription ID. 962 subid_caller2: Caller2 subscription ID. 963 ad_hangup: Android Device Object end the 1st phone call. 964 Optional. Default value is None, and phone call will continue. 965 ad_hangup2: Android Device Object end the 2nd phone call. 966 Optional. Default value is None, and phone call will continue. 967 verify_callee_func: func_ptr to verify callee in correct mode 968 Optional. Default is None 969 end_first_call_before_answering_second_call: If True the 2nd call will 970 be rejected on the ringing stage. 971 wait_time_in_call: the call duration of a connected call 972 incall_ui_display: after answer the call, bring in-call UI to foreground 973 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 974 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 975 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 976 else, do nothing. 977 dialing_number_length: the number of digits used for dialing 978 video_state: video call or voice call. Default is voice call. 979 call_waiting: True to enable call waiting and False to disable. 980 981 Returns: 982 True if call process without any error. 983 False if error happened. 984 985 """ 986 987 CHECK_INTERVAL = 5 988 begin_time = get_current_epoch_time() 989 verify_caller_func = is_phone_in_call 990 if not verify_callee_func: 991 verify_callee_func = is_phone_in_call 992 verify_caller2_func = is_phone_in_call 993 994 caller_number = ad_caller.telephony['subscription'][subid_caller][ 995 'phone_num'] 996 callee_number = ad_callee.telephony['subscription'][subid_callee][ 997 'phone_num'] 998 caller2_number = ad_caller2.telephony['subscription'][subid_caller2][ 999 'phone_num'] 1000 if dialing_number_length: 1001 skip_test = False 1002 trunc_position = 0 - int(dialing_number_length) 1003 try: 1004 caller_area_code = caller_number[:trunc_position] 1005 callee_area_code = callee_number[:trunc_position] 1006 callee_dial_number = callee_number[trunc_position:] 1007 except: 1008 skip_test = True 1009 if caller_area_code != callee_area_code: 1010 skip_test = True 1011 if skip_test: 1012 msg = "Cannot make call from %s to %s by %s digits" % ( 1013 caller_number, callee_number, dialing_number_length) 1014 ad_caller.log.info(msg) 1015 raise signals.TestSkip(msg) 1016 else: 1017 callee_number = callee_dial_number 1018 1019 result = True 1020 msg = "Call from %s to %s" % (caller_number, callee_number) 1021 if video_state: 1022 msg = "Video %s" % msg 1023 video = True 1024 else: 1025 video = False 1026 if ad_hangup: 1027 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call) 1028 ad_caller.log.info(msg) 1029 1030 for ad in (ad_caller, ad_callee, ad_caller2): 1031 call_ids = ad.droid.telecomCallGetCallIds() 1032 setattr(ad, "call_ids", call_ids) 1033 if call_ids: 1034 ad.log.info("Pre-exist CallId %s before making call", call_ids) 1035 1036 if not call_waiting: 1037 set_call_waiting(log, ad_callee, enable=0) 1038 else: 1039 set_call_waiting(log, ad_callee, enable=1) 1040 1041 first_call_ids = [] 1042 try: 1043 if not initiate_call( 1044 log, 1045 ad_caller, 1046 callee_number, 1047 incall_ui_display=incall_ui_display, 1048 video=video): 1049 ad_caller.log.error("Initiate call failed.") 1050 if not call_waiting: 1051 set_call_waiting(log, ad_callee, enable=1) 1052 result = False 1053 return False 1054 else: 1055 ad_caller.log.info("Caller initate call successfully") 1056 if not wait_and_answer_call_for_subscription( 1057 log, 1058 ad_callee, 1059 subid_callee, 1060 incoming_number=caller_number, 1061 caller=ad_caller, 1062 incall_ui_display=incall_ui_display, 1063 video_state=video_state): 1064 ad_callee.log.error("Answer call fail.") 1065 if not call_waiting: 1066 set_call_waiting(log, ad_callee, enable=1) 1067 result = False 1068 return False 1069 else: 1070 ad_callee.log.info("Callee answered the call successfully") 1071 1072 for ad, subid, call_func in zip( 1073 [ad_caller, ad_callee], 1074 [subid_caller, subid_callee], 1075 [verify_caller_func, verify_callee_func]): 1076 call_ids = ad.droid.telecomCallGetCallIds() 1077 new_call_ids = set(call_ids) - set(ad.call_ids) 1078 if not new_call_ids: 1079 ad.log.error( 1080 "No new call ids are found after call establishment") 1081 ad.log.error("telecomCallGetCallIds returns %s", 1082 ad.droid.telecomCallGetCallIds()) 1083 result = False 1084 for new_call_id in new_call_ids: 1085 first_call_ids.append(new_call_id) 1086 if not wait_for_in_call_active(ad, call_id=new_call_id): 1087 result = False 1088 else: 1089 ad.log.info("callProperties = %s", 1090 ad.droid.telecomCallGetProperties(new_call_id)) 1091 1092 if not ad.droid.telecomCallGetAudioState(): 1093 ad.log.error("Audio is not in call state") 1094 result = False 1095 1096 if call_func(log, ad): 1097 ad.log.info("Call is in %s state", call_func.__name__) 1098 else: 1099 ad.log.error("Call is not in %s state, voice in RAT %s", 1100 call_func.__name__, 1101 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 1102 result = False 1103 if not result: 1104 if not call_waiting: 1105 set_call_waiting(log, ad_callee, enable=1) 1106 return False 1107 1108 time.sleep(3) 1109 if not call_waiting: 1110 if not initiate_call( 1111 log, 1112 ad_caller2, 1113 callee_number, 1114 incall_ui_display=incall_ui_display, 1115 video=video): 1116 ad_caller2.log.info("Initiate call failed.") 1117 if not call_waiting: 1118 set_call_waiting(log, ad_callee, enable=1) 1119 result = False 1120 return False 1121 else: 1122 ad_caller2.log.info("Caller 2 initate 2nd call successfully") 1123 1124 if not wait_and_answer_call_for_subscription( 1125 log, 1126 ad_callee, 1127 subid_callee, 1128 incoming_number=caller2_number, 1129 caller=ad_caller2, 1130 incall_ui_display=incall_ui_display, 1131 video_state=video_state): 1132 ad_callee.log.info( 1133 "Answering 2nd call fail due to call waiting deactivate.") 1134 else: 1135 ad_callee.log.error("Callee should not be able to answer the" 1136 " 2nd call due to call waiting deactivated.") 1137 if not call_waiting: 1138 set_call_waiting(log, ad_callee, enable=1) 1139 result = False 1140 return False 1141 1142 time.sleep(3) 1143 if not hangup_call(log, ad_caller2): 1144 ad_caller2.log.info("Failed to hang up the 2nd call") 1145 if not call_waiting: 1146 set_call_waiting(log, ad_callee, enable=1) 1147 result = False 1148 return False 1149 1150 else: 1151 1152 for ad in (ad_callee, ad_caller2): 1153 call_ids = ad.droid.telecomCallGetCallIds() 1154 setattr(ad, "call_ids", call_ids) 1155 if call_ids: 1156 ad.log.info("Current existing CallId %s before making the" 1157 " second call.", call_ids) 1158 1159 if not initiate_call( 1160 log, 1161 ad_caller2, 1162 callee_number, 1163 incall_ui_display=incall_ui_display, 1164 video=video): 1165 ad_caller2.log.info("Initiate 2nd call failed.") 1166 if not call_waiting: 1167 set_call_waiting(log, ad_callee, enable=1) 1168 result = False 1169 return False 1170 else: 1171 ad_caller2.log.info("Caller 2 initate 2nd call successfully") 1172 1173 if end_first_call_before_answering_second_call: 1174 try: 1175 if not wait_for_ringing_call_for_subscription( 1176 log, 1177 ad_callee, 1178 subid_callee, 1179 incoming_number=caller2_number, 1180 caller=ad_caller2, 1181 event_tracking_started=True): 1182 ad_callee.log.info( 1183 "2nd incoming call ringing check failed.") 1184 if not call_waiting: 1185 set_call_waiting(log, ad_callee, enable=1) 1186 return False 1187 1188 time.sleep(3) 1189 1190 ad_hangup.log.info("Disconnecting first call...") 1191 for call_id in first_call_ids: 1192 disconnect_call_by_id(log, ad_hangup, call_id) 1193 time.sleep(3) 1194 1195 ad_callee.log.info("Answering the 2nd ring call...") 1196 ad_callee.droid.telecomAcceptRingingCall(video_state) 1197 1198 if wait_for_call_offhook_for_subscription( 1199 log, 1200 ad_callee, 1201 subid_callee, 1202 event_tracking_started=True): 1203 ad_callee.log.info( 1204 "Callee answered the 2nd call successfully.") 1205 else: 1206 ad_callee.log.error("Could not answer the 2nd call.") 1207 if not call_waiting: 1208 set_call_waiting(log, ad_callee, enable=1) 1209 return False 1210 except Exception as e: 1211 log.error(e) 1212 if not call_waiting: 1213 set_call_waiting(log, ad_callee, enable=1) 1214 return False 1215 1216 else: 1217 if not wait_and_answer_call_for_subscription( 1218 log, 1219 ad_callee, 1220 subid_callee, 1221 incoming_number=caller2_number, 1222 caller=ad_caller2, 1223 incall_ui_display=incall_ui_display, 1224 video_state=video_state): 1225 ad_callee.log.error("Failed to answer 2nd call.") 1226 if not call_waiting: 1227 set_call_waiting(log, ad_callee, enable=1) 1228 result = False 1229 return False 1230 else: 1231 ad_callee.log.info( 1232 "Callee answered the 2nd call successfully.") 1233 1234 for ad, subid, call_func in zip( 1235 [ad_callee, ad_caller2], 1236 [subid_callee, subid_caller2], 1237 [verify_callee_func, verify_caller2_func]): 1238 call_ids = ad.droid.telecomCallGetCallIds() 1239 new_call_ids = set(call_ids) - set(ad.call_ids) 1240 if not new_call_ids: 1241 ad.log.error( 1242 "No new call ids are found after 2nd call establishment") 1243 ad.log.error("telecomCallGetCallIds returns %s", 1244 ad.droid.telecomCallGetCallIds()) 1245 result = False 1246 for new_call_id in new_call_ids: 1247 if not wait_for_in_call_active(ad, call_id=new_call_id): 1248 result = False 1249 else: 1250 ad.log.info("callProperties = %s", 1251 ad.droid.telecomCallGetProperties(new_call_id)) 1252 1253 if not ad.droid.telecomCallGetAudioState(): 1254 ad.log.error("Audio is not in 2nd call state") 1255 result = False 1256 1257 if call_func(log, ad): 1258 ad.log.info("2nd call is in %s state", call_func.__name__) 1259 else: 1260 ad.log.error("2nd call is not in %s state, voice in RAT %s", 1261 call_func.__name__, 1262 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 1263 result = False 1264 if not result: 1265 if not call_waiting: 1266 set_call_waiting(log, ad_callee, enable=1) 1267 return False 1268 1269 elapsed_time = 0 1270 while (elapsed_time < wait_time_in_call): 1271 CHECK_INTERVAL = min(CHECK_INTERVAL, 1272 wait_time_in_call - elapsed_time) 1273 time.sleep(CHECK_INTERVAL) 1274 elapsed_time += CHECK_INTERVAL 1275 time_message = "at <%s>/<%s> second." % (elapsed_time, 1276 wait_time_in_call) 1277 1278 if not end_first_call_before_answering_second_call or \ 1279 not call_waiting: 1280 for ad, subid, call_func in [ 1281 (ad_caller, subid_caller, verify_caller_func), 1282 (ad_callee, subid_callee, verify_callee_func)]: 1283 if not call_func(log, ad): 1284 ad.log.error( 1285 "The first call NOT in correct %s state at %s," 1286 " voice in RAT %s", 1287 call_func.__name__, time_message, 1288 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 1289 result = False 1290 else: 1291 ad.log.info("The first call in correct %s state at %s", 1292 call_func.__name__, time_message) 1293 if not ad.droid.telecomCallGetAudioState(): 1294 ad.log.error( 1295 "The first call audio is not in call state at %s", 1296 time_message) 1297 result = False 1298 if not result: 1299 if not call_waiting: 1300 set_call_waiting(log, ad_callee, enable=1) 1301 return False 1302 1303 if call_waiting: 1304 for ad, call_func in [(ad_caller2, verify_caller2_func), 1305 (ad_callee, verify_callee_func)]: 1306 if not call_func(log, ad): 1307 ad.log.error( 1308 "The 2nd call NOT in correct %s state at %s," 1309 " voice in RAT %s", 1310 call_func.__name__, time_message, 1311 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid)) 1312 result = False 1313 else: 1314 ad.log.info("The 2nd call in correct %s state at %s", 1315 call_func.__name__, time_message) 1316 if not ad.droid.telecomCallGetAudioState(): 1317 ad.log.error( 1318 "The 2nd call audio is not in call state at %s", 1319 time_message) 1320 result = False 1321 if not result: 1322 if not call_waiting: 1323 set_call_waiting(log, ad_callee, enable=1) 1324 return False 1325 1326 if not end_first_call_before_answering_second_call or not call_waiting: 1327 ad_hangup.log.info("Hanging up the first call...") 1328 for call_id in first_call_ids: 1329 disconnect_call_by_id(log, ad_hangup, call_id) 1330 time.sleep(5) 1331 1332 if ad_hangup2 and call_waiting: 1333 if not hangup_call(log, ad_hangup2): 1334 ad_hangup2.log.info("Failed to hang up the 2nd call") 1335 if not call_waiting: 1336 set_call_waiting(log, ad_callee, enable=1) 1337 result = False 1338 return False 1339 finally: 1340 if not result: 1341 for ad in (ad_caller, ad_callee, ad_caller2): 1342 last_call_drop_reason(ad, begin_time) 1343 try: 1344 if ad.droid.telecomIsInCall(): 1345 ad.log.info("In call. End now.") 1346 ad.droid.telecomEndCall() 1347 except Exception as e: 1348 log.error(str(e)) 1349 1350 if ad_hangup or not result: 1351 for ad in (ad_caller, ad_callee): 1352 if not wait_for_call_id_clearing( 1353 ad, getattr(ad, "caller_ids", [])): 1354 result = False 1355 1356 if call_waiting: 1357 if ad_hangup2 or not result: 1358 for ad in (ad_caller2, ad_callee): 1359 if not wait_for_call_id_clearing( 1360 ad, getattr(ad, "caller_ids", [])): 1361 result = False 1362 if not call_waiting: 1363 set_call_waiting(log, ad_callee, enable=1) 1364 return result 1365 1366 1367def get_call_waiting_status(log, ad): 1368 """ (Todo) Get call waiting status (activated or deactivated) when there is 1369 any proper method available. 1370 """ 1371 return True 1372 1373 1374def set_call_waiting(log, ad, enable=1, retry=1): 1375 """ Activate/deactivate call waiting by dialing MMI code. 1376 1377 Args: 1378 log: log object. 1379 ad: android object. 1380 enable: 1 for activation and 0 fir deactivation 1381 retry: times of retry if activation/deactivation fails 1382 1383 Returns: 1384 True by successful activation/deactivation; otherwise False. 1385 """ 1386 operator_name = get_operator_name(log, ad) 1387 1388 if operator_name in ["Verizon", "Sprint"]: 1389 return True 1390 1391 while retry >= 0: 1392 if enable: 1393 ad.log.info("Activating call waiting...") 1394 ad.droid.telecomDialNumber("*43#") 1395 else: 1396 ad.log.info("Deactivating call waiting...") 1397 ad.droid.telecomDialNumber("#43#") 1398 1399 time.sleep(3) 1400 ad.send_keycode("ENTER") 1401 time.sleep(15) 1402 1403 ad.send_keycode("BACK") 1404 time.sleep(5) 1405 ad.send_keycode("BACK") 1406 1407 if get_call_waiting_status(log, ad): 1408 return True 1409 else: 1410 retry = retry + 1 1411 1412 return False 1413 1414 1415def three_phone_call_forwarding_short_seq(log, 1416 phone_a, 1417 phone_a_idle_func, 1418 phone_a_in_call_check_func, 1419 phone_b, 1420 phone_c, 1421 wait_time_in_call=WAIT_TIME_IN_CALL, 1422 call_forwarding_type="unconditional", 1423 retry=2): 1424 """Short sequence of call process with call forwarding. 1425 Test steps: 1426 1. Ensure all phones are initially in idle state. 1427 2. Enable call forwarding on Phone A. 1428 3. Make a call from Phone B to Phone A, The call should be forwarded to 1429 PhoneC. Accept the call on Phone C. 1430 4. Ensure the call is connected and in correct phone state. 1431 5. Hang up the call on Phone B. 1432 6. Ensure all phones are in idle state. 1433 7. Disable call forwarding on Phone A. 1434 7. Make a call from Phone B to Phone A, The call should NOT be forwarded 1435 to PhoneC. Accept the call on Phone A. 1436 8. Ensure the call is connected and in correct phone state. 1437 9. Hang up the call on Phone B. 1438 1439 Args: 1440 phone_a: android object of Phone A 1441 phone_a_idle_func: function to check idle state on Phone A 1442 phone_a_in_call_check_func: function to check in-call state on Phone A 1443 phone_b: android object of Phone B 1444 phone_c: android object of Phone C 1445 wait_time_in_call: time to wait in call. 1446 This is optional, default is WAIT_TIME_IN_CALL 1447 call_forwarding_type: 1448 - "unconditional" 1449 - "busy" 1450 - "not_answered" 1451 - "not_reachable" 1452 retry: times of retry 1453 1454 Returns: 1455 True: if call sequence succeed. 1456 False: for errors 1457 """ 1458 ads = [phone_a, phone_b, phone_c] 1459 1460 call_params = [ 1461 (ads[1], ads[0], ads[2], ads[1], phone_a_in_call_check_func, False) 1462 ] 1463 1464 if call_forwarding_type != "unconditional": 1465 call_params.append(( 1466 ads[1], 1467 ads[0], 1468 ads[2], 1469 ads[1], 1470 phone_a_in_call_check_func, 1471 True)) 1472 1473 for param in call_params: 1474 ensure_phones_idle(log, ads) 1475 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1476 phone_a.log.error("Phone A Failed to Reselect") 1477 return False 1478 1479 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1480 1481 log.info( 1482 "---> Call forwarding %s (caller: %s, callee: %s, callee forwarded:" 1483 " %s) <---", 1484 call_forwarding_type, 1485 param[0].serial, 1486 param[1].serial, 1487 param[2].serial) 1488 while not call_setup_teardown_for_call_forwarding( 1489 log, 1490 *param, 1491 wait_time_in_call=wait_time_in_call, 1492 call_forwarding_type=call_forwarding_type) and retry >= 0: 1493 1494 if retry <= 0: 1495 log.error("Call forwarding %s failed." % call_forwarding_type) 1496 return False 1497 else: 1498 log.info( 1499 "RERUN the test case: 'Call forwarding %s'" % 1500 call_forwarding_type) 1501 1502 retry = retry - 1 1503 1504 return True 1505 1506def three_phone_call_waiting_short_seq(log, 1507 phone_a, 1508 phone_a_idle_func, 1509 phone_a_in_call_check_func, 1510 phone_b, 1511 phone_c, 1512 wait_time_in_call=WAIT_TIME_IN_CALL, 1513 call_waiting=True, 1514 scenario=None, 1515 retry=2): 1516 """Short sequence of call process with call waiting. 1517 Test steps: 1518 1. Ensure all phones are initially in idle state. 1519 2. Enable call waiting on Phone A. 1520 3. Make the 1st call from Phone B to Phone A. Accept the call on Phone B. 1521 4. Ensure the call is connected and in correct phone state. 1522 5. Make the 2nd call from Phone C to Phone A. The call should be able to 1523 income correctly. Whether or not the 2nd call should be answered by 1524 Phone A depends on the scenario listed in the next step. 1525 6. Following 8 scenarios will be tested: 1526 - 1st call ended first by Phone B during 2nd call incoming. 2nd call 1527 ended by Phone C 1528 - 1st call ended first by Phone B during 2nd call incoming. 2nd call 1529 ended by Phone A 1530 - 1st call ended first by Phone A during 2nd call incoming. 2nd call 1531 ended by Phone C 1532 - 1st call ended first by Phone A during 2nd call incoming. 2nd call 1533 ended by Phone A 1534 - 1st call ended by Phone B. 2nd call ended by Phone C 1535 - 1st call ended by Phone B. 2nd call ended by Phone A 1536 - 1st call ended by Phone A. 2nd call ended by Phone C 1537 - 1st call ended by Phone A. 2nd call ended by Phone A 1538 7. Ensure all phones are in idle state. 1539 1540 Args: 1541 phone_a: android object of Phone A 1542 phone_a_idle_func: function to check idle state on Phone A 1543 phone_a_in_call_check_func: function to check in-call state on Phone A 1544 phone_b: android object of Phone B 1545 phone_c: android object of Phone C 1546 wait_time_in_call: time to wait in call. 1547 This is optional, default is WAIT_TIME_IN_CALL 1548 call_waiting: True for call waiting enabled and False for disabled 1549 scenario: 1-8 for scenarios listed above 1550 retry: times of retry 1551 1552 Returns: 1553 True: if call sequence succeed. 1554 False: for errors 1555 """ 1556 ads = [phone_a, phone_b, phone_c] 1557 1558 sub_test_cases = [ 1559 { 1560 "description": "1st call ended first by caller1 during 2nd call" 1561 " incoming. 2nd call ended by caller2", 1562 "params": ( 1563 ads[1], 1564 ads[0], 1565 ads[2], 1566 ads[1], 1567 ads[2], 1568 phone_a_in_call_check_func, 1569 True)}, 1570 { 1571 "description": "1st call ended first by caller1 during 2nd call" 1572 " incoming. 2nd call ended by callee", 1573 "params": ( 1574 ads[1], 1575 ads[0], 1576 ads[2], 1577 ads[1], 1578 ads[0], 1579 phone_a_in_call_check_func, 1580 True)}, 1581 { 1582 "description": "1st call ended first by callee during 2nd call" 1583 " incoming. 2nd call ended by caller2", 1584 "params": ( 1585 ads[1], 1586 ads[0], 1587 ads[2], 1588 ads[0], 1589 ads[2], 1590 phone_a_in_call_check_func, 1591 True)}, 1592 { 1593 "description": "1st call ended first by callee during 2nd call" 1594 " incoming. 2nd call ended by callee", 1595 "params": ( 1596 ads[1], 1597 ads[0], 1598 ads[2], 1599 ads[0], 1600 ads[0], 1601 phone_a_in_call_check_func, 1602 True)}, 1603 { 1604 "description": "1st call ended by caller1. 2nd call ended by" 1605 " caller2", 1606 "params": ( 1607 ads[1], 1608 ads[0], 1609 ads[2], 1610 ads[1], 1611 ads[2], 1612 phone_a_in_call_check_func, 1613 False)}, 1614 { 1615 "description": "1st call ended by caller1. 2nd call ended by callee", 1616 "params": ( 1617 ads[1], 1618 ads[0], 1619 ads[2], 1620 ads[1], 1621 ads[0], 1622 phone_a_in_call_check_func, 1623 False)}, 1624 { 1625 "description": "1st call ended by callee. 2nd call ended by caller2", 1626 "params": ( 1627 ads[1], 1628 ads[0], 1629 ads[2], 1630 ads[0], 1631 ads[2], 1632 phone_a_in_call_check_func, 1633 False)}, 1634 { 1635 "description": "1st call ended by callee. 2nd call ended by callee", 1636 "params": ( 1637 ads[1], 1638 ads[0], 1639 ads[2], 1640 ads[0], 1641 ads[0], 1642 phone_a_in_call_check_func, 1643 False)} 1644 ] 1645 1646 if call_waiting: 1647 if not scenario: 1648 test_cases = sub_test_cases 1649 else: 1650 test_cases = [sub_test_cases[scenario-1]] 1651 else: 1652 test_cases = [ 1653 { 1654 "description": "Call waiting deactivated", 1655 "params": ( 1656 ads[1], 1657 ads[0], 1658 ads[2], 1659 ads[0], 1660 ads[0], 1661 phone_a_in_call_check_func, 1662 False)} 1663 ] 1664 1665 results = [] 1666 1667 for test_case in test_cases: 1668 ensure_phones_idle(log, ads) 1669 if phone_a_idle_func and not phone_a_idle_func(log, phone_a): 1670 phone_a.log.error("Phone A Failed to Reselect") 1671 return False 1672 1673 time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) 1674 1675 log.info( 1676 "---> %s (caller1: %s, caller2: %s, callee: %s) <---", 1677 test_case["description"], 1678 test_case["params"][1].serial, 1679 test_case["params"][2].serial, 1680 test_case["params"][0].serial) 1681 1682 while not call_setup_teardown_for_call_waiting( 1683 log, 1684 *test_case["params"], 1685 wait_time_in_call=wait_time_in_call, 1686 call_waiting=call_waiting) and retry >= 0: 1687 1688 if retry <= 0: 1689 log.error("Call waiting sub-case: '%s' failed." % test_case[ 1690 "description"]) 1691 results.append(False) 1692 else: 1693 log.info("RERUN the sub-case: '%s'" % test_case["description"]) 1694 1695 retry = retry - 1 1696 1697 for result in results: 1698 if not result: 1699 return False 1700 1701 return True