1#!/usr/bin/env python3.4 2# 3# Copyright 2016 - 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 future import standard_library 18standard_library.install_aliases() 19 20import concurrent.futures 21import urllib.parse 22import time 23 24from queue import Empty 25from acts.controllers.android_device import AndroidDevice 26from acts.controllers.event_dispatcher import EventDispatcher 27from acts.test_utils.tel.tel_defines import AOSP_PREFIX 28from acts.test_utils.tel.tel_defines import CARRIER_UNKNOWN 29from acts.test_utils.tel.tel_defines import DATA_STATE_CONNECTED 30from acts.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED 31from acts.test_utils.tel.tel_defines import GEN_4G 32from acts.test_utils.tel.tel_defines import GEN_UNKNOWN 33from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND 34from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 35from acts.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX 36from acts.test_utils.tel.tel_defines import INVALID_SUB_ID 37from acts.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL 38from acts.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME 39from acts.test_utils.tel.tel_defines import \ 40 MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT 41from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT 42from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION 43from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING 44from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 45from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE 46from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT 47from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION 48from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE 49from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS 50from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING 51from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT 52from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED 53from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED 54from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY 55from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL 56from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI 57from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 58from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 59from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT 60from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT 61from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT 62from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT 63from acts.test_utils.tel.tel_defines import RAT_FAMILY_GSM 64from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE 65from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN 66from acts.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA 67from acts.test_utils.tel.tel_defines import RAT_1XRTT 68from acts.test_utils.tel.tel_defines import RAT_UNKNOWN 69from acts.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY 70from acts.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE 71from acts.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE 72from acts.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF 73from acts.test_utils.tel.tel_defines import SIM_STATE_READY 74from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE 75from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK 76from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING 77from acts.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT 78from acts.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH 79from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 80from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID 81from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 82from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL 83from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL 84from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE 85from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED 86from acts.test_utils.tel.tel_defines import EventCallStateChanged 87from acts.test_utils.tel.tel_defines import EventConnectivityChanged 88from acts.test_utils.tel.tel_defines import EventDataConnectionStateChanged 89from acts.test_utils.tel.tel_defines import EventDataSmsReceived 90from acts.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged 91from acts.test_utils.tel.tel_defines import EventServiceStateChanged 92from acts.test_utils.tel.tel_defines import EventMmsSentSuccess 93from acts.test_utils.tel.tel_defines import EventSmsReceived 94from acts.test_utils.tel.tel_defines import EventSmsSentSuccess 95from acts.test_utils.tel.tel_defines import CallStateContainer 96from acts.test_utils.tel.tel_defines import DataConnectionStateContainer 97from acts.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer 98from acts.test_utils.tel.tel_defines import NetworkCallbackContainer 99from acts.test_utils.tel.tel_defines import ServiceStateContainer 100from acts.test_utils.tel.tel_lookup_tables import \ 101 connection_type_from_type_string 102from acts.test_utils.tel.tel_lookup_tables import is_valid_rat 103from acts.test_utils.tel.tel_lookup_tables import get_allowable_network_preference 104from acts.test_utils.tel.tel_lookup_tables import \ 105 get_voice_mail_count_check_function 106from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_number_function 107from acts.test_utils.tel.tel_lookup_tables import \ 108 network_preference_for_generaton 109from acts.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id 110from acts.test_utils.tel.tel_lookup_tables import \ 111 rat_families_for_network_preference 112from acts.test_utils.tel.tel_lookup_tables import rat_family_for_generation 113from acts.test_utils.tel.tel_lookup_tables import rat_family_from_rat 114from acts.test_utils.tel.tel_lookup_tables import rat_generation_from_rat 115from acts.test_utils.tel.tel_subscription_utils import \ 116 get_default_data_sub_id 117from acts.test_utils.tel.tel_subscription_utils import \ 118 get_outgoing_message_sub_id 119from acts.test_utils.tel.tel_subscription_utils import \ 120 get_outgoing_voice_sub_id 121from acts.test_utils.tel.tel_subscription_utils import \ 122 get_incoming_voice_sub_id 123from acts.test_utils.tel.tel_subscription_utils import \ 124 get_incoming_message_sub_id 125from acts.utils import load_config 126from acts.logger import LoggerProxy 127log = LoggerProxy() 128 129 130class TelTestUtilsError(Exception): 131 pass 132 133 134def setup_droid_properties(log, ad, sim_filename): 135 136 # Check to see if droid already has this property 137 if hasattr(ad, 'cfg'): 138 return 139 140 device_props = {} 141 device_props['subscription'] = {} 142 143 try: 144 sim_data = load_config(sim_filename) 145 except Exception: 146 log.warning("Failed to load {}!".format(sim_filename)) 147 sim_data = None 148 sub_info_list = ad.droid.subscriptionGetAllSubInfoList() 149 found_sims = 0 150 for sub_info in sub_info_list: 151 sub_id = sub_info['subscriptionId'] 152 if sub_info['simSlotIndex'] is not INVALID_SIM_SLOT_INDEX: 153 found_sims += 1 154 sim_record = {} 155 try: 156 sim_serial = ad.droid.telephonyGetSimSerialNumberForSubscription( 157 sub_id) 158 if not sim_serial: 159 log.error("Unable to find ICC-ID for SIM on {}!".format( 160 ad.serial)) 161 if sim_data is not None: 162 number = sim_data[sim_serial]["phone_num"] 163 else: 164 raise KeyError("No file to load phone number info!") 165 except KeyError: 166 number = ad.droid.telephonyGetLine1NumberForSubscription( 167 sub_id) 168 if not number or number == "": 169 raise TelTestUtilsError( 170 "Failed to find valid phone number for {}" 171 .format(ad.serial)) 172 173 sim_record['phone_num'] = number 174 sim_record['operator'] = get_operator_name(log, ad, sub_id) 175 device_props['subscription'][sub_id] = sim_record 176 log.info( 177 "phone_info: <{}:{}>, <subId:{}> {} <{}>, ICC-ID:<{}>".format( 178 ad.model, ad.serial, sub_id, number, get_operator_name( 179 log, ad, sub_id), 180 ad.droid.telephonyGetSimSerialNumberForSubscription( 181 sub_id))) 182 183 if found_sims == 0: 184 log.warning("No Valid SIMs found in device {}".format(ad.serial)) 185 186 setattr(ad, 'cfg', device_props) 187 188 189def refresh_droid_config(log, ad): 190 """ Update Android Device cfg records for each sub_id. 191 1. Update Phone Number using Line1Number (if Line1Number is valid). 192 2. Update Operator name. 193 194 Args: 195 log: log object 196 ad: android device object 197 198 Returns: 199 None 200 """ 201 for sub_id in ad.cfg['subscription']: 202 # Update Phone number 203 number = ad.droid.telephonyGetLine1NumberForSubscription(sub_id) 204 if number: 205 number = phone_number_formatter(number) 206 ad.cfg['subscription'][sub_id]['phone_num'] = number 207 # Update Operator Name 208 ad.cfg['subscription'][sub_id]['operator'] = get_operator_name(log, ad, 209 sub_id) 210 211 212def get_slot_index_from_subid(log, ad, sub_id): 213 try: 214 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id) 215 return info['simSlotIndex'] 216 except KeyError: 217 return INVALID_SIM_SLOT_INDEX 218 219 220def get_num_active_sims(log, ad): 221 """ Get the number of active SIM cards by counting slots 222 223 Args: 224 ad: android_device object. 225 226 Returns: 227 result: The number of loaded (physical) SIM cards 228 """ 229 # using a dictionary as a cheap way to prevent double counting 230 # in the situation where multiple subscriptions are on the same SIM. 231 # yes, this is a corner corner case. 232 valid_sims = {} 233 subInfo = ad.droid.subscriptionGetAllSubInfoList() 234 for info in subInfo: 235 ssidx = info['simSlotIndex'] 236 if ssidx == INVALID_SIM_SLOT_INDEX: 237 continue 238 valid_sims[ssidx] = True 239 return len(valid_sims.keys()) 240 241 242def toggle_airplane_mode(log, ad, new_state=None): 243 """ Toggle the state of airplane mode. 244 245 Args: 246 ad: android_device object. 247 new_state: Airplane mode state to set to. 248 If None, opposite of the current state. 249 250 Returns: 251 result: True if operation succeed. False if error happens. 252 """ 253 return toggle_airplane_mode_msim(log, ad, new_state) 254 255 256def is_expected_event(event_to_check, events_list): 257 """ check whether event is present in the event list 258 259 Args: 260 event_to_check: event to be checked. 261 events_list: list of events 262 Returns: 263 result: True if event present in the list. False if not. 264 """ 265 for event in events_list: 266 if event in event_to_check['name']: 267 return True 268 return False 269 270 271def is_sim_ready(log, ad, sim_slot_id=None): 272 """ check whether SIM is ready. 273 274 Args: 275 ad: android_device object. 276 sim_slot_id: check the SIM status for sim_slot_id 277 This is optional. If this is None, check default SIM. 278 279 Returns: 280 result: True if all SIMs are ready. False if not. 281 """ 282 if sim_slot_id is None: 283 status = ad.droid.telephonyGetSimState() 284 else: 285 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id) 286 if status != SIM_STATE_READY: 287 log.info("Sim not ready") 288 return False 289 return True 290 291 292def _is_expecting_event(event_recv_list): 293 """ check for more event is expected in event list 294 295 Args: 296 event_recv_list: list of events 297 Returns: 298 result: True if more events are expected. False if not. 299 """ 300 for state in event_recv_list: 301 if state is False: 302 return True 303 return False 304 305 306def _set_event_list(event_recv_list, sub_id_list, sub_id, value): 307 """ set received event in expected event list 308 309 Args: 310 event_recv_list: list of received events 311 sub_id_list: subscription ID list 312 sub_id: subscription id of current event 313 value: True or False 314 Returns: 315 None. 316 """ 317 for i in range(len(sub_id_list)): 318 if sub_id_list[i] == sub_id: 319 event_recv_list[i] = value 320 321 322def toggle_airplane_mode_msim(log, ad, new_state=None): 323 """ Toggle the state of airplane mode. 324 325 Args: 326 ad: android_device object. 327 new_state: Airplane mode state to set to. 328 If None, opposite of the current state. 329 330 Returns: 331 result: True if operation succeed. False if error happens. 332 """ 333 serial_number = ad.serial 334 335 ad.ed.clear_all_events() 336 sub_id_list = [] 337 338 active_sub_info = ad.droid.subscriptionGetAllSubInfoList() 339 for info in active_sub_info: 340 sub_id_list.append(info['subscriptionId']) 341 342 cur_state = ad.droid.connectivityCheckAirplaneMode() 343 if cur_state == new_state: 344 log.info("Airplane mode already <{}> on {}".format(new_state, 345 serial_number)) 346 return True 347 elif new_state is None: 348 log.info("Current State {} New state {}".format(cur_state, new_state)) 349 350 if new_state is None: 351 new_state = not cur_state 352 353 service_state_list = [] 354 if new_state: 355 service_state_list.append(SERVICE_STATE_POWER_OFF) 356 log.info("Turn on airplane mode: " + serial_number) 357 358 else: 359 # If either one of these 3 events show up, it should be OK. 360 # Normal SIM, phone in service 361 service_state_list.append(SERVICE_STATE_IN_SERVICE) 362 # NO SIM, or Dead SIM, or no Roaming coverage. 363 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE) 364 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY) 365 log.info("Turn off airplane mode: " + serial_number) 366 367 for sub_id in sub_id_list: 368 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription( 369 sub_id) 370 ad.droid.connectivityToggleAirplaneMode(new_state) 371 372 event = None 373 374 try: 375 try: 376 event = ad.ed.wait_for_event( 377 EventServiceStateChanged, 378 is_event_match_for_list, 379 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT, 380 field=ServiceStateContainer.SERVICE_STATE, 381 value_list=service_state_list) 382 except Empty: 383 pass 384 if event is None: 385 log.error("Did not get expected service state {}".format( 386 service_state_list)) 387 log.info("Received event: {}".format(event)) 388 finally: 389 for sub_id in sub_id_list: 390 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription( 391 sub_id) 392 393 if new_state: 394 if (not ad.droid.connectivityCheckAirplaneMode() or 395 ad.droid.wifiCheckState() or ad.droid.bluetoothCheckState()): 396 log.error("Airplane mode ON fail on {}".format(ad.serial)) 397 return False 398 else: 399 if ad.droid.connectivityCheckAirplaneMode(): 400 log.error("Airplane mode OFF fail on {}".format(ad.serial)) 401 return False 402 return True 403 404 405def wait_and_answer_call(log, 406 ad, 407 incoming_number=None, 408 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 409 """Wait for an incoming call on default voice subscription and 410 accepts the call. 411 412 Args: 413 ad: android device object. 414 incoming_number: Expected incoming number. 415 Optional. Default is None 416 incall_ui_display: after answer the call, bring in-call UI to foreground or 417 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 418 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 419 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 420 else, do nothing. 421 422 Returns: 423 True: if incoming call is received and answered successfully. 424 False: for errors 425 """ 426 return wait_and_answer_call_for_subscription( 427 log, ad, get_incoming_voice_sub_id(ad), incoming_number, 428 incall_ui_display) 429 430 431def wait_for_ringing_event(log, ad, wait_time): 432 log.warning("***DEPRECATED*** wait_for_ringing_event()") 433 return _wait_for_ringing_event(log, ad, wait_time) 434 435 436def _wait_for_ringing_event(log, ad, wait_time): 437 """Wait for ringing event. 438 439 Args: 440 log: log object. 441 ad: android device object. 442 wait_time: max time to wait for ringing event. 443 444 Returns: 445 event_ringing if received ringing event. 446 otherwise return None. 447 """ 448 log.info("Wait for ringing.") 449 start_time = time.time() 450 remaining_time = wait_time 451 event_iter_timeout = 4 452 event_ringing = None 453 454 while remaining_time > 0: 455 try: 456 event_ringing = ad.ed.wait_for_event( 457 EventCallStateChanged, 458 is_event_match, 459 timeout=event_iter_timeout, 460 field=CallStateContainer.CALL_STATE, 461 value=TELEPHONY_STATE_RINGING) 462 except Empty: 463 if ad.droid.telecomIsRinging(): 464 log.error("No Ringing event. But Callee in Ringing state.") 465 log.error("Test framework dropped event.") 466 return None 467 remaining_time = start_time + wait_time - time.time() 468 if event_ringing is not None: 469 break 470 if event_ringing is None: 471 log.error("No Ringing Event, Callee not in ringing state.") 472 log.error("No incoming call.") 473 return None 474 475 return event_ringing 476 477 478def wait_for_ringing_call(log, ad, incoming_number=None): 479 """Wait for an incoming call on default voice subscription and 480 accepts the call. 481 482 Args: 483 log: log object. 484 ad: android device object. 485 incoming_number: Expected incoming number. 486 Optional. Default is None 487 488 Returns: 489 True: if incoming call is received and answered successfully. 490 False: for errors 491 """ 492 return wait_for_ringing_call_for_subscription( 493 log, ad, get_incoming_voice_sub_id(ad), incoming_number) 494 495 496def wait_for_ringing_call_for_subscription(log, 497 ad, 498 sub_id, 499 incoming_number=None): 500 """Wait for an incoming call on specified subscription. 501 502 Args: 503 log: log object. 504 ad: android device object. 505 sub_id: subscription ID 506 incoming_number: Expected incoming number. 507 Optional. Default is None 508 509 Returns: 510 True: if incoming call is received and answered successfully. 511 False: for errors 512 """ 513 if (not ad.droid.telecomIsRinging() and 514 ad.droid.telephonyGetCallStateForSubscription(sub_id) != 515 TELEPHONY_STATE_RINGING): 516 ad.ed.clear_all_events() 517 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 518 event_ringing = _wait_for_ringing_event(log, ad, 519 MAX_WAIT_TIME_CALLEE_RINGING) 520 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 521 if event_ringing is None: 522 log.error("No Ringing Event.") 523 return False 524 525 if not incoming_number: 526 result = True 527 else: 528 result = check_phone_number_match( 529 event_ringing['data'][CallStateContainer.INCOMING_NUMBER], 530 incoming_number) 531 532 if not result: 533 log.error("Incoming Number not match") 534 log.error("Expected number:{}, actual number:{}".format( 535 incoming_number, event_ringing['data'][ 536 CallStateContainer.INCOMING_NUMBER])) 537 return False 538 return True 539 540 541def wait_and_answer_call_for_subscription( 542 log, 543 ad, 544 sub_id, 545 incoming_number=None, 546 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 547 """Wait for an incoming call on specified subscription and 548 accepts the call. 549 550 Args: 551 log: log object. 552 ad: android device object. 553 sub_id: subscription ID 554 incoming_number: Expected incoming number. 555 Optional. Default is None 556 incall_ui_display: after answer the call, bring in-call UI to foreground or 557 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 558 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 559 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 560 else, do nothing. 561 562 Returns: 563 True: if incoming call is received and answered successfully. 564 False: for errors 565 """ 566 567 if not wait_for_ringing_call_for_subscription(log, ad, sub_id, 568 incoming_number): 569 log.error("Could not answer a call: phone never rang.") 570 return False 571 572 ad.ed.clear_all_events() 573 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 574 if not wait_for_telecom_ringing(log, ad, MAX_WAIT_TIME_TELECOM_RINGING): 575 log.error("Telecom is not ringing.") 576 return False 577 log.info("Accept on callee.") 578 ad.droid.telecomAcceptRingingCall() 579 try: 580 ad.ed.wait_for_event( 581 EventCallStateChanged, 582 is_event_match, 583 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT, 584 field=CallStateContainer.CALL_STATE, 585 value=TELEPHONY_STATE_OFFHOOK) 586 except Empty: 587 if not ad.droid.telecomIsInCall(): 588 log.error("Accept call failed.") 589 return False 590 finally: 591 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 592 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 593 ad.droid.telecomShowInCallScreen() 594 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 595 ad.droid.showHomeScreen() 596 return True 597 598 599def wait_and_reject_call(log, 600 ad, 601 incoming_number=None, 602 delay_reject=WAIT_TIME_REJECT_CALL, 603 reject=True): 604 """Wait for an incoming call on default voice subscription and 605 reject the call. 606 607 Args: 608 log: log object. 609 ad: android device object. 610 incoming_number: Expected incoming number. 611 Optional. Default is None 612 delay_reject: time to wait before rejecting the call 613 Optional. Default is WAIT_TIME_REJECT_CALL 614 615 Returns: 616 True: if incoming call is received and reject successfully. 617 False: for errors 618 """ 619 return wait_and_reject_call_for_subscription( 620 log, ad, get_incoming_voice_sub_id(ad), incoming_number, delay_reject, 621 reject) 622 623 624def wait_and_reject_call_for_subscription(log, 625 ad, 626 sub_id, 627 incoming_number=None, 628 delay_reject=WAIT_TIME_REJECT_CALL, 629 reject=True): 630 """Wait for an incoming call on specific subscription and 631 reject the call. 632 633 Args: 634 log: log object. 635 ad: android device object. 636 sub_id: subscription ID 637 incoming_number: Expected incoming number. 638 Optional. Default is None 639 delay_reject: time to wait before rejecting the call 640 Optional. Default is WAIT_TIME_REJECT_CALL 641 642 Returns: 643 True: if incoming call is received and reject successfully. 644 False: for errors 645 """ 646 647 if not wait_for_ringing_call_for_subscription(log, ad, sub_id, 648 incoming_number): 649 log.error("Could not reject a call: phone never rang.") 650 return False 651 652 ad.ed.clear_all_events() 653 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 654 if reject is True: 655 # Delay between ringing and reject. 656 time.sleep(delay_reject) 657 log.info("Reject on callee.") 658 is_find = False 659 # Loop the call list and find the matched one to disconnect. 660 for call in ad.droid.telecomCallGetCallIds(): 661 if check_phone_number_match( 662 get_number_from_tel_uri(get_call_uri(ad, call)), 663 incoming_number): 664 ad.droid.telecomCallDisconnect(call) 665 is_find = True 666 if is_find is False: 667 log.error("Did not find matching call to reject.") 668 return False 669 else: 670 # don't reject on callee. Just ignore the incoming call. 671 log.info("Received incoming call. Ignore it.") 672 try: 673 ad.ed.wait_for_event( 674 EventCallStateChanged, 675 is_event_match_for_list, 676 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 677 field=CallStateContainer.CALL_STATE, 678 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK]) 679 except Empty: 680 log.error("No onCallStateChangedIdle event received.") 681 return False 682 finally: 683 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 684 return True 685 686 687def hangup_call(log, ad): 688 """Hang up ongoing active call. 689 690 Args: 691 log: log object. 692 ad: android device object. 693 694 Returns: 695 True: if incoming call is received and reject successfully. 696 False: for errors 697 """ 698 ad.ed.clear_all_events() 699 ad.droid.telephonyStartTrackingCallState() 700 log.info("Hangup call.") 701 ad.droid.telecomEndCall() 702 703 try: 704 ad.ed.wait_for_event(EventCallStateChanged, 705 is_event_match, 706 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 707 field=CallStateContainer.CALL_STATE, 708 value=TELEPHONY_STATE_IDLE) 709 except Empty: 710 if ad.droid.telecomIsInCall(): 711 log.error("Hangup call failed.") 712 return False 713 finally: 714 ad.droid.telephonyStopTrackingCallStateChange() 715 return True 716 717 718def disconnect_call_by_id(log, ad, call_id): 719 """Disconnect call by call id. 720 """ 721 ad.droid.telecomCallDisconnect(call_id) 722 return True 723 724 725def _phone_number_remove_prefix(number): 726 """Remove the country code and other prefix from the input phone number. 727 Currently only handle phone number with the following formats: 728 (US phone number format) 729 +1abcxxxyyyy 730 1abcxxxyyyy 731 abcxxxyyyy 732 abc xxx yyyy 733 abc.xxx.yyyy 734 abc-xxx-yyyy 735 (EEUK phone number format) 736 +44abcxxxyyyy 737 0abcxxxyyyy 738 739 Args: 740 number: input phone number 741 742 Returns: 743 Phone number without country code or prefix 744 """ 745 if number is None: 746 return None, None 747 country_code_list = ["+1", "+44"] 748 for country_code in country_code_list: 749 if number.startswith(country_code): 750 return number[len(country_code):], country_code 751 if number[0] == "1" or number[0] == "0": 752 return number[1:], None 753 return number, None 754 755 756def check_phone_number_match(number1, number2): 757 """Check whether two input phone numbers match or not. 758 759 Compare the two input phone numbers. 760 If they match, return True; otherwise, return False. 761 Currently only handle phone number with the following formats: 762 (US phone number format) 763 +1abcxxxyyyy 764 1abcxxxyyyy 765 abcxxxyyyy 766 abc xxx yyyy 767 abc.xxx.yyyy 768 abc-xxx-yyyy 769 (EEUK phone number format) 770 +44abcxxxyyyy 771 0abcxxxyyyy 772 773 There are some scenarios we can not verify, one example is: 774 number1 = +15555555555, number2 = 5555555555 775 (number2 have no country code) 776 777 Args: 778 number1: 1st phone number to be compared. 779 number2: 2nd phone number to be compared. 780 781 Returns: 782 True if two phone numbers match. Otherwise False. 783 """ 784 # Remove country code and prefix 785 number1, country_code1 = _phone_number_remove_prefix(number1) 786 number2, country_code2 = _phone_number_remove_prefix(number2) 787 if ((country_code1 is not None) and (country_code2 is not None) and 788 (country_code1 != country_code2)): 789 return False 790 # Remove white spaces, dashes, dots 791 number1 = phone_number_formatter(number1) 792 number2 = phone_number_formatter(number2) 793 return number1 == number2 794 795 796def initiate_call(log, ad_caller, callee_number, emergency=False): 797 """Make phone call from caller to callee. 798 799 Args: 800 ad_caller: Caller android device object. 801 callee_number: Callee phone number. 802 emergency : specify the call is emergency. 803 Optional. Default value is False. 804 805 Returns: 806 result: if phone call is placed successfully. 807 """ 808 ad_caller.ed.clear_all_events() 809 sub_id = get_outgoing_voice_sub_id(ad_caller) 810 ad_caller.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 811 812 wait_time_for_incall_state = MAX_WAIT_TIME_CALL_INITIATION 813 814 try: 815 # Make a Call 816 if emergency: 817 ad_caller.droid.telecomCallEmergencyNumber(callee_number) 818 else: 819 ad_caller.droid.telecomCallNumber(callee_number) 820 821 # Verify OFFHOOK event 822 if ad_caller.droid.telephonyGetCallState() != TELEPHONY_STATE_OFFHOOK: 823 event_offhook = ad_caller.ed.wait_for_event( 824 EventCallStateChanged, 825 is_event_match, 826 timeout=wait_time_for_incall_state, 827 field=CallStateContainer.CALL_STATE, 828 value=TELEPHONY_STATE_OFFHOOK) 829 except Empty: 830 log.error("initiate_call did not receive Telephony OFFHOOK event.") 831 return False 832 finally: 833 ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription( 834 sub_id) 835 836 # Verify call state 837 while wait_time_for_incall_state > 0: 838 wait_time_for_incall_state -= 1 839 if (ad_caller.droid.telecomIsInCall() and 840 (ad_caller.droid.telephonyGetCallState() == 841 TELEPHONY_STATE_OFFHOOK) and 842 (ad_caller.droid.telecomGetCallState() == 843 TELEPHONY_STATE_OFFHOOK)): 844 return True 845 time.sleep(1) 846 log.error("Make call fail. telecomIsInCall:{}, Telecom State:{}," 847 " Telephony State:{}".format(ad_caller.droid.telecomIsInCall( 848 ), ad_caller.droid.telephonyGetCallState( 849 ), ad_caller.droid.telecomGetCallState())) 850 return False 851 852 853def call_reject(log, ad_caller, ad_callee, reject=True): 854 """Caller call Callee, then reject on callee. 855 856 857 """ 858 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId() 859 subid_callee = ad_callee.incoming_voice_sub_id 860 log.info("Sub-ID Caller {}, Sub-ID Callee {}".format(subid_caller, 861 subid_callee)) 862 return call_reject_for_subscription(log, ad_caller, ad_callee, 863 subid_caller, subid_callee, reject) 864 865 866def call_reject_for_subscription(log, 867 ad_caller, 868 ad_callee, 869 subid_caller, 870 subid_callee, 871 reject=True): 872 """ 873 """ 874 875 class _CallSequenceException(Exception): 876 pass 877 878 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 879 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 880 881 log.info("Call from {} to {}".format(caller_number, callee_number)) 882 try: 883 if not initiate_call(log, ad_caller, callee_number): 884 raise _CallSequenceException("Initiate call failed.") 885 886 if not wait_and_reject_call_for_subscription( 887 log, ad_callee, subid_callee, caller_number, 888 WAIT_TIME_REJECT_CALL, reject): 889 raise _CallSequenceException("Reject call fail.") 890 # Check if incoming call is cleared on callee or not. 891 if ad_callee.droid.telephonyGetCallStateForSubscription( 892 subid_callee) == TELEPHONY_STATE_RINGING: 893 raise _CallSequenceException("Incoming call is not cleared.") 894 # Hangup on caller 895 hangup_call(log, ad_caller) 896 except _CallSequenceException as e: 897 log.error(e) 898 return False 899 return True 900 901 902def call_reject_leave_message(log, 903 ad_caller, 904 ad_callee, 905 verify_caller_func=None, 906 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 907 """On default voice subscription, Call from caller to callee, 908 reject on callee, caller leave a voice mail. 909 910 1. Caller call Callee. 911 2. Callee reject incoming call. 912 3. Caller leave a voice mail. 913 4. Verify callee received the voice mail notification. 914 915 Args: 916 ad_caller: caller android device object. 917 ad_callee: callee android device object. 918 verify_caller_func: function to verify caller is in correct state while in-call. 919 This is optional, default is None. 920 wait_time_in_call: time to wait when leaving a voice mail. 921 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 922 923 Returns: 924 True: if voice message is received on callee successfully. 925 False: for errors 926 """ 927 subid_caller = get_outgoing_voice_sub_id(ad_caller) 928 subid_callee = get_incoming_voice_sub_id(ad_callee) 929 return call_reject_leave_message_for_subscription( 930 log, ad_caller, ad_callee, subid_caller, subid_callee, 931 verify_caller_func, wait_time_in_call) 932 933 934def call_reject_leave_message_for_subscription( 935 log, 936 ad_caller, 937 ad_callee, 938 subid_caller, 939 subid_callee, 940 verify_caller_func=None, 941 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 942 """On specific voice subscription, Call from caller to callee, 943 reject on callee, caller leave a voice mail. 944 945 1. Caller call Callee. 946 2. Callee reject incoming call. 947 3. Caller leave a voice mail. 948 4. Verify callee received the voice mail notification. 949 950 Args: 951 ad_caller: caller android device object. 952 ad_callee: callee android device object. 953 subid_caller: caller's subscription id. 954 subid_callee: callee's subscription id. 955 verify_caller_func: function to verify caller is in correct state while in-call. 956 This is optional, default is None. 957 wait_time_in_call: time to wait when leaving a voice mail. 958 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 959 960 Returns: 961 True: if voice message is received on callee successfully. 962 False: for errors 963 """ 964 965 class _CallSequenceException(Exception): 966 pass 967 # Currently this test utility only works for TMO and ATT and SPT. 968 # It does not work for VZW (see b/21559800) 969 # "with VVM TelephonyManager APIs won't work for vm" 970 971 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 972 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 973 974 log.info("Call from {} to {}".format(caller_number, callee_number)) 975 976 try: 977 978 if not initiate_call(log, ad_caller, callee_number): 979 raise _CallSequenceException("Initiate call failed.") 980 981 if not wait_and_reject_call_for_subscription( 982 log, 983 ad_callee, 984 subid_callee, 985 incoming_number=caller_number): 986 raise _CallSequenceException("Reject call fail.") 987 988 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription( 989 subid_callee) 990 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 991 subid_callee) 992 993 # -1 means there are unread voice mail, but the count is unknown 994 # 0 means either this API not working (VZW) or no unread voice mail. 995 if voice_mail_count_before != 0: 996 log.warning("--Pending new Voice Mail, please clear on phone.--") 997 998 # ensure that all internal states are updated in telecom 999 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 1000 ad_callee.ed.clear_all_events() 1001 1002 if verify_caller_func and not verify_caller_func(log, ad_caller): 1003 raise _CallSequenceException("Caller not in correct state!") 1004 1005 # TODO: b/26293512 Need to play some sound to leave message. 1006 # Otherwise carrier voice mail server may drop this voice mail. 1007 1008 time.sleep(wait_time_in_call) 1009 1010 if not verify_caller_func: 1011 caller_state_result = ad_caller.droid.telecomIsInCall() 1012 else: 1013 caller_state_result = verify_caller_func(log, ad_caller) 1014 if not caller_state_result: 1015 raise _CallSequenceException( 1016 "Caller not in correct state after {} seconds".format( 1017 wait_time_in_call)) 1018 1019 if not hangup_call(log, ad_caller): 1020 raise _CallSequenceException("Error in Hanging-Up Call") 1021 1022 log.info("Wait for voice mail indicator on callee.") 1023 try: 1024 event = ad_callee.ed.wait_for_event( 1025 EventMessageWaitingIndicatorChanged, 1026 _is_on_message_waiting_event_true) 1027 log.info(event) 1028 except Empty: 1029 raise _CallSequenceException("No expected event {}.".format( 1030 EventMessageWaitingIndicatorChanged)) 1031 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 1032 subid_callee) 1033 log.info( 1034 "telephonyGetVoiceMailCount output - before: {}, after: {}".format( 1035 voice_mail_count_before, voice_mail_count_after)) 1036 1037 # voice_mail_count_after should: 1038 # either equals to (voice_mail_count_before + 1) [For ATT and SPT] 1039 # or equals to -1 [For TMO] 1040 # -1 means there are unread voice mail, but the count is unknown 1041 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before, 1042 voice_mail_count_after): 1043 log.error("telephonyGetVoiceMailCount output is incorrect.") 1044 return False 1045 1046 except _CallSequenceException as e: 1047 log.error(e) 1048 return False 1049 finally: 1050 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription( 1051 subid_callee) 1052 return True 1053 1054 1055def call_voicemail_erase_all_pending_voicemail(log, ad): 1056 """Script for phone to erase all pending voice mail. 1057 This script only works for TMO and ATT and SPT currently. 1058 This script only works if phone have already set up voice mail options, 1059 and phone should disable password protection for voice mail. 1060 1061 1. If phone don't have pending voice message, return True. 1062 2. Dial voice mail number. 1063 For TMO, the number is '123' 1064 For ATT, the number is phone's number 1065 For SPT, the number is phone's number 1066 3. Wait for voice mail connection setup. 1067 4. Wait for voice mail play pending voice message. 1068 5. Send DTMF to delete one message. 1069 The digit is '7'. 1070 6. Repeat steps 4 and 5 until voice mail server drop this call. 1071 (No pending message) 1072 6. Check telephonyGetVoiceMailCount result. it should be 0. 1073 1074 Args: 1075 log: log object 1076 ad: android device object 1077 Returns: 1078 False if error happens. True is succeed. 1079 """ 1080 log.info("Erase all pending voice mail.") 1081 if ad.droid.telephonyGetVoiceMailCount() == 0: 1082 log.info("No Pending voice mail.") 1083 return True 1084 1085 voice_mail_number = get_voice_mail_number(log, ad) 1086 1087 if not initiate_call(log, ad, voice_mail_number): 1088 log.error("Initiate call failed.") 1089 return False 1090 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1091 callId = ad.droid.telecomCallGetCallIds()[0] 1092 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1093 count = MAX_SAVED_VOICE_MAIL 1094 while (is_phone_in_call(log, ad) and (count > 0)): 1095 log.info("Press 7 to delete voice mail.") 1096 ad.droid.telecomCallPlayDtmfTone(callId, VOICEMAIL_DELETE_DIGIT) 1097 ad.droid.telecomCallStopDtmfTone(callId) 1098 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1099 count -= 1 1100 log.info("Voice mail server dropped this call.") 1101 # wait for telephonyGetVoiceMailCount to update correct result 1102 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT 1103 while ((remaining_time > 0) and 1104 (ad.droid.telephonyGetVoiceMailCount() != 0)): 1105 time.sleep(1) 1106 remaining_time -= 1 1107 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount() 1108 log.info("telephonyGetVoiceMailCount: {}".format(current_voice_mail_count)) 1109 return (current_voice_mail_count == 0) 1110 1111 1112def _is_on_message_waiting_event_true(event): 1113 """Private function to return if the received EventMessageWaitingIndicatorChanged 1114 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True. 1115 """ 1116 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING] 1117 1118 1119def call_setup_teardown(log, 1120 ad_caller, 1121 ad_callee, 1122 ad_hangup=None, 1123 verify_caller_func=None, 1124 verify_callee_func=None, 1125 wait_time_in_call=WAIT_TIME_IN_CALL, 1126 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 1127 """ Call process, including make a phone call from caller, 1128 accept from callee, and hang up. The call is on default voice subscription 1129 1130 In call process, call from <droid_caller> to <droid_callee>, 1131 accept the call, (optional)then hang up from <droid_hangup>. 1132 1133 Args: 1134 ad_caller: Caller Android Device Object. 1135 ad_callee: Callee Android Device Object. 1136 ad_hangup: Android Device Object end the phone call. 1137 Optional. Default value is None, and phone call will continue. 1138 verify_call_mode_caller: func_ptr to verify caller in correct mode 1139 Optional. Default is None 1140 verify_call_mode_caller: func_ptr to verify caller in correct mode 1141 Optional. Default is None 1142 incall_ui_display: after answer the call, bring in-call UI to foreground or 1143 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1144 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1145 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1146 else, do nothing. 1147 1148 Returns: 1149 True if call process without any error. 1150 False if error happened. 1151 1152 """ 1153 subid_caller = get_outgoing_voice_sub_id(ad_caller) 1154 subid_callee = get_incoming_voice_sub_id(ad_callee) 1155 log.info("Sub-ID Caller {}, Sub-ID Callee {}".format(subid_caller, 1156 subid_callee)) 1157 return call_setup_teardown_for_subscription( 1158 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup, 1159 verify_caller_func, verify_callee_func, wait_time_in_call, 1160 incall_ui_display) 1161 1162 1163def call_setup_teardown_for_subscription( 1164 log, 1165 ad_caller, 1166 ad_callee, 1167 subid_caller, 1168 subid_callee, 1169 ad_hangup=None, 1170 verify_caller_func=None, 1171 verify_callee_func=None, 1172 wait_time_in_call=WAIT_TIME_IN_CALL, 1173 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 1174 """ Call process, including make a phone call from caller, 1175 accept from callee, and hang up. The call is on specified subscription 1176 1177 In call process, call from <droid_caller> to <droid_callee>, 1178 accept the call, (optional)then hang up from <droid_hangup>. 1179 1180 Args: 1181 ad_caller: Caller Android Device Object. 1182 ad_callee: Callee Android Device Object. 1183 subid_caller: Caller subscription ID 1184 subid_callee: Callee subscription ID 1185 ad_hangup: Android Device Object end the phone call. 1186 Optional. Default value is None, and phone call will continue. 1187 verify_call_mode_caller: func_ptr to verify caller in correct mode 1188 Optional. Default is None 1189 verify_call_mode_caller: func_ptr to verify caller in correct mode 1190 Optional. Default is None 1191 incall_ui_display: after answer the call, bring in-call UI to foreground or 1192 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1193 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1194 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1195 else, do nothing. 1196 1197 Returns: 1198 True if call process without any error. 1199 False if error happened. 1200 1201 """ 1202 CHECK_INTERVAL = 3 1203 1204 class _CallSequenceException(Exception): 1205 pass 1206 1207 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 1208 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 1209 1210 log.info("Call from {} to {}".format(caller_number, callee_number)) 1211 1212 try: 1213 if not initiate_call(log, ad_caller, callee_number): 1214 raise _CallSequenceException("Initiate call failed.") 1215 1216 if not wait_and_answer_call_for_subscription( 1217 log, 1218 ad_callee, 1219 subid_callee, 1220 incoming_number=caller_number, 1221 incall_ui_display=incall_ui_display): 1222 raise _CallSequenceException("Answer call fail.") 1223 1224 # ensure that all internal states are updated in telecom 1225 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 1226 1227 if verify_caller_func and not verify_caller_func(log, ad_caller): 1228 raise _CallSequenceException("Caller not in correct state!") 1229 if verify_callee_func and not verify_callee_func(log, ad_callee): 1230 raise _CallSequenceException("Callee not in correct state!") 1231 1232 elapsed_time = 0 1233 while (elapsed_time < wait_time_in_call): 1234 CHECK_INTERVAL = min(CHECK_INTERVAL, 1235 wait_time_in_call - elapsed_time) 1236 time.sleep(CHECK_INTERVAL) 1237 elapsed_time += CHECK_INTERVAL 1238 if not verify_caller_func: 1239 caller_state_result = ad_caller.droid.telecomIsInCall() 1240 else: 1241 caller_state_result = verify_caller_func(log, ad_caller) 1242 if not caller_state_result: 1243 raise _CallSequenceException( 1244 "Caller not in correct state at <{}>/<{}> second.".format( 1245 elapsed_time, wait_time_in_call)) 1246 if not verify_callee_func: 1247 callee_state_result = ad_callee.droid.telecomIsInCall() 1248 else: 1249 callee_state_result = verify_callee_func(log, ad_callee) 1250 if not callee_state_result: 1251 raise _CallSequenceException( 1252 "Callee not in correct state at <{}>/<{}> second.".format( 1253 elapsed_time, wait_time_in_call)) 1254 1255 if not ad_hangup: 1256 return True 1257 1258 if not hangup_call(log, ad_hangup): 1259 raise _CallSequenceException("Error in Hanging-Up Call") 1260 1261 return True 1262 1263 except _CallSequenceException as e: 1264 log.error(e) 1265 return False 1266 finally: 1267 if ad_hangup: 1268 for ad in [ad_caller, ad_callee]: 1269 try: 1270 if ad.droid.telecomIsInCall(): 1271 ad.droid.telecomEndCall() 1272 except Exception as e: 1273 log.error(str(e)) 1274 1275 1276def phone_number_formatter(input_string, format=None): 1277 """Get expected format of input phone number string. 1278 1279 Args: 1280 input_string: (string) input phone number. 1281 The input could be 10/11/12 digital, with or without " "/"-"/"." 1282 format: (int) expected format, this could be 7/10/11/12 1283 if format is 7: output string would be 7 digital number. 1284 if format is 10: output string would be 10 digital (standard) number. 1285 if format is 11: output string would be "1" + 10 digital number. 1286 if format is 12: output string would be "+1" + 10 digital number. 1287 1288 Returns: 1289 If no error happen, return phone number in expected format. 1290 Else, return None. 1291 """ 1292 # make sure input_string is 10 digital 1293 # Remove white spaces, dashes, dots 1294 input_string = input_string.replace(" ", "").replace("-", "").replace(".", 1295 "") 1296 if not format: 1297 return input_string 1298 # Remove "1" or "+1"from front 1299 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT and 1300 input_string[0] == "1"): 1301 input_string = input_string[1:] 1302 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT and 1303 input_string[0:2] == "+1"): 1304 input_string = input_string[2:] 1305 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT and 1306 format == PHONE_NUMBER_STRING_FORMAT_7_DIGIT): 1307 return input_string 1308 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1309 return None 1310 # change input_string according to format 1311 if format == PHONE_NUMBER_STRING_FORMAT_12_DIGIT: 1312 input_string = "+1" + input_string 1313 elif format == PHONE_NUMBER_STRING_FORMAT_11_DIGIT: 1314 input_string = "1" + input_string 1315 elif format == PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1316 input_string = input_string 1317 elif format == PHONE_NUMBER_STRING_FORMAT_7_DIGIT: 1318 input_string = input_string[3:] 1319 else: 1320 return None 1321 return input_string 1322 1323 1324def get_internet_connection_type(log, ad): 1325 """Get current active connection type name. 1326 1327 Args: 1328 log: Log object. 1329 ad: Android Device Object. 1330 Returns: 1331 current active connection type name. 1332 """ 1333 if not ad.droid.connectivityNetworkIsConnected(): 1334 return 'none' 1335 return connection_type_from_type_string( 1336 ad.droid.connectivityNetworkGetActiveConnectionTypeName()) 1337 1338 1339def verify_http_connection(log, 1340 ad, 1341 url="http://www.google.com/", 1342 retry=3, 1343 retry_interval=5): 1344 """Make ping request and return status. 1345 1346 Args: 1347 log: log object 1348 ad: Android Device Object. 1349 url: Optional. The ping request will be made to this URL. 1350 Default Value is "http://www.google.com/". 1351 1352 """ 1353 for i in range(0, retry + 1): 1354 1355 try: 1356 http_response = ad.droid.httpPing(url) 1357 except: 1358 http_response = None 1359 1360 # If httpPing failed, it may return {} (if phone just turn off APM) or 1361 # None (regular fail) 1362 # So here use "if http_response" to see if it pass or fail 1363 if http_response: 1364 log.info("Verify Internet succeeded after {}s.".format( 1365 i * retry_interval) if i > 0 else "Verify Internet succeeded.") 1366 return True 1367 else: 1368 if i < retry: 1369 time.sleep(retry_interval) 1370 log.info("Verify Internet retry failed after {}s" 1371 .format(i * retry_interval)) 1372 return False 1373 1374 1375def _connection_state_change(_event, target_state, connection_type): 1376 if connection_type: 1377 if 'TypeName' not in _event['data']: 1378 return False 1379 connection_type_string_in_event = _event['data']['TypeName'] 1380 cur_type = connection_type_from_type_string( 1381 connection_type_string_in_event) 1382 if cur_type != connection_type: 1383 log.info( 1384 "_connection_state_change expect: {}, received: {} <type {}>".format( 1385 connection_type, connection_type_string_in_event, 1386 cur_type)) 1387 return False 1388 1389 if 'isConnected' in _event['data'] and _event['data'][ 1390 'isConnected'] == target_state: 1391 return True 1392 return False 1393 1394 1395def wait_for_cell_data_connection( 1396 log, 1397 ad, 1398 state, 1399 timeout_value=EventDispatcher.DEFAULT_TIMEOUT): 1400 """Wait for data connection status to be expected value for default 1401 data subscription. 1402 1403 Wait for the data connection status to be DATA_STATE_CONNECTED 1404 or DATA_STATE_DISCONNECTED. 1405 1406 Args: 1407 log: Log object. 1408 ad: Android Device Object. 1409 state: Expected status: True or False. 1410 If True, it will wait for status to be DATA_STATE_CONNECTED. 1411 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 1412 timeout_value: wait for cell data timeout value. 1413 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT 1414 1415 Returns: 1416 True if success. 1417 False if failed. 1418 """ 1419 sub_id = get_default_data_sub_id(ad) 1420 return wait_for_cell_data_connection_for_subscription(log, ad, sub_id, 1421 state, timeout_value) 1422 1423 1424def _is_data_connection_state_match(log, ad, expected_data_connection_state): 1425 return (expected_data_connection_state == 1426 ad.droid.telephonyGetDataConnectionState()) 1427 1428 1429def _is_network_connected_state_match(log, ad, 1430 expected_network_connected_state): 1431 return (expected_network_connected_state == 1432 ad.droid.connectivityNetworkIsConnected()) 1433 1434 1435def wait_for_cell_data_connection_for_subscription( 1436 log, 1437 ad, 1438 sub_id, 1439 state, 1440 timeout_value=EventDispatcher.DEFAULT_TIMEOUT): 1441 """Wait for data connection status to be expected value for specified 1442 subscrption id. 1443 1444 Wait for the data connection status to be DATA_STATE_CONNECTED 1445 or DATA_STATE_DISCONNECTED. 1446 1447 Args: 1448 log: Log object. 1449 ad: Android Device Object. 1450 sub_id: subscription Id 1451 state: Expected status: True or False. 1452 If True, it will wait for status to be DATA_STATE_CONNECTED. 1453 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 1454 timeout_value: wait for cell data timeout value. 1455 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT 1456 1457 Returns: 1458 True if success. 1459 False if failed. 1460 """ 1461 state_str = { 1462 True: DATA_STATE_CONNECTED, 1463 False: DATA_STATE_DISCONNECTED 1464 }[state] 1465 1466 ad.ed.clear_all_events() 1467 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription( 1468 sub_id) 1469 ad.droid.connectivityStartTrackingConnectivityStateChange() 1470 try: 1471 # TODO: b/26293147 There is no framework API to get data connection 1472 # state by sub id 1473 data_state = ad.droid.telephonyGetDataConnectionState() 1474 if data_state == state_str: 1475 return _wait_for_nw_data_connection( 1476 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 1477 1478 try: 1479 event = ad.ed.wait_for_event( 1480 EventDataConnectionStateChanged, 1481 is_event_match, 1482 timeout=timeout_value, 1483 field=DataConnectionStateContainer.DATA_CONNECTION_STATE, 1484 value=state_str) 1485 except Empty: 1486 log.debug( 1487 "No expected event EventDataConnectionStateChanged {}.".format( 1488 state_str)) 1489 1490 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 1491 # data connection state. 1492 # Otherwise, the network state will not be correct. 1493 # The bug is tracked here: b/20921915 1494 1495 # Previously we use _is_data_connection_state_match, 1496 # but telephonyGetDataConnectionState sometimes return wrong value. 1497 # The bug is tracked here: b/22612607 1498 # So we use _is_network_connected_state_match. 1499 1500 if _wait_for_droid_in_state(log, ad, 1501 MAX_WAIT_TIME_CONNECTION_STATE_UPDATE, 1502 _is_network_connected_state_match, state): 1503 return _wait_for_nw_data_connection( 1504 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 1505 else: 1506 return False 1507 1508 finally: 1509 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription( 1510 sub_id) 1511 1512 1513def wait_for_wifi_data_connection( 1514 log, 1515 ad, 1516 state, 1517 timeout_value=EventDispatcher.DEFAULT_TIMEOUT): 1518 """Wait for data connection status to be expected value and connection is by WiFi. 1519 1520 Args: 1521 log: Log object. 1522 ad: Android Device Object. 1523 state: Expected status: True or False. 1524 If True, it will wait for status to be DATA_STATE_CONNECTED. 1525 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 1526 timeout_value: wait for network data timeout value. 1527 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT 1528 1529 Returns: 1530 True if success. 1531 False if failed. 1532 """ 1533 log.info("{} wait_for_wifi_data_connection".format(ad.serial)) 1534 return _wait_for_nw_data_connection( 1535 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value) 1536 1537 1538def wait_for_data_connection(log, 1539 ad, 1540 state, 1541 timeout_value=EventDispatcher.DEFAULT_TIMEOUT): 1542 """Wait for data connection status to be expected value. 1543 1544 Wait for the data connection status to be DATA_STATE_CONNECTED 1545 or DATA_STATE_DISCONNECTED. 1546 1547 Args: 1548 log: Log object. 1549 ad: Android Device Object. 1550 state: Expected status: True or False. 1551 If True, it will wait for status to be DATA_STATE_CONNECTED. 1552 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 1553 timeout_value: wait for network data timeout value. 1554 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT 1555 1556 Returns: 1557 True if success. 1558 False if failed. 1559 """ 1560 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value) 1561 1562 1563def _wait_for_nw_data_connection( 1564 log, 1565 ad, 1566 is_connected, 1567 connection_type=None, 1568 timeout_value=EventDispatcher.DEFAULT_TIMEOUT): 1569 """Wait for data connection status to be expected value. 1570 1571 Wait for the data connection status to be DATA_STATE_CONNECTED 1572 or DATA_STATE_DISCONNECTED. 1573 1574 Args: 1575 log: Log object. 1576 ad: Android Device Object. 1577 is_connected: Expected connection status: True or False. 1578 If True, it will wait for status to be DATA_STATE_CONNECTED. 1579 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 1580 connection_type: expected connection type. 1581 This is optional, if it is None, then any connection type will return True. 1582 timeout_value: wait for network data timeout value. 1583 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT 1584 1585 Returns: 1586 True if success. 1587 False if failed. 1588 """ 1589 ad.ed.clear_all_events() 1590 ad.droid.connectivityStartTrackingConnectivityStateChange() 1591 try: 1592 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected() 1593 if is_connected == cur_data_connection_state: 1594 current_type = get_internet_connection_type(log, ad) 1595 log.info( 1596 "_wait_for_nw_data_connection: current connection type: {}".format( 1597 current_type)) 1598 if not connection_type: 1599 return True 1600 else: 1601 if not is_connected and current_type != connection_type: 1602 log.info( 1603 "wait_for_nw_data_connection success: {} data not on {}!".format( 1604 ad.serial, connection_type)) 1605 return True 1606 elif is_connected and current_type == connection_type: 1607 log.info( 1608 "wait_for_nw_data_connection success: {} data on {}!".format( 1609 ad.serial, connection_type)) 1610 return True 1611 else: 1612 log.info("{} current state: {} target: {}".format( 1613 ad.serial, cur_data_connection_state, is_connected)) 1614 1615 try: 1616 event = ad.ed.wait_for_event( 1617 EventConnectivityChanged, _connection_state_change, 1618 timeout_value, is_connected, connection_type) 1619 log.info("_wait_for_nw_data_connection received event:{}".format( 1620 event)) 1621 except Empty: 1622 pass 1623 1624 log.info( 1625 "_wait_for_nw_data_connection: check connection after wait event.") 1626 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 1627 # data connection state. 1628 # Otherwise, the network state will not be correct. 1629 # The bug is tracked here: b/20921915 1630 if _wait_for_droid_in_state( 1631 log, ad, MAX_WAIT_TIME_CONNECTION_STATE_UPDATE, 1632 _is_network_connected_state_match, is_connected): 1633 current_type = get_internet_connection_type(log, ad) 1634 log.info( 1635 "_wait_for_nw_data_connection: current connection type: {}".format( 1636 current_type)) 1637 if not connection_type: 1638 return True 1639 else: 1640 if not is_connected and current_type != connection_type: 1641 log.info( 1642 "wait_for_nw_data_connection after event wait, success: {} data not on {}!".format( 1643 ad.serial, connection_type)) 1644 return True 1645 elif is_connected and current_type == connection_type: 1646 log.info( 1647 "wait_for_nw_data_connection after event wait, success: {} data on {}!".format( 1648 ad.serial, connection_type)) 1649 return True 1650 else: 1651 return False 1652 else: 1653 return False 1654 except Exception as e: 1655 log.error( 1656 "tel_test_utils._wait_for_nw_data_connection threw Random exception {}".format( 1657 str(e))) 1658 return False 1659 finally: 1660 ad.droid.connectivityStopTrackingConnectivityStateChange() 1661 1662 1663def verify_incall_state(log, ads, expected_status): 1664 """Verify phones in incall state or not. 1665 1666 Verify if all phones in the array <ads> are in <expected_status>. 1667 1668 Args: 1669 log: Log object. 1670 ads: Array of Android Device Object. All droid in this array will be tested. 1671 expected_status: If True, verify all Phones in incall state. 1672 If False, verify all Phones not in incall state. 1673 1674 """ 1675 result = True 1676 for ad in ads: 1677 if ad.droid.telecomIsInCall() is not expected_status: 1678 log.error("Verify_incall_state: {} status:{}, expected:{}".format( 1679 ad.serial, ad.droid.telecomIsInCall(), expected_status)) 1680 result = False 1681 return result 1682 1683 1684def verify_active_call_number(log, ad, expected_number): 1685 """Verify the number of current active call. 1686 1687 Verify if the number of current active call in <ad> is 1688 equal to <expected_number>. 1689 1690 Args: 1691 ad: Android Device Object. 1692 expected_number: Expected active call number. 1693 """ 1694 calls = ad.droid.telecomCallGetCallIds() 1695 if calls is None: 1696 actual_number = 0 1697 else: 1698 actual_number = len(calls) 1699 if actual_number != expected_number: 1700 log.error("Active Call number in {}".format(ad.serial)) 1701 log.error("Expected:{}, Actual:{}".format(expected_number, 1702 actual_number)) 1703 return False 1704 return True 1705 1706 1707def num_active_calls(log, ad): 1708 """Get the count of current active calls. 1709 1710 Args: 1711 log: Log object. 1712 ad: Android Device Object. 1713 1714 Returns: 1715 Count of current active calls. 1716 """ 1717 calls = ad.droid.telecomCallGetCallIds() 1718 return len(calls) if calls else 0 1719 1720 1721def toggle_volte(log, ad, new_state=None): 1722 """Toggle enable/disable VoLTE for default voice subscription. 1723 1724 Args: 1725 ad: Android device object. 1726 new_state: VoLTE mode state to set to. 1727 True for enable, False for disable. 1728 If None, opposite of the current state. 1729 1730 Raises: 1731 TelTestUtilsError if platform does not support VoLTE. 1732 """ 1733 return toggle_volte_for_subscription( 1734 log, ad, get_outgoing_voice_sub_id(ad), new_state) 1735 1736 1737def toggle_volte_for_subscription(log, ad, sub_id, new_state=None): 1738 """Toggle enable/disable VoLTE for specified voice subscription. 1739 1740 Args: 1741 ad: Android device object. 1742 sub_id: subscription ID 1743 new_state: VoLTE mode state to set to. 1744 True for enable, False for disable. 1745 If None, opposite of the current state. 1746 1747 Raises: 1748 TelTestUtilsError if platform does not support VoLTE. 1749 """ 1750 # TODO: b/26293960 No framework API available to set IMS by SubId. 1751 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(): 1752 raise TelTestUtilsError("VoLTE not supported by platform.") 1753 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() 1754 if new_state is None: 1755 new_state = not current_state 1756 if new_state != current_state: 1757 ad.droid.imsSetEnhanced4gMode(new_state) 1758 return True 1759 1760 1761def set_wfc_mode(log, ad, wfc_mode): 1762 """Set WFC enable/disable and mode. 1763 1764 Args: 1765 log: Log object 1766 ad: Android device object. 1767 wfc_mode: WFC mode to set to. 1768 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED, 1769 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED. 1770 1771 Returns: 1772 True if success. False if ad does not support WFC or error happened. 1773 """ 1774 try: 1775 log.info("{} set wfc mode to {}".format(ad.serial, wfc_mode)) 1776 if not ad.droid.imsIsWfcEnabledByPlatform(): 1777 if wfc_mode == WFC_MODE_DISABLED: 1778 return True 1779 else: 1780 log.error("WFC not supported by platform.") 1781 return False 1782 1783 ad.droid.imsSetWfcMode(wfc_mode) 1784 1785 except Exception as e: 1786 log.error(e) 1787 return False 1788 1789 return True 1790 1791 1792def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args, 1793 **kwargs): 1794 while max_time > 0: 1795 if state_check_func(log, ad, *args, **kwargs): 1796 return True 1797 1798 time.sleep(1) 1799 max_time -= 1 1800 1801 return False 1802 1803 1804def _wait_for_droid_in_state_for_subscription( 1805 log, ad, sub_id, max_time, state_check_func, *args, **kwargs): 1806 while max_time > 0: 1807 if state_check_func(log, ad, sub_id, *args, **kwargs): 1808 return True 1809 1810 time.sleep(1) 1811 max_time -= 1 1812 1813 return False 1814 1815 1816def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args, 1817 **kwargs): 1818 while max_time > 0: 1819 success = True 1820 for ad in ads: 1821 if not state_check_func(log, ad, *args, **kwargs): 1822 success = False 1823 break 1824 if success: 1825 return True 1826 1827 time.sleep(1) 1828 max_time -= 1 1829 1830 return False 1831 1832 1833def is_phone_in_call(log, ad): 1834 """Return True if phone in call. 1835 1836 Args: 1837 log: log object. 1838 ad: android device. 1839 """ 1840 return ad.droid.telecomIsInCall() 1841 1842 1843def is_phone_not_in_call(log, ad): 1844 """Return True if phone not in call. 1845 1846 Args: 1847 log: log object. 1848 ad: android device. 1849 """ 1850 return not ad.droid.telecomIsInCall() 1851 1852 1853def wait_for_droid_in_call(log, ad, max_time): 1854 """Wait for android to be in call state. 1855 1856 Args: 1857 log: log object. 1858 ad: android device. 1859 max_time: maximal wait time. 1860 1861 Returns: 1862 If phone become in call state within max_time, return True. 1863 Return False if timeout. 1864 """ 1865 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call) 1866 1867 1868def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING): 1869 """Wait for android to be in telecom ringing state. 1870 1871 Args: 1872 log: log object. 1873 ad: android device. 1874 max_time: maximal wait time. This is optional. 1875 Default Value is MAX_WAIT_TIME_TELECOM_RINGING. 1876 1877 Returns: 1878 If phone become in telecom ringing state within max_time, return True. 1879 Return False if timeout. 1880 """ 1881 return _wait_for_droid_in_state( 1882 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging()) 1883 1884 1885def wait_for_droid_not_in_call(log, ad, max_time): 1886 """Wait for android to be not in call state. 1887 1888 Args: 1889 log: log object. 1890 ad: android device. 1891 max_time: maximal wait time. 1892 1893 Returns: 1894 If phone become not in call state within max_time, return True. 1895 Return False if timeout. 1896 """ 1897 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call) 1898 1899 1900def _is_attached(log, ad, voice_or_data): 1901 return _is_attached_for_subscription( 1902 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 1903 1904 1905def _is_attached_for_subscription(log, ad, sub_id, voice_or_data): 1906 if get_network_rat_for_subscription(log, ad, sub_id, 1907 voice_or_data) != RAT_UNKNOWN: 1908 return True 1909 else: 1910 return False 1911 1912 1913def wait_for_voice_attach(log, ad, max_time): 1914 """Wait for android device to attach on voice. 1915 1916 Args: 1917 log: log object. 1918 ad: android device. 1919 max_time: maximal wait time. 1920 1921 Returns: 1922 Return True if device attach voice within max_time. 1923 Return False if timeout. 1924 """ 1925 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 1926 NETWORK_SERVICE_VOICE) 1927 1928 1929def wait_for_voice_attach_for_subscription(log, ad, sub_id, max_time): 1930 """Wait for android device to attach on voice in subscription id. 1931 1932 Args: 1933 log: log object. 1934 ad: android device. 1935 sub_id: subscription id. 1936 max_time: maximal wait time. 1937 1938 Returns: 1939 Return True if device attach voice within max_time. 1940 Return False if timeout. 1941 """ 1942 if not _wait_for_droid_in_state_for_subscription( 1943 log, ad, sub_id, max_time, _is_attached_for_subscription, 1944 NETWORK_SERVICE_VOICE): 1945 return False 1946 1947 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not 1948 # receive incoming call immediately. 1949 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT: 1950 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH) 1951 return True 1952 1953 1954def wait_for_data_attach(log, ad, max_time): 1955 """Wait for android device to attach on data. 1956 1957 Args: 1958 log: log object. 1959 ad: android device. 1960 max_time: maximal wait time. 1961 1962 Returns: 1963 Return True if device attach data within max_time. 1964 Return False if timeout. 1965 """ 1966 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 1967 NETWORK_SERVICE_DATA) 1968 1969 1970def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time): 1971 """Wait for android device to attach on data in subscription id. 1972 1973 Args: 1974 log: log object. 1975 ad: android device. 1976 sub_id: subscription id. 1977 max_time: maximal wait time. 1978 1979 Returns: 1980 Return True if device attach data within max_time. 1981 Return False if timeout. 1982 """ 1983 return _wait_for_droid_in_state_for_subscription( 1984 log, ad, sub_id, max_time, _is_attached_for_subscription, 1985 NETWORK_SERVICE_DATA) 1986 1987 1988def is_ims_registered(log, ad): 1989 """Return True if IMS registered. 1990 1991 Args: 1992 log: log object. 1993 ad: android device. 1994 1995 Returns: 1996 Return True if IMS registered. 1997 Return False if IMS not registered. 1998 """ 1999 return ad.droid.telephonyIsImsRegistered() 2000 2001 2002def wait_for_ims_registered(log, ad, max_time): 2003 """Wait for android device to register on ims. 2004 2005 Args: 2006 log: log object. 2007 ad: android device. 2008 max_time: maximal wait time. 2009 2010 Returns: 2011 Return True if device register ims successfully within max_time. 2012 Return False if timeout. 2013 """ 2014 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered) 2015 2016 2017def is_volte_enabled(log, ad): 2018 """Return True if VoLTE feature bit is True. 2019 2020 Args: 2021 log: log object. 2022 ad: android device. 2023 2024 Returns: 2025 Return True if VoLTE feature bit is True and IMS registered. 2026 Return False if VoLTE feature bit is False or IMS not registered. 2027 """ 2028 volte_status = ad.droid.telephonyIsVolteAvailable() 2029 ims_status = is_ims_registered(log, ad) 2030 if volte_status is True and ims_status is False: 2031 log.error("Error! VoLTE is Available, but IMS is not registered.") 2032 return False 2033 return volte_status 2034 2035 2036def is_video_enabled(log, ad): 2037 """Return True if Video Calling feature bit is True. 2038 2039 Args: 2040 log: log object. 2041 ad: android device. 2042 2043 Returns: 2044 Return True if Video Calling feature bit is True and IMS registered. 2045 Return False if Video Calling feature bit is False or IMS not registered. 2046 """ 2047 video_status = ad.droid.telephonyIsVideoCallingAvailable() 2048 ims_status = is_ims_registered(log, ad) 2049 if video_status is True and ims_status is False: 2050 log.error("Error! Video Call is Available, but IMS is not registered.") 2051 return False 2052 return video_status 2053 2054 2055def wait_for_volte_enabled(log, ad, max_time): 2056 """Wait for android device to report VoLTE enabled bit true. 2057 2058 Args: 2059 log: log object. 2060 ad: android device. 2061 max_time: maximal wait time. 2062 2063 Returns: 2064 Return True if device report VoLTE enabled bit true within max_time. 2065 Return False if timeout. 2066 """ 2067 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled) 2068 2069 2070def wait_for_video_enabled(log, ad, max_time): 2071 """Wait for android device to report Video Telephony enabled bit true. 2072 2073 Args: 2074 log: log object. 2075 ad: android device. 2076 max_time: maximal wait time. 2077 2078 Returns: 2079 Return True if device report Video Telephony enabled bit true within max_time. 2080 Return False if timeout. 2081 """ 2082 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled) 2083 2084 2085def is_wfc_enabled(log, ad): 2086 """Return True if WiFi Calling feature bit is True. 2087 2088 Args: 2089 log: log object. 2090 ad: android device. 2091 2092 Returns: 2093 Return True if WiFi Calling feature bit is True and IMS registered. 2094 Return False if WiFi Calling feature bit is False or IMS not registered. 2095 """ 2096 wfc_status = ad.droid.telephonyIsWifiCallingAvailable() 2097 ims_status = is_ims_registered(log, ad) 2098 if wfc_status is True and ims_status is False: 2099 log.error( 2100 "Error! WiFi Calling is Available, but IMS is not registered.") 2101 return False 2102 return wfc_status 2103 2104 2105def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): 2106 """Wait for android device to report WiFi Calling enabled bit true. 2107 2108 Args: 2109 log: log object. 2110 ad: android device. 2111 max_time: maximal wait time. 2112 Default value is MAX_WAIT_TIME_WFC_ENABLED. 2113 2114 Returns: 2115 Return True if device report WiFi Calling enabled bit true within max_time. 2116 Return False if timeout. 2117 """ 2118 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled) 2119 2120 2121def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED): 2122 """Wait for android device to report WiFi Calling enabled bit false. 2123 2124 Args: 2125 log: log object. 2126 ad: android device. 2127 max_time: maximal wait time. 2128 Default value is MAX_WAIT_TIME_WFC_DISABLED. 2129 2130 Returns: 2131 Return True if device report WiFi Calling enabled bit false within max_time. 2132 Return False if timeout. 2133 """ 2134 return _wait_for_droid_in_state( 2135 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad)) 2136 2137 2138def get_phone_number(log, ad): 2139 """Get phone number for default subscription 2140 2141 Args: 2142 log: log object. 2143 ad: Android device object. 2144 2145 Returns: 2146 Phone number. 2147 """ 2148 return get_phone_number_for_subscription(log, ad, 2149 get_outgoing_voice_sub_id(ad)) 2150 2151 2152def get_phone_number_for_subscription(log, ad, subid): 2153 """Get phone number for subscription 2154 2155 Args: 2156 log: log object. 2157 ad: Android device object. 2158 subid: subscription id. 2159 2160 Returns: 2161 Phone number. 2162 """ 2163 number = None 2164 try: 2165 number = ad.cfg['subscription'][subid]['phone_num'] 2166 except KeyError: 2167 number = ad.droid.telephonyGetLine1NumberForSubscription(subid) 2168 return number 2169 2170 2171def set_phone_number(log, ad, phone_num): 2172 """Set phone number for default subscription 2173 2174 Args: 2175 log: log object. 2176 ad: Android device object. 2177 phone_num: phone number string. 2178 2179 Returns: 2180 True if success. 2181 """ 2182 return set_phone_number_for_subscription( 2183 log, ad, get_outgoing_voice_sub_id(ad), phone_num) 2184 2185 2186def set_phone_number_for_subscription(log, ad, subid, phone_num): 2187 """Set phone number for subscription 2188 2189 Args: 2190 log: log object. 2191 ad: Android device object. 2192 subid: subscription id. 2193 phone_num: phone number string. 2194 2195 Returns: 2196 True if success. 2197 """ 2198 try: 2199 ad.cfg['subscription'][subid]['phone_num'] = phone_num 2200 except Exception: 2201 return False 2202 return True 2203 2204 2205def get_operator_name(log, ad, subId=None): 2206 """Get operator name (e.g. vzw, tmo) of droid. 2207 2208 Args: 2209 ad: Android device object. 2210 sub_id: subscription ID 2211 Optional, default is None 2212 2213 Returns: 2214 Operator name. 2215 """ 2216 try: 2217 if subId is not None: 2218 result = operator_name_from_plmn_id( 2219 ad.droid.telephonyGetSimOperatorForSubscription(subId)) 2220 else: 2221 result = operator_name_from_plmn_id( 2222 ad.droid.telephonyGetSimOperator()) 2223 except KeyError: 2224 result = CARRIER_UNKNOWN 2225 return result 2226 2227 2228def get_model_name(ad): 2229 """Get android device model name 2230 2231 Args: 2232 ad: Android device object 2233 2234 Returns: 2235 model name string 2236 """ 2237 # TODO: Create translate table. 2238 model = ad.model 2239 if (model.startswith(AOSP_PREFIX)): 2240 model = model[len(AOSP_PREFIX):] 2241 return model 2242 2243 2244def is_sms_match(event, phonenumber_tx, text): 2245 """Return True if 'text' equals to event['data']['Text'] 2246 and phone number match. 2247 2248 Args: 2249 event: Event object to verify. 2250 phonenumber_tx: phone number for sender. 2251 text: text string to verify. 2252 2253 Returns: 2254 Return True if 'text' equals to event['data']['Text'] 2255 and phone number match. 2256 """ 2257 return ( 2258 check_phone_number_match(event['data']['Sender'], phonenumber_tx) and 2259 event['data']['Text'] == text) 2260 2261 2262def is_sms_partial_match(event, phonenumber_tx, text): 2263 """Return True if 'text' starts with event['data']['Text'] 2264 and phone number match. 2265 2266 Args: 2267 event: Event object to verify. 2268 phonenumber_tx: phone number for sender. 2269 text: text string to verify. 2270 2271 Returns: 2272 Return True if 'text' starts with event['data']['Text'] 2273 and phone number match. 2274 """ 2275 return ( 2276 check_phone_number_match(event['data']['Sender'], phonenumber_tx) and 2277 text.startswith(event['data']['Text'])) 2278 2279 2280def sms_send_receive_verify(log, ad_tx, ad_rx, array_message): 2281 """Send SMS, receive SMS, and verify content and sender's number. 2282 2283 Send (several) SMS from droid_tx to droid_rx. 2284 Verify SMS is sent, delivered and received. 2285 Verify received content and sender's number are correct. 2286 2287 Args: 2288 log: Log object. 2289 ad_tx: Sender's Android Device Object 2290 ad_rx: Receiver's Android Device Object 2291 array_message: the array of message to send/receive 2292 """ 2293 subid_tx = get_outgoing_message_sub_id(ad_tx) 2294 subid_rx = get_incoming_message_sub_id(ad_rx) 2295 return sms_send_receive_verify_for_subscription( 2296 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message) 2297 2298 2299def wait_for_matching_sms(log, 2300 ad_rx, 2301 phonenumber_tx, 2302 text, 2303 allow_multi_part_long_sms=True): 2304 """Wait for matching incoming SMS. 2305 2306 Args: 2307 log: Log object. 2308 ad_rx: Receiver's Android Device Object 2309 phonenumber_tx: Sender's phone number. 2310 text: SMS content string. 2311 allow_multi_part_long_sms: is long SMS allowed to be received as 2312 multiple short SMS. This is optional, default value is True. 2313 2314 Returns: 2315 True if matching incoming SMS is received. 2316 """ 2317 if not allow_multi_part_long_sms: 2318 try: 2319 ad_rx.ed.wait_for_event(EventSmsReceived, is_sms_match, 2320 MAX_WAIT_TIME_SMS_RECEIVE, phonenumber_tx, 2321 text) 2322 return True 2323 except Empty: 2324 log.error("No matched SMS received event.") 2325 return False 2326 else: 2327 try: 2328 received_sms = '' 2329 while (text != ''): 2330 event = ad_rx.ed.wait_for_event( 2331 EventSmsReceived, is_sms_partial_match, 2332 MAX_WAIT_TIME_SMS_RECEIVE, phonenumber_tx, text) 2333 text = text[len(event['data']['Text']):] 2334 received_sms += event['data']['Text'] 2335 return True 2336 except Empty: 2337 log.error("No matched SMS received event.") 2338 if received_sms != '': 2339 log.error("Only received partial matched SMS: {}".format( 2340 received_sms)) 2341 return False 2342 2343 2344def sms_send_receive_verify_for_subscription(log, ad_tx, ad_rx, subid_tx, 2345 subid_rx, array_message): 2346 """Send SMS, receive SMS, and verify content and sender's number. 2347 2348 Send (several) SMS from droid_tx to droid_rx. 2349 Verify SMS is sent, delivered and received. 2350 Verify received content and sender's number are correct. 2351 2352 Args: 2353 log: Log object. 2354 ad_tx: Sender's Android Device Object.. 2355 ad_rx: Receiver's Android Device Object. 2356 subid_tx: Sender's subsciption ID to be used for SMS 2357 subid_rx: Receiver's subsciption ID to be used for SMS 2358 array_message: the array of message to send/receive 2359 """ 2360 2361 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num'] 2362 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num'] 2363 for text in array_message: 2364 log.info("Sending SMS {} to {}, len: {}, content: {}.".format( 2365 phonenumber_tx, phonenumber_rx, len(text), text)) 2366 result = False 2367 ad_rx.ed.clear_all_events() 2368 ad_rx.droid.smsStartTrackingIncomingSmsMessage() 2369 try: 2370 ad_tx.droid.smsSendTextMessage(phonenumber_rx, text, True) 2371 2372 try: 2373 ad_tx.ed.pop_event(EventSmsSentSuccess, 2374 MAX_WAIT_TIME_SMS_SENT_SUCCESS) 2375 except Empty: 2376 log.error("No sent_success event.") 2377 return False 2378 2379 if not wait_for_matching_sms(log, 2380 ad_rx, 2381 phonenumber_tx, 2382 text, 2383 allow_multi_part_long_sms=True): 2384 return False 2385 finally: 2386 ad_rx.droid.smsStopTrackingIncomingSmsMessage() 2387 return True 2388 2389 2390def mms_send_receive_verify(log, ad_tx, ad_rx, array_message): 2391 """Send SMS, receive SMS, and verify content and sender's number. 2392 2393 Send (several) SMS from droid_tx to droid_rx. 2394 Verify SMS is sent, delivered and received. 2395 Verify received content and sender's number are correct. 2396 2397 Args: 2398 log: Log object. 2399 ad_tx: Sender's Android Device Object 2400 ad_rx: Receiver's Android Device Object 2401 array_message: the array of message to send/receive 2402 """ 2403 return mms_send_receive_verify_for_subscription( 2404 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx), 2405 get_incoming_message_sub_id(ad_rx), array_message) 2406 2407 2408#TODO: b/21569494 This function is still a WIP and is disabled 2409def mms_send_receive_verify_for_subscription(log, ad_tx, ad_rx, subid_tx, 2410 subid_rx, array_payload): 2411 """Send SMS, receive SMS, and verify content and sender's number. 2412 2413 Send (several) SMS from droid_tx to droid_rx. 2414 Verify SMS is sent, delivered and received. 2415 Verify received content and sender's number are correct. 2416 2417 Args: 2418 log: Log object. 2419 ad_tx: Sender's Android Device Object.. 2420 ad_rx: Receiver's Android Device Object. 2421 subid_tx: Sender's subsciption ID to be used for SMS 2422 subid_rx: Receiver's subsciption ID to be used for SMS 2423 array_message: the array of message to send/receive 2424 """ 2425 2426 log.error("Function is non-working: b/21569494") 2427 return False 2428 2429 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num'] 2430 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num'] 2431 for subject, message, filename in array_payload: 2432 log.info("Sending MMS {} to {}, subject: {}, message: {}.".format( 2433 phonenumber_tx, phonenumber_rx, subject, message)) 2434 result = False 2435 ad_rx.ed.clear_all_events() 2436 ad_rx.droid.smsStartTrackingIncomingMmsMessage() 2437 ad_rx.droid.smsStartTrackingIncomingSmsMessage() 2438 try: 2439 ad_tx.droid.smsSendMultimediaMessage( 2440 phonenumber_rx, subject, message, phonenumber_tx, filename) 2441 2442 ad_tx.ed.pop_event(EventMmsSentSuccess, 2443 MAX_WAIT_TIME_SMS_SENT_SUCCESS) 2444 2445 start_time = time.time() 2446 remaining_time = MAX_WAIT_TIME_SMS_RECEIVE 2447 while remaining_time > 0: 2448 event = ad_rx.ed.pop_event(EventSmsReceived, remaining_time) 2449 if check_phone_number_match(event['data']['Sender'], 2450 phonenumber_tx): 2451 log.debug("Received SMS Indication") 2452 while remaining_time > 0: 2453 event = ad_rx.ed.pop_event(EventDataSmsReceived, 2454 remaining_time) 2455 if check_phone_number_match(event['data']['Sender'], 2456 phonenumber_tx): 2457 result = True 2458 break 2459 remaining_time = time.time() - start_time 2460 remaining_time = time.time() - start_time 2461 2462 if not result: 2463 log.info("Expected sender:" + phonenumber_tx) 2464 log.error("Received sender:" + event['data']['Sender']) 2465 log.error("Failed in verify receiving MMS.") 2466 return False 2467 finally: 2468 ad_rx.droid.smsStopTrackingIncomingSmsMessage() 2469 ad_rx.droid.smsStopTrackingIncomingMmsMessage() 2470 return True 2471 2472 2473def ensure_network_rat(log, 2474 ad, 2475 network_preference, 2476 rat_family, 2477 voice_or_data=None, 2478 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2479 toggle_apm_after_setting=False): 2480 """Ensure ad's current network is in expected rat_family. 2481 """ 2482 return ensure_network_rat_for_subscription( 2483 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 2484 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting) 2485 2486 2487def ensure_network_rat_for_subscription( 2488 log, 2489 ad, 2490 sub_id, 2491 network_preference, 2492 rat_family, 2493 voice_or_data=None, 2494 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2495 toggle_apm_after_setting=False): 2496 """Ensure ad's current network is in expected rat_family. 2497 """ 2498 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 2499 network_preference, sub_id): 2500 log.error("Set Preferred Networks failed.") 2501 return False 2502 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, 2503 voice_or_data): 2504 return True 2505 2506 if toggle_apm_after_setting: 2507 toggle_airplane_mode(log, ad, True) 2508 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 2509 toggle_airplane_mode(log, ad, False) 2510 2511 result = wait_for_network_rat_for_subscription( 2512 log, ad, sub_id, rat_family, max_wait_time, voice_or_data) 2513 2514 log.info( 2515 "End of ensure_network_rat_for_subscription for {}. " 2516 "Setting to {}, Expecting {} {}. Current: voice: {}(family: {}), " 2517 "data: {}(family: {})".format( 2518 ad.serial, network_preference, rat_family, voice_or_data, 2519 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2520 sub_id), 2521 rat_family_from_rat( 2522 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2523 sub_id)), 2524 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2525 sub_id), rat_family_from_rat( 2526 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2527 sub_id)))) 2528 return result 2529 2530 2531def ensure_network_preference(log, 2532 ad, 2533 network_preference, 2534 voice_or_data=None, 2535 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2536 toggle_apm_after_setting=False): 2537 """Ensure that current rat is within the device's preferred network rats. 2538 """ 2539 return ensure_network_preference_for_subscription( 2540 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 2541 voice_or_data, max_wait_time, toggle_apm_after_setting) 2542 2543 2544def ensure_network_preference_for_subscription( 2545 log, 2546 ad, 2547 sub_id, 2548 network_preference, 2549 voice_or_data=None, 2550 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2551 toggle_apm_after_setting=False): 2552 """Ensure ad's network preference is <network_preference> for sub_id. 2553 """ 2554 rat_family_list = rat_families_for_network_preference(network_preference) 2555 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 2556 network_preference, sub_id): 2557 log.error("Set Preferred Networks failed.") 2558 return False 2559 if is_droid_in_rat_family_list_for_subscription( 2560 log, ad, sub_id, rat_family_list, voice_or_data): 2561 return True 2562 2563 if toggle_apm_after_setting: 2564 toggle_airplane_mode(log, ad, True) 2565 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 2566 toggle_airplane_mode(log, ad, False) 2567 2568 result = wait_for_preferred_network_for_subscription( 2569 log, ad, sub_id, network_preference, max_wait_time, voice_or_data) 2570 2571 log.info( 2572 "End of ensure_network_preference_for_subscription for {}. " 2573 "Setting to {}, Expecting {} {}. Current: voice: {}(family: {}), " 2574 "data: {}(family: {})".format( 2575 ad.serial, network_preference, rat_family_list, voice_or_data, 2576 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2577 sub_id), 2578 rat_family_from_rat( 2579 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2580 sub_id)), 2581 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2582 sub_id), rat_family_from_rat( 2583 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2584 sub_id)))) 2585 return result 2586 2587 2588def ensure_network_generation(log, 2589 ad, 2590 generation, 2591 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2592 voice_or_data=None, 2593 toggle_apm_after_setting=False): 2594 """Ensure ad's network is <network generation> for default subscription ID. 2595 2596 Set preferred network generation to <generation>. 2597 Toggle ON/OFF airplane mode if necessary. 2598 Wait for ad in expected network type. 2599 """ 2600 return ensure_network_generation_for_subscription( 2601 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 2602 max_wait_time, voice_or_data, toggle_apm_after_setting) 2603 2604 2605def ensure_network_generation_for_subscription( 2606 log, 2607 ad, 2608 sub_id, 2609 generation, 2610 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2611 voice_or_data=None, 2612 toggle_apm_after_setting=False): 2613 """Ensure ad's network is <network generation> for specified subscription ID. 2614 2615 Set preferred network generation to <generation>. 2616 Toggle ON/OFF airplane mode if necessary. 2617 Wait for ad in expected network type. 2618 """ 2619 if is_droid_in_network_generation_for_subscription( 2620 log, ad, sub_id, generation, voice_or_data): 2621 return True 2622 2623 operator = get_operator_name(log, ad, sub_id) 2624 try: 2625 network_preference = network_preference_for_generaton(generation, 2626 operator) 2627 rat_family = rat_family_for_generation(generation, operator) 2628 except KeyError: 2629 log.error("Failed to find a rat_family entry for " 2630 "PLMN: {}, operator:{}, generation: {}".format( 2631 ad.droid.telephonyGetSimOperatorForSubscription( 2632 sub_id), operator, generation)) 2633 return False 2634 2635 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 2636 network_preference, sub_id): 2637 log.error("Set Preferred Networks failed.") 2638 return False 2639 2640 if toggle_apm_after_setting: 2641 toggle_airplane_mode(log, ad, True) 2642 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 2643 toggle_airplane_mode(log, ad, False) 2644 2645 result = wait_for_network_generation_for_subscription( 2646 log, ad, sub_id, generation, max_wait_time, voice_or_data) 2647 2648 log.info( 2649 "End of ensure_network_generation_for_subscription for {}. " 2650 "Setting to {}, Expecting {} {}. Current: voice: {}(family: {}), " 2651 "data: {}(family: {})".format( 2652 ad.serial, network_preference, generation, voice_or_data, 2653 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2654 sub_id), 2655 rat_generation_from_rat( 2656 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2657 sub_id)), 2658 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2659 sub_id), rat_generation_from_rat( 2660 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2661 sub_id)))) 2662 2663 return result 2664 2665 2666def wait_for_network_rat(log, 2667 ad, 2668 rat_family, 2669 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2670 voice_or_data=None): 2671 return wait_for_network_rat_for_subscription( 2672 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 2673 max_wait_time, voice_or_data) 2674 2675 2676def wait_for_network_rat_for_subscription( 2677 log, 2678 ad, 2679 sub_id, 2680 rat_family, 2681 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2682 voice_or_data=None): 2683 return _wait_for_droid_in_state_for_subscription( 2684 log, ad, sub_id, max_wait_time, 2685 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data) 2686 2687 2688def wait_for_not_network_rat(log, 2689 ad, 2690 rat_family, 2691 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2692 voice_or_data=None): 2693 return wait_for_not_network_rat_for_subscription( 2694 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 2695 max_wait_time, voice_or_data) 2696 2697 2698def wait_for_not_network_rat_for_subscription( 2699 log, 2700 ad, 2701 sub_id, 2702 rat_family, 2703 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2704 voice_or_data=None): 2705 return _wait_for_droid_in_state_for_subscription( 2706 log, ad, sub_id, max_wait_time, 2707 lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)) 2708 2709 2710def wait_for_preferred_network(log, 2711 ad, 2712 network_preference, 2713 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2714 voice_or_data=None): 2715 return wait_for_preferred_network_for_subscription( 2716 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 2717 max_wait_time, voice_or_data) 2718 2719 2720def wait_for_preferred_network_for_subscription( 2721 log, 2722 ad, 2723 sub_id, 2724 network_preference, 2725 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2726 voice_or_data=None): 2727 rat_family_list = rat_families_for_network_preference(network_preference) 2728 return _wait_for_droid_in_state_for_subscription( 2729 log, ad, sub_id, max_wait_time, 2730 is_droid_in_rat_family_list_for_subscription, rat_family_list, 2731 voice_or_data) 2732 2733 2734def wait_for_network_generation(log, 2735 ad, 2736 generation, 2737 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2738 voice_or_data=None): 2739 return wait_for_network_generation_for_subscription( 2740 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 2741 max_wait_time, voice_or_data) 2742 2743 2744def wait_for_network_generation_for_subscription( 2745 log, 2746 ad, 2747 sub_id, 2748 generation, 2749 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 2750 voice_or_data=None): 2751 return _wait_for_droid_in_state_for_subscription( 2752 log, ad, sub_id, max_wait_time, 2753 is_droid_in_network_generation_for_subscription, generation, 2754 voice_or_data) 2755 2756 2757def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None): 2758 return is_droid_in_rat_family_for_subscription( 2759 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 2760 voice_or_data) 2761 2762 2763def is_droid_in_rat_family_for_subscription(log, 2764 ad, 2765 sub_id, 2766 rat_family, 2767 voice_or_data=None): 2768 return is_droid_in_rat_family_list_for_subscription( 2769 log, ad, sub_id, [rat_family], voice_or_data) 2770 2771 2772def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None): 2773 return is_droid_in_rat_family_list_for_subscription( 2774 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list, 2775 voice_or_data) 2776 2777 2778def is_droid_in_rat_family_list_for_subscription(log, 2779 ad, 2780 sub_id, 2781 rat_family_list, 2782 voice_or_data=None): 2783 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 2784 if voice_or_data: 2785 service_list = [voice_or_data] 2786 2787 for service in service_list: 2788 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 2789 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 2790 continue 2791 if rat_family_from_rat(nw_rat) in rat_family_list: 2792 return True 2793 return False 2794 2795 2796def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data): 2797 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 2798 2799 Args: 2800 log: log object. 2801 ad: android device. 2802 nw_gen: expected generation "4g", "3g", "2g". 2803 voice_or_data: check voice network generation or data network generation 2804 This parameter is optional. If voice_or_data is None, then if 2805 either voice or data in expected generation, function will return True. 2806 2807 Returns: 2808 True if droid in expected network generation. Otherwise False. 2809 """ 2810 return is_droid_in_network_generation_for_subscription( 2811 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data) 2812 2813 2814def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen, 2815 voice_or_data): 2816 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 2817 2818 Args: 2819 log: log object. 2820 ad: android device. 2821 nw_gen: expected generation "4g", "3g", "2g". 2822 voice_or_data: check voice network generation or data network generation 2823 This parameter is optional. If voice_or_data is None, then if 2824 either voice or data in expected generation, function will return True. 2825 2826 Returns: 2827 True if droid in expected network generation. Otherwise False. 2828 """ 2829 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 2830 2831 if voice_or_data: 2832 service_list = [voice_or_data] 2833 2834 for service in service_list: 2835 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 2836 2837 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 2838 continue 2839 2840 if rat_generation_from_rat(nw_rat) == nw_gen: 2841 return True 2842 else: 2843 return False 2844 2845 return False 2846 2847 2848def get_network_rat(log, ad, voice_or_data): 2849 """Get current network type (Voice network type, or data network type) 2850 for default subscription id 2851 2852 Args: 2853 ad: Android Device Object 2854 voice_or_data: Input parameter indicating to get voice network type or 2855 data network type. 2856 2857 Returns: 2858 Current voice/data network type. 2859 """ 2860 return get_network_rat_for_subscription( 2861 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 2862 2863 2864def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data): 2865 """Get current network type (Voice network type, or data network type) 2866 for specified subscription id 2867 2868 Args: 2869 ad: Android Device Object 2870 sub_id: subscription ID 2871 voice_or_data: Input parameter indicating to get voice network type or 2872 data network type. 2873 2874 Returns: 2875 Current voice/data network type. 2876 """ 2877 if voice_or_data == NETWORK_SERVICE_VOICE: 2878 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2879 sub_id) 2880 elif voice_or_data == NETWORK_SERVICE_DATA: 2881 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2882 sub_id) 2883 else: 2884 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id) 2885 2886 if ret_val is None: 2887 log.error("get_network_rat(): Unexpected null return value") 2888 return RAT_UNKNOWN 2889 else: 2890 return ret_val 2891 2892 2893def get_network_gen(log, ad, voice_or_data): 2894 """Get current network generation string (Voice network type, or data network type) 2895 2896 Args: 2897 ad: Android Device Object 2898 voice_or_data: Input parameter indicating to get voice network generation 2899 or data network generation. 2900 2901 Returns: 2902 Current voice/data network generation. 2903 """ 2904 return get_network_gen_for_subscription( 2905 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 2906 2907 2908def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data): 2909 """Get current network generation string (Voice network type, or data network type) 2910 2911 Args: 2912 ad: Android Device Object 2913 voice_or_data: Input parameter indicating to get voice network generation 2914 or data network generation. 2915 2916 Returns: 2917 Current voice/data network generation. 2918 """ 2919 try: 2920 return rat_generation_from_rat(get_network_rat_for_subscription( 2921 log, ad, sub_id, voice_or_data)) 2922 except KeyError: 2923 log.error( 2924 "KeyError happened in get_network_gen, ad:{}, d/v: {}, rat: {}".format( 2925 ad.serial, voice_or_data, get_network_rat_for_subscription( 2926 log, ad, sub_id, voice_or_data))) 2927 return GEN_UNKNOWN 2928 2929 2930def check_voice_mail_count(log, ad, voice_mail_count_before, 2931 voice_mail_count_after): 2932 """function to check if voice mail count is correct after leaving a new voice message. 2933 """ 2934 return get_voice_mail_count_check_function(get_operator_name(log, ad))( 2935 voice_mail_count_before, voice_mail_count_after) 2936 2937 2938def get_voice_mail_number(log, ad): 2939 """function to get the voice mail number 2940 """ 2941 voice_mail_number = get_voice_mail_number_function(get_operator_name(log, 2942 ad))() 2943 if voice_mail_number is None: 2944 return get_phone_number(log, ad) 2945 return voice_mail_number 2946 2947 2948def ensure_phones_idle(log, 2949 ads, 2950 settling_time=WAIT_TIME_ANDROID_STATE_SETTLING): 2951 """Ensure ads idle (not in call). 2952 """ 2953 for ad in ads: 2954 if ad.droid.telecomIsInCall(): 2955 ad.droid.telecomEndCall() 2956 # Leave the delay time to make sure droid can recover to idle from ongoing call. 2957 time.sleep(settling_time) 2958 return True 2959 2960 2961def ensure_phone_idle(log, ad, settling_time=WAIT_TIME_ANDROID_STATE_SETTLING): 2962 """Ensure ad idle (not in call). 2963 """ 2964 return ensure_phones_idle(log, [ad], settling_time) 2965 2966 2967def ensure_phone_default_state(log, ad): 2968 """Ensure ad in default state. 2969 Phone not in call. 2970 Phone have no stored WiFi network and WiFi disconnected. 2971 Phone not in airplane mode. 2972 """ 2973 result = True 2974 if ad.droid.telecomIsInCall(): 2975 ad.droid.telecomEndCall() 2976 set_wfc_mode(log, ad, WFC_MODE_DISABLED) 2977 2978 if not wait_for_not_network_rat(log, 2979 ad, 2980 RAT_FAMILY_WLAN, 2981 voice_or_data=NETWORK_SERVICE_DATA): 2982 log.error( 2983 "ensure_phones_default_state: wait_for_droid_not_in iwlan fail {}.".format( 2984 ad.serial)) 2985 result = False 2986 if (not WifiUtils.wifi_reset(log, ad)): 2987 log.error("ensure_phones_default_state:reset WiFi fail {}.".format( 2988 ad.serial)) 2989 result = False 2990 if not toggle_airplane_mode(log, ad, False): 2991 log.error( 2992 "ensure_phones_default_state:turn off airplane mode fail {}.".format( 2993 ad.serial)) 2994 result = False 2995 # make sure phone data is on 2996 ad.droid.telephonyToggleDataConnection(True) 2997 2998 # Leave the delay time to make sure droid can recover to idle from ongoing call. 2999 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3000 return result 3001 3002 3003def ensure_phones_default_state(log, ads): 3004 """Ensure ads in default state. 3005 Phone not in call. 3006 Phone have no stored WiFi network and WiFi disconnected. 3007 Phone not in airplane mode. 3008 """ 3009 tasks = [] 3010 for ad in ads: 3011 tasks.append((ensure_phone_default_state, (log, ad))) 3012 if not multithread_func(log, tasks): 3013 log.error("Ensure_phones_default_state Fail.") 3014 return False 3015 return True 3016 3017 3018def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retry=0): 3019 """Ensure ad connected to wifi. 3020 3021 Args: 3022 log: Log object. 3023 ad: Android device object. 3024 wifi_ssid: WiFi network SSID. 3025 wifi_pwd: WiFi network password. This is optional. 3026 3027 """ 3028 while (retry >= 0): 3029 WifiUtils.wifi_reset(log, ad) 3030 WifiUtils.wifi_toggle_state(log, ad, True) 3031 if WifiUtils.wifi_connect(log, ad, wifi_ssid, wifi_pwd): 3032 return True 3033 else: 3034 log.info("ensure_wifi_connected: Connect WiFi failed") 3035 retry -= 1 3036 return False 3037 3038 3039def reset_preferred_network_type_to_allowable_range(log, ad): 3040 """If preferred network type is not in allowable range, reset to GEN_4G 3041 preferred network type. 3042 3043 Args: 3044 log: log object 3045 ad: android device object 3046 3047 Returns: 3048 None 3049 """ 3050 sub_info_list = ad.droid.subscriptionGetAllSubInfoList() 3051 for sub_info in sub_info_list: 3052 sub_id = sub_info['subscriptionId'] 3053 operator = get_operator_name(log, ad, sub_id) 3054 current_preference = \ 3055 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id) 3056 try: 3057 if current_preference not in get_allowable_network_preference( 3058 operator): 3059 network_preference = network_preference_for_generaton(GEN_4G, 3060 operator) 3061 ad.droid.telephonySetPreferredNetworkTypesForSubscription( 3062 network_preference, sub_id) 3063 except KeyError: 3064 pass 3065 3066 3067def task_wrapper(task): 3068 """Task wrapper for multithread_func 3069 3070 Args: 3071 task[0]: function to be wrapped. 3072 task[1]: function args. 3073 3074 Returns: 3075 Return value of wrapped function call. 3076 """ 3077 func = task[0] 3078 params = task[1] 3079 return func(*params) 3080 3081 3082def multithread_func(log, tasks): 3083 """Multi-thread function wrapper. 3084 3085 Args: 3086 log: log object. 3087 tasks: tasks to be executed in parallel. 3088 3089 Returns: 3090 True if all tasks return True. 3091 False if any task return False. 3092 """ 3093 MAX_NUMBER_OF_WORKERS = 4 3094 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks)) 3095 executor = concurrent.futures.ThreadPoolExecutor( 3096 max_workers=number_of_workers) 3097 results = list(executor.map(task_wrapper, tasks)) 3098 executor.shutdown() 3099 log.info("multithread_func result: {}".format(results)) 3100 for r in results: 3101 if not r: 3102 return False 3103 return True 3104 3105 3106def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME): 3107 """Set phone screen on time. 3108 3109 Args: 3110 log: Log object. 3111 ad: Android device object. 3112 screen_on_time: screen on time. 3113 This is optional, default value is MAX_SCREEN_ON_TIME. 3114 Returns: 3115 True if set successfully. 3116 """ 3117 ad.droid.setScreenTimeout(screen_on_time) 3118 return screen_on_time == ad.droid.getScreenTimeout() 3119 3120 3121def set_phone_silent_mode(log, ad, silent_mode=True): 3122 """Set phone silent mode. 3123 3124 Args: 3125 log: Log object. 3126 ad: Android device object. 3127 silent_mode: set phone silent or not. 3128 This is optional, default value is True (silent mode on). 3129 Returns: 3130 True if set successfully. 3131 """ 3132 ad.droid.toggleRingerSilentMode(silent_mode) 3133 return silent_mode == ad.droid.checkRingerSilentMode() 3134 3135 3136def set_preferred_subid_for_sms(log, ad, sub_id): 3137 """set subscription id for SMS 3138 3139 Args: 3140 log: Log object. 3141 ad: Android device object. 3142 sub_id :Subscription ID. 3143 3144 """ 3145 log.info("Setting subscription:{} as Message SIM for {}".format(sub_id, 3146 ad.serial)) 3147 ad.droid.subscriptionSetDefaultSmsSubId(sub_id) 3148 # Wait to make sure settings take effect 3149 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3150 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId() 3151 3152 3153def set_preferred_subid_for_data(log, ad, sub_id): 3154 """set subscription id for data 3155 3156 Args: 3157 log: Log object. 3158 ad: Android device object. 3159 sub_id :Subscription ID. 3160 3161 """ 3162 log.info("Setting subscription:{} as Data SIM for {}".format(sub_id, 3163 ad.serial)) 3164 ad.droid.subscriptionSetDefaultDataSubId(sub_id) 3165 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3166 # Wait to make sure settings take effect 3167 # Data SIM change takes around 1 min 3168 # Check whether data has changed to selected sim 3169 if not wait_for_data_connection(log, ad, True, 3170 MAX_WAIT_TIME_DATA_SUB_CHANGE): 3171 log.error("Data Connection failed - Not able to switch Data SIM") 3172 return False 3173 return True 3174 3175 3176def set_preferred_subid_for_voice(log, ad, sub_id): 3177 """set subscription id for voice 3178 3179 Args: 3180 log: Log object. 3181 ad: Android device object. 3182 sub_id :Subscription ID. 3183 3184 """ 3185 log.info("Setting subscription:{} as Voice SIM for {}".format(sub_id, 3186 ad.serial)) 3187 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 3188 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id) 3189 # Wait to make sure settings take effect 3190 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3191 return True 3192 3193 3194def set_call_state_listen_level(log, ad, value, sub_id): 3195 """Set call state listen level for subscription id. 3196 3197 Args: 3198 log: Log object. 3199 ad: Android device object. 3200 value: True or False 3201 sub_id :Subscription ID. 3202 3203 Returns: 3204 True or False 3205 """ 3206 if sub_id == INVALID_SUB_ID: 3207 log.error("Invalid Subscription ID") 3208 return False 3209 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 3210 "Foreground", value, sub_id) 3211 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 3212 "Ringing", value, sub_id) 3213 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 3214 "Background", value, sub_id) 3215 return True 3216 3217 3218def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False): 3219 """set subscription id for voice, sms and data 3220 3221 Args: 3222 log: Log object. 3223 ad: Android device object. 3224 sub_id :Subscription ID. 3225 voice: True if to set subscription as default voice subscription 3226 sms: True if to set subscription as default sms subscription 3227 data: True if to set subscription as default data subscription 3228 3229 """ 3230 if sub_id == INVALID_SUB_ID: 3231 log.error("Invalid Subscription ID") 3232 return False 3233 else: 3234 if voice: 3235 if not set_preferred_subid_for_voice(log, ad, sub_id): 3236 return False 3237 if sms: 3238 if not set_preferred_subid_for_sms(log, ad, sub_id): 3239 return False 3240 if data: 3241 if not set_preferred_subid_for_data(log, ad, sub_id): 3242 return False 3243 return True 3244 3245 3246def is_event_match(event, field, value): 3247 """Return if <field> in "event" match <value> or not. 3248 3249 Args: 3250 event: event to test. This event need to have <field>. 3251 field: field to match. 3252 value: value to match. 3253 3254 Returns: 3255 True if <field> in "event" match <value>. 3256 False otherwise. 3257 """ 3258 return is_event_match_for_list(event, field, [value]) 3259 3260 3261def is_event_match_for_list(event, field, value_list): 3262 """Return if <field> in "event" match any one of the value 3263 in "value_list" or not. 3264 3265 Args: 3266 event: event to test. This event need to have <field>. 3267 field: field to match. 3268 value_list: a list of value to match. 3269 3270 Returns: 3271 True if <field> in "event" match one of the value in "value_list". 3272 False otherwise. 3273 """ 3274 try: 3275 value_in_event = event['data'][field] 3276 except KeyError: 3277 return False 3278 for value in value_list: 3279 if value_in_event == value: 3280 return True 3281 return False 3282 3283 3284def is_network_call_back_event_match(event, network_callback_id, 3285 network_callback_event): 3286 try: 3287 return ((network_callback_id == event[ 3288 'data'][NetworkCallbackContainer.ID]) and 3289 (network_callback_event == event['data'][ 3290 NetworkCallbackContainer.NETWORK_CALLBACK_EVENT])) 3291 except KeyError: 3292 return False 3293 3294 3295def is_build_id(log, ad, build_id): 3296 """Return if ad's build id is the same as input parameter build_id. 3297 3298 Args: 3299 log: log object. 3300 ad: android device object. 3301 build_id: android build id. 3302 3303 Returns: 3304 True if ad's build id is the same as input parameter build_id. 3305 False otherwise. 3306 """ 3307 actual_bid = ad.droid.getBuildID() 3308 3309 log.info("{} BUILD DISPLAY: {}" 3310 .format(ad.serial, ad.droid.getBuildDisplay())) 3311 #In case we want to log more stuff/more granularity... 3312 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID())) 3313 #log.info("{} BUILD FINGERPRINT: {} " 3314 # .format(ad.serial), ad.droid.getBuildFingerprint()) 3315 #log.info("{} BUILD TYPE: {} " 3316 # .format(ad.serial), ad.droid.getBuildType()) 3317 #log.info("{} BUILD NUMBER: {} " 3318 # .format(ad.serial), ad.droid.getBuildNumber()) 3319 if actual_bid.upper() != build_id.upper(): 3320 log.error("{}: Incorrect Build ID".format(ad.model)) 3321 return False 3322 return True 3323 3324 3325def is_uri_equivalent(uri1, uri2): 3326 """Check whether two input uris match or not. 3327 3328 Compare Uris. 3329 If Uris are tel URI, it will only take the digit part 3330 and compare as phone number. 3331 Else, it will just do string compare. 3332 3333 Args: 3334 uri1: 1st uri to be compared. 3335 uri2: 2nd uri to be compared. 3336 3337 Returns: 3338 True if two uris match. Otherwise False. 3339 """ 3340 3341 #If either is None/empty we return false 3342 if not uri1 or not uri2: 3343 return False 3344 3345 try: 3346 if uri1.startswith('tel:') and uri2.startswith('tel:'): 3347 uri1_number = get_number_from_tel_uri(uri1) 3348 uri2_number = get_number_from_tel_uri(uri2) 3349 return check_phone_number_match(uri1_number, uri2_number) 3350 else: 3351 return uri1 == uri2 3352 except AttributeError as e: 3353 return False 3354 3355 3356def get_call_uri(ad, call_id): 3357 """Get call's uri field. 3358 3359 Get Uri for call_id in ad. 3360 3361 Args: 3362 ad: android device object. 3363 call_id: the call id to get Uri from. 3364 3365 Returns: 3366 call's Uri if call is active and have uri field. None otherwise. 3367 """ 3368 try: 3369 call_detail = ad.droid.telecomCallGetDetails(call_id) 3370 return call_detail["Handle"]["Uri"] 3371 except: 3372 return None 3373 3374 3375def get_number_from_tel_uri(uri): 3376 """Get Uri number from tel uri 3377 3378 Args: 3379 uri: input uri 3380 3381 Returns: 3382 If input uri is tel uri, return the number part. 3383 else return None. 3384 """ 3385 if uri.startswith('tel:'): 3386 uri_number = ''.join(i for i in urllib.parse.unquote(uri) 3387 if i.isdigit()) 3388 return uri_number 3389 else: 3390 return None 3391 3392 3393# TODO: b/26294018 Remove wrapper class once wifi_utils methods updated 3394class WifiUtils(): 3395 3396 from acts.test_utils.wifi.wifi_test_utils \ 3397 import reset_wifi as _reset_wifi 3398 from acts.test_utils.wifi.wifi_test_utils \ 3399 import wifi_connect as _wifi_connect 3400 from acts.test_utils.wifi.wifi_test_utils \ 3401 import wifi_toggle_state as _wifi_toggle_state 3402 from acts.test_utils.wifi.wifi_test_utils \ 3403 import start_wifi_tethering as _start_wifi_tethering 3404 from acts.test_utils.wifi.wifi_test_utils \ 3405 import stop_wifi_tethering as _stop_wifi_tethering 3406 from acts.test_utils.wifi.wifi_test_utils \ 3407 import WifiEnums as _WifiEnums 3408 3409 WIFI_CONFIG_APBAND_2G = _WifiEnums.WIFI_CONFIG_APBAND_2G 3410 WIFI_CONFIG_APBAND_5G = _WifiEnums.WIFI_CONFIG_APBAND_5G 3411 SSID_KEY = _WifiEnums.SSID_KEY 3412 PWD_KEY = _WifiEnums.PWD_KEY 3413 3414 @staticmethod 3415 def wifi_toggle_state(log, ad, state): 3416 """Toggle the WiFi State 3417 3418 Args: 3419 log: log object 3420 ad: AndroidDevice object 3421 state: True, False, or None 3422 3423 Returns: 3424 boolean success (True) or failure (False) 3425 """ 3426 try: 3427 WifiUtils._wifi_toggle_state(ad, state) 3428 except Exception as e: 3429 log.error("WifiUtils.wifi_toggle_state exception: {}".format(e)) 3430 return False 3431 return True 3432 3433 @staticmethod 3434 def forget_all_networks(log, ad): 3435 """Forget all stored wifi network information 3436 3437 Args: 3438 log: log object 3439 ad: AndroidDevice object 3440 3441 Returns: 3442 boolean success (True) or failure (False) 3443 """ 3444 networks = ad.droid.wifiGetConfiguredNetworks() 3445 if networks is None: 3446 return True 3447 for network in networks: 3448 ad.droid.wifiForgetNetwork(network['networkId']) 3449 try: 3450 event = ad.ed.pop_event(WifiEventNames.WIFI_FORGET_NW_SUCCESS, 3451 SHORT_TIMEOUT) 3452 except Empty: 3453 log.warning( 3454 "Could not confirm the removal of network {}.".format( 3455 network)) 3456 networks = ad.droid.ad.droid.wifiGetConfiguredNetworks() 3457 if len(networks): 3458 log.error("Failed to forget all networks {}.".format(networks)) 3459 return False 3460 return True 3461 3462 @staticmethod 3463 def wifi_reset(log, ad, disable_wifi=True): 3464 """Forget all stored wifi networks and (optionally) disable WiFi 3465 3466 Args: 3467 log: log object 3468 ad: AndroidDevice object 3469 disable_wifi: boolean to disable wifi, defaults to True 3470 Returns: 3471 boolean success (True) or failure (False) 3472 """ 3473 if disable_wifi is True: 3474 if not WifiUtils.wifi_toggle_state(log, ad, False): 3475 log.error("Failed to disable WiFi during reset!") 3476 return False 3477 # Ensure toggle state has human-time to take effect 3478 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3479 return WifiUtils.forget_all_networks(log, ad) 3480 3481 @staticmethod 3482 def wifi_connect(log, ad, ssid, password=None): 3483 """Connect to a WiFi network with a provided SSID and Password 3484 3485 Args: 3486 log: log object 3487 ad: AndroidDevice object 3488 ssid: the name of the WiFi network 3489 password: optional password, used for secure networks. 3490 Returns: 3491 boolean success (True) or failure (False) 3492 """ 3493 if password == "": 3494 password = None 3495 try: 3496 network = {WifiUtils.SSID_KEY: ssid} 3497 if password: 3498 network[WifiUtils.PWD_KEY] = password 3499 WifiUtils._wifi_connect(ad, network) 3500 except Empty: 3501 # did not get event, then check connection info 3502 try: 3503 if ad.droid.wifiGetConnectionInfo()[ 3504 WifiUtils.SSID_KEY] == ssid: 3505 return True 3506 else: 3507 log.error( 3508 "WifiUtils.wifi_connect not connected." 3509 "No event received. Expected SSID: {}, current SSID:{}".format( 3510 ssid, ad.droid.wifiGetConnectionInfo()[ 3511 WifiUtils.SSID_KEY])) 3512 return False 3513 except Exception as e: 3514 log.error("WifiUtils.wifi_connect not connected, no event.") 3515 return False 3516 except Exception as e: 3517 log.error("WifiUtils.wifi_connect exception: {}".format(e)) 3518 return False 3519 return True 3520 3521 @staticmethod 3522 def start_wifi_tethering(log, ad, ssid, password, ap_band=None): 3523 """Start a Tethering Session 3524 3525 Args: 3526 log: log object 3527 ad: AndroidDevice object 3528 ssid: the name of the WiFi network 3529 password: optional password, used for secure networks. 3530 ap_band=DEPRECATED specification of 2G or 5G tethering 3531 Returns: 3532 boolean success (True) or failure (False) 3533 """ 3534 try: 3535 return WifiUtils._start_wifi_tethering(ad, ssid, password, ap_band) 3536 except Exception as e: 3537 log.error("WifiUtils.start_wifi_tethering exception: {}".format(e)) 3538 return False 3539 3540 @staticmethod 3541 def stop_wifi_tethering(log, ad): 3542 """Stop a Tethering Session 3543 3544 Args: 3545 log: log object 3546 ad: AndroidDevice object 3547 Returns: 3548 boolean success (True) or failure (False) 3549 """ 3550 try: 3551 WifiUtils._stop_wifi_tethering(ad) 3552 return True 3553 except Exception as e: 3554 log.error("WifiUtils.stop_wifi_tethering exception: {}".format(e)) 3555 return False 3556