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 json 22import logging 23import re 24import os 25import urllib.parse 26import time 27 28from acts import utils 29from queue import Empty 30from acts.asserts import abort_all 31from acts.controllers.adb import AdbError 32from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH 33from acts.controllers.android_device import SL4A_APK_NAME 34from acts.controllers.sl4a_lib.event_dispatcher import EventDispatcher 35from acts.test_utils.tel.tel_defines import AOSP_PREFIX 36from acts.test_utils.tel.tel_defines import CARD_POWER_DOWN 37from acts.test_utils.tel.tel_defines import CARD_POWER_UP 38from acts.test_utils.tel.tel_defines import CARRIER_UNKNOWN 39from acts.test_utils.tel.tel_defines import COUNTRY_CODE_LIST 40from acts.test_utils.tel.tel_defines import DATA_STATE_CONNECTED 41from acts.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED 42from acts.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE 43from acts.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE 44from acts.test_utils.tel.tel_defines import GEN_4G 45from acts.test_utils.tel.tel_defines import GEN_UNKNOWN 46from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND 47from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 48from acts.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX 49from acts.test_utils.tel.tel_defines import INVALID_SUB_ID 50from acts.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL 51from acts.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME 52from acts.test_utils.tel.tel_defines import \ 53 MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT 54from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT 55from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP 56from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION 57from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING 58from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 59from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE 60from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT 61from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION 62from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE 63from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS 64from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING 65from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT 66from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED 67from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED 68from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY 69from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL 70from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI 71from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 72from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 73from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT 74from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT 75from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT 76from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT 77from acts.test_utils.tel.tel_defines import RAT_FAMILY_GSM 78from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE 79from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN 80from acts.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA 81from acts.test_utils.tel.tel_defines import RAT_1XRTT 82from acts.test_utils.tel.tel_defines import RAT_UNKNOWN 83from acts.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY 84from acts.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE 85from acts.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING 86from acts.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE 87from acts.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF 88from acts.test_utils.tel.tel_defines import SIM_STATE_LOADED 89from acts.test_utils.tel.tel_defines import SIM_STATE_NOT_READY 90from acts.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED 91from acts.test_utils.tel.tel_defines import SIM_STATE_READY 92from acts.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN 93from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE 94from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK 95from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING 96from acts.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT 97from acts.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH 98from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 99from acts.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK 100from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE 101from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID 102from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 103from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL 104from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL 105from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE 106from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED 107from acts.test_utils.tel.tel_defines import TYPE_MOBILE 108from acts.test_utils.tel.tel_defines import TYPE_WIFI 109from acts.test_utils.tel.tel_defines import EventCallStateChanged 110from acts.test_utils.tel.tel_defines import EventConnectivityChanged 111from acts.test_utils.tel.tel_defines import EventDataConnectionStateChanged 112from acts.test_utils.tel.tel_defines import EventDataSmsReceived 113from acts.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged 114from acts.test_utils.tel.tel_defines import EventServiceStateChanged 115from acts.test_utils.tel.tel_defines import EventMmsSentSuccess 116from acts.test_utils.tel.tel_defines import EventMmsDownloaded 117from acts.test_utils.tel.tel_defines import EventSmsReceived 118from acts.test_utils.tel.tel_defines import EventSmsSentSuccess 119from acts.test_utils.tel.tel_defines import CallStateContainer 120from acts.test_utils.tel.tel_defines import DataConnectionStateContainer 121from acts.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer 122from acts.test_utils.tel.tel_defines import NetworkCallbackContainer 123from acts.test_utils.tel.tel_defines import ServiceStateContainer 124from acts.test_utils.tel.tel_lookup_tables import \ 125 connection_type_from_type_string 126from acts.test_utils.tel.tel_lookup_tables import is_valid_rat 127from acts.test_utils.tel.tel_lookup_tables import get_allowable_network_preference 128from acts.test_utils.tel.tel_lookup_tables import \ 129 get_voice_mail_count_check_function 130from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number 131from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit 132from acts.test_utils.tel.tel_lookup_tables import \ 133 network_preference_for_generation 134from acts.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id 135from acts.test_utils.tel.tel_lookup_tables import \ 136 rat_families_for_network_preference 137from acts.test_utils.tel.tel_lookup_tables import rat_family_for_generation 138from acts.test_utils.tel.tel_lookup_tables import rat_family_from_rat 139from acts.test_utils.tel.tel_lookup_tables import rat_generation_from_rat 140from acts.test_utils.tel.tel_subscription_utils import \ 141 get_default_data_sub_id 142from acts.test_utils.tel.tel_subscription_utils import \ 143 get_outgoing_message_sub_id 144from acts.test_utils.tel.tel_subscription_utils import \ 145 get_outgoing_voice_sub_id 146from acts.test_utils.tel.tel_subscription_utils import \ 147 get_incoming_voice_sub_id 148from acts.test_utils.tel.tel_subscription_utils import \ 149 get_incoming_message_sub_id 150from acts.test_utils.wifi import wifi_test_utils 151from acts.test_utils.wifi import wifi_constants 152from acts.utils import adb_shell_ping 153from acts.utils import load_config 154from acts.utils import create_dir 155from acts.utils import start_standing_subprocess 156from acts.utils import stop_standing_subprocess 157from acts.logger import epoch_to_log_line_timestamp 158from acts.logger import normalize_log_line_timestamp 159from acts.utils import get_current_epoch_time 160from acts.utils import exe_cmd 161 162WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY 163WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY 164WIFI_CONFIG_APBAND_2G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_2G 165WIFI_CONFIG_APBAND_5G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_5G 166WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO 167log = logging 168STORY_LINE = "+19523521350" 169 170 171class _CallSequenceException(Exception): 172 pass 173 174 175class TelTestUtilsError(Exception): 176 pass 177 178 179def abort_all_tests(log, msg): 180 log.error("Aborting all ongoing tests due to: %s.", msg) 181 abort_all(msg) 182 183 184def get_phone_number_by_adb(ad): 185 return phone_number_formatter( 186 ad.adb.shell("service call iphonesubinfo 13")) 187 188 189def get_iccid_by_adb(ad): 190 return ad.adb.shell("service call iphonesubinfo 11") 191 192 193def get_operator_by_adb(ad): 194 return ad.adb.getprop("gsm.sim.operator.alpha") 195 196 197def get_plmn_by_adb(ad): 198 return ad.adb.getprop("gsm.sim.operator.numeric") 199 200 201def get_sub_id_by_adb(ad): 202 return ad.adb.shell("service call iphonesubinfo 5") 203 204 205def setup_droid_properties_by_adb(log, ad, sim_filename=None): 206 207 # Check to see if droid already has this property 208 if hasattr(ad, 'cfg'): 209 return 210 211 sim_data = None 212 if sim_filename: 213 try: 214 sim_data = load_config(sim_filename) 215 except Exception: 216 log.warning("Failed to load %s!", sim_filename) 217 218 sub_id = get_sub_id_by_adb(ad) 219 iccid = get_iccid_by_adb(ad) 220 ad.log.info("iccid = %s", iccid) 221 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"): 222 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"]) 223 else: 224 phone_number = get_phone_number_by_adb(ad) 225 if not phone_number and hasattr(ad, phone_number): 226 phone_number = ad.phone_number 227 if not phone_number: 228 ad.log.error("Failed to find valid phone number for %s", iccid) 229 abort_all_tests("Failed to find valid phone number for %s" % ad.serial) 230 sim_record = { 231 'phone_num': phone_number, 232 'iccid': get_iccid_by_adb(ad), 233 'sim_operator_name': get_operator_by_adb(ad), 234 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad)) 235 } 236 device_props = {'subscription': {sub_id: sim_record}} 237 ad.log.info("subId %s SIM record: %s", sub_id, sim_record) 238 setattr(ad, 'cfg', device_props) 239 240 241def setup_droid_properties(log, ad, sim_filename=None): 242 243 # Check to see if droid already has this property 244 if hasattr(ad, 'cfg'): 245 return 246 247 if ad.skip_sl4a: 248 return setup_droid_properties_by_adb( 249 log, ad, sim_filename=sim_filename) 250 251 refresh_droid_config(log, ad) 252 device_props = {} 253 device_props['subscription'] = {} 254 255 sim_data = {} 256 if sim_filename: 257 try: 258 sim_data = load_config(sim_filename) 259 except Exception: 260 log.warning("Failed to load %s!", sim_filename) 261 if not ad.cfg["subscription"]: 262 abort_all_tests(ad.log, "No Valid SIMs found in device") 263 result = True 264 active_sub_id = get_outgoing_voice_sub_id(ad) 265 for sub_id, sub_info in ad.cfg["subscription"].items(): 266 sub_info["operator"] = get_operator_name(log, ad, sub_id) 267 iccid = sub_info["iccid"] 268 if not iccid: 269 ad.log.warn("Unable to find ICC-ID for SIM") 270 continue 271 if sub_info.get("phone_num"): 272 if getattr(ad, "phone_number", None) and check_phone_number_match( 273 sub_info["phone_num"], ad.phone_number): 274 sub_info["phone_num"] = ad.phone_number 275 elif iccid and iccid in sim_data and sim_data[iccid].get( 276 "phone_num"): 277 if check_phone_number_match(sim_data[iccid]["phone_num"], 278 sub_info["phone_num"]): 279 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 280 else: 281 ad.log.warning( 282 "phone_num %s in sim card data file for iccid %s" 283 " do not match phone_num %s in droid subscription", 284 sim_data[iccid]["phone_num"], iccid, 285 sub_info["phone_num"]) 286 elif iccid and iccid in sim_data and sim_data[iccid].get("phone_num"): 287 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 288 elif sub_id == active_sub_id: 289 phone_number = get_phone_number_by_secret_code( 290 ad, sub_info["sim_operator_name"]) 291 if phone_number: 292 sub_info["phone_num"] = phone_number 293 elif getattr(ad, "phone_num", None): 294 sub_info["phone_num"] = ad.phone_number 295 if (not sub_info.get("phone_num")) and sub_id == active_sub_id: 296 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info) 297 ad.log.error( 298 "Unable to retrieve phone number for sub %s with iccid" 299 " %s from device or testbed config or sim card file %s", 300 sub_id, iccid, sim_filename) 301 result = False 302 if not hasattr( 303 ad, 'roaming' 304 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and ( 305 sub_info["sim_operator_name"].strip() not in 306 sub_info["network_operator_name"].strip()): 307 ad.log.info("roaming is not enabled, enable it") 308 setattr(ad, 'roaming', True) 309 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items())) 310 data_roaming = getattr(ad, 'roaming', False) 311 if get_cell_data_roaming_state_by_adb(ad) != data_roaming: 312 set_cell_data_roaming_state_by_adb(ad, data_roaming) 313 if not result: 314 abort_all_tests(ad.log, "Failed to find valid phone number") 315 316 ad.log.debug("cfg = %s", ad.cfg) 317 318 319def refresh_droid_config(log, ad): 320 """ Update Android Device cfg records for each sub_id. 321 322 Args: 323 log: log object 324 ad: android device object 325 326 Returns: 327 None 328 """ 329 if hasattr(ad, 'cfg'): 330 cfg = ad.cfg.copy() 331 else: 332 cfg = {"subscription": {}} 333 droid = ad.droid 334 sub_info_list = droid.subscriptionGetAllSubInfoList() 335 for sub_info in sub_info_list: 336 sub_id = sub_info["subscriptionId"] 337 sim_slot = sub_info["simSlotIndex"] 338 if sim_slot != INVALID_SIM_SLOT_INDEX: 339 sim_record = {} 340 if sub_info.get("iccId"): 341 sim_record["iccid"] = sub_info["iccId"] 342 else: 343 sim_record[ 344 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription( 345 sub_id) 346 sim_record["sim_slot"] = sim_slot 347 try: 348 sim_record[ 349 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription( 350 sub_id) 351 except: 352 sim_record["phone_type"] = droid.telephonyGetPhoneType() 353 if sub_info.get("mcc"): 354 sim_record["mcc"] = sub_info["mcc"] 355 if sub_info.get("mnc"): 356 sim_record["mnc"] = sub_info["mnc"] 357 sim_record[ 358 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription( 359 sub_id) 360 sim_record["display_name"] = sub_info["displayName"] 361 sim_record[ 362 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription( 363 sub_id) 364 sim_record[ 365 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription( 366 sub_id) 367 sim_record[ 368 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription( 369 sub_id) 370 sim_record[ 371 "network_type"] = droid.telephonyGetNetworkTypeForSubscription( 372 sub_id) 373 sim_record[ 374 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription( 375 sub_id) 376 if sub_info.get("number"): 377 sim_record["phone_num"] = sub_info["number"] 378 else: 379 sim_record["phone_num"] = phone_number_formatter( 380 droid.telephonyGetLine1NumberForSubscription(sub_id)) 381 sim_record[ 382 "phone_tag"] = droid.telephonyGetLine1AlphaTagForSubscription( 383 sub_id) 384 if (not sim_record["phone_num"] 385 ) and cfg["subscription"].get(sub_id): 386 sim_record["phone_num"] = cfg["subscription"][sub_id][ 387 "phone_num"] 388 cfg['subscription'][sub_id] = sim_record 389 ad.log.debug("SubId %s SIM record: %s", sub_id, sim_record) 390 setattr(ad, 'cfg', cfg) 391 392 393def get_phone_number_by_secret_code(ad, operator): 394 if "T-Mobile" in operator: 395 ad.droid.telecomDialNumber("#686#") 396 ad.send_keycode("ENTER") 397 for _ in range(12): 398 output = ad.search_logcat("mobile number") 399 if output: 400 result = re.findall(r"mobile number is (\S+)", 401 output[-1]["log_message"]) 402 ad.send_keycode("BACK") 403 return result[0] 404 else: 405 time.sleep(5) 406 return "" 407 408 409def get_slot_index_from_subid(log, ad, sub_id): 410 try: 411 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id) 412 return info['simSlotIndex'] 413 except KeyError: 414 return INVALID_SIM_SLOT_INDEX 415 416 417def get_num_active_sims(log, ad): 418 """ Get the number of active SIM cards by counting slots 419 420 Args: 421 ad: android_device object. 422 423 Returns: 424 result: The number of loaded (physical) SIM cards 425 """ 426 # using a dictionary as a cheap way to prevent double counting 427 # in the situation where multiple subscriptions are on the same SIM. 428 # yes, this is a corner corner case. 429 valid_sims = {} 430 subInfo = ad.droid.subscriptionGetAllSubInfoList() 431 for info in subInfo: 432 ssidx = info['simSlotIndex'] 433 if ssidx == INVALID_SIM_SLOT_INDEX: 434 continue 435 valid_sims[ssidx] = True 436 return len(valid_sims.keys()) 437 438 439def toggle_airplane_mode_by_adb(log, ad, new_state=None): 440 """ Toggle the state of airplane mode. 441 442 Args: 443 log: log handler. 444 ad: android_device object. 445 new_state: Airplane mode state to set to. 446 If None, opposite of the current state. 447 strict_checking: Whether to turn on strict checking that checks all features. 448 449 Returns: 450 result: True if operation succeed. False if error happens. 451 """ 452 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on"))) 453 if new_state == cur_state: 454 ad.log.info("Airplane mode already in %s", new_state) 455 return True 456 elif new_state is None: 457 new_state = not cur_state 458 459 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state)) 460 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE") 461 return True 462 463 464def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True): 465 """ Toggle the state of airplane mode. 466 467 Args: 468 log: log handler. 469 ad: android_device object. 470 new_state: Airplane mode state to set to. 471 If None, opposite of the current state. 472 strict_checking: Whether to turn on strict checking that checks all features. 473 474 Returns: 475 result: True if operation succeed. False if error happens. 476 """ 477 if ad.skip_sl4a: 478 return toggle_airplane_mode_by_adb(log, ad, new_state) 479 else: 480 return toggle_airplane_mode_msim( 481 log, ad, new_state, strict_checking=strict_checking) 482 483 484def get_telephony_signal_strength(ad): 485 signal_strength = ad.droid.telephonyGetSignalStrength() 486 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0, 487 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160, 488 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0, 489 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0, 490 # 'lteDbm': -112, 'gsmSignalStrength': 99} 491 if not signal_strength: signal_strength = {} 492 out = ad.adb.shell("dumpsys telephony.registry | grep -i signalstrength") 493 signals = re.findall(r"(-*\d+)", out) 494 for i, val in enumerate( 495 ("gsmSignalStrength", "gsmBitErrorRate", "cdmaDbm", "cdmaEcio", 496 "evdoDbm", "evdoEcio", "evdoSnr", "lteSignalStrength", "lteRsrp", 497 "lteRsrq", "lteRssnr", "lteCqi", "lteRsrpBoost")): 498 signal_strength[val] = signal_strength.get(val, int(signals[i])) 499 ad.log.info("Telephony Signal strength = %s", signal_strength) 500 return signal_strength 501 502 503def get_wifi_signal_strength(ad): 504 signal_strength = ad.droid.wifiGetConnectionInfo()['rssi'] 505 ad.log.info("WiFi Signal Strength is %s" % signal_strength) 506 return signal_strength 507 508 509def is_expected_event(event_to_check, events_list): 510 """ check whether event is present in the event list 511 512 Args: 513 event_to_check: event to be checked. 514 events_list: list of events 515 Returns: 516 result: True if event present in the list. False if not. 517 """ 518 for event in events_list: 519 if event in event_to_check['name']: 520 return True 521 return False 522 523 524def is_sim_ready(log, ad, sim_slot_id=None): 525 """ check whether SIM is ready. 526 527 Args: 528 ad: android_device object. 529 sim_slot_id: check the SIM status for sim_slot_id 530 This is optional. If this is None, check default SIM. 531 532 Returns: 533 result: True if all SIMs are ready. False if not. 534 """ 535 if sim_slot_id is None: 536 status = ad.droid.telephonyGetSimState() 537 else: 538 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id) 539 if status != SIM_STATE_READY: 540 log.info("Sim not ready") 541 return False 542 return True 543 544 545def is_sim_ready_by_adb(log, ad): 546 state = ad.adb.getprop("gsm.sim.state") 547 return state == SIM_STATE_READY or state == SIM_STATE_LOADED 548 549 550def wait_for_sim_ready_by_adb(log, ad, wait_time=90): 551 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb) 552 553 554def get_service_state_by_adb(log, ad): 555 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState") 556 if "mVoiceRegState" in output: 557 result = re.search(r"mVoiceRegState=(\S+)\((\S+)\)", output) 558 if result: 559 ad.log.info("mVoiceRegState is %s %s", result.group(1), 560 result.group(2)) 561 return result.group(2) 562 else: 563 result = re.search(r"mServiceState=(\S+)", output) 564 if result: 565 ad.log.info("mServiceState=%s %s", result.group(1), 566 SERVICE_STATE_MAPPING[result.group(1)]) 567 return SERVICE_STATE_MAPPING[result.group(1)] 568 569 570def _is_expecting_event(event_recv_list): 571 """ check for more event is expected in event list 572 573 Args: 574 event_recv_list: list of events 575 Returns: 576 result: True if more events are expected. False if not. 577 """ 578 for state in event_recv_list: 579 if state is False: 580 return True 581 return False 582 583 584def _set_event_list(event_recv_list, sub_id_list, sub_id, value): 585 """ set received event in expected event list 586 587 Args: 588 event_recv_list: list of received events 589 sub_id_list: subscription ID list 590 sub_id: subscription id of current event 591 value: True or False 592 Returns: 593 None. 594 """ 595 for i in range(len(sub_id_list)): 596 if sub_id_list[i] == sub_id: 597 event_recv_list[i] = value 598 599 600def _wait_for_bluetooth_in_state(log, ad, state, max_wait): 601 # FIXME: These event names should be defined in a common location 602 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn' 603 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff' 604 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT) 605 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT) 606 607 ad.droid.bluetoothStartListeningForAdapterStateChange() 608 try: 609 bt_state = ad.droid.bluetoothCheckState() 610 if bt_state == state: 611 return True 612 if max_wait <= 0: 613 ad.log.error("Time out: bluetooth state still %s, expecting %s", 614 bt_state, state) 615 return False 616 617 event = { 618 False: _BLUETOOTH_STATE_OFF_EVENT, 619 True: _BLUETOOTH_STATE_ON_EVENT 620 }[state] 621 ad.ed.pop_event(event, max_wait) 622 return True 623 except Empty: 624 ad.log.error("Time out: bluetooth state still in %s, expecting %s", 625 bt_state, state) 626 return False 627 finally: 628 ad.droid.bluetoothStopListeningForAdapterStateChange() 629 630 631# TODO: replace this with an event-based function 632def _wait_for_wifi_in_state(log, ad, state, max_wait): 633 return _wait_for_droid_in_state(log, ad, max_wait, 634 lambda log, ad, state: \ 635 (True if ad.droid.wifiCheckState() == state else False), 636 state) 637 638 639def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True): 640 """ Toggle the state of airplane mode. 641 642 Args: 643 log: log handler. 644 ad: android_device object. 645 new_state: Airplane mode state to set to. 646 If None, opposite of the current state. 647 strict_checking: Whether to turn on strict checking that checks all features. 648 649 Returns: 650 result: True if operation succeed. False if error happens. 651 """ 652 653 ad.ed.clear_all_events() 654 sub_id_list = [] 655 656 active_sub_info = ad.droid.subscriptionGetAllSubInfoList() 657 for info in active_sub_info: 658 sub_id_list.append(info['subscriptionId']) 659 660 cur_state = ad.droid.connectivityCheckAirplaneMode() 661 if cur_state == new_state: 662 ad.log.info("Airplane mode already in %s", new_state) 663 return True 664 elif new_state is None: 665 ad.log.info("APM Current State %s New state %s", cur_state, new_state) 666 667 if new_state is None: 668 new_state = not cur_state 669 670 service_state_list = [] 671 if new_state: 672 service_state_list.append(SERVICE_STATE_POWER_OFF) 673 ad.log.info("Turn on airplane mode") 674 675 else: 676 # If either one of these 3 events show up, it should be OK. 677 # Normal SIM, phone in service 678 service_state_list.append(SERVICE_STATE_IN_SERVICE) 679 # NO SIM, or Dead SIM, or no Roaming coverage. 680 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE) 681 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY) 682 ad.log.info("Turn off airplane mode") 683 684 for sub_id in sub_id_list: 685 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription( 686 sub_id) 687 688 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT 689 ad.droid.connectivityToggleAirplaneMode(new_state) 690 691 event = None 692 693 try: 694 try: 695 event = ad.ed.wait_for_event( 696 EventServiceStateChanged, 697 is_event_match_for_list, 698 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT, 699 field=ServiceStateContainer.SERVICE_STATE, 700 value_list=service_state_list) 701 except Empty: 702 pass 703 if event is None: 704 ad.log.error("Did not get expected service state %s", 705 service_state_list) 706 return False 707 else: 708 ad.log.info("Received event: %s", event) 709 finally: 710 for sub_id in sub_id_list: 711 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription( 712 sub_id) 713 714 # APM on (new_state=True) will turn off bluetooth but may not turn it on 715 try: 716 if new_state and not _wait_for_bluetooth_in_state( 717 log, ad, False, timeout_time - time.time()): 718 ad.log.error( 719 "Failed waiting for bluetooth during airplane mode toggle") 720 if strict_checking: return False 721 except Exception as e: 722 ad.log.error("Failed to check bluetooth state due to %s", e) 723 if strict_checking: 724 raise 725 726 # APM on (new_state=True) will turn off wifi but may not turn it on 727 if new_state and not _wait_for_wifi_in_state(log, ad, False, 728 timeout_time - time.time()): 729 ad.log.error("Failed waiting for wifi during airplane mode toggle on") 730 if strict_checking: return False 731 732 if ad.droid.connectivityCheckAirplaneMode() != new_state: 733 ad.log.error("Set airplane mode to %s failed", new_state) 734 return False 735 return True 736 737 738def wait_and_answer_call(log, 739 ad, 740 incoming_number=None, 741 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 742 caller=None): 743 """Wait for an incoming call on default voice subscription and 744 accepts the call. 745 746 Args: 747 ad: android device object. 748 incoming_number: Expected incoming number. 749 Optional. Default is None 750 incall_ui_display: after answer the call, bring in-call UI to foreground or 751 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 752 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 753 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 754 else, do nothing. 755 756 Returns: 757 True: if incoming call is received and answered successfully. 758 False: for errors 759 """ 760 return wait_and_answer_call_for_subscription( 761 log, 762 ad, 763 get_incoming_voice_sub_id(ad), 764 incoming_number, 765 incall_ui_display=incall_ui_display, 766 caller=caller) 767 768 769def wait_for_ringing_event(log, ad, wait_time): 770 log.warning("***DEPRECATED*** wait_for_ringing_event()") 771 return _wait_for_ringing_event(log, ad, wait_time) 772 773 774def _wait_for_ringing_event(log, ad, wait_time): 775 """Wait for ringing event. 776 777 Args: 778 log: log object. 779 ad: android device object. 780 wait_time: max time to wait for ringing event. 781 782 Returns: 783 event_ringing if received ringing event. 784 otherwise return None. 785 """ 786 event_ringing = None 787 788 try: 789 event_ringing = ad.ed.wait_for_event( 790 EventCallStateChanged, 791 is_event_match, 792 timeout=wait_time, 793 field=CallStateContainer.CALL_STATE, 794 value=TELEPHONY_STATE_RINGING) 795 ad.log.info("Receive ringing event") 796 except Empty: 797 ad.log.info("No Ringing Event") 798 finally: 799 return event_ringing 800 801 802def wait_for_ringing_call(log, ad, incoming_number=None): 803 """Wait for an incoming call on default voice subscription and 804 accepts the call. 805 806 Args: 807 log: log object. 808 ad: android device object. 809 incoming_number: Expected incoming number. 810 Optional. Default is None 811 812 Returns: 813 True: if incoming call is received and answered successfully. 814 False: for errors 815 """ 816 return wait_for_ringing_call_for_subscription( 817 log, ad, get_incoming_voice_sub_id(ad), incoming_number) 818 819 820def wait_for_ringing_call_for_subscription( 821 log, 822 ad, 823 sub_id, 824 incoming_number=None, 825 caller=None, 826 event_tracking_started=False, 827 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 828 retries=1): 829 """Wait for an incoming call on specified subscription. 830 831 Args: 832 log: log object. 833 ad: android device object. 834 sub_id: subscription ID 835 incoming_number: Expected incoming number. Default is None 836 event_tracking_started: True if event tracking already state outside 837 timeout: time to wait for ring 838 839 Returns: 840 True: if incoming call is received and answered successfully. 841 False: for errors 842 """ 843 if not event_tracking_started: 844 ad.ed.clear_events(EventCallStateChanged) 845 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 846 event_ringing = None 847 for i in range(retries): 848 event_ringing = _wait_for_ringing_event(log, ad, timeout) 849 if event_ringing: 850 ad.log.info("callee received ring event") 851 break 852 if ad.droid.telephonyGetCallStateForSubscription( 853 sub_id 854 ) == TELEPHONY_STATE_RINGING or ad.droid.telecomIsRinging(): 855 ad.log.info("callee in ringing state") 856 break 857 if i == retries - 1: 858 ad.log.info( 859 "callee didn't receive ring event or got into ringing state") 860 return False 861 if not event_tracking_started: 862 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 863 if caller and not caller.droid.telecomIsInCall(): 864 caller.log.error("Caller not in call state") 865 raise _CallSequenceException("Caller not in call state") 866 if not incoming_number: 867 return True 868 869 if event_ringing and not check_phone_number_match( 870 event_ringing['data'][CallStateContainer.INCOMING_NUMBER], 871 incoming_number): 872 ad.log.error( 873 "Incoming Number not match. Expected number:%s, actual number:%s", 874 incoming_number, 875 event_ringing['data'][CallStateContainer.INCOMING_NUMBER]) 876 return False 877 return True 878 879 880def wait_for_call_offhook_event( 881 log, 882 ad, 883 sub_id, 884 event_tracking_started=False, 885 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT): 886 """Wait for an incoming call on specified subscription. 887 888 Args: 889 log: log object. 890 ad: android device object. 891 event_tracking_started: True if event tracking already state outside 892 timeout: time to wait for event 893 894 Returns: 895 True: if call offhook event is received. 896 False: if call offhook event is not received. 897 """ 898 if not event_tracking_started: 899 ad.ed.clear_events(EventCallStateChanged) 900 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 901 try: 902 ad.ed.wait_for_event( 903 EventCallStateChanged, 904 is_event_match, 905 timeout=timeout, 906 field=CallStateContainer.CALL_STATE, 907 value=TELEPHONY_STATE_OFFHOOK) 908 except Empty: 909 ad.log.info("No event for call state change to OFFHOOK") 910 return False 911 finally: 912 if not event_tracking_started: 913 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 914 sub_id) 915 return True 916 917 918def wait_and_answer_call_for_subscription( 919 log, 920 ad, 921 sub_id, 922 incoming_number=None, 923 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 924 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 925 caller=None): 926 """Wait for an incoming call on specified subscription and 927 accepts the call. 928 929 Args: 930 log: log object. 931 ad: android device object. 932 sub_id: subscription ID 933 incoming_number: Expected incoming number. 934 Optional. Default is None 935 incall_ui_display: after answer the call, bring in-call UI to foreground or 936 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 937 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 938 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 939 else, do nothing. 940 941 Returns: 942 True: if incoming call is received and answered successfully. 943 False: for errors 944 """ 945 ad.ed.clear_events(EventCallStateChanged) 946 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 947 try: 948 if not _wait_for_droid_in_state( 949 log, 950 ad, 951 timeout, 952 wait_for_ringing_call_for_subscription, 953 sub_id, 954 incoming_number=None, 955 caller=caller, 956 event_tracking_started=True, 957 timeout=WAIT_TIME_BETWEEN_STATE_CHECK): 958 ad.log.info("Could not answer a call: phone never rang.") 959 return False 960 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 961 ad.log.info("Accept the ring call") 962 ad.droid.telecomAcceptRingingCall() 963 964 if ad.droid.telecomIsInCall() or wait_for_call_offhook_event( 965 log, ad, sub_id, event_tracking_started=True, 966 timeout=timeout) or ad.droid.telecomIsInCall(): 967 ad.log.info("Call answered successfully.") 968 return True 969 else: 970 ad.log.error("Could not answer the call.") 971 return False 972 except Exception as e: 973 log.error(e) 974 return False 975 finally: 976 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 977 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 978 ad.droid.telecomShowInCallScreen() 979 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 980 ad.droid.showHomeScreen() 981 982 983def wait_and_reject_call(log, 984 ad, 985 incoming_number=None, 986 delay_reject=WAIT_TIME_REJECT_CALL, 987 reject=True): 988 """Wait for an incoming call on default voice subscription and 989 reject the call. 990 991 Args: 992 log: log object. 993 ad: android device object. 994 incoming_number: Expected incoming number. 995 Optional. Default is None 996 delay_reject: time to wait before rejecting the call 997 Optional. Default is WAIT_TIME_REJECT_CALL 998 999 Returns: 1000 True: if incoming call is received and reject successfully. 1001 False: for errors 1002 """ 1003 return wait_and_reject_call_for_subscription(log, ad, 1004 get_incoming_voice_sub_id(ad), 1005 incoming_number, delay_reject, 1006 reject) 1007 1008 1009def wait_and_reject_call_for_subscription(log, 1010 ad, 1011 sub_id, 1012 incoming_number=None, 1013 delay_reject=WAIT_TIME_REJECT_CALL, 1014 reject=True): 1015 """Wait for an incoming call on specific subscription and 1016 reject the call. 1017 1018 Args: 1019 log: log object. 1020 ad: android device object. 1021 sub_id: subscription ID 1022 incoming_number: Expected incoming number. 1023 Optional. Default is None 1024 delay_reject: time to wait before rejecting the call 1025 Optional. Default is WAIT_TIME_REJECT_CALL 1026 1027 Returns: 1028 True: if incoming call is received and reject successfully. 1029 False: for errors 1030 """ 1031 1032 if not wait_for_ringing_call_for_subscription(log, ad, sub_id, 1033 incoming_number): 1034 ad.log.error("Could not reject a call: phone never rang.") 1035 return False 1036 1037 ad.ed.clear_events(EventCallStateChanged) 1038 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1039 if reject is True: 1040 # Delay between ringing and reject. 1041 time.sleep(delay_reject) 1042 is_find = False 1043 # Loop the call list and find the matched one to disconnect. 1044 for call in ad.droid.telecomCallGetCallIds(): 1045 if check_phone_number_match( 1046 get_number_from_tel_uri(get_call_uri(ad, call)), 1047 incoming_number): 1048 ad.droid.telecomCallDisconnect(call) 1049 ad.log.info("Callee reject the call") 1050 is_find = True 1051 if is_find is False: 1052 ad.log.error("Callee did not find matching call to reject.") 1053 return False 1054 else: 1055 # don't reject on callee. Just ignore the incoming call. 1056 ad.log.info("Callee received incoming call. Ignore it.") 1057 try: 1058 ad.ed.wait_for_event( 1059 EventCallStateChanged, 1060 is_event_match_for_list, 1061 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 1062 field=CallStateContainer.CALL_STATE, 1063 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK]) 1064 except Empty: 1065 ad.log.error("No onCallStateChangedIdle event received.") 1066 return False 1067 finally: 1068 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 1069 return True 1070 1071 1072def hangup_call(log, ad): 1073 """Hang up ongoing active call. 1074 1075 Args: 1076 log: log object. 1077 ad: android device object. 1078 1079 Returns: 1080 True: if all calls are cleared 1081 False: for errors 1082 """ 1083 # short circuit in case no calls are active 1084 if not ad.droid.telecomIsInCall(): 1085 return True 1086 ad.ed.clear_events(EventCallStateChanged) 1087 ad.droid.telephonyStartTrackingCallState() 1088 ad.log.info("Hangup call.") 1089 ad.droid.telecomEndCall() 1090 1091 try: 1092 ad.ed.wait_for_event( 1093 EventCallStateChanged, 1094 is_event_match, 1095 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 1096 field=CallStateContainer.CALL_STATE, 1097 value=TELEPHONY_STATE_IDLE) 1098 except Empty: 1099 if ad.droid.telecomIsInCall(): 1100 log.error("Hangup call failed.") 1101 return False 1102 finally: 1103 ad.droid.telephonyStopTrackingCallStateChange() 1104 return not ad.droid.telecomIsInCall() 1105 1106 1107def disconnect_call_by_id(log, ad, call_id): 1108 """Disconnect call by call id. 1109 """ 1110 ad.droid.telecomCallDisconnect(call_id) 1111 return True 1112 1113 1114def _phone_number_remove_prefix(number): 1115 """Remove the country code and other prefix from the input phone number. 1116 Currently only handle phone number with the following formats: 1117 (US phone number format) 1118 +1abcxxxyyyy 1119 1abcxxxyyyy 1120 abcxxxyyyy 1121 abc xxx yyyy 1122 abc.xxx.yyyy 1123 abc-xxx-yyyy 1124 (EEUK phone number format) 1125 +44abcxxxyyyy 1126 0abcxxxyyyy 1127 1128 Args: 1129 number: input phone number 1130 1131 Returns: 1132 Phone number without country code or prefix 1133 """ 1134 if number is None: 1135 return None, None 1136 for country_code in COUNTRY_CODE_LIST: 1137 if number.startswith(country_code): 1138 return number[len(country_code):], country_code 1139 if number[0] == "1" or number[0] == "0": 1140 return number[1:], None 1141 return number, None 1142 1143 1144def check_phone_number_match(number1, number2): 1145 """Check whether two input phone numbers match or not. 1146 1147 Compare the two input phone numbers. 1148 If they match, return True; otherwise, return False. 1149 Currently only handle phone number with the following formats: 1150 (US phone number format) 1151 +1abcxxxyyyy 1152 1abcxxxyyyy 1153 abcxxxyyyy 1154 abc xxx yyyy 1155 abc.xxx.yyyy 1156 abc-xxx-yyyy 1157 (EEUK phone number format) 1158 +44abcxxxyyyy 1159 0abcxxxyyyy 1160 1161 There are some scenarios we can not verify, one example is: 1162 number1 = +15555555555, number2 = 5555555555 1163 (number2 have no country code) 1164 1165 Args: 1166 number1: 1st phone number to be compared. 1167 number2: 2nd phone number to be compared. 1168 1169 Returns: 1170 True if two phone numbers match. Otherwise False. 1171 """ 1172 number1 = phone_number_formatter(number1) 1173 number2 = phone_number_formatter(number2) 1174 # Handle extra country code attachment when matching phone number 1175 if number1[-7:] in number2 or number2[-7:] in number1: 1176 return True 1177 else: 1178 logging.info("phone number1 %s and number2 %s does not match" % 1179 (number1, number2)) 1180 return False 1181 1182 1183def initiate_call(log, 1184 ad, 1185 callee_number, 1186 emergency=False, 1187 timeout=MAX_WAIT_TIME_CALL_INITIATION, 1188 checking_interval=5, 1189 wait_time_betwn_call_initcheck=0): 1190 """Make phone call from caller to callee. 1191 1192 Args: 1193 ad_caller: Caller android device object. 1194 callee_number: Callee phone number. 1195 emergency : specify the call is emergency. 1196 Optional. Default value is False. 1197 1198 Returns: 1199 result: if phone call is placed successfully. 1200 """ 1201 ad.ed.clear_events(EventCallStateChanged) 1202 sub_id = get_outgoing_voice_sub_id(ad) 1203 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1204 1205 try: 1206 # Make a Call 1207 ad.log.info("Make a phone call to %s", callee_number) 1208 if emergency: 1209 ad.droid.telecomCallEmergencyNumber(callee_number) 1210 else: 1211 ad.droid.telecomCallNumber(callee_number) 1212 1213 # Sleep time for stress test b/64915613 1214 time.sleep(wait_time_betwn_call_initcheck) 1215 1216 # Verify OFFHOOK event 1217 checking_retries = int(timeout / checking_interval) 1218 for i in range(checking_retries): 1219 if (ad.droid.telecomIsInCall() and 1220 ad.droid.telephonyGetCallState() == TELEPHONY_STATE_OFFHOOK 1221 and ad.droid.telecomGetCallState() == 1222 TELEPHONY_STATE_OFFHOOK) or wait_for_call_offhook_event( 1223 log, ad, sub_id, True, checking_interval): 1224 return True 1225 ad.log.info( 1226 "Make call to %s fail. telecomIsInCall:%s, Telecom State:%s," 1227 " Telephony State:%s", callee_number, ad.droid.telecomIsInCall(), 1228 ad.droid.telephonyGetCallState(), ad.droid.telecomGetCallState()) 1229 reasons = ad.search_logcat( 1230 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause") 1231 if reasons: 1232 ad.log.info(reasons[-1]["log_message"]) 1233 return False 1234 finally: 1235 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 1236 1237 1238def dial_phone_number(ad, callee_number): 1239 for number in str(callee_number): 1240 if number == "#": 1241 ad.send_keycode("POUND") 1242 elif number == "*": 1243 ad.send_keycode("STAR") 1244 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]: 1245 ad.send_keycode("%s" % number) 1246 1247 1248def get_call_state_by_adb(ad): 1249 return ad.adb.shell("dumpsys telephony.registry | grep mCallState") 1250 1251 1252def check_call_state_connected_by_adb(ad): 1253 return "2" in get_call_state_by_adb(ad) 1254 1255 1256def check_call_state_idle_by_adb(ad): 1257 return "0" in get_call_state_by_adb(ad) 1258 1259 1260def check_call_state_ring_by_adb(ad): 1261 return "1" in get_call_state_by_adb(ad) 1262 1263 1264def get_incoming_call_number_by_adb(ad): 1265 output = ad.adb.shell( 1266 "dumpsys telephony.registry | grep mCallIncomingNumber") 1267 return re.search(r"mCallIncomingNumber=(.*)", output).group(1) 1268 1269 1270def emergency_dialer_call_by_keyevent(ad, callee_number): 1271 for i in range(3): 1272 if "EmergencyDialer" in ad.get_my_current_focus_window(): 1273 ad.log.info("EmergencyDialer is the current focus window") 1274 break 1275 elif i <= 2: 1276 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 1277 time.sleep(1) 1278 else: 1279 ad.log.error("Unable to bring up EmergencyDialer") 1280 return False 1281 ad.log.info("Make a phone call to %s", callee_number) 1282 dial_phone_number(ad, callee_number) 1283 ad.send_keycode("CALL") 1284 1285 1286def initiate_emergency_dialer_call_by_adb( 1287 log, 1288 ad, 1289 callee_number, 1290 timeout=MAX_WAIT_TIME_CALL_INITIATION, 1291 checking_interval=5): 1292 """Make emergency call by EmergencyDialer. 1293 1294 Args: 1295 ad: Caller android device object. 1296 callee_number: Callee phone number. 1297 emergency : specify the call is emergency. 1298 Optional. Default value is False. 1299 1300 Returns: 1301 result: if phone call is placed successfully. 1302 """ 1303 try: 1304 # Make a Call 1305 ad.wakeup_screen() 1306 ad.send_keycode("MENU") 1307 ad.log.info("Call %s", callee_number) 1308 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 1309 ad.adb.shell( 1310 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" % 1311 callee_number) 1312 ad.log.info("Check call state") 1313 # Verify Call State 1314 elapsed_time = 0 1315 while elapsed_time < timeout: 1316 time.sleep(checking_interval) 1317 elapsed_time += checking_interval 1318 if check_call_state_connected_by_adb(ad): 1319 ad.log.info("Call to %s is connected", callee_number) 1320 return True 1321 if check_call_state_idle_by_adb(ad): 1322 ad.log.info("Call to %s failed", callee_number) 1323 return False 1324 ad.log.info("Make call to %s failed", callee_number) 1325 return False 1326 except Exception as e: 1327 ad.log.error("initiate emergency call failed with error %s", e) 1328 1329 1330def hangup_call_by_adb(ad): 1331 """Make emergency call by EmergencyDialer. 1332 1333 Args: 1334 ad: Caller android device object. 1335 callee_number: Callee phone number. 1336 """ 1337 ad.log.info("End call by adb") 1338 ad.send_keycode("ENDCALL") 1339 1340 1341def dumpsys_telecom_call_info(ad): 1342 """ Get call information by dumpsys telecom. """ 1343 output = ad.adb.shell("dumpsys telecom") 1344 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL) 1345 calls_info = [] 1346 for call in calls: 1347 call_info = {} 1348 for attr in ("startTime", "endTime", "direction", "isInterrupted", 1349 "callTechnologies", "callTerminationsReason", 1350 "connectionService", "isVedeoCall", "callProperties"): 1351 match = re.search(r"%s: (.*)" % attr, call) 1352 if match: 1353 call_info[attr] = match.group(1) 1354 call_info["inCallServices"] = re.findall(r"name: (.*)", call) 1355 calls_info.append(call_info) 1356 ad.log.debug("calls_info = %s", calls_info) 1357 return calls_info 1358 1359 1360def call_reject(log, ad_caller, ad_callee, reject=True): 1361 """Caller call Callee, then reject on callee. 1362 1363 1364 """ 1365 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId() 1366 subid_callee = ad_callee.incoming_voice_sub_id 1367 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller, 1368 subid_callee) 1369 return call_reject_for_subscription(log, ad_caller, ad_callee, 1370 subid_caller, subid_callee, reject) 1371 1372 1373def call_reject_for_subscription(log, 1374 ad_caller, 1375 ad_callee, 1376 subid_caller, 1377 subid_callee, 1378 reject=True): 1379 """ 1380 """ 1381 1382 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 1383 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 1384 1385 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 1386 try: 1387 if not initiate_call(log, ad_caller, callee_number): 1388 raise _CallSequenceException("Initiate call failed.") 1389 1390 if not wait_and_reject_call_for_subscription( 1391 log, ad_callee, subid_callee, caller_number, 1392 WAIT_TIME_REJECT_CALL, reject): 1393 raise _CallSequenceException("Reject call fail.") 1394 # Check if incoming call is cleared on callee or not. 1395 if ad_callee.droid.telephonyGetCallStateForSubscription( 1396 subid_callee) == TELEPHONY_STATE_RINGING: 1397 raise _CallSequenceException("Incoming call is not cleared.") 1398 # Hangup on caller 1399 hangup_call(log, ad_caller) 1400 except _CallSequenceException as e: 1401 log.error(e) 1402 return False 1403 return True 1404 1405 1406def call_reject_leave_message(log, 1407 ad_caller, 1408 ad_callee, 1409 verify_caller_func=None, 1410 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 1411 """On default voice subscription, Call from caller to callee, 1412 reject on callee, caller leave a voice mail. 1413 1414 1. Caller call Callee. 1415 2. Callee reject incoming call. 1416 3. Caller leave a voice mail. 1417 4. Verify callee received the voice mail notification. 1418 1419 Args: 1420 ad_caller: caller android device object. 1421 ad_callee: callee android device object. 1422 verify_caller_func: function to verify caller is in correct state while in-call. 1423 This is optional, default is None. 1424 wait_time_in_call: time to wait when leaving a voice mail. 1425 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 1426 1427 Returns: 1428 True: if voice message is received on callee successfully. 1429 False: for errors 1430 """ 1431 subid_caller = get_outgoing_voice_sub_id(ad_caller) 1432 subid_callee = get_incoming_voice_sub_id(ad_callee) 1433 return call_reject_leave_message_for_subscription( 1434 log, ad_caller, ad_callee, subid_caller, subid_callee, 1435 verify_caller_func, wait_time_in_call) 1436 1437 1438def call_reject_leave_message_for_subscription( 1439 log, 1440 ad_caller, 1441 ad_callee, 1442 subid_caller, 1443 subid_callee, 1444 verify_caller_func=None, 1445 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 1446 """On specific voice subscription, Call from caller to callee, 1447 reject on callee, caller leave a voice mail. 1448 1449 1. Caller call Callee. 1450 2. Callee reject incoming call. 1451 3. Caller leave a voice mail. 1452 4. Verify callee received the voice mail notification. 1453 1454 Args: 1455 ad_caller: caller android device object. 1456 ad_callee: callee android device object. 1457 subid_caller: caller's subscription id. 1458 subid_callee: callee's subscription id. 1459 verify_caller_func: function to verify caller is in correct state while in-call. 1460 This is optional, default is None. 1461 wait_time_in_call: time to wait when leaving a voice mail. 1462 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 1463 1464 Returns: 1465 True: if voice message is received on callee successfully. 1466 False: for errors 1467 """ 1468 1469 # Currently this test utility only works for TMO and ATT and SPT. 1470 # It does not work for VZW (see b/21559800) 1471 # "with VVM TelephonyManager APIs won't work for vm" 1472 1473 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 1474 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 1475 1476 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 1477 1478 try: 1479 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 1480 subid_callee) 1481 ad_callee.log.info("voice mail count is %s", voice_mail_count_before) 1482 # -1 means there are unread voice mail, but the count is unknown 1483 # 0 means either this API not working (VZW) or no unread voice mail. 1484 if voice_mail_count_before != 0: 1485 log.warning("--Pending new Voice Mail, please clear on phone.--") 1486 1487 if not initiate_call(log, ad_caller, callee_number): 1488 raise _CallSequenceException("Initiate call failed.") 1489 1490 if not wait_and_reject_call_for_subscription( 1491 log, ad_callee, subid_callee, incoming_number=caller_number): 1492 raise _CallSequenceException("Reject call fail.") 1493 1494 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription( 1495 subid_callee) 1496 1497 # ensure that all internal states are updated in telecom 1498 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 1499 ad_callee.ed.ad.ed.clear_events(EventCallStateChanged) 1500 1501 if verify_caller_func and not verify_caller_func(log, ad_caller): 1502 raise _CallSequenceException("Caller not in correct state!") 1503 1504 # TODO: b/26293512 Need to play some sound to leave message. 1505 # Otherwise carrier voice mail server may drop this voice mail. 1506 time.sleep(wait_time_in_call) 1507 1508 if not verify_caller_func: 1509 caller_state_result = ad_caller.droid.telecomIsInCall() 1510 else: 1511 caller_state_result = verify_caller_func(log, ad_caller) 1512 if not caller_state_result: 1513 raise _CallSequenceException( 1514 "Caller %s not in correct state after %s seconds" % 1515 (ad_caller.serial, wait_time_in_call)) 1516 1517 if not hangup_call(log, ad_caller): 1518 raise _CallSequenceException("Error in Hanging-Up Call") 1519 1520 log.info("Wait for voice mail indicator on callee.") 1521 try: 1522 event = ad_callee.ed.wait_for_event( 1523 EventMessageWaitingIndicatorChanged, 1524 _is_on_message_waiting_event_true) 1525 log.info(event) 1526 except Empty: 1527 ad_callee.log.warning("No expected event %s", 1528 EventMessageWaitingIndicatorChanged) 1529 raise _CallSequenceException("No expected event {}.".format( 1530 EventMessageWaitingIndicatorChanged)) 1531 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 1532 subid_callee) 1533 ad_callee.log.info( 1534 "telephonyGetVoiceMailCount output - before: %s, after: %s", 1535 voice_mail_count_before, voice_mail_count_after) 1536 1537 # voice_mail_count_after should: 1538 # either equals to (voice_mail_count_before + 1) [For ATT and SPT] 1539 # or equals to -1 [For TMO] 1540 # -1 means there are unread voice mail, but the count is unknown 1541 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before, 1542 voice_mail_count_after): 1543 log.error("before and after voice mail count is not incorrect.") 1544 return False 1545 1546 except _CallSequenceException as e: 1547 log.error(e) 1548 return False 1549 finally: 1550 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription( 1551 subid_callee) 1552 return True 1553 1554 1555def call_voicemail_erase_all_pending_voicemail(log, ad): 1556 """Script for phone to erase all pending voice mail. 1557 This script only works for TMO and ATT and SPT currently. 1558 This script only works if phone have already set up voice mail options, 1559 and phone should disable password protection for voice mail. 1560 1561 1. If phone don't have pending voice message, return True. 1562 2. Dial voice mail number. 1563 For TMO, the number is '123' 1564 For ATT, the number is phone's number 1565 For SPT, the number is phone's number 1566 3. Wait for voice mail connection setup. 1567 4. Wait for voice mail play pending voice message. 1568 5. Send DTMF to delete one message. 1569 The digit is '7'. 1570 6. Repeat steps 4 and 5 until voice mail server drop this call. 1571 (No pending message) 1572 6. Check telephonyGetVoiceMailCount result. it should be 0. 1573 1574 Args: 1575 log: log object 1576 ad: android device object 1577 Returns: 1578 False if error happens. True is succeed. 1579 """ 1580 log.info("Erase all pending voice mail.") 1581 count = ad.droid.telephonyGetVoiceMailCount() 1582 if count == 0: 1583 ad.log.info("No Pending voice mail.") 1584 return True 1585 if count == -1: 1586 ad.log.info("There is pending voice mail, but the count is unknown") 1587 count = MAX_SAVED_VOICE_MAIL 1588 else: 1589 ad.log.info("There are %s voicemails", count) 1590 1591 voice_mail_number = get_voice_mail_number(log, ad) 1592 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad)) 1593 if not initiate_call(log, ad, voice_mail_number): 1594 log.error("Initiate call to voice mail failed.") 1595 return False 1596 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1597 callId = ad.droid.telecomCallGetCallIds()[0] 1598 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1599 while (is_phone_in_call(log, ad) and (count > 0)): 1600 ad.log.info("Press %s to delete voice mail.", delete_digit) 1601 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit) 1602 ad.droid.telecomCallStopDtmfTone(callId) 1603 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 1604 count -= 1 1605 if is_phone_in_call(log, ad): 1606 hangup_call(log, ad) 1607 1608 # wait for telephonyGetVoiceMailCount to update correct result 1609 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT 1610 while ((remaining_time > 0) 1611 and (ad.droid.telephonyGetVoiceMailCount() != 0)): 1612 time.sleep(1) 1613 remaining_time -= 1 1614 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount() 1615 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count) 1616 return (current_voice_mail_count == 0) 1617 1618 1619def _is_on_message_waiting_event_true(event): 1620 """Private function to return if the received EventMessageWaitingIndicatorChanged 1621 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True. 1622 """ 1623 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING] 1624 1625 1626def call_setup_teardown(log, 1627 ad_caller, 1628 ad_callee, 1629 ad_hangup=None, 1630 verify_caller_func=None, 1631 verify_callee_func=None, 1632 wait_time_in_call=WAIT_TIME_IN_CALL, 1633 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 1634 extra_sleep=0): 1635 """ Call process, including make a phone call from caller, 1636 accept from callee, and hang up. The call is on default voice subscription 1637 1638 In call process, call from <droid_caller> to <droid_callee>, 1639 accept the call, (optional)then hang up from <droid_hangup>. 1640 1641 Args: 1642 ad_caller: Caller Android Device Object. 1643 ad_callee: Callee Android Device Object. 1644 ad_hangup: Android Device Object end the phone call. 1645 Optional. Default value is None, and phone call will continue. 1646 verify_call_mode_caller: func_ptr to verify caller in correct mode 1647 Optional. Default is None 1648 verify_call_mode_caller: func_ptr to verify caller in correct mode 1649 Optional. Default is None 1650 incall_ui_display: after answer the call, bring in-call UI to foreground or 1651 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1652 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1653 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1654 else, do nothing. 1655 extra_sleep: for stress test only - b/64915613 1656 1657 Returns: 1658 True if call process without any error. 1659 False if error happened. 1660 1661 """ 1662 subid_caller = get_outgoing_voice_sub_id(ad_caller) 1663 subid_callee = get_incoming_voice_sub_id(ad_callee) 1664 return call_setup_teardown_for_subscription( 1665 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup, 1666 verify_caller_func, verify_callee_func, wait_time_in_call, 1667 incall_ui_display, extra_sleep) 1668 1669 1670def call_setup_teardown_for_subscription( 1671 log, 1672 ad_caller, 1673 ad_callee, 1674 subid_caller, 1675 subid_callee, 1676 ad_hangup=None, 1677 verify_caller_func=None, 1678 verify_callee_func=None, 1679 wait_time_in_call=WAIT_TIME_IN_CALL, 1680 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 1681 extra_sleep=0): 1682 """ Call process, including make a phone call from caller, 1683 accept from callee, and hang up. The call is on specified subscription 1684 1685 In call process, call from <droid_caller> to <droid_callee>, 1686 accept the call, (optional)then hang up from <droid_hangup>. 1687 1688 Args: 1689 ad_caller: Caller Android Device Object. 1690 ad_callee: Callee Android Device Object. 1691 subid_caller: Caller subscription ID 1692 subid_callee: Callee subscription ID 1693 ad_hangup: Android Device Object end the phone call. 1694 Optional. Default value is None, and phone call will continue. 1695 verify_call_mode_caller: func_ptr to verify caller in correct mode 1696 Optional. Default is None 1697 verify_call_mode_caller: func_ptr to verify caller in correct mode 1698 Optional. Default is None 1699 incall_ui_display: after answer the call, bring in-call UI to foreground or 1700 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1701 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1702 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1703 else, do nothing. 1704 extra_sleep: for stress test only - b/64915613 1705 1706 Returns: 1707 True if call process without any error. 1708 False if error happened. 1709 1710 """ 1711 CHECK_INTERVAL = 5 1712 begin_time = get_current_epoch_time() 1713 1714 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num'] 1715 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num'] 1716 1717 if not verify_caller_func: 1718 verify_caller_func = is_phone_in_call 1719 if not verify_callee_func: 1720 verify_callee_func = is_phone_in_call 1721 result = True 1722 msg = "Call from %s to %s" % (caller_number, callee_number) 1723 if ad_hangup: 1724 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call) 1725 ad_caller.log.info(msg) 1726 1727 for ad in (ad_caller, ad_callee): 1728 call_ids = ad.droid.telecomCallGetCallIds() 1729 setattr(ad, "call_ids", call_ids) 1730 ad.log.info("Before making call, existing phone calls %s", call_ids) 1731 try: 1732 if not initiate_call( 1733 log, 1734 ad_caller, 1735 callee_number, 1736 wait_time_betwn_call_initcheck=extra_sleep): 1737 ad_caller.log.error("Initiate call failed.") 1738 return False 1739 else: 1740 ad_caller.log.info("Caller initate call successfully") 1741 if not wait_and_answer_call_for_subscription( 1742 log, 1743 ad_callee, 1744 subid_callee, 1745 incoming_number=caller_number, 1746 caller=ad_caller, 1747 incall_ui_display=incall_ui_display): 1748 ad_callee.log.error("Answer call fail.") 1749 return False 1750 else: 1751 ad_callee.log.info("Callee answered the call successfully") 1752 1753 for ad in (ad_caller, ad_callee): 1754 call_ids = ad.droid.telecomCallGetCallIds() 1755 new_call_id = list(set(call_ids) - set(ad.call_ids))[0] 1756 if not wait_for_in_call_active(ad, call_id=new_call_id): 1757 result = False 1758 if not ad.droid.telecomCallGetAudioState(): 1759 ad.log.error("Audio is not in call state") 1760 result = False 1761 1762 elapsed_time = 0 1763 while (elapsed_time < wait_time_in_call): 1764 CHECK_INTERVAL = min(CHECK_INTERVAL, 1765 wait_time_in_call - elapsed_time) 1766 time.sleep(CHECK_INTERVAL) 1767 elapsed_time += CHECK_INTERVAL 1768 time_message = "at <%s>/<%s> second." % (elapsed_time, 1769 wait_time_in_call) 1770 for ad, call_func in [(ad_caller, verify_caller_func), 1771 (ad_callee, verify_callee_func)]: 1772 if not call_func(log, ad): 1773 ad.log.error("NOT in correct %s state at %s", 1774 call_func.__name__, time_message) 1775 result = False 1776 else: 1777 ad.log.info("In correct %s state at %s", 1778 call_func.__name__, time_message) 1779 if not ad.droid.telecomCallGetAudioState(): 1780 ad.log.error("Audio is not in call state at %s", 1781 time_message) 1782 result = False 1783 if not result: 1784 break 1785 if ad_hangup and not hangup_call(log, ad_hangup): 1786 ad_hangup.log.info("Failed to hang up the call") 1787 result = False 1788 return result 1789 finally: 1790 if not result: 1791 for ad in [ad_caller, ad_callee]: 1792 reasons = ad.search_logcat( 1793 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", 1794 begin_time) 1795 if reasons: 1796 ad.log.info(reasons[-1]["log_message"]) 1797 try: 1798 if ad.droid.telecomIsInCall(): 1799 ad.droid.telecomEndCall() 1800 except Exception as e: 1801 log.error(str(e)) 1802 1803 1804def phone_number_formatter(input_string, formatter=None): 1805 """Get expected format of input phone number string. 1806 1807 Args: 1808 input_string: (string) input phone number. 1809 The input could be 10/11/12 digital, with or without " "/"-"/"." 1810 formatter: (int) expected format, this could be 7/10/11/12 1811 if formatter is 7: output string would be 7 digital number. 1812 if formatter is 10: output string would be 10 digital (standard) number. 1813 if formatter is 11: output string would be "1" + 10 digital number. 1814 if formatter is 12: output string would be "+1" + 10 digital number. 1815 1816 Returns: 1817 If no error happen, return phone number in expected format. 1818 Else, return None. 1819 """ 1820 if not input_string: 1821 return "" 1822 # make sure input_string is 10 digital 1823 # Remove white spaces, dashes, dots 1824 input_string = input_string.replace(" ", "").replace("-", "").replace( 1825 ".", "").lstrip("0") 1826 if not formatter: 1827 return input_string 1828 # Remove "1" or "+1"from front 1829 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT 1830 and input_string[0] == "1"): 1831 input_string = input_string[1:] 1832 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT 1833 and input_string[0:2] == "+1"): 1834 input_string = input_string[2:] 1835 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT 1836 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT): 1837 return input_string 1838 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1839 return None 1840 # change input_string according to format 1841 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT: 1842 input_string = "+1" + input_string 1843 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT: 1844 input_string = "1" + input_string 1845 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1846 input_string = input_string 1847 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT: 1848 input_string = input_string[3:] 1849 else: 1850 return None 1851 return input_string 1852 1853 1854def get_internet_connection_type(log, ad): 1855 """Get current active connection type name. 1856 1857 Args: 1858 log: Log object. 1859 ad: Android Device Object. 1860 Returns: 1861 current active connection type name. 1862 """ 1863 if not ad.droid.connectivityNetworkIsConnected(): 1864 return 'none' 1865 return connection_type_from_type_string( 1866 ad.droid.connectivityNetworkGetActiveConnectionTypeName()) 1867 1868 1869def verify_http_connection(log, 1870 ad, 1871 url="www.google.com", 1872 retry=5, 1873 retry_interval=15, 1874 expected_state=True): 1875 """Make ping request and return status. 1876 1877 Args: 1878 log: log object 1879 ad: Android Device Object. 1880 url: Optional. The ping request will be made to this URL. 1881 Default Value is "http://www.google.com/". 1882 1883 """ 1884 for i in range(0, retry + 1): 1885 # b/18899134 httpPing will hang 1886 #try: 1887 # http_response = ad.droid.httpPing(url) 1888 #except: 1889 # http_response = None 1890 # If httpPing failed, it may return {} (if phone just turn off APM) or 1891 # None (regular fail) 1892 state = ad.droid.pingHost(url) 1893 ad.log.info("Connection to %s is %s", url, state) 1894 if expected_state == state: 1895 ad.log.info("Verify Internet connection state is %s succeeded", 1896 str(expected_state)) 1897 return True 1898 if i < retry: 1899 ad.log.info( 1900 "Verify Internet connection state=%s failed. Try again", 1901 str(expected_state)) 1902 time.sleep(retry_interval) 1903 ad.log.info("Verify Internet state=%s failed after %s second", 1904 expected_state, i * retry_interval) 1905 return False 1906 1907 1908def _generate_file_directory_and_file_name(url, out_path): 1909 file_name = url.split("/")[-1] 1910 if not out_path: 1911 file_directory = "/sdcard/Download/" 1912 elif not out_path.endswith("/"): 1913 file_directory, file_name = os.path.split(out_path) 1914 else: 1915 file_directory = out_path 1916 return file_directory, file_name 1917 1918 1919def _check_file_existance(ad, file_path, expected_file_size=None): 1920 """Check file existance by file_path. If expected_file_size 1921 is provided, then also check if the file meet the file size requirement. 1922 """ 1923 out = None 1924 try: 1925 out = ad.adb.shell('stat -c "%%s" %s' % file_path) 1926 except AdbError: 1927 pass 1928 # Handle some old version adb returns error message "No such" into std_out 1929 if out and "No such" not in out: 1930 if expected_file_size: 1931 file_size = int(out) 1932 if file_size >= expected_file_size: 1933 ad.log.info("File %s of size %s exists", file_path, file_size) 1934 return True 1935 else: 1936 ad.log.info("File %s is of size %s, does not meet expected %s", 1937 file_path, file_size, expected_file_size) 1938 return False 1939 else: 1940 ad.log.info("File %s exists", file_path) 1941 return True 1942 else: 1943 ad.log.info("File %s does not exist.", file_path) 1944 return False 1945 1946 1947def check_curl_availability(ad): 1948 if not hasattr(ad, "curl_capable"): 1949 try: 1950 out = ad.adb.shell("/data/curl --version") 1951 if not out or "not found" in out: 1952 setattr(ad, "curl_capable", False) 1953 ad.log.info("curl is unavailable, use chrome to download file") 1954 else: 1955 setattr(ad, "curl_capable", True) 1956 except Exception: 1957 setattr(ad, "curl_capable", False) 1958 ad.log.info("curl is unavailable, use chrome to download file") 1959 return ad.curl_capable 1960 1961 1962def active_file_download_task(log, ad, file_name="5MB", method="chrome"): 1963 # files available for download on the same website: 1964 # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip 1965 # download file by adb command, as phone call will use sl4a 1966 file_map_dict = { 1967 '5MB': 5000000, 1968 '10MB': 10000000, 1969 '20MB': 20000000, 1970 '50MB': 50000000, 1971 '100MB': 100000000, 1972 '200MB': 200000000, 1973 '512MB': 512000000 1974 } 1975 file_size = file_map_dict.get(file_name) 1976 if not file_size: 1977 log.warning("file_name %s for download is not available", file_name) 1978 return False 1979 timeout = min(max(file_size / 100000, 600), 3600) 1980 output_path = "/sdcard/Download/" + file_name + ".zip" 1981 url = "http://ipv4.download.thinkbroadband.com/" + file_name + ".zip" 1982 if method == "sl4a": 1983 return (http_file_download_by_sl4a, (ad, url, output_path, file_size, 1984 True, timeout)) 1985 if method == "curl" and check_curl_availability(ad): 1986 url = "http://146.148.91.8/download/" + file_name + ".zip" 1987 return (http_file_download_by_curl, (ad, url, output_path, file_size, 1988 True, timeout)) 1989 elif method == "sl4a": 1990 return (http_file_download_by_sl4a, (ad, url, output_path, file_size, 1991 True, timeout)) 1992 else: 1993 return (http_file_download_by_chrome, (ad, url, file_size, True, 1994 timeout)) 1995 1996 1997def active_file_download_test(log, ad, file_name="5MB", method="chrome"): 1998 task = active_file_download_task(log, ad, file_name, method=method) 1999 return task[0](*task[1]) 2000 2001 2002def verify_internet_connection(log, ad, retries=1): 2003 """Verify internet connection by ping test. 2004 2005 Args: 2006 log: log object 2007 ad: Android Device Object. 2008 2009 """ 2010 for i in range(retries): 2011 ad.log.info("Verify internet connection - attempt %d", i + 1) 2012 dest_to_ping = ["www.google.com", "www.amazon.com", "54.230.144.105"] 2013 for dest in dest_to_ping: 2014 result = adb_shell_ping( 2015 ad, count=5, timeout=60, loss_tolerance=40, dest_ip=dest) 2016 if result: 2017 return True 2018 return False 2019 2020 2021def iperf_test_by_adb(log, 2022 ad, 2023 iperf_server, 2024 port_num=None, 2025 reverse=False, 2026 timeout=180, 2027 limit_rate=None, 2028 omit=10, 2029 ipv6=False, 2030 rate_dict=None, 2031 blocking=True, 2032 log_file_path=None): 2033 """Iperf test by adb. 2034 2035 Args: 2036 log: log object 2037 ad: Android Device Object. 2038 iperf_Server: The iperf host url". 2039 port_num: TCP/UDP server port 2040 timeout: timeout for file download to complete. 2041 limit_rate: iperf bandwidth option. None by default 2042 omit: the omit option provided in iperf command. 2043 """ 2044 iperf_option = "-t %s -O %s -J" % (timeout, omit) 2045 if limit_rate: iperf_option += " -b %s" % limit_rate 2046 if port_num: iperf_option += " -p %s" % port_num 2047 if ipv6: iperf_option += " -6" 2048 if reverse: iperf_option += " -R" 2049 try: 2050 if log_file_path: 2051 ad.adb.shell("rm %s" % log_file_path, ignore_status=True) 2052 ad.log.info("Running adb iperf test with server %s", iperf_server) 2053 if not blocking: 2054 ad.run_iperf_client_nb( 2055 iperf_server, 2056 iperf_option, 2057 timeout=timeout + 60, 2058 log_file_path=log_file_path) 2059 return True 2060 result, data = ad.run_iperf_client( 2061 iperf_server, iperf_option, timeout=timeout + 60) 2062 ad.log.info("Iperf test result with server %s is %s", iperf_server, 2063 result) 2064 if result: 2065 data_json = json.loads(''.join(data)) 2066 tx_rate = data_json['end']['sum_sent']['bits_per_second'] 2067 rx_rate = data_json['end']['sum_received']['bits_per_second'] 2068 ad.log.info( 2069 'iPerf3 upload speed is %sbps, download speed is %sbps', 2070 tx_rate, rx_rate) 2071 if rate_dict is not None: 2072 rate_dict["Uplink"] = tx_rate 2073 rate_dict["Downlink"] = rx_rate 2074 return result 2075 except Exception as e: 2076 ad.log.warning("Fail to run iperf test with exception %s", e) 2077 return False 2078 2079 2080def http_file_download_by_curl(ad, 2081 url, 2082 out_path=None, 2083 expected_file_size=None, 2084 remove_file_after_check=True, 2085 timeout=3600, 2086 limit_rate=None, 2087 retry=3): 2088 """Download http file by adb curl. 2089 2090 Args: 2091 ad: Android Device Object. 2092 url: The url that file to be downloaded from". 2093 out_path: Optional. Where to download file to. 2094 out_path is /sdcard/Download/ by default. 2095 expected_file_size: Optional. Provided if checking the download file meet 2096 expected file size in unit of byte. 2097 remove_file_after_check: Whether to remove the downloaded file after 2098 check. 2099 timeout: timeout for file download to complete. 2100 limit_rate: download rate in bps. None, if do not apply rate limit. 2101 retry: the retry request times provided in curl command. 2102 """ 2103 file_directory, file_name = _generate_file_directory_and_file_name( 2104 url, out_path) 2105 file_path = os.path.join(file_directory, file_name) 2106 curl_cmd = "/data/curl" 2107 if limit_rate: 2108 curl_cmd += " --limit-rate %s" % limit_rate 2109 if retry: 2110 curl_cmd += " --retry %s" % retry 2111 curl_cmd += " --url %s > %s" % (url, file_path) 2112 accounting_apk = "com.android.server.telecom" #"com.quicinc.cne.CNEService" 2113 result = True 2114 try: 2115 data_accounting = { 2116 "mobile_rx_bytes": 2117 ad.droid.getMobileRxBytes(), 2118 "subscriber_mobile_data_usage": 2119 get_mobile_data_usage(ad, None, None), 2120 "curl_mobile_data_usage": 2121 get_mobile_data_usage(ad, None, accounting_apk) 2122 } 2123 ad.log.info("Before downloading: %s", data_accounting) 2124 ad.log.info("Download %s to %s by adb shell command %s", url, 2125 file_path, curl_cmd) 2126 ad.adb.shell(curl_cmd, timeout=timeout) 2127 if _check_file_existance(ad, file_path, expected_file_size): 2128 ad.log.info("%s is downloaded to %s successfully", url, file_path) 2129 new_data_accounting = { 2130 "mobile_rx_bytes": 2131 ad.droid.getMobileRxBytes(), 2132 "subscriber_mobile_data_usage": 2133 get_mobile_data_usage(ad, None, None), 2134 "curl_mobile_data_usage": 2135 get_mobile_data_usage(ad, None, accounting_apk) 2136 } 2137 ad.log.info("After downloading: %s", new_data_accounting) 2138 accounting_diff = { 2139 key: value - data_accounting[key] 2140 for key, value in new_data_accounting.items() 2141 } 2142 ad.log.info("Data accounting difference: %s", accounting_diff) 2143 if getattr(ad, "on_mobile_data", False): 2144 for key, value in accounting_diff.items(): 2145 if value < expected_file_size: 2146 ad.log.warning("%s diff is %s less than %s", key, 2147 value, expected_file_size) 2148 ad.data_accounting["%s_failure" % key] += 1 2149 else: 2150 for key, value in accounting_diff.items(): 2151 if value >= expected_file_size: 2152 ad.log.error("%s diff is %s. File download is " 2153 "consuming mobile data", key, value) 2154 result = False 2155 ad.log.info("data_accounting_failure: %s", dict( 2156 ad.data_accounting)) 2157 return result 2158 else: 2159 ad.log.warning("Fail to download %s", url) 2160 return False 2161 except Exception as e: 2162 ad.log.warning("Download %s failed with exception %s", url, e) 2163 return False 2164 finally: 2165 if remove_file_after_check: 2166 ad.log.info("Remove the downloaded file %s", file_path) 2167 ad.adb.shell("rm %s" % file_path, ignore_status=True) 2168 2169 2170def open_url_by_adb(ad, url): 2171 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url) 2172 2173 2174def http_file_download_by_chrome(ad, 2175 url, 2176 expected_file_size=None, 2177 remove_file_after_check=True, 2178 timeout=3600): 2179 """Download http file by chrome. 2180 2181 Args: 2182 ad: Android Device Object. 2183 url: The url that file to be downloaded from". 2184 expected_file_size: Optional. Provided if checking the download file meet 2185 expected file size in unit of byte. 2186 remove_file_after_check: Whether to remove the downloaded file after 2187 check. 2188 timeout: timeout for file download to complete. 2189 """ 2190 chrome_apk = "com.android.chrome" 2191 file_directory, file_name = _generate_file_directory_and_file_name( 2192 url, "/sdcard/Download/") 2193 file_path = os.path.join(file_directory, file_name) 2194 # Remove pre-existing file 2195 ad.force_stop_apk(chrome_apk) 2196 file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name) 2197 ad.adb.shell("rm -f %s" % file_to_be_delete) 2198 ad.adb.shell("rm -rf /sdcard/Download/.*") 2199 ad.adb.shell("rm -f /sdcard/Download/.*") 2200 data_accounting = { 2201 "total_rx_bytes": ad.droid.getTotalRxBytes(), 2202 "mobile_rx_bytes": ad.droid.getMobileRxBytes(), 2203 "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None), 2204 "chrome_mobile_data_usage": get_mobile_data_usage( 2205 ad, None, chrome_apk) 2206 } 2207 ad.log.info("Before downloading: %s", data_accounting) 2208 ad.ensure_screen_on() 2209 ad.log.info("Download %s with timeout %s", url, timeout) 2210 open_url_by_adb(ad, url) 2211 elapse_time = 0 2212 result = True 2213 while elapse_time < timeout: 2214 time.sleep(30) 2215 if _check_file_existance(ad, file_path, expected_file_size): 2216 ad.log.info("%s is downloaded successfully", url) 2217 if remove_file_after_check: 2218 ad.log.info("Remove the downloaded file %s", file_path) 2219 ad.adb.shell("rm -f %s" % file_to_be_delete) 2220 ad.adb.shell("rm -rf /sdcard/Download/.*") 2221 ad.adb.shell("rm -f /sdcard/Download/.*") 2222 #time.sleep(30) 2223 new_data_accounting = { 2224 "mobile_rx_bytes": 2225 ad.droid.getMobileRxBytes(), 2226 "subscriber_mobile_data_usage": 2227 get_mobile_data_usage(ad, None, None), 2228 "chrome_mobile_data_usage": 2229 get_mobile_data_usage(ad, None, chrome_apk) 2230 } 2231 ad.log.info("After downloading: %s", new_data_accounting) 2232 accounting_diff = { 2233 key: value - data_accounting[key] 2234 for key, value in new_data_accounting.items() 2235 } 2236 ad.log.info("Data accounting difference: %s", accounting_diff) 2237 if getattr(ad, "on_mobile_data", False): 2238 for key, value in accounting_diff.items(): 2239 if value < expected_file_size: 2240 ad.log.warning("%s diff is %s less than %s", key, 2241 value, expected_file_size) 2242 ad.data_accounting["%s_failure" % key] += 1 2243 else: 2244 for key, value in accounting_diff.items(): 2245 if value >= expected_file_size: 2246 ad.log.error("%s diff is %s. File download is " 2247 "consuming mobile data", key, value) 2248 result = False 2249 return result 2250 elif _check_file_existance(ad, "%s.crdownload" % file_path): 2251 ad.log.info("Chrome is downloading %s", url) 2252 elif elapse_time < 60: 2253 # download not started, retry download wit chrome again 2254 open_url_by_adb(ad, url) 2255 else: 2256 ad.log.error("Unable to download file from %s", url) 2257 break 2258 elapse_time += 30 2259 ad.log.warning("Fail to download file from %s", url) 2260 ad.force_stop_apk("com.android.chrome") 2261 ad.adb.shell("rm -f %s" % file_to_be_delete) 2262 ad.adb.shell("rm -rf /sdcard/Download/.*") 2263 ad.adb.shell("rm -f /sdcard/Download/.*") 2264 return False 2265 2266 2267def http_file_download_by_sl4a(ad, 2268 url, 2269 out_path=None, 2270 expected_file_size=None, 2271 remove_file_after_check=True, 2272 timeout=300): 2273 """Download http file by sl4a RPC call. 2274 2275 Args: 2276 ad: Android Device Object. 2277 url: The url that file to be downloaded from". 2278 out_path: Optional. Where to download file to. 2279 out_path is /sdcard/Download/ by default. 2280 expected_file_size: Optional. Provided if checking the download file meet 2281 expected file size in unit of byte. 2282 remove_file_after_check: Whether to remove the downloaded file after 2283 check. 2284 timeout: timeout for file download to complete. 2285 """ 2286 file_folder, file_name = _generate_file_directory_and_file_name( 2287 url, out_path) 2288 file_path = os.path.join(file_folder, file_name) 2289 ad.adb.shell("rm -f %s" % file_path) 2290 accounting_apk = SL4A_APK_NAME 2291 result = True 2292 try: 2293 if not getattr(ad, "downloading_droid", None): 2294 ad.downloading_droid, ad.downloading_ed = ad.get_droid() 2295 ad.downloading_ed.start() 2296 else: 2297 try: 2298 if not ad.downloading_droid.is_live: 2299 ad.downloading_droid, ad.downloading_ed = ad.get_droid() 2300 ad.downloading_ed.start() 2301 except Exception as e: 2302 ad.log.info(e) 2303 ad.downloading_droid, ad.downloading_ed = ad.get_droid() 2304 ad.downloading_ed.start() 2305 data_accounting = { 2306 "mobile_rx_bytes": 2307 ad.droid.getMobileRxBytes(), 2308 "subscriber_mobile_data_usage": 2309 get_mobile_data_usage(ad, None, None), 2310 "sl4a_mobile_data_usage": 2311 get_mobile_data_usage(ad, None, accounting_apk) 2312 } 2313 ad.log.info("Before downloading: %s", data_accounting) 2314 ad.log.info("Download file from %s to %s by sl4a RPC call", url, 2315 file_path) 2316 try: 2317 ad.downloading_droid.httpDownloadFile( 2318 url, file_path, timeout=timeout) 2319 except Exception as e: 2320 ad.log.warning("SL4A file download error: %s", e) 2321 return False 2322 if _check_file_existance(ad, file_path, expected_file_size): 2323 ad.log.info("%s is downloaded successfully", url) 2324 new_data_accounting = { 2325 "mobile_rx_bytes": 2326 ad.droid.getMobileRxBytes(), 2327 "subscriber_mobile_data_usage": 2328 get_mobile_data_usage(ad, None, None), 2329 "sl4a_mobile_data_usage": 2330 get_mobile_data_usage(ad, None, accounting_apk) 2331 } 2332 ad.log.info("After downloading: %s", new_data_accounting) 2333 accounting_diff = { 2334 key: value - data_accounting[key] 2335 for key, value in new_data_accounting.items() 2336 } 2337 ad.log.info("Data accounting difference: %s", accounting_diff) 2338 if getattr(ad, "on_mobile_data", False): 2339 for key, value in accounting_diff.items(): 2340 if value < expected_file_size: 2341 ad.log.warning("%s diff is %s less than %s", key, 2342 value, expected_file_size) 2343 ad.data_accounting["%s_failure"] += 1 2344 else: 2345 for key, value in accounting_diff.items(): 2346 if value >= expected_file_size: 2347 ad.log.error("%s diff is %s. File download is " 2348 "consuming mobile data", key, value) 2349 result = False 2350 return result 2351 else: 2352 ad.log.warning("Fail to download %s", url) 2353 return False 2354 except Exception as e: 2355 ad.log.error("Download %s failed with exception %s", url, e) 2356 raise 2357 finally: 2358 if remove_file_after_check: 2359 ad.log.info("Remove the downloaded file %s", file_path) 2360 ad.adb.shell("rm %s" % file_path, ignore_status=True) 2361 2362 2363def get_mobile_data_usage(ad, subscriber_id=None, apk=None): 2364 if not subscriber_id: 2365 subscriber_id = ad.droid.telephonyGetSubscriberId() 2366 if not getattr(ad, "data_metering_begin_time", None) or not getattr( 2367 ad, "data_metering_end_time", None): 2368 current_time = int(time.time() * 1000) 2369 setattr(ad, "data_metering_begin_time", 2370 current_time - 24 * 60 * 60 * 1000) 2371 setattr(ad, "data_metering_end_time", 2372 current_time + 30 * 24 * 60 * 60 * 1000) 2373 begin_time = ad.data_metering_begin_time 2374 end_time = ad.data_metering_end_time 2375 if apk: 2376 uid = ad.get_apk_uid(apk) 2377 try: 2378 usage = ad.droid.connectivityQueryDetailsForUid( 2379 TYPE_MOBILE, subscriber_id, begin_time, end_time, uid) 2380 except Exception: 2381 usage = ad.droid.connectivityQueryDetailsForUid( 2382 subscriber_id, begin_time, end_time, uid) 2383 ad.log.debug("The mobile data usage for apk %s is %s", apk, usage) 2384 else: 2385 try: 2386 usage = ad.droid.connectivityQuerySummaryForDevice( 2387 TYPE_MOBILE, subscriber_id, begin_time, end_time) 2388 except Exception: 2389 usage = ad.droid.connectivityQuerySummaryForDevice( 2390 subscriber_id, begin_time, end_time) 2391 ad.log.debug("The mobile data usage for subscriber is %s", usage) 2392 return usage 2393 2394 2395def set_mobile_data_usage_limit(ad, limit, subscriber_id=None): 2396 if not subscriber_id: 2397 subscriber_id = ad.droid.telephonyGetSubscriberId() 2398 ad.log.info("Set subscriber mobile data usage limit to %s", limit) 2399 ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit)) 2400 2401 2402def remove_mobile_data_usage_limit(ad, subscriber_id=None): 2403 if not subscriber_id: 2404 subscriber_id = ad.droid.telephonyGetSubscriberId() 2405 ad.log.info("Remove subscriber mobile data usage limit") 2406 ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1") 2407 2408 2409def trigger_modem_crash(ad, timeout=120): 2410 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem" 2411 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd) 2412 ad.adb.shell(cmd) 2413 time.sleep(timeout) 2414 return True 2415 2416 2417def trigger_modem_crash_by_modem(ad, timeout=120): 2418 begin_time = get_current_epoch_time() 2419 ad.adb.shell( 2420 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) 2421 # Legacy pixels use persist.sys.modem.diag.mdlog. 2422 ad.adb.shell( 2423 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 2424 stop_qxdm_logger(ad) 2425 cmd = ('am instrument -w -e request "4b 25 03 00" ' 2426 '"com.google.mdstest/com.google.mdstest.instrument.' 2427 'ModemCommandInstrumentation"') 2428 ad.log.info("Crash modem by %s", cmd) 2429 ad.adb.shell(cmd, ignore_status=True) 2430 time.sleep(timeout) # sleep time for sl4a stability 2431 reasons = ad.search_logcat("modem subsystem failure reason", begin_time) 2432 if reasons: 2433 ad.log.info("Modem crash is triggered successfully") 2434 ad.log.info(reasons[-1]["log_message"]) 2435 return True 2436 else: 2437 ad.log.info("Modem crash is not triggered successfully") 2438 return False 2439 2440 2441def _connection_state_change(_event, target_state, connection_type): 2442 if connection_type: 2443 if 'TypeName' not in _event['data']: 2444 return False 2445 connection_type_string_in_event = _event['data']['TypeName'] 2446 cur_type = connection_type_from_type_string( 2447 connection_type_string_in_event) 2448 if cur_type != connection_type: 2449 log.info( 2450 "_connection_state_change expect: %s, received: %s <type %s>", 2451 connection_type, connection_type_string_in_event, cur_type) 2452 return False 2453 2454 if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state: 2455 return True 2456 return False 2457 2458 2459def wait_for_cell_data_connection( 2460 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 2461 """Wait for data connection status to be expected value for default 2462 data subscription. 2463 2464 Wait for the data connection status to be DATA_STATE_CONNECTED 2465 or DATA_STATE_DISCONNECTED. 2466 2467 Args: 2468 log: Log object. 2469 ad: Android Device Object. 2470 state: Expected status: True or False. 2471 If True, it will wait for status to be DATA_STATE_CONNECTED. 2472 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 2473 timeout_value: wait for cell data timeout value. 2474 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 2475 2476 Returns: 2477 True if success. 2478 False if failed. 2479 """ 2480 sub_id = get_default_data_sub_id(ad) 2481 return wait_for_cell_data_connection_for_subscription( 2482 log, ad, sub_id, state, timeout_value) 2483 2484 2485def _is_data_connection_state_match(log, ad, expected_data_connection_state): 2486 return (expected_data_connection_state == 2487 ad.droid.telephonyGetDataConnectionState()) 2488 2489 2490def _is_network_connected_state_match(log, ad, 2491 expected_network_connected_state): 2492 return (expected_network_connected_state == 2493 ad.droid.connectivityNetworkIsConnected()) 2494 2495 2496def wait_for_cell_data_connection_for_subscription( 2497 log, 2498 ad, 2499 sub_id, 2500 state, 2501 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 2502 """Wait for data connection status to be expected value for specified 2503 subscrption id. 2504 2505 Wait for the data connection status to be DATA_STATE_CONNECTED 2506 or DATA_STATE_DISCONNECTED. 2507 2508 Args: 2509 log: Log object. 2510 ad: Android Device Object. 2511 sub_id: subscription Id 2512 state: Expected status: True or False. 2513 If True, it will wait for status to be DATA_STATE_CONNECTED. 2514 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 2515 timeout_value: wait for cell data timeout value. 2516 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 2517 2518 Returns: 2519 True if success. 2520 False if failed. 2521 """ 2522 state_str = { 2523 True: DATA_STATE_CONNECTED, 2524 False: DATA_STATE_DISCONNECTED 2525 }[state] 2526 2527 data_state = ad.droid.telephonyGetDataConnectionState() 2528 if not state and ad.droid.telephonyGetDataConnectionState() == state_str: 2529 return True 2530 ad.ed.clear_events(EventDataConnectionStateChanged) 2531 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription( 2532 sub_id) 2533 ad.droid.connectivityStartTrackingConnectivityStateChange() 2534 try: 2535 # TODO: b/26293147 There is no framework API to get data connection 2536 # state by sub id 2537 data_state = ad.droid.telephonyGetDataConnectionState() 2538 if data_state == state_str: 2539 return _wait_for_nw_data_connection( 2540 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 2541 2542 try: 2543 event = ad.ed.wait_for_event( 2544 EventDataConnectionStateChanged, 2545 is_event_match, 2546 timeout=timeout_value, 2547 field=DataConnectionStateContainer.DATA_CONNECTION_STATE, 2548 value=state_str) 2549 except Empty: 2550 ad.log.info("No expected event EventDataConnectionStateChanged %s", 2551 state_str) 2552 2553 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 2554 # data connection state. 2555 # Otherwise, the network state will not be correct. 2556 # The bug is tracked here: b/20921915 2557 2558 # Previously we use _is_data_connection_state_match, 2559 # but telephonyGetDataConnectionState sometimes return wrong value. 2560 # The bug is tracked here: b/22612607 2561 # So we use _is_network_connected_state_match. 2562 2563 if _wait_for_droid_in_state(log, ad, timeout_value, 2564 _is_network_connected_state_match, state): 2565 return _wait_for_nw_data_connection( 2566 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 2567 else: 2568 return False 2569 2570 finally: 2571 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription( 2572 sub_id) 2573 2574 2575def wait_for_wifi_data_connection( 2576 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 2577 """Wait for data connection status to be expected value and connection is by WiFi. 2578 2579 Args: 2580 log: Log object. 2581 ad: Android Device Object. 2582 state: Expected status: True or False. 2583 If True, it will wait for status to be DATA_STATE_CONNECTED. 2584 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 2585 timeout_value: wait for network data timeout value. 2586 This is optional, default value is MAX_WAIT_TIME_NW_SELECTION 2587 2588 Returns: 2589 True if success. 2590 False if failed. 2591 """ 2592 ad.log.info("wait_for_wifi_data_connection") 2593 return _wait_for_nw_data_connection( 2594 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value) 2595 2596 2597def wait_for_data_connection( 2598 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 2599 """Wait for data connection status to be expected value. 2600 2601 Wait for the data connection status to be DATA_STATE_CONNECTED 2602 or DATA_STATE_DISCONNECTED. 2603 2604 Args: 2605 log: Log object. 2606 ad: Android Device Object. 2607 state: Expected status: True or False. 2608 If True, it will wait for status to be DATA_STATE_CONNECTED. 2609 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 2610 timeout_value: wait for network data timeout value. 2611 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 2612 2613 Returns: 2614 True if success. 2615 False if failed. 2616 """ 2617 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value) 2618 2619 2620def _wait_for_nw_data_connection( 2621 log, 2622 ad, 2623 is_connected, 2624 connection_type=None, 2625 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 2626 """Wait for data connection status to be expected value. 2627 2628 Wait for the data connection status to be DATA_STATE_CONNECTED 2629 or DATA_STATE_DISCONNECTED. 2630 2631 Args: 2632 log: Log object. 2633 ad: Android Device Object. 2634 is_connected: Expected connection status: True or False. 2635 If True, it will wait for status to be DATA_STATE_CONNECTED. 2636 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 2637 connection_type: expected connection type. 2638 This is optional, if it is None, then any connection type will return True. 2639 timeout_value: wait for network data timeout value. 2640 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 2641 2642 Returns: 2643 True if success. 2644 False if failed. 2645 """ 2646 ad.ed.clear_events(EventConnectivityChanged) 2647 ad.droid.connectivityStartTrackingConnectivityStateChange() 2648 try: 2649 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected() 2650 if is_connected == cur_data_connection_state: 2651 current_type = get_internet_connection_type(log, ad) 2652 ad.log.info("current data connection type: %s", current_type) 2653 if not connection_type: 2654 return True 2655 else: 2656 if not is_connected and current_type != connection_type: 2657 ad.log.info("data connection not on %s!", connection_type) 2658 return True 2659 elif is_connected and current_type == connection_type: 2660 ad.log.info("data connection on %s as expected", 2661 connection_type) 2662 return True 2663 else: 2664 ad.log.info("current data connection state: %s target: %s", 2665 cur_data_connection_state, is_connected) 2666 2667 try: 2668 event = ad.ed.wait_for_event( 2669 EventConnectivityChanged, _connection_state_change, 2670 timeout_value, is_connected, connection_type) 2671 ad.log.info("received event: %s", event) 2672 except Empty: 2673 pass 2674 2675 log.info( 2676 "_wait_for_nw_data_connection: check connection after wait event.") 2677 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 2678 # data connection state. 2679 # Otherwise, the network state will not be correct. 2680 # The bug is tracked here: b/20921915 2681 if _wait_for_droid_in_state(log, ad, timeout_value, 2682 _is_network_connected_state_match, 2683 is_connected): 2684 current_type = get_internet_connection_type(log, ad) 2685 ad.log.info("current data connection type: %s", current_type) 2686 if not connection_type: 2687 return True 2688 else: 2689 if not is_connected and current_type != connection_type: 2690 ad.log.info("data connection not on %s", connection_type) 2691 return True 2692 elif is_connected and current_type == connection_type: 2693 ad.log.info("after event wait, data connection on %s", 2694 connection_type) 2695 return True 2696 else: 2697 return False 2698 else: 2699 return False 2700 except Exception as e: 2701 ad.log.error("Exception error %s", str(e)) 2702 return False 2703 finally: 2704 ad.droid.connectivityStopTrackingConnectivityStateChange() 2705 2706 2707def get_cell_data_roaming_state_by_adb(ad): 2708 """Get Cell Data Roaming state. True for enabled, False for disabled""" 2709 adb_str = {"1": True, "0": False} 2710 out = ad.adb.shell("settings get global data_roaming") 2711 return adb_str[out] 2712 2713 2714def get_cell_data_roaming_state_by_adb(ad): 2715 """Get Cell Data Roaming state. True for enabled, False for disabled""" 2716 state_mapping = {"1": True, "0": False} 2717 return state_mapping[ad.adb.shell("settings get global data_roaming")] 2718 2719 2720def set_cell_data_roaming_state_by_adb(ad, state): 2721 """Set Cell Data Roaming state.""" 2722 state_mapping = {True: "1", False: "0"} 2723 ad.log.info("Set data roaming to %s", state) 2724 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state]) 2725 2726 2727def toggle_cell_data_roaming(ad, state): 2728 """Enable cell data roaming for default data subscription. 2729 2730 Wait for the data roaming status to be DATA_STATE_CONNECTED 2731 or DATA_STATE_DISCONNECTED. 2732 2733 Args: 2734 log: Log object. 2735 ad: Android Device Object. 2736 state: True or False for enable or disable cell data roaming. 2737 2738 Returns: 2739 True if success. 2740 False if failed. 2741 """ 2742 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state] 2743 action_str = {True: "Enable", False: "Disable"}[state] 2744 if ad.droid.connectivityCheckDataRoamingMode() == state: 2745 ad.log.info("Data roaming is already in state %s", state) 2746 return True 2747 if not ad.droid.connectivitySetDataRoaming(state_int): 2748 ad.error.info("Fail to config data roaming into state %s", state) 2749 return False 2750 if ad.droid.connectivityCheckDataRoamingMode() == state: 2751 ad.log.info("Data roaming is configured into state %s", state) 2752 return True 2753 else: 2754 ad.log.error("Data roaming is not configured into state %s", state) 2755 return False 2756 2757 2758def verify_incall_state(log, ads, expected_status): 2759 """Verify phones in incall state or not. 2760 2761 Verify if all phones in the array <ads> are in <expected_status>. 2762 2763 Args: 2764 log: Log object. 2765 ads: Array of Android Device Object. All droid in this array will be tested. 2766 expected_status: If True, verify all Phones in incall state. 2767 If False, verify all Phones not in incall state. 2768 2769 """ 2770 result = True 2771 for ad in ads: 2772 if ad.droid.telecomIsInCall() is not expected_status: 2773 ad.log.error("InCall status:%s, expected:%s", 2774 ad.droid.telecomIsInCall(), expected_status) 2775 result = False 2776 return result 2777 2778 2779def verify_active_call_number(log, ad, expected_number): 2780 """Verify the number of current active call. 2781 2782 Verify if the number of current active call in <ad> is 2783 equal to <expected_number>. 2784 2785 Args: 2786 ad: Android Device Object. 2787 expected_number: Expected active call number. 2788 """ 2789 calls = ad.droid.telecomCallGetCallIds() 2790 if calls is None: 2791 actual_number = 0 2792 else: 2793 actual_number = len(calls) 2794 if actual_number != expected_number: 2795 ad.log.error("Active Call number is %s, expecting", actual_number, 2796 expected_number) 2797 return False 2798 return True 2799 2800 2801def num_active_calls(log, ad): 2802 """Get the count of current active calls. 2803 2804 Args: 2805 log: Log object. 2806 ad: Android Device Object. 2807 2808 Returns: 2809 Count of current active calls. 2810 """ 2811 calls = ad.droid.telecomCallGetCallIds() 2812 return len(calls) if calls else 0 2813 2814 2815def toggle_volte(log, ad, new_state=None): 2816 """Toggle enable/disable VoLTE for default voice subscription. 2817 2818 Args: 2819 ad: Android device object. 2820 new_state: VoLTE mode state to set to. 2821 True for enable, False for disable. 2822 If None, opposite of the current state. 2823 2824 Raises: 2825 TelTestUtilsError if platform does not support VoLTE. 2826 """ 2827 return toggle_volte_for_subscription( 2828 log, ad, get_outgoing_voice_sub_id(ad), new_state) 2829 2830 2831def toggle_volte_for_subscription(log, ad, sub_id, new_state=None): 2832 """Toggle enable/disable VoLTE for specified voice subscription. 2833 2834 Args: 2835 ad: Android device object. 2836 sub_id: subscription ID 2837 new_state: VoLTE mode state to set to. 2838 True for enable, False for disable. 2839 If None, opposite of the current state. 2840 2841 Raises: 2842 TelTestUtilsError if platform does not support VoLTE. 2843 """ 2844 # TODO: b/26293960 No framework API available to set IMS by SubId. 2845 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(): 2846 ad.log.info("VoLTE not supported by platform.") 2847 raise TelTestUtilsError( 2848 "VoLTE not supported by platform %s." % ad.serial) 2849 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() 2850 if new_state is None: 2851 new_state = not current_state 2852 if new_state != current_state: 2853 ad.droid.imsSetEnhanced4gMode(new_state) 2854 return True 2855 2856 2857def set_wfc_mode(log, ad, wfc_mode): 2858 """Set WFC enable/disable and mode. 2859 2860 Args: 2861 log: Log object 2862 ad: Android device object. 2863 wfc_mode: WFC mode to set to. 2864 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED, 2865 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED. 2866 2867 Returns: 2868 True if success. False if ad does not support WFC or error happened. 2869 """ 2870 try: 2871 ad.log.info("Set wfc mode to %s", wfc_mode) 2872 if not ad.droid.imsIsWfcEnabledByPlatform(): 2873 if wfc_mode == WFC_MODE_DISABLED: 2874 return True 2875 else: 2876 ad.log.error("WFC not supported by platform.") 2877 return False 2878 ad.droid.imsSetWfcMode(wfc_mode) 2879 mode = ad.droid.imsGetWfcMode() 2880 if mode != wfc_mode: 2881 ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode) 2882 return False 2883 except Exception as e: 2884 log.error(e) 2885 return False 2886 return True 2887 2888 2889def toggle_video_calling(log, ad, new_state=None): 2890 """Toggle enable/disable Video calling for default voice subscription. 2891 2892 Args: 2893 ad: Android device object. 2894 new_state: Video mode state to set to. 2895 True for enable, False for disable. 2896 If None, opposite of the current state. 2897 2898 Raises: 2899 TelTestUtilsError if platform does not support Video calling. 2900 """ 2901 if not ad.droid.imsIsVtEnabledByPlatform(): 2902 if new_state is not False: 2903 raise TelTestUtilsError("VT not supported by platform.") 2904 # if the user sets VT false and it's unavailable we just let it go 2905 return False 2906 2907 current_state = ad.droid.imsIsVtEnabledByUser() 2908 if new_state is None: 2909 new_state = not current_state 2910 if new_state != current_state: 2911 ad.droid.imsSetVtSetting(new_state) 2912 return True 2913 2914 2915def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args, 2916 **kwargs): 2917 while max_time >= 0: 2918 if state_check_func(log, ad, *args, **kwargs): 2919 return True 2920 2921 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 2922 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 2923 2924 return False 2925 2926 2927def _wait_for_droid_in_state_for_subscription( 2928 log, ad, sub_id, max_time, state_check_func, *args, **kwargs): 2929 while max_time >= 0: 2930 if state_check_func(log, ad, sub_id, *args, **kwargs): 2931 return True 2932 2933 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 2934 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 2935 2936 return False 2937 2938 2939def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args, 2940 **kwargs): 2941 while max_time > 0: 2942 success = True 2943 for ad in ads: 2944 if not state_check_func(log, ad, *args, **kwargs): 2945 success = False 2946 break 2947 if success: 2948 return True 2949 2950 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 2951 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 2952 2953 return False 2954 2955 2956def is_phone_in_call(log, ad): 2957 """Return True if phone in call. 2958 2959 Args: 2960 log: log object. 2961 ad: android device. 2962 """ 2963 try: 2964 return ad.droid.telecomIsInCall() 2965 except: 2966 return "mCallState=2" in ad.adb.shell( 2967 "dumpsys telephony.registry | grep mCallState") 2968 2969 2970def is_phone_not_in_call(log, ad): 2971 """Return True if phone not in call. 2972 2973 Args: 2974 log: log object. 2975 ad: android device. 2976 """ 2977 in_call = ad.droid.telecomIsInCall() 2978 call_state = ad.droid.telephonyGetCallState() 2979 if in_call: 2980 ad.log.info("Device is In Call") 2981 if call_state != TELEPHONY_STATE_IDLE: 2982 ad.log.info("Call_state is %s, not %s", call_state, 2983 TELEPHONY_STATE_IDLE) 2984 return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE)) 2985 2986 2987def wait_for_droid_in_call(log, ad, max_time): 2988 """Wait for android to be in call state. 2989 2990 Args: 2991 log: log object. 2992 ad: android device. 2993 max_time: maximal wait time. 2994 2995 Returns: 2996 If phone become in call state within max_time, return True. 2997 Return False if timeout. 2998 """ 2999 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call) 3000 3001 3002def is_phone_in_call_active(ad, call_id=None): 3003 """Return True if phone in active call. 3004 3005 Args: 3006 log: log object. 3007 ad: android device. 3008 call_id: the call id 3009 """ 3010 if not call_id: 3011 call_id = ad.droid.telecomCallGetCallIds()[0] 3012 call_state = ad.droid.telecomCallGetCallState(call_id) 3013 ad.log.info("%s state is %s", call_id, call_state) 3014 return call_state == "ACTIVE" 3015 3016 3017def wait_for_in_call_active(ad, timeout=5, interval=1, call_id=None): 3018 """Wait for call reach active state. 3019 3020 Args: 3021 log: log object. 3022 ad: android device. 3023 call_id: the call id 3024 """ 3025 if not call_id: 3026 call_id = ad.droid.telecomCallGetCallIds()[0] 3027 args = [ad, call_id] 3028 if not wait_for_state(is_phone_in_call_active, True, timeout, interval, 3029 *args): 3030 ad.log.error("Call did not reach ACTIVE state") 3031 return False 3032 else: 3033 return True 3034 3035 3036def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING): 3037 """Wait for android to be in telecom ringing state. 3038 3039 Args: 3040 log: log object. 3041 ad: android device. 3042 max_time: maximal wait time. This is optional. 3043 Default Value is MAX_WAIT_TIME_TELECOM_RINGING. 3044 3045 Returns: 3046 If phone become in telecom ringing state within max_time, return True. 3047 Return False if timeout. 3048 """ 3049 return _wait_for_droid_in_state( 3050 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging()) 3051 3052 3053def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP): 3054 """Wait for android to be not in call state. 3055 3056 Args: 3057 log: log object. 3058 ad: android device. 3059 max_time: maximal wait time. 3060 3061 Returns: 3062 If phone become not in call state within max_time, return True. 3063 Return False if timeout. 3064 """ 3065 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call) 3066 3067 3068def _is_attached(log, ad, voice_or_data): 3069 return _is_attached_for_subscription( 3070 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 3071 3072 3073def _is_attached_for_subscription(log, ad, sub_id, voice_or_data): 3074 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data) 3075 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat, 3076 voice_or_data) 3077 return rat != RAT_UNKNOWN 3078 3079 3080def is_voice_attached(log, ad): 3081 return _is_attached_for_subscription( 3082 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE) 3083 3084 3085def wait_for_voice_attach(log, ad, max_time): 3086 """Wait for android device to attach on voice. 3087 3088 Args: 3089 log: log object. 3090 ad: android device. 3091 max_time: maximal wait time. 3092 3093 Returns: 3094 Return True if device attach voice within max_time. 3095 Return False if timeout. 3096 """ 3097 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 3098 NETWORK_SERVICE_VOICE) 3099 3100 3101def wait_for_voice_attach_for_subscription(log, ad, sub_id, max_time): 3102 """Wait for android device to attach on voice in subscription id. 3103 3104 Args: 3105 log: log object. 3106 ad: android device. 3107 sub_id: subscription id. 3108 max_time: maximal wait time. 3109 3110 Returns: 3111 Return True if device attach voice within max_time. 3112 Return False if timeout. 3113 """ 3114 if not _wait_for_droid_in_state_for_subscription( 3115 log, ad, sub_id, max_time, _is_attached_for_subscription, 3116 NETWORK_SERVICE_VOICE): 3117 return False 3118 3119 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not 3120 # receive incoming call immediately. 3121 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT: 3122 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH) 3123 return True 3124 3125 3126def wait_for_data_attach(log, ad, max_time): 3127 """Wait for android device to attach on data. 3128 3129 Args: 3130 log: log object. 3131 ad: android device. 3132 max_time: maximal wait time. 3133 3134 Returns: 3135 Return True if device attach data within max_time. 3136 Return False if timeout. 3137 """ 3138 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 3139 NETWORK_SERVICE_DATA) 3140 3141 3142def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time): 3143 """Wait for android device to attach on data in subscription id. 3144 3145 Args: 3146 log: log object. 3147 ad: android device. 3148 sub_id: subscription id. 3149 max_time: maximal wait time. 3150 3151 Returns: 3152 Return True if device attach data within max_time. 3153 Return False if timeout. 3154 """ 3155 return _wait_for_droid_in_state_for_subscription( 3156 log, ad, sub_id, max_time, _is_attached_for_subscription, 3157 NETWORK_SERVICE_DATA) 3158 3159 3160def is_ims_registered(log, ad): 3161 """Return True if IMS registered. 3162 3163 Args: 3164 log: log object. 3165 ad: android device. 3166 3167 Returns: 3168 Return True if IMS registered. 3169 Return False if IMS not registered. 3170 """ 3171 return ad.droid.telephonyIsImsRegistered() 3172 3173 3174def wait_for_ims_registered(log, ad, max_time): 3175 """Wait for android device to register on ims. 3176 3177 Args: 3178 log: log object. 3179 ad: android device. 3180 max_time: maximal wait time. 3181 3182 Returns: 3183 Return True if device register ims successfully within max_time. 3184 Return False if timeout. 3185 """ 3186 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered) 3187 3188 3189def is_volte_enabled(log, ad): 3190 """Return True if VoLTE feature bit is True. 3191 3192 Args: 3193 log: log object. 3194 ad: android device. 3195 3196 Returns: 3197 Return True if VoLTE feature bit is True and IMS registered. 3198 Return False if VoLTE feature bit is False or IMS not registered. 3199 """ 3200 result = True 3201 if not ad.droid.telephonyIsVolteAvailable(): 3202 ad.log.info("IsVolteCallingAvailble is False") 3203 result = False 3204 else: 3205 ad.log.info("IsVolteCallingAvailble is True") 3206 if not is_ims_registered(log, ad): 3207 ad.log.info("IMS is not registered.") 3208 result = False 3209 else: 3210 ad.log.info("IMS is registered") 3211 return result 3212 3213 3214def is_video_enabled(log, ad): 3215 """Return True if Video Calling feature bit is True. 3216 3217 Args: 3218 log: log object. 3219 ad: android device. 3220 3221 Returns: 3222 Return True if Video Calling feature bit is True and IMS registered. 3223 Return False if Video Calling feature bit is False or IMS not registered. 3224 """ 3225 video_status = ad.droid.telephonyIsVideoCallingAvailable() 3226 if video_status is True and is_ims_registered(log, ad) is False: 3227 log.error("Error! Video Call is Available, but IMS is not registered.") 3228 return False 3229 return video_status 3230 3231 3232def wait_for_volte_enabled(log, ad, max_time): 3233 """Wait for android device to report VoLTE enabled bit true. 3234 3235 Args: 3236 log: log object. 3237 ad: android device. 3238 max_time: maximal wait time. 3239 3240 Returns: 3241 Return True if device report VoLTE enabled bit true within max_time. 3242 Return False if timeout. 3243 """ 3244 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled) 3245 3246 3247def wait_for_video_enabled(log, ad, max_time): 3248 """Wait for android device to report Video Telephony enabled bit true. 3249 3250 Args: 3251 log: log object. 3252 ad: android device. 3253 max_time: maximal wait time. 3254 3255 Returns: 3256 Return True if device report Video Telephony enabled bit true within max_time. 3257 Return False if timeout. 3258 """ 3259 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled) 3260 3261 3262def is_wfc_enabled(log, ad): 3263 """Return True if WiFi Calling feature bit is True. 3264 3265 Args: 3266 log: log object. 3267 ad: android device. 3268 3269 Returns: 3270 Return True if WiFi Calling feature bit is True and IMS registered. 3271 Return False if WiFi Calling feature bit is False or IMS not registered. 3272 """ 3273 if not ad.droid.telephonyIsWifiCallingAvailable(): 3274 ad.log.info("IsWifiCallingAvailble is False") 3275 return False 3276 else: 3277 ad.log.info("IsWifiCallingAvailble is True") 3278 if not is_ims_registered(log, ad): 3279 ad.log.info( 3280 "WiFi Calling is Available, but IMS is not registered.") 3281 return False 3282 return True 3283 3284 3285def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): 3286 """Wait for android device to report WiFi Calling enabled bit true. 3287 3288 Args: 3289 log: log object. 3290 ad: android device. 3291 max_time: maximal wait time. 3292 Default value is MAX_WAIT_TIME_WFC_ENABLED. 3293 3294 Returns: 3295 Return True if device report WiFi Calling enabled bit true within max_time. 3296 Return False if timeout. 3297 """ 3298 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled) 3299 3300 3301def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED): 3302 """Wait for android device to report WiFi Calling enabled bit false. 3303 3304 Args: 3305 log: log object. 3306 ad: android device. 3307 max_time: maximal wait time. 3308 Default value is MAX_WAIT_TIME_WFC_DISABLED. 3309 3310 Returns: 3311 Return True if device report WiFi Calling enabled bit false within max_time. 3312 Return False if timeout. 3313 """ 3314 return _wait_for_droid_in_state( 3315 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad)) 3316 3317 3318def get_phone_number(log, ad): 3319 """Get phone number for default subscription 3320 3321 Args: 3322 log: log object. 3323 ad: Android device object. 3324 3325 Returns: 3326 Phone number. 3327 """ 3328 return get_phone_number_for_subscription(log, ad, 3329 get_outgoing_voice_sub_id(ad)) 3330 3331 3332def get_phone_number_for_subscription(log, ad, subid): 3333 """Get phone number for subscription 3334 3335 Args: 3336 log: log object. 3337 ad: Android device object. 3338 subid: subscription id. 3339 3340 Returns: 3341 Phone number. 3342 """ 3343 number = None 3344 try: 3345 number = ad.cfg['subscription'][subid]['phone_num'] 3346 except KeyError: 3347 number = ad.droid.telephonyGetLine1NumberForSubscription(subid) 3348 return number 3349 3350 3351def set_phone_number(log, ad, phone_num): 3352 """Set phone number for default subscription 3353 3354 Args: 3355 log: log object. 3356 ad: Android device object. 3357 phone_num: phone number string. 3358 3359 Returns: 3360 True if success. 3361 """ 3362 return set_phone_number_for_subscription(log, ad, 3363 get_outgoing_voice_sub_id(ad), 3364 phone_num) 3365 3366 3367def set_phone_number_for_subscription(log, ad, subid, phone_num): 3368 """Set phone number for subscription 3369 3370 Args: 3371 log: log object. 3372 ad: Android device object. 3373 subid: subscription id. 3374 phone_num: phone number string. 3375 3376 Returns: 3377 True if success. 3378 """ 3379 try: 3380 ad.cfg['subscription'][subid]['phone_num'] = phone_num 3381 except Exception: 3382 return False 3383 return True 3384 3385 3386def get_operator_name(log, ad, subId=None): 3387 """Get operator name (e.g. vzw, tmo) of droid. 3388 3389 Args: 3390 ad: Android device object. 3391 sub_id: subscription ID 3392 Optional, default is None 3393 3394 Returns: 3395 Operator name. 3396 """ 3397 try: 3398 if subId is not None: 3399 result = operator_name_from_plmn_id( 3400 ad.droid.telephonyGetNetworkOperatorForSubscription(subId)) 3401 else: 3402 result = operator_name_from_plmn_id( 3403 ad.droid.telephonyGetNetworkOperator()) 3404 except KeyError: 3405 result = CARRIER_UNKNOWN 3406 return result 3407 3408 3409def get_model_name(ad): 3410 """Get android device model name 3411 3412 Args: 3413 ad: Android device object 3414 3415 Returns: 3416 model name string 3417 """ 3418 # TODO: Create translate table. 3419 model = ad.model 3420 if (model.startswith(AOSP_PREFIX)): 3421 model = model[len(AOSP_PREFIX):] 3422 return model 3423 3424 3425def is_sms_match(event, phonenumber_tx, text): 3426 """Return True if 'text' equals to event['data']['Text'] 3427 and phone number match. 3428 3429 Args: 3430 event: Event object to verify. 3431 phonenumber_tx: phone number for sender. 3432 text: text string to verify. 3433 3434 Returns: 3435 Return True if 'text' equals to event['data']['Text'] 3436 and phone number match. 3437 """ 3438 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx) 3439 and event['data']['Text'] == text) 3440 3441 3442def is_sms_partial_match(event, phonenumber_tx, text): 3443 """Return True if 'text' starts with event['data']['Text'] 3444 and phone number match. 3445 3446 Args: 3447 event: Event object to verify. 3448 phonenumber_tx: phone number for sender. 3449 text: text string to verify. 3450 3451 Returns: 3452 Return True if 'text' starts with event['data']['Text'] 3453 and phone number match. 3454 """ 3455 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx) 3456 and text.startswith(event['data']['Text'])) 3457 3458 3459def sms_send_receive_verify(log, 3460 ad_tx, 3461 ad_rx, 3462 array_message, 3463 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3464 """Send SMS, receive SMS, and verify content and sender's number. 3465 3466 Send (several) SMS from droid_tx to droid_rx. 3467 Verify SMS is sent, delivered and received. 3468 Verify received content and sender's number are correct. 3469 3470 Args: 3471 log: Log object. 3472 ad_tx: Sender's Android Device Object 3473 ad_rx: Receiver's Android Device Object 3474 array_message: the array of message to send/receive 3475 """ 3476 subid_tx = get_outgoing_message_sub_id(ad_tx) 3477 subid_rx = get_incoming_message_sub_id(ad_rx) 3478 return sms_send_receive_verify_for_subscription( 3479 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time) 3480 3481 3482def wait_for_matching_sms(log, 3483 ad_rx, 3484 phonenumber_tx, 3485 text, 3486 allow_multi_part_long_sms=True, 3487 begin_time=None, 3488 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3489 """Wait for matching incoming SMS. 3490 3491 Args: 3492 log: Log object. 3493 ad_rx: Receiver's Android Device Object 3494 phonenumber_tx: Sender's phone number. 3495 text: SMS content string. 3496 allow_multi_part_long_sms: is long SMS allowed to be received as 3497 multiple short SMS. This is optional, default value is True. 3498 3499 Returns: 3500 True if matching incoming SMS is received. 3501 """ 3502 if not allow_multi_part_long_sms: 3503 try: 3504 ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match, 3505 max_wait_time, phonenumber_tx, 3506 text) 3507 return True 3508 except Empty: 3509 ad_rx.log.error("No matched SMS received event.") 3510 if begin_time: 3511 if sms_mms_receive_logcat_check(ad_rx, "sms", begin_time): 3512 ad_rx.log.info("Receivd SMS message is seen in logcat") 3513 return False 3514 else: 3515 try: 3516 received_sms = '' 3517 while (text != ''): 3518 event = ad_rx.messaging_ed.wait_for_event( 3519 EventSmsReceived, is_sms_partial_match, max_wait_time, 3520 phonenumber_tx, text) 3521 text = text[len(event['data']['Text']):] 3522 received_sms += event['data']['Text'] 3523 return True 3524 except Empty: 3525 ad_rx.log.error("No matched SMS received event.") 3526 if begin_time: 3527 if sms_mms_receive_logcat_check(ad_rx, "sms", begin_time): 3528 ad_rx.log.info("Receivd SMS message is seen in logcat") 3529 if received_sms != '': 3530 ad_rx.log.error("Only received partial matched SMS: %s", 3531 received_sms) 3532 return False 3533 3534 3535def is_mms_match(event, phonenumber_tx, text): 3536 """Return True if 'text' equals to event['data']['Text'] 3537 and phone number match. 3538 3539 Args: 3540 event: Event object to verify. 3541 phonenumber_tx: phone number for sender. 3542 text: text string to verify. 3543 3544 Returns: 3545 Return True if 'text' equals to event['data']['Text'] 3546 and phone number match. 3547 """ 3548 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948 3549 return True 3550 3551 3552def wait_for_matching_mms(log, 3553 ad_rx, 3554 phonenumber_tx, 3555 text, 3556 begin_time=None, 3557 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3558 """Wait for matching incoming SMS. 3559 3560 Args: 3561 log: Log object. 3562 ad_rx: Receiver's Android Device Object 3563 phonenumber_tx: Sender's phone number. 3564 text: SMS content string. 3565 allow_multi_part_long_sms: is long SMS allowed to be received as 3566 multiple short SMS. This is optional, default value is True. 3567 3568 Returns: 3569 True if matching incoming SMS is received. 3570 """ 3571 try: 3572 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948 3573 ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match, 3574 max_wait_time, phonenumber_tx, text) 3575 return True 3576 except Empty: 3577 ad_rx.log.warning("No matched MMS downloaded event.") 3578 if begin_time: 3579 if sms_mms_receive_logcat_check(ad_rx, "mms", begin_time): 3580 return True 3581 return False 3582 3583 3584def sms_send_receive_verify_for_subscription( 3585 log, 3586 ad_tx, 3587 ad_rx, 3588 subid_tx, 3589 subid_rx, 3590 array_message, 3591 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3592 """Send SMS, receive SMS, and verify content and sender's number. 3593 3594 Send (several) SMS from droid_tx to droid_rx. 3595 Verify SMS is sent, delivered and received. 3596 Verify received content and sender's number are correct. 3597 3598 Args: 3599 log: Log object. 3600 ad_tx: Sender's Android Device Object.. 3601 ad_rx: Receiver's Android Device Object. 3602 subid_tx: Sender's subsciption ID to be used for SMS 3603 subid_rx: Receiver's subsciption ID to be used for SMS 3604 array_message: the array of message to send/receive 3605 """ 3606 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num'] 3607 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num'] 3608 3609 for ad in (ad_tx, ad_rx): 3610 if not getattr(ad, "messaging_droid", None): 3611 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 3612 ad.messaging_ed.start() 3613 else: 3614 try: 3615 if not ad.messaging_droid.is_live: 3616 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 3617 ad.messaging_ed.start() 3618 except Exception as e: 3619 ad.log.info(e) 3620 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 3621 ad.messaging_ed.start() 3622 3623 for text in array_message: 3624 # set begin_time 300ms before current time to system time discrepency 3625 begin_time = get_current_epoch_time() - 300 3626 length = len(text) 3627 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.", 3628 phonenumber_tx, phonenumber_rx, length, text) 3629 try: 3630 ad_rx.messaging_ed.clear_events(EventSmsReceived) 3631 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess) 3632 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage() 3633 time.sleep(1) #sleep 100ms after starting event tracking 3634 ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text, 3635 False) 3636 try: 3637 ad_tx.messaging_ed.pop_event(EventSmsSentSuccess, 3638 max_wait_time) 3639 except Empty: 3640 ad_tx.log.error("No sent_success event for SMS of length %s.", 3641 length) 3642 # check log message as a work around for the missing sl4a 3643 # event dispatcher event 3644 if not sms_mms_send_logcat_check(ad_tx, "sms", begin_time): 3645 return False 3646 3647 if not wait_for_matching_sms( 3648 log, 3649 ad_rx, 3650 phonenumber_tx, 3651 text, 3652 allow_multi_part_long_sms=True, 3653 begin_time=begin_time): 3654 ad_rx.log.error("No matching received SMS of length %s.", 3655 length) 3656 return False 3657 except Exception as e: 3658 log.error("Exception error %s", e) 3659 raise 3660 finally: 3661 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage() 3662 return True 3663 3664 3665def mms_send_receive_verify(log, 3666 ad_tx, 3667 ad_rx, 3668 array_message, 3669 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3670 """Send MMS, receive MMS, and verify content and sender's number. 3671 3672 Send (several) MMS from droid_tx to droid_rx. 3673 Verify MMS is sent, delivered and received. 3674 Verify received content and sender's number are correct. 3675 3676 Args: 3677 log: Log object. 3678 ad_tx: Sender's Android Device Object 3679 ad_rx: Receiver's Android Device Object 3680 array_message: the array of message to send/receive 3681 """ 3682 return mms_send_receive_verify_for_subscription( 3683 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx), 3684 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time) 3685 3686 3687def sms_mms_send_logcat_check(ad, type, begin_time): 3688 type = type.upper() 3689 log_results = ad.search_logcat( 3690 "%s Message sent successfully" % type, begin_time=begin_time) 3691 if log_results: 3692 ad.log.info("Found %s sent succeessful log message: %s", type, 3693 log_results[-1]["log_message"]) 3694 return True 3695 else: 3696 log_results = ad.search_logcat( 3697 "ProcessSentMessageAction: Done sending %s message" % type, 3698 begin_time=begin_time) 3699 if log_results: 3700 for log_result in log_results: 3701 if "status is SUCCEEDED" in log_result["log_message"]: 3702 ad.log.info( 3703 "Found BugleDataModel %s send succeed log message: %s", 3704 type, log_result["log_message"]) 3705 return True 3706 return False 3707 3708 3709def sms_mms_receive_logcat_check(ad, type, begin_time): 3710 type = type.upper() 3711 log_results = ad.search_logcat( 3712 "New %s Received" % type, begin_time=begin_time) or \ 3713 ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time) 3714 if log_results: 3715 ad.log.info("Found SL4A %s received log message: %s", type, 3716 log_results[-1]["log_message"]) 3717 return True 3718 else: 3719 log_results = ad.search_logcat( 3720 "Received %s message" % type, begin_time=begin_time) 3721 if log_results: 3722 ad.log.info("Found %s received log message: %s", type, 3723 log_results[-1]["log_message"]) 3724 return True 3725 return False 3726 3727 3728#TODO: add mms matching after mms message parser is added in sl4a. b/34276948 3729def mms_send_receive_verify_for_subscription( 3730 log, 3731 ad_tx, 3732 ad_rx, 3733 subid_tx, 3734 subid_rx, 3735 array_payload, 3736 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3737 """Send MMS, receive MMS, and verify content and sender's number. 3738 3739 Send (several) MMS from droid_tx to droid_rx. 3740 Verify MMS is sent, delivered and received. 3741 Verify received content and sender's number are correct. 3742 3743 Args: 3744 log: Log object. 3745 ad_tx: Sender's Android Device Object.. 3746 ad_rx: Receiver's Android Device Object. 3747 subid_tx: Sender's subsciption ID to be used for SMS 3748 subid_rx: Receiver's subsciption ID to be used for SMS 3749 array_message: the array of message to send/receive 3750 """ 3751 3752 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num'] 3753 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num'] 3754 3755 for ad in (ad_rx, ad_tx): 3756 if "Permissive" not in ad.adb.shell("su root getenforce"): 3757 ad.adb.shell("su root setenforce 0") 3758 if not getattr(ad, "messaging_droid", None): 3759 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 3760 ad.messaging_ed.start() 3761 3762 for subject, message, filename in array_payload: 3763 begin_time = get_current_epoch_time() 3764 ad_tx.messaging_ed.clear_events(EventMmsSentSuccess) 3765 ad_rx.messaging_ed.clear_events(EventMmsDownloaded) 3766 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage() 3767 ad_tx.log.info( 3768 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.", 3769 phonenumber_tx, phonenumber_rx, subject, message, filename) 3770 try: 3771 ad_tx.messaging_droid.smsSendMultimediaMessage( 3772 phonenumber_rx, subject, message, phonenumber_tx, filename) 3773 try: 3774 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess, 3775 max_wait_time) 3776 except Empty: 3777 ad_tx.log.warning("No sent_success event.") 3778 # check log message as a work around for the missing sl4a 3779 # event dispatcher event 3780 if not sms_mms_send_logcat_check(ad_tx, "mms", begin_time): 3781 return False 3782 3783 if not wait_for_matching_mms( 3784 log, ad_rx, phonenumber_tx, message, 3785 begin_time=begin_time): 3786 return False 3787 except Exception as e: 3788 log.error("Exception error %s", e) 3789 raise 3790 finally: 3791 ad_rx.droid.smsStopTrackingIncomingMmsMessage() 3792 return True 3793 3794 3795def mms_receive_verify_after_call_hangup( 3796 log, ad_tx, ad_rx, array_message, 3797 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3798 """Verify the suspanded MMS during call will send out after call release. 3799 3800 Hangup call from droid_tx to droid_rx. 3801 Verify MMS is sent, delivered and received. 3802 Verify received content and sender's number are correct. 3803 3804 Args: 3805 log: Log object. 3806 ad_tx: Sender's Android Device Object 3807 ad_rx: Receiver's Android Device Object 3808 array_message: the array of message to send/receive 3809 """ 3810 return mms_receive_verify_after_call_hangup_for_subscription( 3811 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx), 3812 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time) 3813 3814 3815#TODO: add mms matching after mms message parser is added in sl4a. b/34276948 3816def mms_receive_verify_after_call_hangup_for_subscription( 3817 log, 3818 ad_tx, 3819 ad_rx, 3820 subid_tx, 3821 subid_rx, 3822 array_payload, 3823 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 3824 """Verify the suspanded MMS during call will send out after call release. 3825 3826 Hangup call from droid_tx to droid_rx. 3827 Verify MMS is sent, delivered and received. 3828 Verify received content and sender's number are correct. 3829 3830 Args: 3831 log: Log object. 3832 ad_tx: Sender's Android Device Object.. 3833 ad_rx: Receiver's Android Device Object. 3834 subid_tx: Sender's subsciption ID to be used for SMS 3835 subid_rx: Receiver's subsciption ID to be used for SMS 3836 array_message: the array of message to send/receive 3837 """ 3838 3839 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num'] 3840 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num'] 3841 for ad in (ad_tx, ad_rx): 3842 if not getattr(ad, "messaging_droid", None): 3843 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 3844 ad.messaging_ed.start() 3845 for subject, message, filename in array_payload: 3846 begin_time = get_current_epoch_time() 3847 ad_rx.log.info( 3848 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.", 3849 phonenumber_tx, phonenumber_rx, subject, message, filename) 3850 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage() 3851 time.sleep(5) 3852 try: 3853 hangup_call(log, ad_tx) 3854 hangup_call(log, ad_rx) 3855 try: 3856 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess, 3857 max_wait_time) 3858 except Empty: 3859 log.warning("No sent_success event.") 3860 if not sms_mms_send_logcat_check(ad_tx, "mms", begin_time): 3861 return False 3862 if not wait_for_matching_mms( 3863 log, ad_rx, phonenumber_tx, message, 3864 begin_time=begin_time): 3865 return False 3866 finally: 3867 ad_rx.droid.smsStopTrackingIncomingMmsMessage() 3868 return True 3869 3870 3871def ensure_network_rat(log, 3872 ad, 3873 network_preference, 3874 rat_family, 3875 voice_or_data=None, 3876 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 3877 toggle_apm_after_setting=False): 3878 """Ensure ad's current network is in expected rat_family. 3879 """ 3880 return ensure_network_rat_for_subscription( 3881 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 3882 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting) 3883 3884 3885def ensure_network_rat_for_subscription( 3886 log, 3887 ad, 3888 sub_id, 3889 network_preference, 3890 rat_family, 3891 voice_or_data=None, 3892 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 3893 toggle_apm_after_setting=False): 3894 """Ensure ad's current network is in expected rat_family. 3895 """ 3896 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 3897 network_preference, sub_id): 3898 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.", 3899 sub_id, network_preference) 3900 return False 3901 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, 3902 voice_or_data): 3903 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family, 3904 voice_or_data) 3905 return True 3906 3907 if toggle_apm_after_setting: 3908 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 3909 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3910 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False) 3911 3912 result = wait_for_network_rat_for_subscription( 3913 log, ad, sub_id, rat_family, max_wait_time, voice_or_data) 3914 3915 log.info( 3916 "End of ensure_network_rat_for_subscription for %s. " 3917 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), " 3918 "data: %s(family: %s)", ad.serial, network_preference, rat_family, 3919 voice_or_data, 3920 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 3921 rat_family_from_rat( 3922 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 3923 sub_id)), 3924 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 3925 rat_family_from_rat( 3926 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 3927 sub_id))) 3928 return result 3929 3930 3931def ensure_network_preference(log, 3932 ad, 3933 network_preference, 3934 voice_or_data=None, 3935 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 3936 toggle_apm_after_setting=False): 3937 """Ensure that current rat is within the device's preferred network rats. 3938 """ 3939 return ensure_network_preference_for_subscription( 3940 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 3941 voice_or_data, max_wait_time, toggle_apm_after_setting) 3942 3943 3944def ensure_network_preference_for_subscription( 3945 log, 3946 ad, 3947 sub_id, 3948 network_preference, 3949 voice_or_data=None, 3950 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 3951 toggle_apm_after_setting=False): 3952 """Ensure ad's network preference is <network_preference> for sub_id. 3953 """ 3954 rat_family_list = rat_families_for_network_preference(network_preference) 3955 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 3956 network_preference, sub_id): 3957 log.error("Set Preferred Networks failed.") 3958 return False 3959 if is_droid_in_rat_family_list_for_subscription( 3960 log, ad, sub_id, rat_family_list, voice_or_data): 3961 return True 3962 3963 if toggle_apm_after_setting: 3964 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 3965 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 3966 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False) 3967 3968 result = wait_for_preferred_network_for_subscription( 3969 log, ad, sub_id, network_preference, max_wait_time, voice_or_data) 3970 3971 ad.log.info( 3972 "End of ensure_network_preference_for_subscription. " 3973 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), " 3974 "data: %s(family: %s)", network_preference, rat_family_list, 3975 voice_or_data, 3976 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 3977 rat_family_from_rat( 3978 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 3979 sub_id)), 3980 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 3981 rat_family_from_rat( 3982 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 3983 sub_id))) 3984 return result 3985 3986 3987def ensure_network_generation(log, 3988 ad, 3989 generation, 3990 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 3991 voice_or_data=None, 3992 toggle_apm_after_setting=False): 3993 """Ensure ad's network is <network generation> for default subscription ID. 3994 3995 Set preferred network generation to <generation>. 3996 Toggle ON/OFF airplane mode if necessary. 3997 Wait for ad in expected network type. 3998 """ 3999 return ensure_network_generation_for_subscription( 4000 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 4001 max_wait_time, voice_or_data, toggle_apm_after_setting) 4002 4003 4004def ensure_network_generation_for_subscription( 4005 log, 4006 ad, 4007 sub_id, 4008 generation, 4009 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4010 voice_or_data=None, 4011 toggle_apm_after_setting=False): 4012 """Ensure ad's network is <network generation> for specified subscription ID. 4013 4014 Set preferred network generation to <generation>. 4015 Toggle ON/OFF airplane mode if necessary. 4016 Wait for ad in expected network type. 4017 """ 4018 ad.log.info( 4019 "RAT network type voice: %s, data: %s", 4020 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 4021 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id)) 4022 4023 try: 4024 ad.log.info("Finding the network preference for generation %s for " 4025 "operator %s phone type %s", generation, 4026 ad.cfg["subscription"][sub_id]["operator"], 4027 ad.cfg["subscription"][sub_id]["phone_type"]) 4028 network_preference = network_preference_for_generation( 4029 generation, ad.cfg["subscription"][sub_id]["operator"], 4030 ad.cfg["subscription"][sub_id]["phone_type"]) 4031 ad.log.info("Network preference for %s is %s", generation, 4032 network_preference) 4033 rat_family = rat_family_for_generation( 4034 generation, ad.cfg["subscription"][sub_id]["operator"], 4035 ad.cfg["subscription"][sub_id]["phone_type"]) 4036 except KeyError as e: 4037 ad.log.error("Failed to find a rat_family entry for generation %s" 4038 " for subscriber %s with error %s", generation, 4039 ad.cfg["subscription"][sub_id], e) 4040 return False 4041 4042 current_network_preference = \ 4043 ad.droid.telephonyGetPreferredNetworkTypesForSubscription( 4044 sub_id) 4045 for _ in range(3): 4046 if current_network_preference == network_preference: 4047 break 4048 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4049 network_preference, sub_id): 4050 ad.log.info( 4051 "Network preference is %s. Set Preferred Networks to %s failed.", 4052 current_network_preference, network_preference) 4053 reasons = ad.search_logcat( 4054 "REQUEST_SET_PREFERRED_NETWORK_TYPE error") 4055 if reasons: 4056 reason_log = reasons[-1]["log_message"] 4057 ad.log.info(reason_log) 4058 if "DEVICE_IN_USE" in reason_log: 4059 time.sleep(5) 4060 else: 4061 ad.log.error("Failed to set Preferred Networks to %s", 4062 network_preference) 4063 return False 4064 else: 4065 ad.log.error("Failed to set Preferred Networks to %s", 4066 network_preference) 4067 return False 4068 4069 if is_droid_in_network_generation_for_subscription( 4070 log, ad, sub_id, generation, voice_or_data): 4071 return True 4072 4073 if toggle_apm_after_setting: 4074 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 4075 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4076 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False) 4077 4078 result = wait_for_network_generation_for_subscription( 4079 log, ad, sub_id, generation, max_wait_time, voice_or_data) 4080 4081 ad.log.info( 4082 "Ensure network %s %s %s. With network preference %s, " 4083 "current: voice: %s(family: %s), data: %s(family: %s)", generation, 4084 voice_or_data, result, network_preference, 4085 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 4086 rat_generation_from_rat( 4087 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 4088 sub_id)), 4089 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 4090 rat_generation_from_rat( 4091 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 4092 sub_id))) 4093 if not result: 4094 ad.log.info("singal strength = %s", get_telephony_signal_strength(ad)) 4095 return result 4096 4097 4098def wait_for_network_rat(log, 4099 ad, 4100 rat_family, 4101 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4102 voice_or_data=None): 4103 return wait_for_network_rat_for_subscription( 4104 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 4105 max_wait_time, voice_or_data) 4106 4107 4108def wait_for_network_rat_for_subscription( 4109 log, 4110 ad, 4111 sub_id, 4112 rat_family, 4113 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4114 voice_or_data=None): 4115 return _wait_for_droid_in_state_for_subscription( 4116 log, ad, sub_id, max_wait_time, 4117 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data) 4118 4119 4120def wait_for_not_network_rat(log, 4121 ad, 4122 rat_family, 4123 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4124 voice_or_data=None): 4125 return wait_for_not_network_rat_for_subscription( 4126 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 4127 max_wait_time, voice_or_data) 4128 4129 4130def wait_for_not_network_rat_for_subscription( 4131 log, 4132 ad, 4133 sub_id, 4134 rat_family, 4135 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4136 voice_or_data=None): 4137 return _wait_for_droid_in_state_for_subscription( 4138 log, ad, sub_id, max_wait_time, 4139 lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data) 4140 ) 4141 4142 4143def wait_for_preferred_network(log, 4144 ad, 4145 network_preference, 4146 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4147 voice_or_data=None): 4148 return wait_for_preferred_network_for_subscription( 4149 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 4150 max_wait_time, voice_or_data) 4151 4152 4153def wait_for_preferred_network_for_subscription( 4154 log, 4155 ad, 4156 sub_id, 4157 network_preference, 4158 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4159 voice_or_data=None): 4160 rat_family_list = rat_families_for_network_preference(network_preference) 4161 return _wait_for_droid_in_state_for_subscription( 4162 log, ad, sub_id, max_wait_time, 4163 is_droid_in_rat_family_list_for_subscription, rat_family_list, 4164 voice_or_data) 4165 4166 4167def wait_for_network_generation(log, 4168 ad, 4169 generation, 4170 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4171 voice_or_data=None): 4172 return wait_for_network_generation_for_subscription( 4173 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 4174 max_wait_time, voice_or_data) 4175 4176 4177def wait_for_network_generation_for_subscription( 4178 log, 4179 ad, 4180 sub_id, 4181 generation, 4182 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4183 voice_or_data=None): 4184 return _wait_for_droid_in_state_for_subscription( 4185 log, ad, sub_id, max_wait_time, 4186 is_droid_in_network_generation_for_subscription, generation, 4187 voice_or_data) 4188 4189 4190def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None): 4191 return is_droid_in_rat_family_for_subscription( 4192 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 4193 voice_or_data) 4194 4195 4196def is_droid_in_rat_family_for_subscription(log, 4197 ad, 4198 sub_id, 4199 rat_family, 4200 voice_or_data=None): 4201 return is_droid_in_rat_family_list_for_subscription( 4202 log, ad, sub_id, [rat_family], voice_or_data) 4203 4204 4205def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None): 4206 return is_droid_in_rat_family_list_for_subscription( 4207 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list, 4208 voice_or_data) 4209 4210 4211def is_droid_in_rat_family_list_for_subscription(log, 4212 ad, 4213 sub_id, 4214 rat_family_list, 4215 voice_or_data=None): 4216 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 4217 if voice_or_data: 4218 service_list = [voice_or_data] 4219 4220 for service in service_list: 4221 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 4222 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 4223 continue 4224 if rat_family_from_rat(nw_rat) in rat_family_list: 4225 return True 4226 return False 4227 4228 4229def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data): 4230 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 4231 4232 Args: 4233 log: log object. 4234 ad: android device. 4235 nw_gen: expected generation "4g", "3g", "2g". 4236 voice_or_data: check voice network generation or data network generation 4237 This parameter is optional. If voice_or_data is None, then if 4238 either voice or data in expected generation, function will return True. 4239 4240 Returns: 4241 True if droid in expected network generation. Otherwise False. 4242 """ 4243 return is_droid_in_network_generation_for_subscription( 4244 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data) 4245 4246 4247def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen, 4248 voice_or_data): 4249 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 4250 4251 Args: 4252 log: log object. 4253 ad: android device. 4254 nw_gen: expected generation "4g", "3g", "2g". 4255 voice_or_data: check voice network generation or data network generation 4256 This parameter is optional. If voice_or_data is None, then if 4257 either voice or data in expected generation, function will return True. 4258 4259 Returns: 4260 True if droid in expected network generation. Otherwise False. 4261 """ 4262 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 4263 4264 if voice_or_data: 4265 service_list = [voice_or_data] 4266 4267 for service in service_list: 4268 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 4269 ad.log.info("%s network rat is %s", service, nw_rat) 4270 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 4271 continue 4272 4273 if rat_generation_from_rat(nw_rat) == nw_gen: 4274 ad.log.info("%s network rat %s is expected %s", service, nw_rat, 4275 nw_gen) 4276 return True 4277 else: 4278 ad.log.info("%s network rat %s is %s, does not meet expected %s", 4279 service, nw_rat, rat_generation_from_rat(nw_rat), 4280 nw_gen) 4281 return False 4282 4283 return False 4284 4285 4286def get_network_rat(log, ad, voice_or_data): 4287 """Get current network type (Voice network type, or data network type) 4288 for default subscription id 4289 4290 Args: 4291 ad: Android Device Object 4292 voice_or_data: Input parameter indicating to get voice network type or 4293 data network type. 4294 4295 Returns: 4296 Current voice/data network type. 4297 """ 4298 return get_network_rat_for_subscription( 4299 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 4300 4301 4302def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data): 4303 """Get current network type (Voice network type, or data network type) 4304 for specified subscription id 4305 4306 Args: 4307 ad: Android Device Object 4308 sub_id: subscription ID 4309 voice_or_data: Input parameter indicating to get voice network type or 4310 data network type. 4311 4312 Returns: 4313 Current voice/data network type. 4314 """ 4315 if voice_or_data == NETWORK_SERVICE_VOICE: 4316 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 4317 sub_id) 4318 elif voice_or_data == NETWORK_SERVICE_DATA: 4319 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 4320 sub_id) 4321 else: 4322 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id) 4323 4324 if ret_val is None: 4325 log.error("get_network_rat(): Unexpected null return value") 4326 return RAT_UNKNOWN 4327 else: 4328 return ret_val 4329 4330 4331def get_network_gen(log, ad, voice_or_data): 4332 """Get current network generation string (Voice network type, or data network type) 4333 4334 Args: 4335 ad: Android Device Object 4336 voice_or_data: Input parameter indicating to get voice network generation 4337 or data network generation. 4338 4339 Returns: 4340 Current voice/data network generation. 4341 """ 4342 return get_network_gen_for_subscription( 4343 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 4344 4345 4346def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data): 4347 """Get current network generation string (Voice network type, or data network type) 4348 4349 Args: 4350 ad: Android Device Object 4351 voice_or_data: Input parameter indicating to get voice network generation 4352 or data network generation. 4353 4354 Returns: 4355 Current voice/data network generation. 4356 """ 4357 try: 4358 return rat_generation_from_rat( 4359 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)) 4360 except KeyError as e: 4361 ad.log.error("KeyError %s", e) 4362 return GEN_UNKNOWN 4363 4364 4365def check_voice_mail_count(log, ad, voice_mail_count_before, 4366 voice_mail_count_after): 4367 """function to check if voice mail count is correct after leaving a new voice message. 4368 """ 4369 return get_voice_mail_count_check_function(get_operator_name(log, ad))( 4370 voice_mail_count_before, voice_mail_count_after) 4371 4372 4373def get_voice_mail_number(log, ad): 4374 """function to get the voice mail number 4375 """ 4376 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad)) 4377 if voice_mail_number is None: 4378 return get_phone_number(log, ad) 4379 return voice_mail_number 4380 4381 4382def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP): 4383 """Ensure ads idle (not in call). 4384 """ 4385 result = True 4386 for ad in ads: 4387 if not ensure_phone_idle(log, ad, max_time=max_time): 4388 result = False 4389 return result 4390 4391 4392def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP): 4393 """Ensure ad idle (not in call). 4394 """ 4395 if ad.droid.telecomIsInCall(): 4396 ad.droid.telecomEndCall() 4397 if not wait_for_droid_not_in_call(log, ad, max_time=max_time): 4398 ad.log.error("Failed to end call") 4399 return False 4400 return True 4401 4402 4403def ensure_phone_subscription(log, ad): 4404 """Ensure Phone Subscription. 4405 """ 4406 #check for sim and service 4407 duration = 0 4408 while duration < MAX_WAIT_TIME_NW_SELECTION: 4409 subInfo = ad.droid.subscriptionGetAllSubInfoList() 4410 if subInfo and len(subInfo) >= 1: 4411 ad.log.debug("Find valid subcription %s", subInfo) 4412 break 4413 else: 4414 ad.log.info("Did not find a valid subscription") 4415 time.sleep(5) 4416 duration += 5 4417 else: 4418 ad.log.error("Unable to find A valid subscription!") 4419 return False 4420 if ad.droid.subscriptionGetDefaultDataSubId() <= INVALID_SUB_ID and ( 4421 ad.droid.subscriptionGetDefaultVoiceSubId() <= INVALID_SUB_ID): 4422 ad.log.error("No Valid Voice or Data Sub ID") 4423 return False 4424 voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 4425 data_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 4426 if not wait_for_voice_attach_for_subscription( 4427 log, ad, voice_sub_id, MAX_WAIT_TIME_NW_SELECTION - 4428 duration) and not wait_for_data_attach_for_subscription( 4429 log, ad, data_sub_id, MAX_WAIT_TIME_NW_SELECTION - duration): 4430 ad.log.error("Did Not Attach For Voice or Data Services") 4431 return False 4432 return True 4433 4434 4435def ensure_phone_default_state(log, ad, check_subscription=True): 4436 """Ensure ad in default state. 4437 Phone not in call. 4438 Phone have no stored WiFi network and WiFi disconnected. 4439 Phone not in airplane mode. 4440 """ 4441 result = True 4442 if not toggle_airplane_mode(log, ad, False, False): 4443 ad.log.error("Fail to turn off airplane mode") 4444 result = False 4445 try: 4446 set_wifi_to_default(log, ad) 4447 if ad.droid.telecomIsInCall(): 4448 ad.droid.telecomEndCall() 4449 if not wait_for_droid_not_in_call(log, ad): 4450 ad.log.error("Failed to end call") 4451 ad.droid.telephonyFactoryReset() 4452 ad.droid.imsFactoryReset() 4453 data_roaming = getattr(ad, 'roaming', False) 4454 if get_cell_data_roaming_state_by_adb(ad) != data_roaming: 4455 set_cell_data_roaming_state_by_adb(ad, data_roaming) 4456 remove_mobile_data_usage_limit(ad) 4457 if not wait_for_not_network_rat( 4458 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA): 4459 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA, 4460 RAT_FAMILY_WLAN) 4461 result = False 4462 4463 if check_subscription and not ensure_phone_subscription(log, ad): 4464 ad.log.error("Unable to find a valid subscription!") 4465 result = False 4466 except Exception as e: 4467 ad.log.error("%s failure, toggle APM instead", e) 4468 toggle_airplane_mode_by_adb(log, ad, True) 4469 toggle_airplane_mode_by_adb(log, ad, False) 4470 ad.send_keycode("ENDCALL") 4471 ad.adb.shell("settings put global wfc_ims_enabled 0") 4472 ad.adb.shell("settings put global mobile_data 1") 4473 4474 return result 4475 4476 4477def ensure_phones_default_state(log, ads, check_subscription=True): 4478 """Ensure ads in default state. 4479 Phone not in call. 4480 Phone have no stored WiFi network and WiFi disconnected. 4481 Phone not in airplane mode. 4482 4483 Returns: 4484 True if all steps of restoring default state succeed. 4485 False if any of the steps to restore default state fails. 4486 """ 4487 tasks = [] 4488 for ad in ads: 4489 tasks.append((ensure_phone_default_state, (log, ad, 4490 check_subscription))) 4491 if not multithread_func(log, tasks): 4492 log.error("Ensure_phones_default_state Fail.") 4493 return False 4494 return True 4495 4496 4497def check_is_wifi_connected(log, ad, wifi_ssid): 4498 """Check if ad is connected to wifi wifi_ssid. 4499 4500 Args: 4501 log: Log object. 4502 ad: Android device object. 4503 wifi_ssid: WiFi network SSID. 4504 4505 Returns: 4506 True if wifi is connected to wifi_ssid 4507 False if wifi is not connected to wifi_ssid 4508 """ 4509 wifi_info = ad.droid.wifiGetConnectionInfo() 4510 if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid: 4511 ad.log.info("Wifi is connected to %s", wifi_ssid) 4512 ad.on_mobile_data = False 4513 return True 4514 else: 4515 ad.log.info("Wifi is not connected to %s", wifi_ssid) 4516 ad.log.debug("Wifi connection_info=%s", wifi_info) 4517 ad.on_mobile_data = True 4518 return False 4519 4520 4521def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3): 4522 """Ensure ad connected to wifi on network wifi_ssid. 4523 4524 Args: 4525 log: Log object. 4526 ad: Android device object. 4527 wifi_ssid: WiFi network SSID. 4528 wifi_pwd: optional secure network password. 4529 retries: the number of retries. 4530 4531 Returns: 4532 True if wifi is connected to wifi_ssid 4533 False if wifi is not connected to wifi_ssid 4534 """ 4535 network = {WIFI_SSID_KEY: wifi_ssid} 4536 if wifi_pwd: 4537 network[WIFI_PWD_KEY] = wifi_pwd 4538 for i in range(retries): 4539 if not ad.droid.wifiCheckState(): 4540 ad.log.info("Wifi state is down. Turn on Wifi") 4541 ad.droid.wifiToggleState(True) 4542 if check_is_wifi_connected(log, ad, wifi_ssid): 4543 ad.log.info("Wifi is connected to %s", wifi_ssid) 4544 return True 4545 else: 4546 ad.log.info("Connecting to wifi %s", wifi_ssid) 4547 try: 4548 ad.droid.wifiConnectByConfig(network) 4549 except Exception: 4550 ad.log.info("Connecting to wifi by wifiConnect instead") 4551 ad.droid.wifiConnect(network) 4552 time.sleep(20) 4553 if check_is_wifi_connected(log, ad, wifi_ssid): 4554 ad.log.info("Connected to Wifi %s", wifi_ssid) 4555 return True 4556 ad.log.info("Fail to connected to wifi %s", wifi_ssid) 4557 return False 4558 4559 4560def forget_all_wifi_networks(log, ad): 4561 """Forget all stored wifi network information 4562 4563 Args: 4564 log: log object 4565 ad: AndroidDevice object 4566 4567 Returns: 4568 boolean success (True) or failure (False) 4569 """ 4570 if not ad.droid.wifiGetConfiguredNetworks(): 4571 ad.on_mobile_data = True 4572 return True 4573 try: 4574 old_state = ad.droid.wifiCheckState() 4575 wifi_test_utils.reset_wifi(ad) 4576 wifi_toggle_state(log, ad, old_state) 4577 except Exception as e: 4578 log.error("forget_all_wifi_networks with exception: %s", e) 4579 return False 4580 ad.on_mobile_data = True 4581 return True 4582 4583 4584def wifi_reset(log, ad, disable_wifi=True): 4585 """Forget all stored wifi networks and (optionally) disable WiFi 4586 4587 Args: 4588 log: log object 4589 ad: AndroidDevice object 4590 disable_wifi: boolean to disable wifi, defaults to True 4591 Returns: 4592 boolean success (True) or failure (False) 4593 """ 4594 if not forget_all_wifi_networks(log, ad): 4595 ad.log.error("Unable to forget all networks") 4596 return False 4597 if not wifi_toggle_state(log, ad, not disable_wifi): 4598 ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi) 4599 return False 4600 return True 4601 4602 4603def set_wifi_to_default(log, ad): 4604 """Set wifi to default state (Wifi disabled and no configured network) 4605 4606 Args: 4607 log: log object 4608 ad: AndroidDevice object 4609 4610 Returns: 4611 boolean success (True) or failure (False) 4612 """ 4613 ad.droid.wifiFactoryReset() 4614 ad.droid.wifiToggleState(False) 4615 ad.on_mobile_data = True 4616 4617 4618def wifi_toggle_state(log, ad, state, retries=3): 4619 """Toggle the WiFi State 4620 4621 Args: 4622 log: log object 4623 ad: AndroidDevice object 4624 state: True, False, or None 4625 4626 Returns: 4627 boolean success (True) or failure (False) 4628 """ 4629 for i in range(retries): 4630 if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False): 4631 ad.on_mobile_data = not state 4632 return True 4633 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 4634 return False 4635 4636 4637def start_wifi_tethering(log, ad, ssid, password, ap_band=None): 4638 """Start a Tethering Session 4639 4640 Args: 4641 log: log object 4642 ad: AndroidDevice object 4643 ssid: the name of the WiFi network 4644 password: optional password, used for secure networks. 4645 ap_band=DEPRECATED specification of 2G or 5G tethering 4646 Returns: 4647 boolean success (True) or failure (False) 4648 """ 4649 return wifi_test_utils._assert_on_fail_handler( 4650 wifi_test_utils.start_wifi_tethering, 4651 False, 4652 ad, 4653 ssid, 4654 password, 4655 band=ap_band) 4656 4657 4658def stop_wifi_tethering(log, ad): 4659 """Stop a Tethering Session 4660 4661 Args: 4662 log: log object 4663 ad: AndroidDevice object 4664 Returns: 4665 boolean success (True) or failure (False) 4666 """ 4667 return wifi_test_utils._assert_on_fail_handler( 4668 wifi_test_utils.stop_wifi_tethering, False, ad) 4669 4670 4671def reset_preferred_network_type_to_allowable_range(log, ad): 4672 """If preferred network type is not in allowable range, reset to GEN_4G 4673 preferred network type. 4674 4675 Args: 4676 log: log object 4677 ad: android device object 4678 4679 Returns: 4680 None 4681 """ 4682 for sub_id, sub_info in ad.cfg["subscription"].items(): 4683 current_preference = \ 4684 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id) 4685 ad.log.debug("sub_id network preference is %s", current_preference) 4686 try: 4687 if current_preference not in get_allowable_network_preference( 4688 sub_info["operator"], sub_info["phone_type"]): 4689 network_preference = network_preference_for_generation( 4690 GEN_4G, sub_info["operator"], sub_info["phone_type"]) 4691 ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4692 network_preference, sub_id) 4693 except KeyError: 4694 pass 4695 4696 4697def task_wrapper(task): 4698 """Task wrapper for multithread_func 4699 4700 Args: 4701 task[0]: function to be wrapped. 4702 task[1]: function args. 4703 4704 Returns: 4705 Return value of wrapped function call. 4706 """ 4707 func = task[0] 4708 params = task[1] 4709 return func(*params) 4710 4711 4712def run_multithread_func_async(log, task): 4713 """Starts a multi-threaded function asynchronously. 4714 4715 Args: 4716 log: log object. 4717 task: a task to be executed in parallel. 4718 4719 Returns: 4720 Future object representing the execution of the task. 4721 """ 4722 executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) 4723 try: 4724 future_object = executor.submit(task_wrapper, task) 4725 except Exception as e: 4726 log.error("Exception error %s", e) 4727 raise 4728 return future_object 4729 4730 4731def run_multithread_func(log, tasks): 4732 """Run multi-thread functions and return results. 4733 4734 Args: 4735 log: log object. 4736 tasks: a list of tasks to be executed in parallel. 4737 4738 Returns: 4739 results for tasks. 4740 """ 4741 MAX_NUMBER_OF_WORKERS = 10 4742 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks)) 4743 executor = concurrent.futures.ThreadPoolExecutor( 4744 max_workers=number_of_workers) 4745 if not log: log = logging 4746 try: 4747 results = list(executor.map(task_wrapper, tasks)) 4748 except Exception as e: 4749 log.error("Exception error %s", e) 4750 raise 4751 executor.shutdown() 4752 if log: 4753 log.info("multithread_func %s result: %s", 4754 [task[0].__name__ for task in tasks], results) 4755 return results 4756 4757 4758def multithread_func(log, tasks): 4759 """Multi-thread function wrapper. 4760 4761 Args: 4762 log: log object. 4763 tasks: tasks to be executed in parallel. 4764 4765 Returns: 4766 True if all tasks return True. 4767 False if any task return False. 4768 """ 4769 results = run_multithread_func(log, tasks) 4770 for r in results: 4771 if not r: 4772 return False 4773 return True 4774 4775 4776def multithread_func_and_check_results(log, tasks, expected_results): 4777 """Multi-thread function wrapper. 4778 4779 Args: 4780 log: log object. 4781 tasks: tasks to be executed in parallel. 4782 expected_results: check if the results from tasks match expected_results. 4783 4784 Returns: 4785 True if expected_results are met. 4786 False if expected_results are not met. 4787 """ 4788 return_value = True 4789 results = run_multithread_func(log, tasks) 4790 log.info("multithread_func result: %s, expecting %s", results, 4791 expected_results) 4792 for task, result, expected_result in zip(tasks, results, expected_results): 4793 if result != expected_result: 4794 logging.info("Result for task %s is %s, expecting %s", task[0], 4795 result, expected_result) 4796 return_value = False 4797 return return_value 4798 4799 4800def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME): 4801 """Set phone screen on time. 4802 4803 Args: 4804 log: Log object. 4805 ad: Android device object. 4806 screen_on_time: screen on time. 4807 This is optional, default value is MAX_SCREEN_ON_TIME. 4808 Returns: 4809 True if set successfully. 4810 """ 4811 ad.droid.setScreenTimeout(screen_on_time) 4812 return screen_on_time == ad.droid.getScreenTimeout() 4813 4814 4815def set_phone_silent_mode(log, ad, silent_mode=True): 4816 """Set phone silent mode. 4817 4818 Args: 4819 log: Log object. 4820 ad: Android device object. 4821 silent_mode: set phone silent or not. 4822 This is optional, default value is True (silent mode on). 4823 Returns: 4824 True if set successfully. 4825 """ 4826 ad.droid.toggleRingerSilentMode(silent_mode) 4827 ad.droid.setMediaVolume(0) 4828 ad.droid.setVoiceCallVolume(0) 4829 ad.droid.setAlarmVolume(0) 4830 out = ad.adb.shell("settings list system | grep volume") 4831 for attr in re.findall(r"(volume_.*)=\d+", out): 4832 ad.adb.shell("settings put system %s 0" % attr) 4833 return silent_mode == ad.droid.checkRingerSilentMode() 4834 4835 4836def set_preferred_network_mode_pref(log, ad, sub_id, network_preference): 4837 """Set Preferred Network Mode for Sub_id 4838 Args: 4839 log: Log object. 4840 ad: Android device object. 4841 sub_id: Subscription ID. 4842 network_preference: Network Mode Type 4843 """ 4844 ad.log.info("Setting ModePref to %s for Sub %s", network_preference, 4845 sub_id) 4846 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4847 network_preference, sub_id): 4848 ad.log.error("Set sub_id %s PreferredNetworkType %s failed", sub_id, 4849 network_preference) 4850 return False 4851 return True 4852 4853 4854def set_preferred_subid_for_sms(log, ad, sub_id): 4855 """set subscription id for SMS 4856 4857 Args: 4858 log: Log object. 4859 ad: Android device object. 4860 sub_id :Subscription ID. 4861 4862 """ 4863 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id) 4864 ad.droid.subscriptionSetDefaultSmsSubId(sub_id) 4865 # Wait to make sure settings take effect 4866 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4867 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId() 4868 4869 4870def set_preferred_subid_for_data(log, ad, sub_id): 4871 """set subscription id for data 4872 4873 Args: 4874 log: Log object. 4875 ad: Android device object. 4876 sub_id :Subscription ID. 4877 4878 """ 4879 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id) 4880 ad.droid.subscriptionSetDefaultDataSubId(sub_id) 4881 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4882 # Wait to make sure settings take effect 4883 # Data SIM change takes around 1 min 4884 # Check whether data has changed to selected sim 4885 if not wait_for_data_connection(log, ad, True, 4886 MAX_WAIT_TIME_DATA_SUB_CHANGE): 4887 log.error("Data Connection failed - Not able to switch Data SIM") 4888 return False 4889 return True 4890 4891 4892def set_preferred_subid_for_voice(log, ad, sub_id): 4893 """set subscription id for voice 4894 4895 Args: 4896 log: Log object. 4897 ad: Android device object. 4898 sub_id :Subscription ID. 4899 4900 """ 4901 ad.log.info("Setting subscription %s as Voice SIM", sub_id) 4902 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 4903 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id) 4904 # Wait to make sure settings take effect 4905 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4906 return True 4907 4908 4909def set_call_state_listen_level(log, ad, value, sub_id): 4910 """Set call state listen level for subscription id. 4911 4912 Args: 4913 log: Log object. 4914 ad: Android device object. 4915 value: True or False 4916 sub_id :Subscription ID. 4917 4918 Returns: 4919 True or False 4920 """ 4921 if sub_id == INVALID_SUB_ID: 4922 log.error("Invalid Subscription ID") 4923 return False 4924 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 4925 "Foreground", value, sub_id) 4926 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 4927 "Ringing", value, sub_id) 4928 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 4929 "Background", value, sub_id) 4930 return True 4931 4932 4933def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False): 4934 """set subscription id for voice, sms and data 4935 4936 Args: 4937 log: Log object. 4938 ad: Android device object. 4939 sub_id :Subscription ID. 4940 voice: True if to set subscription as default voice subscription 4941 sms: True if to set subscription as default sms subscription 4942 data: True if to set subscription as default data subscription 4943 4944 """ 4945 if sub_id == INVALID_SUB_ID: 4946 log.error("Invalid Subscription ID") 4947 return False 4948 else: 4949 if voice: 4950 if not set_preferred_subid_for_voice(log, ad, sub_id): 4951 return False 4952 if sms: 4953 if not set_preferred_subid_for_sms(log, ad, sub_id): 4954 return False 4955 if data: 4956 if not set_preferred_subid_for_data(log, ad, sub_id): 4957 return False 4958 return True 4959 4960 4961def is_event_match(event, field, value): 4962 """Return if <field> in "event" match <value> or not. 4963 4964 Args: 4965 event: event to test. This event need to have <field>. 4966 field: field to match. 4967 value: value to match. 4968 4969 Returns: 4970 True if <field> in "event" match <value>. 4971 False otherwise. 4972 """ 4973 return is_event_match_for_list(event, field, [value]) 4974 4975 4976def is_event_match_for_list(event, field, value_list): 4977 """Return if <field> in "event" match any one of the value 4978 in "value_list" or not. 4979 4980 Args: 4981 event: event to test. This event need to have <field>. 4982 field: field to match. 4983 value_list: a list of value to match. 4984 4985 Returns: 4986 True if <field> in "event" match one of the value in "value_list". 4987 False otherwise. 4988 """ 4989 try: 4990 value_in_event = event['data'][field] 4991 except KeyError: 4992 return False 4993 for value in value_list: 4994 if value_in_event == value: 4995 return True 4996 return False 4997 4998 4999def is_network_call_back_event_match(event, network_callback_id, 5000 network_callback_event): 5001 try: 5002 return ( 5003 (network_callback_id == event['data'][NetworkCallbackContainer.ID]) 5004 and (network_callback_event == event['data'] 5005 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT])) 5006 except KeyError: 5007 return False 5008 5009 5010def is_build_id(log, ad, build_id): 5011 """Return if ad's build id is the same as input parameter build_id. 5012 5013 Args: 5014 log: log object. 5015 ad: android device object. 5016 build_id: android build id. 5017 5018 Returns: 5019 True if ad's build id is the same as input parameter build_id. 5020 False otherwise. 5021 """ 5022 actual_bid = ad.droid.getBuildID() 5023 5024 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay()) 5025 #In case we want to log more stuff/more granularity... 5026 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID())) 5027 #log.info("{} BUILD FINGERPRINT: {} " 5028 # .format(ad.serial), ad.droid.getBuildFingerprint()) 5029 #log.info("{} BUILD TYPE: {} " 5030 # .format(ad.serial), ad.droid.getBuildType()) 5031 #log.info("{} BUILD NUMBER: {} " 5032 # .format(ad.serial), ad.droid.getBuildNumber()) 5033 if actual_bid.upper() != build_id.upper(): 5034 ad.log.error("%s: Incorrect Build ID", ad.model) 5035 return False 5036 return True 5037 5038 5039def is_uri_equivalent(uri1, uri2): 5040 """Check whether two input uris match or not. 5041 5042 Compare Uris. 5043 If Uris are tel URI, it will only take the digit part 5044 and compare as phone number. 5045 Else, it will just do string compare. 5046 5047 Args: 5048 uri1: 1st uri to be compared. 5049 uri2: 2nd uri to be compared. 5050 5051 Returns: 5052 True if two uris match. Otherwise False. 5053 """ 5054 5055 #If either is None/empty we return false 5056 if not uri1 or not uri2: 5057 return False 5058 5059 try: 5060 if uri1.startswith('tel:') and uri2.startswith('tel:'): 5061 uri1_number = get_number_from_tel_uri(uri1) 5062 uri2_number = get_number_from_tel_uri(uri2) 5063 return check_phone_number_match(uri1_number, uri2_number) 5064 else: 5065 return uri1 == uri2 5066 except AttributeError as e: 5067 return False 5068 5069 5070def get_call_uri(ad, call_id): 5071 """Get call's uri field. 5072 5073 Get Uri for call_id in ad. 5074 5075 Args: 5076 ad: android device object. 5077 call_id: the call id to get Uri from. 5078 5079 Returns: 5080 call's Uri if call is active and have uri field. None otherwise. 5081 """ 5082 try: 5083 call_detail = ad.droid.telecomCallGetDetails(call_id) 5084 return call_detail["Handle"]["Uri"] 5085 except: 5086 return None 5087 5088 5089def get_number_from_tel_uri(uri): 5090 """Get Uri number from tel uri 5091 5092 Args: 5093 uri: input uri 5094 5095 Returns: 5096 If input uri is tel uri, return the number part. 5097 else return None. 5098 """ 5099 if uri.startswith('tel:'): 5100 uri_number = ''.join( 5101 i for i in urllib.parse.unquote(uri) if i.isdigit()) 5102 return uri_number 5103 else: 5104 return None 5105 5106 5107def find_qxdm_log_mask(ad, mask="default.cfg"): 5108 """Find QXDM logger mask.""" 5109 if "/" not in mask: 5110 # Call nexuslogger to generate log mask 5111 start_nexuslogger(ad) 5112 # Find the log mask path 5113 for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs", 5114 "/vendor/etc/mdlog/"): 5115 out = ad.adb.shell( 5116 "find %s -type f -iname %s" % (path, mask), ignore_status=True) 5117 if out and "No such" not in out and "Permission denied" not in out: 5118 if path.startswith("/vendor/"): 5119 ad.qxdm_log_path = DEFAULT_QXDM_LOG_PATH 5120 else: 5121 ad.qxdm_log_path = path 5122 return out.split("\n")[0] 5123 if mask in ad.adb.shell("ls /vendor/etc/mdlog/"): 5124 ad.qxdm_log_path = DEFAULT_QXDM_LOG_PATH 5125 return "%s/%s" % ("/vendor/etc/mdlog/", mask) 5126 else: 5127 out = ad.adb.shell("ls %s" % mask, ignore_status=True) 5128 if out and "No such" not in out: 5129 ad.qxdm_log_path = "/data/vendor/radio/diag_logs" 5130 return mask 5131 ad.log.warning("Could NOT find QXDM logger mask path for %s", mask) 5132 5133 5134def set_qxdm_logger_command(ad, mask=None): 5135 """Set QXDM logger always on. 5136 5137 Args: 5138 ad: android device object. 5139 5140 """ 5141 ## Neet to check if log mask will be generated without starting nexus logger 5142 masks = [] 5143 mask_path = None 5144 if mask: 5145 masks = [mask] 5146 masks.extend(["QC_Default.cfg", "default.cfg"]) 5147 for mask in masks: 5148 mask_path = find_qxdm_log_mask(ad, mask) 5149 if mask_path: break 5150 if not mask_path: 5151 ad.log.error("Cannot find QXDM mask %s", mask) 5152 ad.qxdm_logger_command = None 5153 return False 5154 else: 5155 ad.log.info("Use QXDM log mask %s", mask_path) 5156 ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path) 5157 output_path = os.path.join(ad.qxdm_log_path, "logs") 5158 ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 50 -c" % 5159 (mask_path, output_path)) 5160 conf_path = os.path.join(ad.qxdm_log_path, "diag.conf") 5161 # Enable qxdm always on so that after device reboot, qxdm will be 5162 # turned on automatically 5163 ad.adb.shell('echo "%s" > %s' % (ad.qxdm_logger_command, conf_path)) 5164 ad.adb.shell( 5165 "setprop persist.vendor.sys.modem.diag.mdlog true", ignore_status=True) 5166 # Legacy pixels use persist.sys.modem.diag.mdlog. 5167 ad.adb.shell( 5168 "setprop persist.sys.modem.diag.mdlog true", ignore_status=True) 5169 return True 5170 5171 5172def stop_qxdm_logger(ad): 5173 """Stop QXDM logger.""" 5174 for cmd in ("diag_mdlog -k", "killall diag_mdlog"): 5175 output = ad.adb.shell("ps -ef | grep mdlog") or "" 5176 if "diag_mdlog" not in output: 5177 break 5178 ad.log.debug("Kill the existing qxdm process") 5179 ad.adb.shell(cmd, ignore_status=True) 5180 time.sleep(5) 5181 5182 5183def start_qxdm_logger(ad, begin_time=None): 5184 """Start QXDM logger.""" 5185 if not getattr(ad, "qxdm_log", True): return 5186 # Delete existing QXDM logs 5 minutes earlier than the begin_time 5187 if getattr(ad, "qxdm_log_path", None): 5188 seconds = None 5189 if begin_time: 5190 current_time = get_current_epoch_time() 5191 seconds = int((current_time - begin_time) / 1000.0) + 10 * 60 5192 elif len(ad.get_file_names(ad.qxdm_log_path)) > 50: 5193 seconds = 900 5194 if seconds: 5195 ad.adb.shell( 5196 "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" % 5197 (ad.qxdm_log_path, seconds)) 5198 if getattr(ad, "qxdm_logger_command", None): 5199 output = ad.adb.shell("ps -ef | grep mdlog") or "" 5200 if ad.qxdm_logger_command not in output: 5201 ad.log.debug("QXDM logging command %s is not running", 5202 ad.qxdm_logger_command) 5203 if "diag_mdlog" in output: 5204 # Kill the existing diag_mdlog process 5205 # Only one diag_mdlog process can be run 5206 stop_qxdm_logger(ad) 5207 ad.log.info("Start QXDM logger") 5208 ad.adb.shell_nb(ad.qxdm_logger_command) 5209 elif not ad.get_file_names(ad.qxdm_log_path, 60): 5210 ad.log.debug("Existing diag_mdlog is not generating logs") 5211 stop_qxdm_logger(ad) 5212 ad.adb.shell_nb(ad.qxdm_logger_command) 5213 return True 5214 5215 5216def start_qxdm_loggers(log, ads, begin_time=None): 5217 tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads 5218 if getattr(ad, "qxdm_log", True)] 5219 if tasks: run_multithread_func(log, tasks) 5220 5221 5222def stop_qxdm_loggers(log, ads): 5223 tasks = [(stop_qxdm_logger, [ad]) for ad in ads] 5224 run_multithread_func(log, tasks) 5225 5226 5227def start_nexuslogger(ad): 5228 """Start Nexus/Pixel Logger Apk.""" 5229 qxdm_logger_apk = None 5230 for apk, activity in (("com.android.nexuslogger", ".MainActivity"), 5231 ("com.android.pixellogger", 5232 ".ui.main.MainActivity")): 5233 if ad.is_apk_installed(apk): 5234 qxdm_logger_apk = apk 5235 break 5236 if not qxdm_logger_apk: return 5237 if ad.is_apk_running(qxdm_logger_apk): 5238 if "granted=true" in ad.adb.shell( 5239 "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk): 5240 return True 5241 else: 5242 ad.log.info("Kill %s" % qxdm_logger_apk) 5243 ad.force_stop_apk(qxdm_logger_apk) 5244 time.sleep(5) 5245 for perm in ("READ", "WRITE"): 5246 ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" % 5247 (qxdm_logger_apk, perm)) 5248 time.sleep(2) 5249 for i in range(3): 5250 ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1)) 5251 ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity)) 5252 time.sleep(5) 5253 if ad.is_apk_running(qxdm_logger_apk): 5254 ad.send_keycode("HOME") 5255 return True 5256 return False 5257 5258 5259def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"): 5260 """Check if QXDM logger always on is set. 5261 5262 Args: 5263 ad: android device object. 5264 5265 """ 5266 output = ad.adb.shell( 5267 "ls /data/vendor/radio/diag_logs/", ignore_status=True) 5268 if not output or "No such" in output: 5269 return True 5270 if mask_file not in ad.adb.shell( 5271 "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True): 5272 return False 5273 return True 5274 5275 5276def start_adb_tcpdump(ad, test_name, mask="ims"): 5277 """Start tcpdump on any iface 5278 5279 Args: 5280 ad: android device object. 5281 test_name: tcpdump file name will have this 5282 5283 """ 5284 ad.log.debug("Ensuring no tcpdump is running in background") 5285 try: 5286 ad.adb.shell("killall -9 tcpdump") 5287 except AdbError: 5288 ad.log.warn("Killing existing tcpdump processes failed") 5289 out = ad.adb.shell("ls -l /sdcard/tcpdump/") 5290 if "No such file" in out or not out: 5291 ad.adb.shell("mkdir /sdcard/tcpdump") 5292 else: 5293 ad.adb.shell("rm -rf /sdcard/tcpdump/*", ignore_status=True) 5294 5295 begin_time = epoch_to_log_line_timestamp(get_current_epoch_time()) 5296 begin_time = normalize_log_line_timestamp(begin_time) 5297 5298 file_name = "/sdcard/tcpdump/tcpdump_%s_%s_%s.pcap" % (ad.serial, 5299 test_name, 5300 begin_time) 5301 ad.log.info("tcpdump file is %s", file_name) 5302 if mask == "all": 5303 cmd = "adb -s {} shell tcpdump -i any -s0 -w {}" . \ 5304 format(ad.serial, file_name) 5305 else: 5306 cmd = "adb -s {} shell tcpdump -i any -s0 -n -p udp port 500 or \ 5307 udp port 4500 -w {}".format(ad.serial, file_name) 5308 ad.log.debug("%s" % cmd) 5309 return start_standing_subprocess(cmd, 5) 5310 5311 5312def stop_adb_tcpdump(ad, proc=None, pull_tcpdump=False, test_name=""): 5313 """Stops tcpdump on any iface 5314 Pulls the tcpdump file in the tcpdump dir 5315 5316 Args: 5317 ad: android device object. 5318 tcpdump_pid: need to know which pid to stop 5319 tcpdump_file: filename needed to pull out 5320 5321 """ 5322 ad.log.info("Stopping and pulling tcpdump if any") 5323 try: 5324 if proc is not None: 5325 stop_standing_subprocess(proc) 5326 except Exception as e: 5327 ad.log.warning(e) 5328 if pull_tcpdump: 5329 log_path = os.path.join(ad.log_path, test_name, 5330 "TCPDUMP_%s" % ad.serial) 5331 utils.create_dir(log_path) 5332 ad.adb.pull("/sdcard/tcpdump/. %s" % log_path) 5333 ad.adb.shell("rm -rf /sdcard/tcpdump/*", ignore_status=True) 5334 return True 5335 5336 5337def fastboot_wipe(ad, skip_setup_wizard=True): 5338 """Wipe the device in fastboot mode. 5339 5340 Pull sl4a apk from device. Terminate all sl4a sessions, 5341 Reboot the device to bootloader, wipe the device by fastboot. 5342 Reboot the device. wait for device to complete booting 5343 Re-intall and start an sl4a session. 5344 """ 5345 status = True 5346 # Pull sl4a apk from device 5347 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME) 5348 result = re.search(r"package:(.*)", out) 5349 if not result: 5350 ad.log.error("Couldn't find sl4a apk") 5351 else: 5352 sl4a_apk = result.group(1) 5353 ad.log.info("Get sl4a apk from %s", sl4a_apk) 5354 ad.pull_files([sl4a_apk], "/tmp/") 5355 ad.stop_services() 5356 ad.log.info("Reboot to bootloader") 5357 ad.adb.reboot_bootloader(ignore_status=True) 5358 ad.log.info("Wipe in fastboot") 5359 try: 5360 ad.fastboot._w() 5361 except Exception as e: 5362 ad.log.error(e) 5363 status = False 5364 time.sleep(30) #sleep time after fastboot wipe 5365 for _ in range(2): 5366 try: 5367 ad.log.info("Reboot in fastboot") 5368 ad.fastboot.reboot() 5369 ad.wait_for_boot_completion() 5370 break 5371 except Exception as e: 5372 ad.log.error("Exception error %s", e) 5373 ad.root_adb() 5374 if result: 5375 # Try to reinstall for three times as the device might not be 5376 # ready to apk install shortly after boot complete. 5377 for _ in range(3): 5378 if ad.is_sl4a_installed(): 5379 break 5380 ad.log.info("Re-install sl4a") 5381 ad.adb.install("-r /tmp/base.apk", ignore_status=True) 5382 time.sleep(10) 5383 try: 5384 ad.start_adb_logcat() 5385 except: 5386 ad.log.exception("Failed to start adb logcat!") 5387 if skip_setup_wizard: 5388 ad.exit_setup_wizard() 5389 if ad.skip_sl4a: return status 5390 bring_up_sl4a(ad) 5391 5392 return status 5393 5394 5395def bring_up_sl4a(ad, attemps=3): 5396 for i in range(attemps): 5397 try: 5398 droid, ed = ad.get_droid() 5399 ed.start() 5400 ad.log.info("Broght up new sl4a session") 5401 except Exception as e: 5402 if i < attemps - 1: 5403 ad.log.info(e) 5404 time.sleep(10) 5405 else: 5406 ad.log.error(e) 5407 raise 5408 5409 5410def reboot_device(ad): 5411 ad.reboot() 5412 ad.ensure_screen_on() 5413 unlock_sim(ad) 5414 5415 5416def unlocking_device(ad, device_password=None): 5417 """First unlock device attempt, required after reboot""" 5418 ad.unlock_screen(device_password) 5419 time.sleep(2) 5420 ad.adb.wait_for_device(timeout=180) 5421 if not ad.is_waiting_for_unlock_pin(): 5422 return True 5423 else: 5424 ad.unlock_screen(device_password) 5425 time.sleep(2) 5426 ad.adb.wait_for_device(timeout=180) 5427 if ad.wait_for_window_ready(): 5428 return True 5429 ad.log.error("Unable to unlock to user window") 5430 return False 5431 5432 5433def refresh_sl4a_session(ad): 5434 try: 5435 ad.droid.logI("Checking SL4A connection") 5436 ad.log.info("Existing sl4a session is active") 5437 except: 5438 ad.terminate_all_sessions() 5439 ad.ensure_screen_on() 5440 ad.log.info("Open new sl4a connection") 5441 bring_up_sl4a(ad) 5442 5443 5444def reset_device_password(ad, device_password=None): 5445 # Enable or Disable Device Password per test bed config 5446 unlock_sim(ad) 5447 screen_lock = ad.is_screen_lock_enabled() 5448 if device_password: 5449 try: 5450 refresh_sl4a_session(ad) 5451 ad.droid.setDevicePassword(device_password) 5452 except Exception as e: 5453 ad.log.warning("setDevicePassword failed with %s", e) 5454 try: 5455 ad.droid.setDevicePassword(device_password, "1111") 5456 except Exception as e: 5457 ad.log.warning( 5458 "setDevicePassword providing previous password error: %s", 5459 e) 5460 time.sleep(2) 5461 if screen_lock: 5462 # existing password changed 5463 return 5464 else: 5465 # enable device password and log in for the first time 5466 ad.log.info("Enable device password") 5467 ad.adb.wait_for_device(timeout=180) 5468 else: 5469 if not screen_lock: 5470 # no existing password, do not set password 5471 return 5472 else: 5473 # password is enabled on the device 5474 # need to disable the password and log in on the first time 5475 # with unlocking with a swipe 5476 ad.log.info("Disable device password") 5477 ad.unlock_screen(password="1111") 5478 refresh_sl4a_session(ad) 5479 ad.ensure_screen_on() 5480 try: 5481 ad.droid.disableDevicePassword() 5482 except Exception as e: 5483 ad.log.warning("disableDevicePassword failed with %s", e) 5484 fastboot_wipe(ad) 5485 time.sleep(2) 5486 ad.adb.wait_for_device(timeout=180) 5487 refresh_sl4a_session(ad) 5488 if not ad.is_adb_logcat_on: 5489 ad.start_adb_logcat() 5490 5491 5492def get_sim_state(ad): 5493 try: 5494 state = ad.droid.telephonyGetSimState() 5495 except: 5496 state = ad.adb.getprop("gsm.sim.state") 5497 return state 5498 5499 5500def is_sim_locked(ad): 5501 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED 5502 5503 5504def unlock_sim(ad): 5505 #The puk and pin can be provided in testbed config file. 5506 #"AndroidDevice": [{"serial": "84B5T15A29018214", 5507 # "adb_logcat_param": "-b all", 5508 # "puk": "12345678", 5509 # "puk_pin": "1234"}] 5510 if not is_sim_locked(ad): 5511 return True 5512 else: 5513 ad.is_sim_locked = True 5514 puk_pin = getattr(ad, "puk_pin", "1111") 5515 try: 5516 if not hasattr(ad, 'puk'): 5517 ad.log.info("Enter SIM pin code") 5518 ad.droid.telephonySupplyPin(puk_pin) 5519 else: 5520 ad.log.info("Enter PUK code and pin") 5521 ad.droid.telephonySupplyPuk(ad.puk, puk_pin) 5522 except: 5523 # if sl4a is not available, use adb command 5524 ad.unlock_screen(puk_pin) 5525 if is_sim_locked(ad): 5526 ad.unlock_screen(puk_pin) 5527 time.sleep(30) 5528 return not is_sim_locked(ad) 5529 5530 5531def send_dialer_secret_code(ad, secret_code): 5532 """Send dialer secret code. 5533 5534 ad: android device controller 5535 secret_code: the secret code to be sent to dialer. the string between 5536 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#* 5537 """ 5538 action = 'android.provider.Telephony.SECRET_CODE' 5539 uri = 'android_secret_code://%s' % secret_code 5540 intent = ad.droid.makeIntent( 5541 action, 5542 uri, 5543 None, # type 5544 None, # extras 5545 None, # categories, 5546 None, # packagename, 5547 None, # classname, 5548 0x01000000) # flags 5549 ad.log.info('Issuing dialer secret dialer code: %s', secret_code) 5550 ad.droid.sendBroadcastIntent(intent) 5551 5552 5553def system_file_push(ad, src_file_path, dst_file_path): 5554 """Push system file on a device. 5555 5556 Push system file need to change some system setting and remount. 5557 """ 5558 cmd = "%s %s" % (src_file_path, dst_file_path) 5559 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 5560 skip_sl4a = True if "sl4a.apk" in src_file_path else False 5561 if "Read-only file system" in out: 5562 ad.log.info("Change read-only file system") 5563 ad.adb.disable_verity() 5564 ad.reboot(skip_sl4a) 5565 ad.adb.remount() 5566 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 5567 if "Read-only file system" in out: 5568 ad.reboot(skip_sl4a) 5569 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 5570 if "error" in out: 5571 ad.log.error("%s failed with %s", cmd, out) 5572 return False 5573 else: 5574 ad.log.info("push %s succeed") 5575 if skip_sl4a: ad.reboot(skip_sl4a) 5576 return True 5577 else: 5578 return True 5579 elif "error" in out: 5580 return False 5581 else: 5582 return True 5583 5584 5585def flash_radio(ad, file_path, skip_setup_wizard=True): 5586 """Flash radio image.""" 5587 ad.stop_services() 5588 ad.log.info("Reboot to bootloader") 5589 ad.adb.reboot_bootloader(ignore_status=True) 5590 ad.log.info("Flash radio in fastboot") 5591 try: 5592 ad.fastboot.flash("radio %s" % file_path, timeout=300) 5593 except Exception as e: 5594 ad.log.error(e) 5595 for _ in range(2): 5596 try: 5597 ad.log.info("Reboot in fastboot") 5598 ad.fastboot.reboot() 5599 ad.wait_for_boot_completion() 5600 break 5601 except Exception as e: 5602 ad.log.error("Exception error %s", e) 5603 ad.root_adb() 5604 if not ad.ensure_screen_on(): 5605 ad.log.error("User window cannot come up") 5606 ad.start_services(ad.skip_sl4a, skip_setup_wizard=skip_setup_wizard) 5607 unlock_sim(ad) 5608 5609 5610def set_preferred_apn_by_adb(ad, pref_apn_name): 5611 """Select Pref APN 5612 Set Preferred APN on UI using content query/insert 5613 It needs apn name as arg, and it will match with plmn id 5614 """ 5615 try: 5616 plmn_id = get_plmn_by_adb(ad) 5617 out = ad.adb.shell("content query --uri content://telephony/carriers " 5618 "--where \"apn='%s' and numeric='%s'\"" % 5619 (pref_apn_name, plmn_id)) 5620 if "No result found" in out: 5621 ad.log.warning("Cannot find APN %s on device", pref_apn_name) 5622 return False 5623 else: 5624 apn_id = re.search(r'_id=(\d+)', out).group(1) 5625 ad.log.info("APN ID is %s", apn_id) 5626 ad.adb.shell("content insert --uri content:" 5627 "//telephony/carriers/preferapn --bind apn_id:i:%s" % 5628 (apn_id)) 5629 out = ad.adb.shell("content query --uri " 5630 "content://telephony/carriers/preferapn") 5631 if "No result found" in out: 5632 ad.log.error("Failed to set prefer APN %s", pref_apn_name) 5633 return False 5634 elif apn_id == re.search(r'_id=(\d+)', out).group(1): 5635 ad.log.info("Preferred APN set to %s", pref_apn_name) 5636 return True 5637 except Exception as e: 5638 ad.log.error("Exception while setting pref apn %s", e) 5639 return True 5640 5641 5642def check_apm_mode_on_by_serial(ad, serial_id): 5643 try: 5644 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id, 5645 "grep -i airplanemodeon", "cut -f2 -d ' '")) 5646 output = exe_cmd(apm_check_cmd) 5647 if output.decode("utf-8").split("\n")[0] == "true": 5648 return True 5649 else: 5650 return False 5651 except Exception as e: 5652 ad.log.warning("Exception during check apm mode on %s", e) 5653 return True 5654 5655 5656def set_apm_mode_on_by_serial(ad, serial_id): 5657 try: 5658 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id 5659 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id 5660 exe_cmd(cmd1) 5661 exe_cmd(cmd2) 5662 except Exception as e: 5663 ad.log.warning("Exception during set apm mode on %s", e) 5664 return True 5665 5666 5667def print_radio_info(ad, extra_msg=""): 5668 for prop in ("gsm.version.baseband", "persist.radio.ver_info", 5669 "persist.radio.cnv.ver_info"): 5670 output = ad.adb.getprop(prop) 5671 ad.log.info("%s%s = %s", extra_msg, prop, output) 5672 5673 5674def wait_for_state(state_check_func, 5675 state, 5676 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE, 5677 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK, 5678 *args, 5679 **kwargs): 5680 while max_wait_time >= 0: 5681 if state_check_func(*args, **kwargs) == state: 5682 return True 5683 time.sleep(checking_interval) 5684 max_wait_time -= checking_interval 5685 return False 5686 5687 5688def power_off_sim(ad, sim_slot_id=None): 5689 try: 5690 if sim_slot_id is None: 5691 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN) 5692 verify_func = ad.droid.telephonyGetSimState 5693 verify_args = [] 5694 else: 5695 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, 5696 CARD_POWER_DOWN) 5697 verify_func = ad.droid.telephonyGetSimStateForSlotId 5698 verify_args = [sim_slot_id] 5699 except Exception as e: 5700 ad.log.error(e) 5701 return False 5702 if wait_for_state(verify_func, SIM_STATE_UNKNOWN, 5703 MAX_WAIT_TIME_FOR_STATE_CHANGE, 5704 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args): 5705 ad.log.info("SIM slot is powered off, SIM state is UNKNOWN") 5706 return True 5707 else: 5708 ad.log.info("SIM state = %s", verify_func(*verify_args)) 5709 ad.log.warning("Fail to power off SIM slot") 5710 return False 5711 5712 5713def power_on_sim(ad, sim_slot_id=None): 5714 try: 5715 if sim_slot_id is None: 5716 ad.droid.telephonySetSimPowerState(CARD_POWER_UP) 5717 verify_func = ad.droid.telephonyGetSimState 5718 verify_args = [] 5719 else: 5720 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP) 5721 verify_func = ad.droid.telephonyGetSimStateForSlotId 5722 verify_args = [sim_slot_id] 5723 except Exception as e: 5724 ad.log.error(e) 5725 return False 5726 if wait_for_state(verify_func, SIM_STATE_READY, 5727 MAX_WAIT_TIME_FOR_STATE_CHANGE, 5728 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args): 5729 ad.log.info("SIM slot is powered on, SIM state is READY") 5730 return True 5731 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED: 5732 ad.log.info("SIM is pin locked") 5733 return True 5734 else: 5735 ad.log.error("Fail to power on SIM slot") 5736 return False 5737 5738 5739def log_screen_shot(ad, test_name): 5740 file_name = "/sdcard/Pictures/screencap_%s.png" % ( 5741 utils.get_current_epoch_time()) 5742 screen_shot_path = os.path.join(ad.log_path, test_name, 5743 "Screenshot_%s" % ad.serial) 5744 utils.create_dir(screen_shot_path) 5745 ad.adb.shell("screencap -p %s" % file_name) 5746 ad.adb.pull("%s %s" % (file_name, screen_shot_path)) 5747