1#!/usr/bin/env python3 2# 3# Copyright 2022 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from future import standard_library 18standard_library.install_aliases() 19 20import json 21import logging 22import re 23import os 24import urllib.parse 25import time 26import acts.controllers.iperf_server as ipf 27import struct 28 29from acts import signals 30from queue import Empty 31from acts.asserts import abort_all 32from acts.controllers.adb_lib.error import AdbCommandError, AdbError 33from acts.controllers.android_device import list_adb_devices 34from acts.controllers.android_device import list_fastboot_devices 35 36from acts.libs.proc.job import TimeoutError 37from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult 38from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs 39from acts_contrib.test_utils.tel.tel_defines import AOSP_PREFIX 40from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_DOWN 41from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_UP 42from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE 43from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE 44from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_PROVISIONING 45from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING 46from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL 47from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VT 48from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC 49from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC_MODE_CHANGE 50from acts_contrib.test_utils.tel.tel_defines import CARRIER_UNKNOWN 51from acts_contrib.test_utils.tel.tel_defines import COUNTRY_CODE_LIST 52from acts_contrib.test_utils.tel.tel_defines import DIALER_PACKAGE_NAME 53from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE 54from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE 55from acts_contrib.test_utils.tel.tel_defines import GEN_4G 56from acts_contrib.test_utils.tel.tel_defines import GEN_UNKNOWN 57from acts_contrib.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX 58from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID 59from acts_contrib.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME 60from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT 61from acts_contrib.test_utils.tel.tel_defines import MESSAGE_PACKAGE_NAME 62from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 63from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 64from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT 65from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT 66from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT 67from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT 68from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN 69from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY 70from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE 71from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING 72from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE 73from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF 74from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT 75from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_LOADED 76from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_NOT_READY 77from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED 78from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_READY 79from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN 80from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 81from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK 82from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE 83from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK 84from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED 85from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY 86from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED 87from acts_contrib.test_utils.tel.tel_defines import EventActiveDataSubIdChanged 88from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged 89from acts_contrib.test_utils.tel.tel_defines import EventServiceStateChanged 90from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackContainer 91from acts_contrib.test_utils.tel.tel_defines import ServiceStateContainer 92from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer 93from acts_contrib.test_utils.tel.tel_defines import OverrideNetworkContainer 94from acts_contrib.test_utils.tel.tel_logging_utils import disable_qxdm_logger 95from acts_contrib.test_utils.tel.tel_logging_utils import get_screen_shot_log 96from acts_contrib.test_utils.tel.tel_logging_utils import log_screen_shot 97from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_logger 98from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string 99from acts_contrib.test_utils.tel.tel_lookup_tables import is_valid_rat 100from acts_contrib.test_utils.tel.tel_lookup_tables import get_allowable_network_preference 101from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_count_check_function 102from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number 103from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation 104from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_network_name 105from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id 106from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat 107from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat 108from acts_contrib.test_utils.tel.tel_subscription_utils import get_slot_index_from_subid 109from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_by_adb 110from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index 111from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id 112from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id 113from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id 114from acts.utils import adb_shell_ping 115from acts.utils import load_config 116from acts.logger import epoch_to_log_line_timestamp 117from acts.utils import get_current_epoch_time 118from acts.utils import exe_cmd 119 120log = logging 121STORY_LINE = "+19523521350" 122CallResult = TelephonyVoiceTestResult.CallResult.Value 123 124 125class TelResultWrapper(object): 126 """Test results wrapper for Telephony test utils. 127 128 In order to enable metrics reporting without refactoring 129 all of the test utils this class is used to keep the 130 current return boolean scheme in tact. 131 """ 132 133 def __init__(self, result_value): 134 self._result_value = result_value 135 136 @property 137 def result_value(self): 138 return self._result_value 139 140 @result_value.setter 141 def result_value(self, result_value): 142 self._result_value = result_value 143 144 def __bool__(self): 145 return self._result_value == CallResult('SUCCESS') 146 147 148def abort_all_tests(log, msg): 149 log.error("Aborting all ongoing tests due to: %s.", msg) 150 abort_all(msg) 151 152 153def get_phone_number_by_adb(ad): 154 return phone_number_formatter( 155 ad.adb.shell("service call iphonesubinfo 13")) 156 157 158def get_iccid_by_adb(ad): 159 return ad.adb.shell("service call iphonesubinfo 11") 160 161 162def get_operator_by_adb(ad): 163 operator = ad.adb.getprop("gsm.sim.operator.alpha") 164 if "," in operator: 165 operator = operator.strip()[0] 166 return operator 167 168 169def get_plmn_by_adb(ad): 170 plmn_id = ad.adb.getprop("gsm.sim.operator.numeric") 171 if "," in plmn_id: 172 plmn_id = plmn_id.strip()[0] 173 return plmn_id 174 175 176def get_sub_id_by_adb(ad): 177 return ad.adb.shell("service call iphonesubinfo 5") 178 179 180def setup_droid_properties_by_adb(log, ad, sim_filename=None): 181 182 sim_data = None 183 if sim_filename: 184 try: 185 sim_data = load_config(sim_filename) 186 except Exception: 187 log.warning("Failed to load %s!", sim_filename) 188 189 sub_id = get_sub_id_by_adb(ad) 190 iccid = get_iccid_by_adb(ad) 191 ad.log.info("iccid = %s", iccid) 192 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"): 193 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"]) 194 else: 195 phone_number = get_phone_number_by_adb(ad) 196 if not phone_number and hasattr(ad, phone_number): 197 phone_number = ad.phone_number 198 if not phone_number: 199 ad.log.error("Failed to find valid phone number for %s", iccid) 200 abort_all_tests(ad.log, "Failed to find valid phone number for %s") 201 sub_record = { 202 'phone_num': phone_number, 203 'iccid': get_iccid_by_adb(ad), 204 'sim_operator_name': get_operator_by_adb(ad), 205 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad)) 206 } 207 device_props = {'subscription': {sub_id: sub_record}} 208 ad.log.info("subId %s SIM record: %s", sub_id, sub_record) 209 setattr(ad, 'telephony', device_props) 210 211 212def setup_droid_properties(log, ad, sim_filename=None): 213 214 if ad.skip_sl4a: 215 return setup_droid_properties_by_adb( 216 log, ad, sim_filename=sim_filename) 217 refresh_droid_config(log, ad) 218 sim_data = {} 219 if sim_filename: 220 try: 221 sim_data = load_config(sim_filename) 222 except Exception: 223 log.warning("Failed to load %s!", sim_filename) 224 if not ad.telephony["subscription"]: 225 abort_all_tests(ad.log, "No valid subscription") 226 ad.log.debug("Subscription DB %s", ad.telephony["subscription"]) 227 result = True 228 active_sub_id = get_outgoing_voice_sub_id(ad) 229 for sub_id, sub_info in ad.telephony["subscription"].items(): 230 ad.log.debug("Loop for Subid %s", sub_id) 231 sub_info["operator"] = get_operator_name(log, ad, sub_id) 232 iccid = sub_info["iccid"] 233 if not iccid: 234 ad.log.warning("Unable to find ICC-ID for subscriber %s", sub_id) 235 continue 236 if sub_info.get("phone_num"): 237 if iccid in sim_data and sim_data[iccid].get("phone_num"): 238 if not check_phone_number_match(sim_data[iccid]["phone_num"], 239 sub_info["phone_num"]): 240 ad.log.warning( 241 "phone_num %s in sim card data file for iccid %s" 242 " do not match phone_num %s from subscription", 243 sim_data[iccid]["phone_num"], iccid, 244 sub_info["phone_num"]) 245 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 246 else: 247 if iccid in sim_data and sim_data[iccid].get("phone_num"): 248 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 249 elif sub_id == active_sub_id: 250 phone_number = get_phone_number_by_secret_code( 251 ad, sub_info["sim_operator_name"]) 252 if phone_number: 253 sub_info["phone_num"] = phone_number 254 elif getattr(ad, "phone_num", None): 255 sub_info["phone_num"] = ad.phone_number 256 if (not sub_info.get("phone_num")) and sub_id == active_sub_id: 257 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info) 258 ad.log.error( 259 "Unable to retrieve phone number for sub %s with iccid" 260 " %s from device or testbed config or sim card file %s", 261 sub_id, iccid, sim_filename) 262 result = False 263 if not hasattr( 264 ad, 'roaming' 265 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and sub_info["sim_operator_name"].strip( 266 ) not in sub_info["network_operator_name"].strip(): 267 ad.log.info("roaming is not enabled, enable it") 268 setattr(ad, 'roaming', True) 269 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items())) 270 get_phone_capability(ad) 271 data_roaming = getattr(ad, 'roaming', False) 272 if get_cell_data_roaming_state_by_adb(ad) != data_roaming: 273 set_cell_data_roaming_state_by_adb(ad, data_roaming) 274 # Setup VoWiFi MDN for Verizon. b/33187374 275 if not result: 276 abort_all_tests(ad.log, "Failed to find valid phone number") 277 278 ad.log.debug("telephony = %s", ad.telephony) 279 280 281def refresh_droid_config(log, ad): 282 """ Update Android Device telephony records for each sub_id. 283 284 Args: 285 log: log object 286 ad: android device object 287 288 Returns: 289 None 290 """ 291 if not getattr(ad, 'telephony', {}): 292 setattr(ad, 'telephony', {"subscription": {}}) 293 droid = ad.droid 294 sub_info_list = droid.subscriptionGetAllSubInfoList() 295 ad.log.info("SubInfoList is %s", sub_info_list) 296 if not sub_info_list: return 297 active_sub_id = get_outgoing_voice_sub_id(ad) 298 for sub_info in sub_info_list: 299 sub_id = sub_info["subscriptionId"] 300 sim_slot = sub_info["simSlotIndex"] 301 if sub_info.get("carrierId"): 302 carrier_id = sub_info["carrierId"] 303 else: 304 carrier_id = -1 305 if sub_info.get("isOpportunistic"): 306 isopportunistic = sub_info["isOpportunistic"] 307 else: 308 isopportunistic = -1 309 310 if sim_slot != INVALID_SIM_SLOT_INDEX: 311 if sub_id not in ad.telephony["subscription"]: 312 ad.telephony["subscription"][sub_id] = {} 313 sub_record = ad.telephony["subscription"][sub_id] 314 if sub_info.get("iccId"): 315 sub_record["iccid"] = sub_info["iccId"] 316 else: 317 sub_record[ 318 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription( 319 sub_id) 320 sub_record["sim_slot"] = sim_slot 321 if sub_info.get("mcc"): 322 sub_record["mcc"] = sub_info["mcc"] 323 if sub_info.get("mnc"): 324 sub_record["mnc"] = sub_info["mnc"] 325 if sub_info.get("displayName"): 326 sub_record["display_name"] = sub_info["displayName"] 327 try: 328 sub_record[ 329 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription( 330 sub_id) 331 except: 332 if not sub_record.get("phone_type"): 333 sub_record["phone_type"] = droid.telephonyGetPhoneType() 334 sub_record[ 335 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription( 336 sub_id) 337 sub_record[ 338 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription( 339 sub_id) 340 sub_record[ 341 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription( 342 sub_id) 343 sub_record[ 344 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription( 345 sub_id) 346 sub_record[ 347 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription( 348 sub_id) 349 if active_sub_id == sub_id: 350 try: 351 sub_record[ 352 "carrier_id"] = ad.droid.telephonyGetSimCarrierId() 353 sub_record[ 354 "carrier_id_name"] = ad.droid.telephonyGetSimCarrierIdName( 355 ) 356 except: 357 ad.log.info("Carrier ID is not supported") 358 if carrier_id == 2340: 359 ad.log.info("SubId %s info: %s", sub_id, sorted( 360 sub_record.items())) 361 continue 362 if carrier_id == 1989 and isopportunistic == "true": 363 ad.log.info("SubId %s info: %s", sub_id, sorted( 364 sub_record.items())) 365 continue 366 if not sub_info.get("number"): 367 sub_info[ 368 "number"] = droid.telephonyGetLine1NumberForSubscription( 369 sub_id) 370 if sub_info.get("number"): 371 if sub_record.get("phone_num"): 372 # Use the phone number provided in sim info file by default 373 # as the sub_info["number"] may not be formatted in a 374 # dialable number 375 if not check_phone_number_match(sub_info["number"], 376 sub_record["phone_num"]): 377 ad.log.info( 378 "Subscriber phone number changed from %s to %s", 379 sub_record["phone_num"], sub_info["number"]) 380 sub_record["phone_num"] = sub_info["number"] 381 else: 382 sub_record["phone_num"] = phone_number_formatter( 383 sub_info["number"]) 384 ad.log.info("SubId %s info: %s", sub_id, sorted( 385 sub_record.items())) 386 387 388def get_phone_number_by_secret_code(ad, operator): 389 if "T-Mobile" in operator: 390 ad.droid.telecomDialNumber("#686#") 391 ad.send_keycode("ENTER") 392 for _ in range(12): 393 output = ad.search_logcat("mobile number") 394 if output: 395 result = re.findall(r"mobile number is (\S+)", 396 output[-1]["log_message"]) 397 ad.send_keycode("BACK") 398 return result[0] 399 else: 400 time.sleep(5) 401 return "" 402 403 404def get_user_config_profile(ad): 405 return { 406 "Airplane Mode": 407 ad.droid.connectivityCheckAirplaneMode(), 408 "IMS Registered": 409 ad.droid.telephonyIsImsRegistered(), 410 "Preferred Network Type": 411 ad.droid.telephonyGetPreferredNetworkTypes(), 412 "VoLTE Platform Enabled": 413 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(), 414 "VoLTE Enabled": 415 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser(), 416 "VoLTE Available": 417 ad.droid.telephonyIsVolteAvailable(), 418 "VT Available": 419 ad.droid.telephonyIsVideoCallingAvailable(), 420 "VT Enabled": 421 ad.droid.imsIsVtEnabledByUser(), 422 "VT Platform Enabled": 423 ad.droid.imsIsVtEnabledByPlatform(), 424 "WiFi State": 425 ad.droid.wifiCheckState(), 426 "WFC Available": 427 ad.droid.telephonyIsWifiCallingAvailable(), 428 "WFC Enabled": 429 ad.droid.imsIsWfcEnabledByUser(), 430 "WFC Platform Enabled": 431 ad.droid.imsIsWfcEnabledByPlatform(), 432 "WFC Mode": 433 ad.droid.imsGetWfcMode() 434 } 435 436 437def get_num_active_sims(log, ad): 438 """ Get the number of active SIM cards by counting slots 439 440 Args: 441 ad: android_device object. 442 443 Returns: 444 result: The number of loaded (physical) SIM cards 445 """ 446 # using a dictionary as a cheap way to prevent double counting 447 # in the situation where multiple subscriptions are on the same SIM. 448 # yes, this is a corner corner case. 449 valid_sims = {} 450 subInfo = ad.droid.subscriptionGetAllSubInfoList() 451 for info in subInfo: 452 ssidx = info['simSlotIndex'] 453 if ssidx == INVALID_SIM_SLOT_INDEX: 454 continue 455 valid_sims[ssidx] = True 456 return len(valid_sims.keys()) 457 458 459def toggle_airplane_mode_by_adb(log, ad, new_state=None): 460 """ Toggle the state of airplane mode. 461 462 Args: 463 log: log handler. 464 ad: android_device object. 465 new_state: Airplane mode state to set to. 466 If None, opposite of the current state. 467 strict_checking: Whether to turn on strict checking that checks all features. 468 469 Returns: 470 result: True if operation succeed. False if error happens. 471 """ 472 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on"))) 473 if new_state == cur_state: 474 ad.log.info("Airplane mode already in %s", new_state) 475 return True 476 elif new_state is None: 477 new_state = not cur_state 478 ad.log.info("Change airplane mode from %s to %s", cur_state, new_state) 479 try: 480 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state)) 481 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE") 482 except Exception as e: 483 ad.log.error(e) 484 return False 485 changed_state = bool(int(ad.adb.shell("settings get global airplane_mode_on"))) 486 return changed_state == new_state 487 488 489def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True): 490 """ Toggle the state of airplane mode. 491 492 Args: 493 log: log handler. 494 ad: android_device object. 495 new_state: Airplane mode state to set to. 496 If None, opposite of the current state. 497 strict_checking: Whether to turn on strict checking that checks all features. 498 499 Returns: 500 result: True if operation succeed. False if error happens. 501 """ 502 if ad.skip_sl4a: 503 return toggle_airplane_mode_by_adb(log, ad, new_state) 504 else: 505 return toggle_airplane_mode_msim( 506 log, ad, new_state, strict_checking=strict_checking) 507 508 509def get_telephony_signal_strength(ad): 510 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0, 511 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160, 512 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0, 513 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0, 514 # 'lteDbm': -112, 'gsmSignalStrength': 99} 515 try: 516 signal_strength = ad.droid.telephonyGetSignalStrength() 517 if not signal_strength: 518 signal_strength = {} 519 except Exception as e: 520 ad.log.error(e) 521 signal_strength = {} 522 return signal_strength 523 524 525def get_lte_rsrp(ad): 526 try: 527 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"): 528 out = ad.adb.shell( 529 "dumpsys telephony.registry | grep -i signalstrength") 530 if out: 531 lte_rsrp = out.split()[9] 532 if lte_rsrp: 533 ad.log.info("lte_rsrp: %s ", lte_rsrp) 534 return lte_rsrp 535 else: 536 out = ad.adb.shell( 537 "dumpsys telephony.registry |grep -i primary=CellSignalStrengthLte") 538 if out: 539 lte_cell_info = out.split('mLte=')[1] 540 lte_rsrp = re.match(r'.*rsrp=(\S+).*', lte_cell_info).group(1) 541 if lte_rsrp: 542 ad.log.info("lte_rsrp: %s ", lte_rsrp) 543 return lte_rsrp 544 except Exception as e: 545 ad.log.error(e) 546 return None 547 548 549def break_internet_except_sl4a_port(ad, sl4a_port): 550 ad.log.info("Breaking internet using iptables rules") 551 ad.adb.shell("iptables -I INPUT 1 -p tcp --dport %s -j ACCEPT" % sl4a_port, 552 ignore_status=True) 553 ad.adb.shell("iptables -I INPUT 2 -p tcp --sport %s -j ACCEPT" % sl4a_port, 554 ignore_status=True) 555 ad.adb.shell("iptables -I INPUT 3 -j DROP", ignore_status=True) 556 ad.adb.shell("ip6tables -I INPUT -j DROP", ignore_status=True) 557 return True 558 559 560def resume_internet_with_sl4a_port(ad, sl4a_port): 561 ad.log.info("Bring internet back using iptables rules") 562 ad.adb.shell("iptables -D INPUT -p tcp --dport %s -j ACCEPT" % sl4a_port, 563 ignore_status=True) 564 ad.adb.shell("iptables -D INPUT -p tcp --sport %s -j ACCEPT" % sl4a_port, 565 ignore_status=True) 566 ad.adb.shell("iptables -D INPUT -j DROP", ignore_status=True) 567 ad.adb.shell("ip6tables -D INPUT -j DROP", ignore_status=True) 568 return True 569 570 571def test_data_browsing_success_using_sl4a(log, ad): 572 result = True 573 web_page_list = ['https://www.google.com', 'https://www.yahoo.com', 574 'https://www.amazon.com', 'https://www.nike.com', 575 'https://www.facebook.com'] 576 for website in web_page_list: 577 if not verify_http_connection(log, ad, website, retry=0): 578 ad.log.error("Failed to browse %s successfully!", website) 579 result = False 580 return result 581 582 583def test_data_browsing_failure_using_sl4a(log, ad): 584 result = True 585 web_page_list = ['https://www.youtube.com', 'https://www.cnn.com', 586 'https://www.att.com', 'https://www.nbc.com', 587 'https://www.verizonwireless.com'] 588 for website in web_page_list: 589 if not verify_http_connection(log, ad, website, retry=0, 590 expected_state=False): 591 ad.log.error("Browsing to %s worked!", website) 592 result = False 593 return result 594 595 596def is_expected_event(event_to_check, events_list): 597 """ check whether event is present in the event list 598 599 Args: 600 event_to_check: event to be checked. 601 events_list: list of events 602 Returns: 603 result: True if event present in the list. False if not. 604 """ 605 for event in events_list: 606 if event in event_to_check['name']: 607 return True 608 return False 609 610 611def is_sim_ready(log, ad, sim_slot_id=None): 612 """ check whether SIM is ready. 613 614 Args: 615 ad: android_device object. 616 sim_slot_id: check the SIM status for sim_slot_id 617 This is optional. If this is None, check default SIM. 618 619 Returns: 620 result: True if all SIMs are ready. False if not. 621 """ 622 if sim_slot_id is None: 623 status = ad.droid.telephonyGetSimState() 624 else: 625 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id) 626 if status != SIM_STATE_READY: 627 ad.log.info("Sim state is %s, not ready", status) 628 return False 629 return True 630 631 632def is_sim_ready_by_adb(log, ad): 633 state = ad.adb.getprop("gsm.sim.state") 634 ad.log.info("gsm.sim.state = %s", state) 635 return state == SIM_STATE_READY or state == SIM_STATE_LOADED 636 637 638def wait_for_sim_ready_by_adb(log, ad, wait_time=90): 639 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb) 640 641 642def is_sims_ready_by_adb(log, ad): 643 states = list(ad.adb.getprop("gsm.sim.state").split(",")) 644 ad.log.info("gsm.sim.state = %s", states) 645 for state in states: 646 if state != SIM_STATE_READY and state != SIM_STATE_LOADED: 647 return False 648 return True 649 650 651def wait_for_sims_ready_by_adb(log, ad, wait_time=90): 652 return _wait_for_droid_in_state(log, ad, wait_time, is_sims_ready_by_adb) 653 654 655def get_service_state_by_adb(log, ad): 656 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState") 657 if "mVoiceRegState" in output: 658 result = re.findall(r"mVoiceRegState=(\S+)\((\S+)\)", output) 659 if result: 660 if getattr(ad, 'dsds', False): 661 default_slot = getattr(ad, 'default_slot', 0) 662 ad.log.info("mVoiceRegState is %s %s", result[default_slot][0], 663 result[default_slot][1]) 664 return result[default_slot][1] 665 else: 666 ad.log.info("mVoiceRegState is %s %s", result[0][0], 667 result[0][1]) 668 return result[0][1] 669 else: 670 result = re.search(r"mServiceState=(\S+)", output) 671 if result: 672 ad.log.info("mServiceState=%s %s", result.group(1), 673 SERVICE_STATE_MAPPING[result.group(1)]) 674 return SERVICE_STATE_MAPPING[result.group(1)] 675 676 677def _is_expecting_event(event_recv_list): 678 """ check for more event is expected in event list 679 680 Args: 681 event_recv_list: list of events 682 Returns: 683 result: True if more events are expected. False if not. 684 """ 685 for state in event_recv_list: 686 if state is False: 687 return True 688 return False 689 690 691def _set_event_list(event_recv_list, sub_id_list, sub_id, value): 692 """ set received event in expected event list 693 694 Args: 695 event_recv_list: list of received events 696 sub_id_list: subscription ID list 697 sub_id: subscription id of current event 698 value: True or False 699 Returns: 700 None. 701 """ 702 for i in range(len(sub_id_list)): 703 if sub_id_list[i] == sub_id: 704 event_recv_list[i] = value 705 706 707def _wait_for_bluetooth_in_state(log, ad, state, max_wait): 708 # FIXME: These event names should be defined in a common location 709 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn' 710 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff' 711 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT) 712 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT) 713 714 ad.droid.bluetoothStartListeningForAdapterStateChange() 715 try: 716 bt_state = ad.droid.bluetoothCheckState() 717 if bt_state == state: 718 return True 719 if max_wait <= 0: 720 ad.log.error("Time out: bluetooth state still %s, expecting %s", 721 bt_state, state) 722 return False 723 724 event = { 725 False: _BLUETOOTH_STATE_OFF_EVENT, 726 True: _BLUETOOTH_STATE_ON_EVENT 727 }[state] 728 event = ad.ed.pop_event(event, max_wait) 729 ad.log.info("Got event %s", event['name']) 730 return True 731 except Empty: 732 ad.log.error("Time out: bluetooth state still in %s, expecting %s", 733 bt_state, state) 734 return False 735 finally: 736 ad.droid.bluetoothStopListeningForAdapterStateChange() 737 738 739# TODO: replace this with an event-based function 740def _wait_for_wifi_in_state(log, ad, state, max_wait): 741 return _wait_for_droid_in_state(log, ad, max_wait, 742 lambda log, ad, state: \ 743 (True if ad.droid.wifiCheckState() == state else False), 744 state) 745 746 747def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True): 748 """ Toggle the state of airplane mode. 749 750 Args: 751 log: log handler. 752 ad: android_device object. 753 new_state: Airplane mode state to set to. 754 If None, opposite of the current state. 755 strict_checking: Whether to turn on strict checking that checks all features. 756 757 Returns: 758 result: True if operation succeed. False if error happens. 759 """ 760 761 cur_state = ad.droid.connectivityCheckAirplaneMode() 762 if cur_state == new_state: 763 ad.log.info("Airplane mode already in %s", new_state) 764 return True 765 elif new_state is None: 766 new_state = not cur_state 767 ad.log.info("Toggle APM mode, from current tate %s to %s", cur_state, 768 new_state) 769 sub_id_list = [] 770 active_sub_info = ad.droid.subscriptionGetAllSubInfoList() 771 if active_sub_info: 772 for info in active_sub_info: 773 sub_id_list.append(info['subscriptionId']) 774 775 ad.ed.clear_all_events() 776 time.sleep(0.1) 777 service_state_list = [] 778 if new_state: 779 service_state_list.append(SERVICE_STATE_POWER_OFF) 780 ad.log.info("Turn on airplane mode") 781 782 else: 783 # If either one of these 3 events show up, it should be OK. 784 # Normal SIM, phone in service 785 service_state_list.append(SERVICE_STATE_IN_SERVICE) 786 # NO SIM, or Dead SIM, or no Roaming coverage. 787 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE) 788 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY) 789 ad.log.info("Turn off airplane mode") 790 791 for sub_id in sub_id_list: 792 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription( 793 sub_id) 794 795 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT 796 ad.droid.connectivityToggleAirplaneMode(new_state) 797 798 try: 799 try: 800 event = ad.ed.wait_for_event( 801 EventServiceStateChanged, 802 is_event_match_for_list, 803 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT, 804 field=ServiceStateContainer.SERVICE_STATE, 805 value_list=service_state_list) 806 ad.log.info("Got event %s", event) 807 except Empty: 808 ad.log.warning("Did not get expected service state change to %s", 809 service_state_list) 810 finally: 811 for sub_id in sub_id_list: 812 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription( 813 sub_id) 814 except Exception as e: 815 ad.log.error(e) 816 817 # APM on (new_state=True) will turn off bluetooth but may not turn it on 818 try: 819 if new_state and not _wait_for_bluetooth_in_state( 820 log, ad, False, timeout_time - time.time()): 821 ad.log.error( 822 "Failed waiting for bluetooth during airplane mode toggle") 823 if strict_checking: return False 824 except Exception as e: 825 ad.log.error("Failed to check bluetooth state due to %s", e) 826 if strict_checking: 827 raise 828 829 # APM on (new_state=True) will turn off wifi but may not turn it on 830 if new_state and not _wait_for_wifi_in_state(log, ad, False, 831 timeout_time - time.time()): 832 ad.log.error("Failed waiting for wifi during airplane mode toggle on") 833 if strict_checking: return False 834 835 if ad.droid.connectivityCheckAirplaneMode() != new_state: 836 ad.log.error("Set airplane mode to %s failed", new_state) 837 return False 838 return True 839 840 841def wait_for_cbrs_data_active_sub_change_event( 842 ad, 843 event_tracking_started=False, 844 timeout=120): 845 """Wait for an data change event on specified subscription. 846 847 Args: 848 ad: android device object. 849 event_tracking_started: True if event tracking already state outside 850 timeout: time to wait for event 851 852 Returns: 853 True: if data change event is received. 854 False: if data change event is not received. 855 """ 856 if not event_tracking_started: 857 ad.ed.clear_events(EventActiveDataSubIdChanged) 858 ad.droid.telephonyStartTrackingActiveDataChange() 859 try: 860 ad.ed.wait_for_event( 861 EventActiveDataSubIdChanged, 862 is_event_match, 863 timeout=timeout) 864 ad.log.info("Got event activedatasubidchanged") 865 except Empty: 866 ad.log.info("No event for data subid change") 867 return False 868 finally: 869 if not event_tracking_started: 870 ad.droid.telephonyStopTrackingActiveDataChange() 871 return True 872 873 874def is_current_data_on_cbrs(ad, cbrs_subid): 875 """Verifies if current data sub is on CBRS 876 877 Args: 878 ad: android device object. 879 cbrs_subid: sub_id against which we need to check 880 881 Returns: 882 True: if data is on cbrs 883 False: if data is not on cbrs 884 """ 885 if cbrs_subid is None: 886 return False 887 current_data = ad.droid.subscriptionGetActiveDataSubscriptionId() 888 ad.log.info("Current Data subid %s cbrs_subid %s", current_data, cbrs_subid) 889 if current_data == cbrs_subid: 890 return True 891 else: 892 return False 893 894 895def get_current_override_network_type(ad, timeout=30): 896 """Returns current override network type 897 898 Args: 899 ad: android device object. 900 timeout: max time to wait for event 901 902 Returns: 903 value: current override type 904 -1: if no event received 905 """ 906 override_value_list = [OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA, 907 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NONE, 908 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE, 909 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_CA, 910 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO] 911 ad.ed.clear_events(EventDisplayInfoChanged) 912 ad.droid.telephonyStartTrackingDisplayInfoChange() 913 try: 914 event = ad.ed.wait_for_event( 915 EventDisplayInfoChanged, 916 is_event_match_for_list, 917 timeout=timeout, 918 field=DisplayInfoContainer.OVERRIDE, 919 value_list=override_value_list) 920 override_type = event['data']['override'] 921 ad.log.info("Current Override Type is %s", override_type) 922 return override_type 923 except Empty: 924 ad.log.info("No event for display info change") 925 return -1 926 finally: 927 ad.droid.telephonyStopTrackingDisplayInfoChange() 928 return -1 929 930 931def _phone_number_remove_prefix(number): 932 """Remove the country code and other prefix from the input phone number. 933 Currently only handle phone number with the following formats: 934 (US phone number format) 935 +1abcxxxyyyy 936 1abcxxxyyyy 937 abcxxxyyyy 938 abc xxx yyyy 939 abc.xxx.yyyy 940 abc-xxx-yyyy 941 (EEUK phone number format) 942 +44abcxxxyyyy 943 0abcxxxyyyy 944 945 Args: 946 number: input phone number 947 948 Returns: 949 Phone number without country code or prefix 950 """ 951 if number is None: 952 return None, None 953 for country_code in COUNTRY_CODE_LIST: 954 if number.startswith(country_code): 955 return number[len(country_code):], country_code 956 if number[0] == "1" or number[0] == "0": 957 return number[1:], None 958 return number, None 959 960 961def check_phone_number_match(number1, number2): 962 """Check whether two input phone numbers match or not. 963 964 Compare the two input phone numbers. 965 If they match, return True; otherwise, return False. 966 Currently only handle phone number with the following formats: 967 (US phone number format) 968 +1abcxxxyyyy 969 1abcxxxyyyy 970 abcxxxyyyy 971 abc xxx yyyy 972 abc.xxx.yyyy 973 abc-xxx-yyyy 974 (EEUK phone number format) 975 +44abcxxxyyyy 976 0abcxxxyyyy 977 978 There are some scenarios we can not verify, one example is: 979 number1 = +15555555555, number2 = 5555555555 980 (number2 have no country code) 981 982 Args: 983 number1: 1st phone number to be compared. 984 number2: 2nd phone number to be compared. 985 986 Returns: 987 True if two phone numbers match. Otherwise False. 988 """ 989 number1 = phone_number_formatter(number1) 990 number2 = phone_number_formatter(number2) 991 # Handle extra country code attachment when matching phone number 992 if number1[-7:] in number2 or number2[-7:] in number1: 993 return True 994 else: 995 logging.info("phone number1 %s and number2 %s does not match" % 996 (number1, number2)) 997 return False 998 999 1000def get_call_state_by_adb(ad): 1001 slot_index_of_default_voice_subid = get_slot_index_from_subid(ad, 1002 get_incoming_voice_sub_id(ad)) 1003 output = ad.adb.shell("dumpsys telephony.registry | grep mCallState") 1004 if "mCallState" in output: 1005 call_state_list = re.findall("mCallState=(\d)", output) 1006 if call_state_list: 1007 return call_state_list[slot_index_of_default_voice_subid] 1008 1009 1010def check_call_state_connected_by_adb(ad): 1011 return "2" in get_call_state_by_adb(ad) 1012 1013 1014def check_call_state_idle_by_adb(ad): 1015 return "0" in get_call_state_by_adb(ad) 1016 1017 1018def check_call_state_ring_by_adb(ad): 1019 return "1" in get_call_state_by_adb(ad) 1020 1021 1022def get_incoming_call_number_by_adb(ad): 1023 output = ad.adb.shell( 1024 "dumpsys telephony.registry | grep mCallIncomingNumber") 1025 return re.search(r"mCallIncomingNumber=(.*)", output).group(1) 1026 1027 1028def dumpsys_all_call_info(ad): 1029 """ Get call information by dumpsys telecom. """ 1030 output = ad.adb.shell("dumpsys telecom") 1031 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL) 1032 calls_info = [] 1033 for call in calls: 1034 call_info = {} 1035 for attr in ("startTime", "endTime", "direction", "isInterrupted", 1036 "callTechnologies", "callTerminationsReason", 1037 "connectionService", "isVideoCall", "callProperties"): 1038 match = re.search(r"%s: (.*)" % attr, call) 1039 if match: 1040 if attr in ("startTime", "endTime"): 1041 call_info[attr] = epoch_to_log_line_timestamp( 1042 int(match.group(1))) 1043 else: 1044 call_info[attr] = match.group(1) 1045 call_info["inCallServices"] = re.findall(r"name: (.*)", call) 1046 calls_info.append(call_info) 1047 ad.log.debug("calls_info = %s", calls_info) 1048 return calls_info 1049 1050 1051def dumpsys_carrier_config(ad): 1052 output = ad.adb.shell("dumpsys carrier_config").split("\n") 1053 output_phone_id_0 = [] 1054 output_phone_id_1 = [] 1055 current_output = [] 1056 for line in output: 1057 if "Phone Id = 0" in line: 1058 current_output = output_phone_id_0 1059 elif "Phone Id = 1" in line: 1060 current_output = output_phone_id_1 1061 current_output.append(line.strip()) 1062 1063 configs = {} 1064 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"): 1065 phone_count = 1 1066 if "," in ad.adb.getprop("gsm.network.type"): 1067 phone_count = 2 1068 else: 1069 phone_count = ad.droid.telephonyGetPhoneCount() 1070 1071 slot_0_subid = get_subid_from_slot_index(ad.log, ad, 0) 1072 if slot_0_subid != INVALID_SUB_ID: 1073 configs[slot_0_subid] = {} 1074 1075 if phone_count == 2: 1076 slot_1_subid = get_subid_from_slot_index(ad.log, ad, 1) 1077 if slot_1_subid != INVALID_SUB_ID: 1078 configs[slot_1_subid] = {} 1079 1080 attrs = [attr for attr in dir(CarrierConfigs) if not attr.startswith("__")] 1081 for attr in attrs: 1082 attr_string = getattr(CarrierConfigs, attr) 1083 values = re.findall( 1084 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_0)) 1085 1086 if slot_0_subid != INVALID_SUB_ID: 1087 if values: 1088 value = values[-1] 1089 if value == "true": 1090 configs[slot_0_subid][attr_string] = True 1091 elif value == "false": 1092 configs[slot_0_subid][attr_string] = False 1093 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT: 1094 if value == "0": 1095 configs[slot_0_subid][attr_string] = WFC_MODE_WIFI_ONLY 1096 elif value == "1": 1097 configs[slot_0_subid][attr_string] = \ 1098 WFC_MODE_CELLULAR_PREFERRED 1099 elif value == "2": 1100 configs[slot_0_subid][attr_string] = \ 1101 WFC_MODE_WIFI_PREFERRED 1102 else: 1103 try: 1104 configs[slot_0_subid][attr_string] = int(value) 1105 except Exception: 1106 configs[slot_0_subid][attr_string] = value 1107 else: 1108 configs[slot_0_subid][attr_string] = None 1109 1110 if phone_count == 2: 1111 if slot_1_subid != INVALID_SUB_ID: 1112 values = re.findall( 1113 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_1)) 1114 if values: 1115 value = values[-1] 1116 if value == "true": 1117 configs[slot_1_subid][attr_string] = True 1118 elif value == "false": 1119 configs[slot_1_subid][attr_string] = False 1120 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT: 1121 if value == "0": 1122 configs[slot_1_subid][attr_string] = \ 1123 WFC_MODE_WIFI_ONLY 1124 elif value == "1": 1125 configs[slot_1_subid][attr_string] = \ 1126 WFC_MODE_CELLULAR_PREFERRED 1127 elif value == "2": 1128 configs[slot_1_subid][attr_string] = \ 1129 WFC_MODE_WIFI_PREFERRED 1130 else: 1131 try: 1132 configs[slot_1_subid][attr_string] = int(value) 1133 except Exception: 1134 configs[slot_1_subid][attr_string] = value 1135 else: 1136 configs[slot_1_subid][attr_string] = None 1137 return configs 1138 1139 1140def get_phone_capability(ad): 1141 carrier_configs = dumpsys_carrier_config(ad) 1142 for sub_id in carrier_configs: 1143 capabilities = [] 1144 if carrier_configs[sub_id][CarrierConfigs.VOLTE_AVAILABLE_BOOL]: 1145 capabilities.append(CAPABILITY_VOLTE) 1146 if carrier_configs[sub_id][CarrierConfigs.WFC_IMS_AVAILABLE_BOOL]: 1147 capabilities.append(CAPABILITY_WFC) 1148 if carrier_configs[sub_id][CarrierConfigs.EDITABLE_WFC_MODE_BOOL]: 1149 capabilities.append(CAPABILITY_WFC_MODE_CHANGE) 1150 if carrier_configs[sub_id][CarrierConfigs.SUPPORT_CONFERENCE_CALL_BOOL]: 1151 capabilities.append(CAPABILITY_CONFERENCE) 1152 if carrier_configs[sub_id][CarrierConfigs.VT_AVAILABLE_BOOL]: 1153 capabilities.append(CAPABILITY_VT) 1154 if carrier_configs[sub_id][CarrierConfigs.VOLTE_PROVISIONED_BOOL]: 1155 capabilities.append(CAPABILITY_VOLTE_PROVISIONING) 1156 if carrier_configs[sub_id][CarrierConfigs.VOLTE_OVERRIDE_WFC_BOOL]: 1157 capabilities.append(CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING) 1158 if carrier_configs[sub_id][CarrierConfigs.HIDE_ENHANCED_4G_LTE_BOOL]: 1159 capabilities.append(CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL) 1160 1161 ad.log.info("Capabilities of sub ID %s: %s", sub_id, capabilities) 1162 if not getattr(ad, 'telephony', {}): 1163 ad.telephony["subscription"] = {} 1164 ad.telephony["subscription"][sub_id] = {} 1165 setattr( 1166 ad.telephony["subscription"][sub_id], 1167 'capabilities', capabilities) 1168 1169 else: 1170 ad.telephony["subscription"][sub_id]["capabilities"] = capabilities 1171 if CAPABILITY_WFC not in capabilities: 1172 wfc_modes = [] 1173 else: 1174 if carrier_configs[sub_id].get( 1175 CarrierConfigs.EDITABLE_WFC_MODE_BOOL, False): 1176 wfc_modes = [ 1177 WFC_MODE_CELLULAR_PREFERRED, 1178 WFC_MODE_WIFI_PREFERRED] 1179 else: 1180 wfc_modes = [ 1181 carrier_configs[sub_id].get( 1182 CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, 1183 WFC_MODE_CELLULAR_PREFERRED) 1184 ] 1185 if carrier_configs[sub_id].get( 1186 CarrierConfigs.WFC_SUPPORTS_WIFI_ONLY_BOOL, 1187 False) and WFC_MODE_WIFI_ONLY not in wfc_modes: 1188 wfc_modes.append(WFC_MODE_WIFI_ONLY) 1189 ad.telephony["subscription"][sub_id]["wfc_modes"] = wfc_modes 1190 if wfc_modes: 1191 ad.log.info("Supported WFC modes for sub ID %s: %s", sub_id, 1192 wfc_modes) 1193 1194 1195def get_capability_for_subscription(ad, capability, subid): 1196 if capability in ad.telephony["subscription"][subid].get( 1197 "capabilities", []): 1198 ad.log.info('Capability "%s" is available for sub ID %s.', 1199 capability, subid) 1200 return True 1201 else: 1202 ad.log.info('Capability "%s" is NOT available for sub ID %s.', 1203 capability, subid) 1204 return False 1205 1206 1207def phone_number_formatter(input_string, formatter=None): 1208 """Get expected format of input phone number string. 1209 1210 Args: 1211 input_string: (string) input phone number. 1212 The input could be 10/11/12 digital, with or without " "/"-"/"." 1213 formatter: (int) expected format, this could be 7/10/11/12 1214 if formatter is 7: output string would be 7 digital number. 1215 if formatter is 10: output string would be 10 digital (standard) number. 1216 if formatter is 11: output string would be "1" + 10 digital number. 1217 if formatter is 12: output string would be "+1" + 10 digital number. 1218 1219 Returns: 1220 If no error happen, return phone number in expected format. 1221 Else, return None. 1222 """ 1223 if not input_string: 1224 return "" 1225 # make sure input_string is 10 digital 1226 # Remove white spaces, dashes, dots 1227 input_string = input_string.replace(" ", "").replace("-", "").replace( 1228 ".", "") 1229 1230 # Remove a country code with '+' sign and add 0 for Japan/Korea Carriers. 1231 if (len(input_string) == 13 1232 and (input_string[0:3] == "+81" or input_string[0:3] == "+82")): 1233 input_string = "0" + input_string[3:] 1234 return input_string 1235 1236 if not formatter: 1237 return input_string 1238 1239 # Remove leading 0 for the phone with area code started with 0 1240 input_string = input_string.lstrip("0") 1241 1242 # Remove "1" or "+1"from front 1243 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT 1244 and input_string[0] == "1"): 1245 input_string = input_string[1:] 1246 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT 1247 and input_string[0:2] == "+1"): 1248 input_string = input_string[2:] 1249 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT 1250 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT): 1251 return input_string 1252 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1253 return None 1254 # change input_string according to format 1255 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT: 1256 input_string = "+1" + input_string 1257 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT: 1258 input_string = "1" + input_string 1259 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 1260 input_string = input_string 1261 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT: 1262 input_string = input_string[3:] 1263 else: 1264 return None 1265 return input_string 1266 1267 1268def get_internet_connection_type(log, ad): 1269 """Get current active connection type name. 1270 1271 Args: 1272 log: Log object. 1273 ad: Android Device Object. 1274 Returns: 1275 current active connection type name. 1276 """ 1277 if not ad.droid.connectivityNetworkIsConnected(): 1278 return 'none' 1279 return connection_type_from_type_string( 1280 ad.droid.connectivityNetworkGetActiveConnectionTypeName()) 1281 1282 1283def verify_http_connection(log, 1284 ad, 1285 url="https://www.google.com", 1286 retry=5, 1287 retry_interval=15, 1288 expected_state=True): 1289 """Make ping request and return status. 1290 1291 Args: 1292 log: log object 1293 ad: Android Device Object. 1294 url: Optional. The ping request will be made to this URL. 1295 Default Value is "http://www.google.com/". 1296 1297 """ 1298 if not getattr(ad, "data_droid", None): 1299 ad.data_droid, ad.data_ed = ad.get_droid() 1300 ad.data_ed.start() 1301 else: 1302 try: 1303 if not ad.data_droid.is_live: 1304 ad.data_droid, ad.data_ed = ad.get_droid() 1305 ad.data_ed.start() 1306 except Exception: 1307 ad.log.info("Start new sl4a session for file download") 1308 ad.data_droid, ad.data_ed = ad.get_droid() 1309 ad.data_ed.start() 1310 for i in range(0, retry + 1): 1311 try: 1312 http_response = ad.data_droid.httpPing(url) 1313 except Exception as e: 1314 ad.log.info("httpPing with %s", e) 1315 http_response = None 1316 if (expected_state and http_response) or (not expected_state 1317 and not http_response): 1318 ad.log.info("Http ping response for %s meet expected %s", url, 1319 expected_state) 1320 return True 1321 if i < retry: 1322 time.sleep(retry_interval) 1323 ad.log.error("Http ping to %s is %s after %s second, expecting %s", url, 1324 http_response, i * retry_interval, expected_state) 1325 return False 1326 1327 1328def _generate_file_directory_and_file_name(url, out_path): 1329 file_name = url.split("/")[-1] 1330 if not out_path: 1331 file_directory = "/sdcard/Download/" 1332 elif not out_path.endswith("/"): 1333 file_directory, file_name = os.path.split(out_path) 1334 else: 1335 file_directory = out_path 1336 return file_directory, file_name 1337 1338 1339def _check_file_existence(ad, file_path, expected_file_size=None): 1340 """Check file existance by file_path. If expected_file_size 1341 is provided, then also check if the file meet the file size requirement. 1342 """ 1343 out = None 1344 try: 1345 out = ad.adb.shell('stat -c "%%s" %s' % file_path) 1346 except AdbError: 1347 pass 1348 # Handle some old version adb returns error message "No such" into std_out 1349 if out and "No such" not in out: 1350 if expected_file_size: 1351 file_size = int(out) 1352 if file_size >= expected_file_size: 1353 ad.log.info("File %s of size %s exists", file_path, file_size) 1354 return True 1355 else: 1356 ad.log.info("File %s is of size %s, does not meet expected %s", 1357 file_path, file_size, expected_file_size) 1358 return False 1359 else: 1360 ad.log.info("File %s exists", file_path) 1361 return True 1362 else: 1363 ad.log.info("File %s does not exist.", file_path) 1364 return False 1365 1366 1367def verify_internet_connection_by_ping(log, 1368 ad, 1369 retries=1, 1370 expected_state=True, 1371 timeout=60): 1372 """Verify internet connection by ping test. 1373 1374 Args: 1375 log: log object 1376 ad: Android Device Object. 1377 1378 """ 1379 begin_time = get_current_epoch_time() 1380 ip_addr = "54.230.144.105" 1381 for dest in ("www.google.com", "www.amazon.com", ip_addr): 1382 for i in range(retries): 1383 ad.log.info("Ping %s - attempt %d", dest, i + 1) 1384 result = adb_shell_ping( 1385 ad, count=5, timeout=timeout, loss_tolerance=40, dest_ip=dest) 1386 if result == expected_state: 1387 ad.log.info( 1388 "Internet connection by pinging to %s is %s as expected", 1389 dest, expected_state) 1390 if dest == ip_addr: 1391 ad.log.warning("Suspect dns failure") 1392 ad.log.info("DNS config: %s", 1393 ad.adb.shell("getprop | grep dns").replace( 1394 "\n", " ")) 1395 return False 1396 return True 1397 else: 1398 ad.log.warning( 1399 "Internet connection test by pinging %s is %s, expecting %s", 1400 dest, result, expected_state) 1401 if get_current_epoch_time() - begin_time < timeout * 1000: 1402 time.sleep(5) 1403 ad.log.error("Ping test doesn't meet expected %s", expected_state) 1404 return False 1405 1406 1407def verify_internet_connection(log, ad, retries=3, expected_state=True): 1408 """Verify internet connection by ping test and http connection. 1409 1410 Args: 1411 log: log object 1412 ad: Android Device Object. 1413 1414 """ 1415 if ad.droid.connectivityNetworkIsConnected() != expected_state: 1416 ad.log.info("NetworkIsConnected = %s, expecting %s", 1417 not expected_state, expected_state) 1418 if verify_internet_connection_by_ping( 1419 log, ad, retries=retries, expected_state=expected_state): 1420 return True 1421 for url in ("https://www.google.com", "https://www.amazon.com"): 1422 if verify_http_connection( 1423 log, ad, url=url, retry=retries, 1424 expected_state=expected_state): 1425 return True 1426 ad.log.info("DNS config: %s", " ".join( 1427 ad.adb.shell("getprop | grep dns").split())) 1428 ad.log.info("Interface info:\n%s", ad.adb.shell("ifconfig")) 1429 ad.log.info("NetworkAgentInfo: %s", 1430 ad.adb.shell("dumpsys connectivity | grep NetworkAgentInfo")) 1431 return False 1432 1433 1434def iperf_test_with_options(log, 1435 ad, 1436 iperf_server, 1437 iperf_option, 1438 timeout=180, 1439 rate_dict=None, 1440 blocking=True, 1441 log_file_path=None): 1442 """iperf adb run helper. 1443 1444 Args: 1445 log: log object 1446 ad: Android Device Object. 1447 iperf_server: The iperf host url". 1448 iperf_option: The options to pass to iperf client 1449 timeout: timeout for file download to complete. 1450 rate_dict: dictionary that can be passed in to save data 1451 blocking: run iperf in blocking mode if True 1452 log_file_path: location to save logs 1453 Returns: 1454 True if iperf runs without throwing an exception 1455 """ 1456 try: 1457 if log_file_path: 1458 ad.adb.shell("rm %s" % log_file_path, ignore_status=True) 1459 ad.log.info("Running adb iperf test with server %s", iperf_server) 1460 ad.log.info("iperf options are %s", iperf_option) 1461 if not blocking: 1462 ad.run_iperf_client_nb( 1463 iperf_server, 1464 iperf_option, 1465 timeout=timeout + 60, 1466 log_file_path=log_file_path) 1467 return True 1468 result, data = ad.run_iperf_client( 1469 iperf_server, iperf_option, timeout=timeout + 120) 1470 ad.log.info("iperf test result with server %s is %s", iperf_server, 1471 result) 1472 if result: 1473 iperf_str = ''.join(data) 1474 iperf_result = ipf.IPerfResult(iperf_str, 'None') 1475 if "-u" in iperf_option: 1476 udp_rate = iperf_result.avg_rate 1477 if udp_rate is None: 1478 ad.log.warning( 1479 "UDP rate is none, IPerf server returned error: %s", 1480 iperf_result.error) 1481 ad.log.info("iperf3 UDP DL speed is %.6s Mbps", (udp_rate/1000000)) 1482 else: 1483 tx_rate = iperf_result.avg_send_rate 1484 rx_rate = iperf_result.avg_receive_rate 1485 if (tx_rate or rx_rate) is None: 1486 ad.log.warning( 1487 "A TCP rate is none, iperf server returned error: %s", 1488 iperf_result.error) 1489 ad.log.info( 1490 "iperf3 TCP - UL speed is %.6s Mbps, DL speed is %.6s Mbps", 1491 (tx_rate/1000000), (rx_rate/1000000)) 1492 if rate_dict is not None: 1493 rate_dict["Uplink"] = tx_rate 1494 rate_dict["Downlink"] = rx_rate 1495 return result 1496 except AdbError as e: 1497 ad.log.warning("Fail to run iperf test with exception %s", e) 1498 raise 1499 1500 1501def iperf_udp_test_by_adb(log, 1502 ad, 1503 iperf_server, 1504 port_num=None, 1505 reverse=False, 1506 timeout=180, 1507 limit_rate=None, 1508 pacing_timer=None, 1509 omit=10, 1510 ipv6=False, 1511 rate_dict=None, 1512 blocking=True, 1513 log_file_path=None, 1514 retry=5): 1515 """Iperf test by adb using UDP. 1516 1517 Args: 1518 log: log object 1519 ad: Android Device Object. 1520 iperf_Server: The iperf host url". 1521 port_num: TCP/UDP server port 1522 reverse: whether to test download instead of upload 1523 timeout: timeout for file download to complete. 1524 limit_rate: iperf bandwidth option. None by default 1525 omit: the omit option provided in iperf command. 1526 ipv6: whether to run the test as ipv6 1527 rate_dict: dictionary that can be passed in to save data 1528 blocking: run iperf in blocking mode if True 1529 log_file_path: location to save logs 1530 retry: times of retry when the server is unavailable 1531 """ 1532 iperf_option = "-u -i 1 -t %s -O %s -J" % (timeout, omit) 1533 if limit_rate: 1534 iperf_option += " -b %s" % limit_rate 1535 if pacing_timer: 1536 iperf_option += " --pacing-timer %s" % pacing_timer 1537 if ipv6: 1538 iperf_option += " -6" 1539 if reverse: 1540 iperf_option += " -R" 1541 for _ in range(retry): 1542 if port_num: 1543 iperf_option_final = iperf_option + " -p %s" % port_num 1544 port_num += 1 1545 else: 1546 iperf_option_final = iperf_option 1547 try: 1548 return iperf_test_with_options(log, 1549 ad, 1550 iperf_server, 1551 iperf_option_final, 1552 timeout, 1553 rate_dict, 1554 blocking, 1555 log_file_path) 1556 except (AdbCommandError, TimeoutError) as error: 1557 continue 1558 except AdbError: 1559 return False 1560 1561 1562def iperf_test_by_adb(log, 1563 ad, 1564 iperf_server, 1565 port_num=None, 1566 reverse=False, 1567 timeout=180, 1568 limit_rate=None, 1569 omit=10, 1570 ipv6=False, 1571 rate_dict=None, 1572 blocking=True, 1573 log_file_path=None, 1574 retry=5): 1575 """Iperf test by adb using TCP. 1576 1577 Args: 1578 log: log object 1579 ad: Android Device Object. 1580 iperf_server: The iperf host url". 1581 port_num: TCP/UDP server port 1582 reverse: whether to test download instead of upload 1583 timeout: timeout for file download to complete. 1584 limit_rate: iperf bandwidth option. None by default 1585 omit: the omit option provided in iperf command. 1586 ipv6: whether to run the test as ipv6 1587 rate_dict: dictionary that can be passed in to save data 1588 blocking: run iperf in blocking mode if True 1589 log_file_path: location to save logs 1590 retry: times of retry when the server is unavailable 1591 """ 1592 iperf_option = "-t %s -O %s -J" % (timeout, omit) 1593 if limit_rate: 1594 iperf_option += " -b %s" % limit_rate 1595 if ipv6: 1596 iperf_option += " -6" 1597 if reverse: 1598 iperf_option += " -R" 1599 for _ in range(retry): 1600 if port_num: 1601 iperf_option_final = iperf_option + " -p %s" % port_num 1602 port_num += 1 1603 else: 1604 iperf_option_final = iperf_option 1605 try: 1606 return iperf_test_with_options(log, 1607 ad, 1608 iperf_server, 1609 iperf_option_final, 1610 timeout, 1611 rate_dict=rate_dict, 1612 blocking=blocking, 1613 log_file_path=log_file_path) 1614 except (AdbCommandError, TimeoutError) as error: 1615 continue 1616 except AdbError: 1617 return False 1618 1619 1620def trigger_modem_crash(ad, timeout=120): 1621 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem" 1622 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd) 1623 ad.adb.shell(cmd) 1624 time.sleep(timeout) 1625 return True 1626 1627 1628def trigger_modem_crash_by_modem(ad, timeout=120): 1629 begin_time = get_device_epoch_time(ad) 1630 ad.adb.shell( 1631 "setprop persist.vendor.sys.modem.diag.mdlog false", 1632 ignore_status=True) 1633 # Legacy pixels use persist.sys.modem.diag.mdlog. 1634 ad.adb.shell( 1635 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 1636 disable_qxdm_logger(ad) 1637 cmd = ('am instrument -w -e request "4b 25 03 00" ' 1638 '"com.google.mdstest/com.google.mdstest.instrument.' 1639 'ModemCommandInstrumentation"') 1640 ad.log.info("Crash modem by %s", cmd) 1641 ad.adb.shell(cmd, ignore_status=True) 1642 time.sleep(timeout) # sleep time for sl4a stability 1643 reasons = ad.search_logcat("modem subsystem failure reason", begin_time) 1644 if reasons: 1645 ad.log.info("Modem crash is triggered successfully") 1646 ad.log.info(reasons[-1]["log_message"]) 1647 return True 1648 else: 1649 ad.log.warning("There is no modem subsystem failure reason logcat") 1650 return False 1651 1652 1653def phone_switch_to_msim_mode(ad, retries=3, timeout=60): 1654 result = False 1655 if not ad.is_apk_installed("com.google.mdstest"): 1656 raise signals.TestAbortClass("mdstest is not installed") 1657 mode = ad.droid.telephonyGetPhoneCount() 1658 if mode == 2: 1659 ad.log.info("Device already in MSIM mode") 1660 return True 1661 for i in range(retries): 1662 ad.adb.shell( 1663 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) 1664 ad.adb.shell( 1665 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 1666 disable_qxdm_logger(ad) 1667 cmd = ('am instrument -w -e request "WriteEFS" -e item ' 1668 '"/google/pixel_multisim_config" -e data "02 00 00 00" ' 1669 '"com.google.mdstest/com.google.mdstest.instrument.' 1670 'ModemConfigInstrumentation"') 1671 ad.log.info("Switch to MSIM mode by using %s", cmd) 1672 ad.adb.shell(cmd, ignore_status=True) 1673 time.sleep(timeout) 1674 ad.adb.shell("setprop persist.radio.multisim.config dsds") 1675 reboot_device(ad) 1676 # Verify if device is really in msim mode 1677 mode = ad.droid.telephonyGetPhoneCount() 1678 if mode == 2: 1679 ad.log.info("Device correctly switched to MSIM mode") 1680 result = True 1681 if "Sprint" in ad.adb.getprop("gsm.sim.operator.alpha"): 1682 cmd = ('am instrument -w -e request "WriteEFS" -e item ' 1683 '"/google/pixel_dsds_imei_mapping_slot_record" -e data "03"' 1684 ' "com.google.mdstest/com.google.mdstest.instrument.' 1685 'ModemConfigInstrumentation"') 1686 ad.log.info("Switch Sprint to IMEI1 slot using %s", cmd) 1687 ad.adb.shell(cmd, ignore_status=True) 1688 time.sleep(timeout) 1689 reboot_device(ad) 1690 break 1691 else: 1692 ad.log.warning("Attempt %d - failed to switch to MSIM", (i + 1)) 1693 return result 1694 1695 1696def phone_switch_to_ssim_mode(ad, retries=3, timeout=30): 1697 result = False 1698 if not ad.is_apk_installed("com.google.mdstest"): 1699 raise signals.TestAbortClass("mdstest is not installed") 1700 mode = ad.droid.telephonyGetPhoneCount() 1701 if mode == 1: 1702 ad.log.info("Device already in SSIM mode") 1703 return True 1704 for i in range(retries): 1705 ad.adb.shell( 1706 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) 1707 ad.adb.shell( 1708 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 1709 disable_qxdm_logger(ad) 1710 cmds = ('am instrument -w -e request "WriteEFS" -e item ' 1711 '"/google/pixel_multisim_config" -e data "01 00 00 00" ' 1712 '"com.google.mdstest/com.google.mdstest.instrument.' 1713 'ModemConfigInstrumentation"', 1714 'am instrument -w -e request "WriteEFS" -e item "/nv/item_files' 1715 '/modem/uim/uimdrv/uim_extended_slot_mapping_config" -e data ' 1716 '"00 01 02 01" "com.google.mdstest/com.google.mdstest.' 1717 'instrument.ModemConfigInstrumentation"') 1718 for cmd in cmds: 1719 ad.log.info("Switch to SSIM mode by using %s", cmd) 1720 ad.adb.shell(cmd, ignore_status=True) 1721 time.sleep(timeout) 1722 ad.adb.shell("setprop persist.radio.multisim.config ssss") 1723 reboot_device(ad) 1724 # Verify if device is really in ssim mode 1725 mode = ad.droid.telephonyGetPhoneCount() 1726 if mode == 1: 1727 ad.log.info("Device correctly switched to SSIM mode") 1728 result = True 1729 break 1730 else: 1731 ad.log.warning("Attempt %d - failed to switch to SSIM", (i + 1)) 1732 return result 1733 1734 1735def lock_lte_band_by_mds(ad, band): 1736 disable_qxdm_logger(ad) 1737 ad.log.info("Write band %s locking to efs file", band) 1738 if band == "4": 1739 item_string = ( 1740 "4B 13 26 00 08 00 00 00 40 00 08 00 0B 00 08 00 00 00 00 00 00 00 " 1741 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D " 1742 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00") 1743 elif band == "13": 1744 item_string = ( 1745 "4B 13 26 00 08 00 00 00 40 00 08 00 0A 00 00 10 00 00 00 00 00 00 " 1746 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D " 1747 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00") 1748 else: 1749 ad.log.error("Band %s is not supported", band) 1750 return False 1751 cmd = ('am instrument -w -e request "%s" com.google.mdstest/com.google.' 1752 'mdstest.instrument.ModemCommandInstrumentation') 1753 for _ in range(3): 1754 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True): 1755 break 1756 else: 1757 ad.log.error("Fail to write band by %s" % (cmd % item_string)) 1758 return False 1759 1760 # EFS Sync 1761 item_string = "4B 13 30 00 2A 00 2F 00" 1762 1763 for _ in range(3): 1764 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True): 1765 break 1766 else: 1767 ad.log.error("Fail to sync efs by %s" % (cmd % item_string)) 1768 return False 1769 time.sleep(5) 1770 reboot_device(ad) 1771 1772 1773def get_cell_data_roaming_state_by_adb(ad): 1774 """Get Cell Data Roaming state. True for enabled, False for disabled""" 1775 state_mapping = {"1": True, "0": False} 1776 return state_mapping[ad.adb.shell("settings get global data_roaming")] 1777 1778 1779def set_cell_data_roaming_state_by_adb(ad, state): 1780 """Set Cell Data Roaming state.""" 1781 state_mapping = {True: "1", False: "0"} 1782 ad.log.info("Set data roaming to %s", state) 1783 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state]) 1784 1785 1786def toggle_cell_data_roaming(ad, state): 1787 """Enable cell data roaming for default data subscription. 1788 1789 Wait for the data roaming status to be DATA_STATE_CONNECTED 1790 or DATA_STATE_DISCONNECTED. 1791 1792 Args: 1793 log: Log object. 1794 ad: Android Device Object. 1795 state: True or False for enable or disable cell data roaming. 1796 1797 Returns: 1798 True if success. 1799 False if failed. 1800 """ 1801 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state] 1802 action_str = {True: "Enable", False: "Disable"}[state] 1803 if ad.droid.connectivityCheckDataRoamingMode() == state: 1804 ad.log.info("Data roaming is already in state %s", state) 1805 return True 1806 if not ad.droid.connectivitySetDataRoaming(state_int): 1807 ad.error.info("Fail to config data roaming into state %s", state) 1808 return False 1809 if ad.droid.connectivityCheckDataRoamingMode() == state: 1810 ad.log.info("Data roaming is configured into state %s", state) 1811 return True 1812 else: 1813 ad.log.error("Data roaming is not configured into state %s", state) 1814 return False 1815 1816 1817def verify_incall_state(log, ads, expected_status): 1818 """Verify phones in incall state or not. 1819 1820 Verify if all phones in the array <ads> are in <expected_status>. 1821 1822 Args: 1823 log: Log object. 1824 ads: Array of Android Device Object. All droid in this array will be tested. 1825 expected_status: If True, verify all Phones in incall state. 1826 If False, verify all Phones not in incall state. 1827 1828 """ 1829 result = True 1830 for ad in ads: 1831 if ad.droid.telecomIsInCall() is not expected_status: 1832 ad.log.error("InCall status:%s, expected:%s", 1833 ad.droid.telecomIsInCall(), expected_status) 1834 result = False 1835 return result 1836 1837 1838def verify_active_call_number(log, ad, expected_number): 1839 """Verify the number of current active call. 1840 1841 Verify if the number of current active call in <ad> is 1842 equal to <expected_number>. 1843 1844 Args: 1845 ad: Android Device Object. 1846 expected_number: Expected active call number. 1847 """ 1848 calls = ad.droid.telecomCallGetCallIds() 1849 if calls is None: 1850 actual_number = 0 1851 else: 1852 actual_number = len(calls) 1853 if actual_number != expected_number: 1854 ad.log.error("Active Call number is %s, expecting", actual_number, 1855 expected_number) 1856 return False 1857 return True 1858 1859 1860def num_active_calls(log, ad): 1861 """Get the count of current active calls. 1862 1863 Args: 1864 log: Log object. 1865 ad: Android Device Object. 1866 1867 Returns: 1868 Count of current active calls. 1869 """ 1870 calls = ad.droid.telecomCallGetCallIds() 1871 return len(calls) if calls else 0 1872 1873 1874def get_carrier_provisioning_for_subscription(ad, feature_flag, 1875 tech, sub_id=None): 1876 """ Gets Provisioning Values for Subscription Id 1877 1878 Args: 1879 ad: Android device object. 1880 sub_id: Subscription Id 1881 feature_flag: voice, video, ut, sms 1882 tech: wlan, wwan 1883 1884 """ 1885 try: 1886 if sub_id is None: 1887 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 1888 result = ad.droid.imsMmTelIsSupported(sub_id, feature_flag, tech) 1889 ad.log.info("SubId %s - imsMmTelIsSupported for %s on %s - %s", 1890 sub_id, feature_flag, tech, result) 1891 return result 1892 except Exception as e: 1893 ad.log.error(e) 1894 return False 1895 1896 1897def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args, 1898 **kwargs): 1899 while max_time >= 0: 1900 if state_check_func(log, ad, *args, **kwargs): 1901 return True 1902 1903 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 1904 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 1905 1906 return False 1907 1908 1909def _wait_for_droid_in_state_for_subscription( 1910 log, ad, sub_id, max_time, state_check_func, *args, **kwargs): 1911 while max_time >= 0: 1912 if state_check_func(log, ad, sub_id, *args, **kwargs): 1913 return True 1914 1915 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 1916 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 1917 1918 return False 1919 1920 1921def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args, 1922 **kwargs): 1923 while max_time > 0: 1924 success = True 1925 for ad in ads: 1926 if not state_check_func(log, ad, *args, **kwargs): 1927 success = False 1928 break 1929 if success: 1930 return True 1931 1932 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 1933 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 1934 1935 return False 1936 1937 1938def _is_attached(log, ad, voice_or_data): 1939 return _is_attached_for_subscription( 1940 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 1941 1942 1943def _is_attached_for_subscription(log, ad, sub_id, voice_or_data): 1944 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data) 1945 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat, 1946 voice_or_data) 1947 return rat != RAT_UNKNOWN 1948 1949 1950def is_voice_attached(log, ad): 1951 return _is_attached_for_subscription( 1952 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE) 1953 1954 1955def wait_for_data_attach(log, ad, max_time): 1956 """Wait for android device to attach on data. 1957 1958 Args: 1959 log: log object. 1960 ad: android device. 1961 max_time: maximal wait time. 1962 1963 Returns: 1964 Return True if device attach data within max_time. 1965 Return False if timeout. 1966 """ 1967 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 1968 NETWORK_SERVICE_DATA) 1969 1970 1971def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time): 1972 """Wait for android device to attach on data in subscription id. 1973 1974 Args: 1975 log: log object. 1976 ad: android device. 1977 sub_id: subscription id. 1978 max_time: maximal wait time. 1979 1980 Returns: 1981 Return True if device attach data within max_time. 1982 Return False if timeout. 1983 """ 1984 return _wait_for_droid_in_state_for_subscription( 1985 log, ad, sub_id, max_time, _is_attached_for_subscription, 1986 NETWORK_SERVICE_DATA) 1987 1988 1989def get_phone_number(log, ad): 1990 """Get phone number for default subscription 1991 1992 Args: 1993 log: log object. 1994 ad: Android device object. 1995 1996 Returns: 1997 Phone number. 1998 """ 1999 return get_phone_number_for_subscription(log, ad, 2000 get_outgoing_voice_sub_id(ad)) 2001 2002 2003def get_phone_number_for_subscription(log, ad, subid): 2004 """Get phone number for subscription 2005 2006 Args: 2007 log: log object. 2008 ad: Android device object. 2009 subid: subscription id. 2010 2011 Returns: 2012 Phone number. 2013 """ 2014 number = None 2015 try: 2016 number = ad.telephony['subscription'][subid]['phone_num'] 2017 except KeyError: 2018 number = ad.droid.telephonyGetLine1NumberForSubscription(subid) 2019 return number 2020 2021 2022def set_phone_number(log, ad, phone_num): 2023 """Set phone number for default subscription 2024 2025 Args: 2026 log: log object. 2027 ad: Android device object. 2028 phone_num: phone number string. 2029 2030 Returns: 2031 True if success. 2032 """ 2033 return set_phone_number_for_subscription(log, ad, 2034 get_outgoing_voice_sub_id(ad), 2035 phone_num) 2036 2037 2038def set_phone_number_for_subscription(log, ad, subid, phone_num): 2039 """Set phone number for subscription 2040 2041 Args: 2042 log: log object. 2043 ad: Android device object. 2044 subid: subscription id. 2045 phone_num: phone number string. 2046 2047 Returns: 2048 True if success. 2049 """ 2050 try: 2051 ad.telephony['subscription'][subid]['phone_num'] = phone_num 2052 except Exception: 2053 return False 2054 return True 2055 2056 2057def get_operator_name(log, ad, subId=None): 2058 """Get operator name (e.g. vzw, tmo) of droid. 2059 2060 Args: 2061 ad: Android device object. 2062 sub_id: subscription ID 2063 Optional, default is None 2064 2065 Returns: 2066 Operator name. 2067 """ 2068 try: 2069 if subId is not None: 2070 result = operator_name_from_plmn_id( 2071 ad.droid.telephonyGetNetworkOperatorForSubscription(subId)) 2072 else: 2073 result = operator_name_from_plmn_id( 2074 ad.droid.telephonyGetNetworkOperator()) 2075 except KeyError: 2076 try: 2077 if subId is not None: 2078 result = ad.droid.telephonyGetNetworkOperatorNameForSubscription( 2079 subId) 2080 else: 2081 result = ad.droid.telephonyGetNetworkOperatorName() 2082 result = operator_name_from_network_name(result) 2083 except Exception: 2084 result = CARRIER_UNKNOWN 2085 ad.log.info("Operator Name is %s", result) 2086 return result 2087 2088 2089def get_model_name(ad): 2090 """Get android device model name 2091 2092 Args: 2093 ad: Android device object 2094 2095 Returns: 2096 model name string 2097 """ 2098 # TODO: Create translate table. 2099 model = ad.model 2100 if (model.startswith(AOSP_PREFIX)): 2101 model = model[len(AOSP_PREFIX):] 2102 return model 2103 2104 2105def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None): 2106 return is_droid_in_rat_family_for_subscription( 2107 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 2108 voice_or_data) 2109 2110 2111def is_droid_in_rat_family_for_subscription(log, 2112 ad, 2113 sub_id, 2114 rat_family, 2115 voice_or_data=None): 2116 return is_droid_in_rat_family_list_for_subscription( 2117 log, ad, sub_id, [rat_family], voice_or_data) 2118 2119 2120def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None): 2121 return is_droid_in_rat_family_list_for_subscription( 2122 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list, 2123 voice_or_data) 2124 2125 2126def is_droid_in_rat_family_list_for_subscription(log, 2127 ad, 2128 sub_id, 2129 rat_family_list, 2130 voice_or_data=None): 2131 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 2132 if voice_or_data: 2133 service_list = [voice_or_data] 2134 2135 for service in service_list: 2136 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 2137 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 2138 continue 2139 if rat_family_from_rat(nw_rat) in rat_family_list: 2140 return True 2141 return False 2142 2143 2144def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data): 2145 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 2146 2147 Args: 2148 log: log object. 2149 ad: android device. 2150 nw_gen: expected generation "4g", "3g", "2g". 2151 voice_or_data: check voice network generation or data network generation 2152 This parameter is optional. If voice_or_data is None, then if 2153 either voice or data in expected generation, function will return True. 2154 2155 Returns: 2156 True if droid in expected network generation. Otherwise False. 2157 """ 2158 return is_droid_in_network_generation_for_subscription( 2159 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data) 2160 2161 2162def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen, 2163 voice_or_data): 2164 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 2165 2166 Args: 2167 log: log object. 2168 ad: android device. 2169 nw_gen: expected generation "4g", "3g", "2g". 2170 voice_or_data: check voice network generation or data network generation 2171 This parameter is optional. If voice_or_data is None, then if 2172 either voice or data in expected generation, function will return True. 2173 2174 Returns: 2175 True if droid in expected network generation. Otherwise False. 2176 """ 2177 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 2178 2179 if voice_or_data: 2180 service_list = [voice_or_data] 2181 2182 for service in service_list: 2183 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 2184 ad.log.info("%s network rat is %s", service, nw_rat) 2185 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 2186 continue 2187 2188 if rat_generation_from_rat(nw_rat) == nw_gen: 2189 ad.log.info("%s network rat %s is expected %s", service, nw_rat, 2190 nw_gen) 2191 return True 2192 else: 2193 ad.log.info("%s network rat %s is %s, does not meet expected %s", 2194 service, nw_rat, rat_generation_from_rat(nw_rat), 2195 nw_gen) 2196 return False 2197 2198 return False 2199 2200 2201def get_network_rat(log, ad, voice_or_data): 2202 """Get current network type (Voice network type, or data network type) 2203 for default subscription id 2204 2205 Args: 2206 ad: Android Device Object 2207 voice_or_data: Input parameter indicating to get voice network type or 2208 data network type. 2209 2210 Returns: 2211 Current voice/data network type. 2212 """ 2213 return get_network_rat_for_subscription( 2214 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 2215 2216 2217def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data): 2218 """Get current network type (Voice network type, or data network type) 2219 for specified subscription id 2220 2221 Args: 2222 ad: Android Device Object 2223 sub_id: subscription ID 2224 voice_or_data: Input parameter indicating to get voice network type or 2225 data network type. 2226 2227 Returns: 2228 Current voice/data network type. 2229 """ 2230 if voice_or_data == NETWORK_SERVICE_VOICE: 2231 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 2232 sub_id) 2233 elif voice_or_data == NETWORK_SERVICE_DATA: 2234 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 2235 sub_id) 2236 else: 2237 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id) 2238 2239 if ret_val is None: 2240 log.error("get_network_rat(): Unexpected null return value") 2241 return RAT_UNKNOWN 2242 else: 2243 return ret_val 2244 2245 2246def get_network_gen(log, ad, voice_or_data): 2247 """Get current network generation string (Voice network type, or data network type) 2248 2249 Args: 2250 ad: Android Device Object 2251 voice_or_data: Input parameter indicating to get voice network generation 2252 or data network generation. 2253 2254 Returns: 2255 Current voice/data network generation. 2256 """ 2257 return get_network_gen_for_subscription( 2258 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 2259 2260 2261def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data): 2262 """Get current network generation string (Voice network type, or data network type) 2263 2264 Args: 2265 ad: Android Device Object 2266 voice_or_data: Input parameter indicating to get voice network generation 2267 or data network generation. 2268 2269 Returns: 2270 Current voice/data network generation. 2271 """ 2272 try: 2273 return rat_generation_from_rat( 2274 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)) 2275 except KeyError as e: 2276 ad.log.error("KeyError %s", e) 2277 return GEN_UNKNOWN 2278 2279 2280def check_voice_mail_count(log, ad, voice_mail_count_before, 2281 voice_mail_count_after): 2282 """function to check if voice mail count is correct after leaving a new voice message. 2283 """ 2284 return get_voice_mail_count_check_function(get_operator_name(log, ad))( 2285 voice_mail_count_before, voice_mail_count_after) 2286 2287 2288def get_voice_mail_number(log, ad): 2289 """function to get the voice mail number 2290 """ 2291 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad)) 2292 if voice_mail_number is None: 2293 return get_phone_number(log, ad) 2294 return voice_mail_number 2295 2296 2297def reset_preferred_network_type_to_allowable_range(log, ad): 2298 """If preferred network type is not in allowable range, reset to GEN_4G 2299 preferred network type. 2300 2301 Args: 2302 log: log object 2303 ad: android device object 2304 2305 Returns: 2306 None 2307 """ 2308 for sub_id, sub_info in ad.telephony["subscription"].items(): 2309 current_preference = \ 2310 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id) 2311 ad.log.debug("sub_id network preference is %s", current_preference) 2312 try: 2313 if current_preference not in get_allowable_network_preference( 2314 sub_info["operator"], sub_info["phone_type"]): 2315 network_preference = network_preference_for_generation( 2316 GEN_4G, sub_info["operator"], sub_info["phone_type"]) 2317 ad.droid.telephonySetPreferredNetworkTypesForSubscription( 2318 network_preference, sub_id) 2319 except KeyError: 2320 pass 2321 2322 2323def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME): 2324 """Set phone screen on time. 2325 2326 Args: 2327 log: Log object. 2328 ad: Android device object. 2329 screen_on_time: screen on time. 2330 This is optional, default value is MAX_SCREEN_ON_TIME. 2331 Returns: 2332 True if set successfully. 2333 """ 2334 ad.droid.setScreenTimeout(screen_on_time) 2335 return screen_on_time == ad.droid.getScreenTimeout() 2336 2337 2338def set_phone_silent_mode(log, ad, silent_mode=True): 2339 """Set phone silent mode. 2340 2341 Args: 2342 log: Log object. 2343 ad: Android device object. 2344 silent_mode: set phone silent or not. 2345 This is optional, default value is True (silent mode on). 2346 Returns: 2347 True if set successfully. 2348 """ 2349 ad.droid.toggleRingerSilentMode(silent_mode) 2350 ad.droid.setMediaVolume(0) 2351 ad.droid.setVoiceCallVolume(0) 2352 ad.droid.setAlarmVolume(0) 2353 ad.adb.ensure_root() 2354 ad.adb.shell("setprop ro.audio.silent 1", ignore_status=True) 2355 ad.adb.shell("cmd notification set_dnd on", ignore_status=True) 2356 return silent_mode == ad.droid.checkRingerSilentMode() 2357 2358 2359def set_preferred_network_mode_pref(log, 2360 ad, 2361 sub_id, 2362 network_preference, 2363 timeout=WAIT_TIME_ANDROID_STATE_SETTLING): 2364 """Set Preferred Network Mode for Sub_id 2365 Args: 2366 log: Log object. 2367 ad: Android device object. 2368 sub_id: Subscription ID. 2369 network_preference: Network Mode Type 2370 """ 2371 begin_time = get_device_epoch_time(ad) 2372 if ad.droid.telephonyGetPreferredNetworkTypesForSubscription( 2373 sub_id) == network_preference: 2374 ad.log.info("Current ModePref for Sub %s is in %s", sub_id, 2375 network_preference) 2376 return True 2377 ad.log.info("Setting ModePref to %s for Sub %s", network_preference, 2378 sub_id) 2379 while timeout >= 0: 2380 if ad.droid.telephonySetPreferredNetworkTypesForSubscription( 2381 network_preference, sub_id): 2382 return True 2383 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 2384 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 2385 error_msg = "Failed to set sub_id %s PreferredNetworkType to %s" % ( 2386 sub_id, network_preference) 2387 search_results = ad.search_logcat( 2388 "REQUEST_SET_PREFERRED_NETWORK_TYPE error", begin_time=begin_time) 2389 if search_results: 2390 log_message = search_results[-1]["log_message"] 2391 if "DEVICE_IN_USE" in log_message: 2392 error_msg = "%s due to DEVICE_IN_USE" % error_msg 2393 else: 2394 error_msg = "%s due to %s" % (error_msg, log_message) 2395 ad.log.error(error_msg) 2396 return False 2397 2398 2399def set_call_state_listen_level(log, ad, value, sub_id): 2400 """Set call state listen level for subscription id. 2401 2402 Args: 2403 log: Log object. 2404 ad: Android device object. 2405 value: True or False 2406 sub_id :Subscription ID. 2407 2408 Returns: 2409 True or False 2410 """ 2411 if sub_id == INVALID_SUB_ID: 2412 log.error("Invalid Subscription ID") 2413 return False 2414 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 2415 "Foreground", value, sub_id) 2416 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 2417 "Ringing", value, sub_id) 2418 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 2419 "Background", value, sub_id) 2420 return True 2421 2422 2423def is_event_match(event, field, value): 2424 """Return if <field> in "event" match <value> or not. 2425 2426 Args: 2427 event: event to test. This event need to have <field>. 2428 field: field to match. 2429 value: value to match. 2430 2431 Returns: 2432 True if <field> in "event" match <value>. 2433 False otherwise. 2434 """ 2435 return is_event_match_for_list(event, field, [value]) 2436 2437 2438def is_event_match_for_list(event, field, value_list): 2439 """Return if <field> in "event" match any one of the value 2440 in "value_list" or not. 2441 2442 Args: 2443 event: event to test. This event need to have <field>. 2444 field: field to match. 2445 value_list: a list of value to match. 2446 2447 Returns: 2448 True if <field> in "event" match one of the value in "value_list". 2449 False otherwise. 2450 """ 2451 try: 2452 value_in_event = event['data'][field] 2453 except KeyError: 2454 return False 2455 for value in value_list: 2456 if value_in_event == value: 2457 return True 2458 return False 2459 2460 2461def is_network_call_back_event_match(event, network_callback_id, 2462 network_callback_event): 2463 try: 2464 return ( 2465 (network_callback_id == event['data'][NetworkCallbackContainer.ID]) 2466 and (network_callback_event == event['data'] 2467 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT])) 2468 except KeyError: 2469 return False 2470 2471 2472def is_build_id(log, ad, build_id): 2473 """Return if ad's build id is the same as input parameter build_id. 2474 2475 Args: 2476 log: log object. 2477 ad: android device object. 2478 build_id: android build id. 2479 2480 Returns: 2481 True if ad's build id is the same as input parameter build_id. 2482 False otherwise. 2483 """ 2484 actual_bid = ad.droid.getBuildID() 2485 2486 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay()) 2487 #In case we want to log more stuff/more granularity... 2488 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID())) 2489 #log.info("{} BUILD FINGERPRINT: {} " 2490 # .format(ad.serial), ad.droid.getBuildFingerprint()) 2491 #log.info("{} BUILD TYPE: {} " 2492 # .format(ad.serial), ad.droid.getBuildType()) 2493 #log.info("{} BUILD NUMBER: {} " 2494 # .format(ad.serial), ad.droid.getBuildNumber()) 2495 if actual_bid.upper() != build_id.upper(): 2496 ad.log.error("%s: Incorrect Build ID", ad.model) 2497 return False 2498 return True 2499 2500 2501def is_uri_equivalent(uri1, uri2): 2502 """Check whether two input uris match or not. 2503 2504 Compare Uris. 2505 If Uris are tel URI, it will only take the digit part 2506 and compare as phone number. 2507 Else, it will just do string compare. 2508 2509 Args: 2510 uri1: 1st uri to be compared. 2511 uri2: 2nd uri to be compared. 2512 2513 Returns: 2514 True if two uris match. Otherwise False. 2515 """ 2516 2517 #If either is None/empty we return false 2518 if not uri1 or not uri2: 2519 return False 2520 2521 try: 2522 if uri1.startswith('tel:') and uri2.startswith('tel:'): 2523 uri1_number = get_number_from_tel_uri(uri1) 2524 uri2_number = get_number_from_tel_uri(uri2) 2525 return check_phone_number_match(uri1_number, uri2_number) 2526 else: 2527 return uri1 == uri2 2528 except AttributeError as e: 2529 return False 2530 2531 2532def get_call_uri(ad, call_id): 2533 """Get call's uri field. 2534 2535 Get Uri for call_id in ad. 2536 2537 Args: 2538 ad: android device object. 2539 call_id: the call id to get Uri from. 2540 2541 Returns: 2542 call's Uri if call is active and have uri field. None otherwise. 2543 """ 2544 try: 2545 call_detail = ad.droid.telecomCallGetDetails(call_id) 2546 return call_detail["Handle"]["Uri"] 2547 except: 2548 return None 2549 2550 2551def get_number_from_tel_uri(uri): 2552 """Get Uri number from tel uri 2553 2554 Args: 2555 uri: input uri 2556 2557 Returns: 2558 If input uri is tel uri, return the number part. 2559 else return None. 2560 """ 2561 if uri.startswith('tel:'): 2562 uri_number = ''.join( 2563 i for i in urllib.parse.unquote(uri) if i.isdigit()) 2564 return uri_number 2565 else: 2566 return None 2567 2568 2569def install_carriersettings_apk(ad, carriersettingsapk, skip_setup_wizard=True): 2570 """ Carrier Setting Installation Steps 2571 2572 Pull sl4a apk from device. Terminate all sl4a sessions, 2573 Reboot the device to bootloader, wipe the device by fastboot. 2574 Reboot the device. wait for device to complete booting 2575 """ 2576 status = True 2577 if carriersettingsapk is None: 2578 ad.log.warning("CarrierSettingsApk is not provided, aborting") 2579 return False 2580 ad.log.info("Push carriersettings apk to the Android device.") 2581 android_apk_path = "/product/priv-app/CarrierSettings/CarrierSettings.apk" 2582 ad.adb.push("%s %s" % (carriersettingsapk, android_apk_path)) 2583 ad.stop_services() 2584 2585 attempts = 3 2586 for i in range(1, attempts + 1): 2587 try: 2588 if ad.serial in list_adb_devices(): 2589 ad.log.info("Reboot to bootloader") 2590 ad.adb.reboot("bootloader", ignore_status=True) 2591 time.sleep(30) 2592 if ad.serial in list_fastboot_devices(): 2593 ad.log.info("Reboot in fastboot") 2594 ad.fastboot.reboot() 2595 ad.wait_for_boot_completion() 2596 ad.root_adb() 2597 if ad.is_sl4a_installed(): 2598 break 2599 time.sleep(10) 2600 break 2601 except Exception as e: 2602 ad.log.warning(e) 2603 if i == attempts: 2604 abort_all_tests(log, str(e)) 2605 time.sleep(5) 2606 try: 2607 ad.start_adb_logcat() 2608 except: 2609 ad.log.error("Failed to start adb logcat!") 2610 if skip_setup_wizard: 2611 ad.exit_setup_wizard() 2612 return status 2613 2614 2615def bring_up_sl4a(ad, attemps=3): 2616 for i in range(attemps): 2617 try: 2618 droid, ed = ad.get_droid() 2619 ed.start() 2620 ad.log.info("Brought up new sl4a session") 2621 break 2622 except Exception as e: 2623 if i < attemps - 1: 2624 ad.log.info(e) 2625 time.sleep(10) 2626 else: 2627 ad.log.error(e) 2628 raise 2629 2630 2631def reboot_device(ad, recover_sim_state=True): 2632 sim_state = is_sim_ready(ad.log, ad) 2633 ad.reboot() 2634 if ad.qxdm_log: 2635 start_qxdm_logger(ad) 2636 ad.unlock_screen() 2637 if recover_sim_state: 2638 if not unlock_sim(ad): 2639 ad.log.error("Unable to unlock SIM") 2640 return False 2641 if sim_state and not _wait_for_droid_in_state( 2642 log, ad, MAX_WAIT_TIME_FOR_STATE_CHANGE, is_sim_ready): 2643 ad.log.error("Sim state didn't reach pre-reboot ready state") 2644 return False 2645 return True 2646 2647 2648def unlocking_device(ad, device_password=None): 2649 """First unlock device attempt, required after reboot""" 2650 ad.unlock_screen(device_password) 2651 time.sleep(2) 2652 ad.adb.wait_for_device(timeout=180) 2653 if not ad.is_waiting_for_unlock_pin(): 2654 return True 2655 else: 2656 ad.unlock_screen(device_password) 2657 time.sleep(2) 2658 ad.adb.wait_for_device(timeout=180) 2659 if ad.wait_for_window_ready(): 2660 return True 2661 ad.log.error("Unable to unlock to user window") 2662 return False 2663 2664 2665def refresh_sl4a_session(ad): 2666 try: 2667 ad.droid.logI("Checking SL4A connection") 2668 ad.log.debug("Existing sl4a session is active") 2669 return True 2670 except Exception as e: 2671 ad.log.warning("Existing sl4a session is NOT active: %s", e) 2672 try: 2673 ad.terminate_all_sessions() 2674 except Exception as e: 2675 ad.log.info("terminate_all_sessions with error %s", e) 2676 ad.ensure_screen_on() 2677 ad.log.info("Open new sl4a connection") 2678 bring_up_sl4a(ad) 2679 2680 2681def get_sim_state(ad): 2682 try: 2683 state = ad.droid.telephonyGetSimState() 2684 except Exception as e: 2685 ad.log.error(e) 2686 state = ad.adb.getprop("gsm.sim.state") 2687 return state 2688 2689 2690def is_sim_locked(ad): 2691 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED 2692 2693 2694def is_sim_lock_enabled(ad): 2695 # TODO: add sl4a fascade to check if sim is locked 2696 return getattr(ad, "is_sim_locked", False) 2697 2698 2699def unlock_sim(ad): 2700 #The puk and pin can be provided in testbed config file. 2701 #"AndroidDevice": [{"serial": "84B5T15A29018214", 2702 # "adb_logcat_param": "-b all", 2703 # "puk": "12345678", 2704 # "puk_pin": "1234"}] 2705 if not is_sim_locked(ad): 2706 return True 2707 else: 2708 ad.is_sim_locked = True 2709 puk_pin = getattr(ad, "puk_pin", "1111") 2710 try: 2711 if not hasattr(ad, 'puk'): 2712 ad.log.info("Enter SIM pin code") 2713 ad.droid.telephonySupplyPin(puk_pin) 2714 else: 2715 ad.log.info("Enter PUK code and pin") 2716 ad.droid.telephonySupplyPuk(ad.puk, puk_pin) 2717 except: 2718 # if sl4a is not available, use adb command 2719 ad.unlock_screen(puk_pin) 2720 if is_sim_locked(ad): 2721 ad.unlock_screen(puk_pin) 2722 time.sleep(30) 2723 return not is_sim_locked(ad) 2724 2725 2726def send_dialer_secret_code(ad, secret_code): 2727 """Send dialer secret code. 2728 2729 ad: android device controller 2730 secret_code: the secret code to be sent to dialer. the string between 2731 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#* 2732 """ 2733 action = 'android.provider.Telephony.SECRET_CODE' 2734 uri = 'android_secret_code://%s' % secret_code 2735 intent = ad.droid.makeIntent( 2736 action, 2737 uri, 2738 None, # type 2739 None, # extras 2740 None, # categories, 2741 None, # packagename, 2742 None, # classname, 2743 0x01000000) # flags 2744 ad.log.info('Issuing dialer secret dialer code: %s', secret_code) 2745 ad.droid.sendBroadcastIntent(intent) 2746 2747 2748def enable_radio_log_on(ad): 2749 if ad.adb.getprop("persist.vendor.radio.adb_log_on") != "1": 2750 ad.log.info("Enable radio adb_log_on and reboot") 2751 adb_disable_verity(ad) 2752 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1") 2753 reboot_device(ad) 2754 2755 2756def adb_disable_verity(ad): 2757 if ad.adb.getprop("ro.boot.veritymode") == "enforcing": 2758 ad.adb.disable_verity() 2759 reboot_device(ad) 2760 ad.adb.remount() 2761 2762 2763def recover_build_id(ad): 2764 build_fingerprint = ad.adb.getprop( 2765 "ro.vendor.build.fingerprint") or ad.adb.getprop( 2766 "ro.build.fingerprint") 2767 if not build_fingerprint: 2768 return 2769 build_id = build_fingerprint.split("/")[3] 2770 if ad.adb.getprop("ro.build.id") != build_id: 2771 build_id_override(ad, build_id) 2772 2773 2774def enable_privacy_usage_diagnostics(ad): 2775 try: 2776 ad.ensure_screen_on() 2777 ad.send_keycode('HOME') 2778 # open the UI page on which we need to enable the setting 2779 cmd = ('am start -n com.google.android.gms/com.google.android.gms.' 2780 'usagereporting.settings.UsageReportingActivity') 2781 ad.adb.shell(cmd) 2782 # perform the toggle 2783 ad.send_keycode('TAB') 2784 ad.send_keycode('ENTER') 2785 except Exception: 2786 ad.log.info("Unable to toggle Usage and Diagnostics") 2787 2788 2789def build_id_override(ad, new_build_id=None, postfix=None): 2790 build_fingerprint = ad.adb.getprop( 2791 "ro.build.fingerprint") or ad.adb.getprop( 2792 "ro.vendor.build.fingerprint") 2793 if build_fingerprint: 2794 build_id = build_fingerprint.split("/")[3] 2795 else: 2796 build_id = None 2797 existing_build_id = ad.adb.getprop("ro.build.id") 2798 if postfix is not None and postfix in build_id: 2799 ad.log.info("Build id already contains %s", postfix) 2800 return 2801 if not new_build_id: 2802 if postfix and build_id: 2803 new_build_id = "%s.%s" % (build_id, postfix) 2804 if not new_build_id or existing_build_id == new_build_id: 2805 return 2806 ad.log.info("Override build id %s with %s", existing_build_id, 2807 new_build_id) 2808 enable_privacy_usage_diagnostics(ad) 2809 adb_disable_verity(ad) 2810 ad.adb.remount() 2811 if "backup.prop" not in ad.adb.shell("ls /sdcard/"): 2812 ad.adb.shell("cp /system/build.prop /sdcard/backup.prop") 2813 ad.adb.shell("cat /system/build.prop | grep -v ro.build.id > /sdcard/test.prop") 2814 ad.adb.shell("echo ro.build.id=%s >> /sdcard/test.prop" % new_build_id) 2815 ad.adb.shell("cp /sdcard/test.prop /system/build.prop") 2816 reboot_device(ad) 2817 ad.log.info("ro.build.id = %s", ad.adb.getprop("ro.build.id")) 2818 2819 2820def enable_connectivity_metrics(ad): 2821 cmds = [ 2822 "pm enable com.android.connectivity.metrics", 2823 "am startservice -a com.google.android.gms.usagereporting.OPTIN_UR", 2824 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 2825 " -e usagestats:connectivity_metrics:enable_data_collection 1", 2826 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 2827 " -e usagestats:connectivity_metrics:telephony_snapshot_period_millis 180000" 2828 # By default it turn on all modules 2829 #"am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 2830 #" -e usagestats:connectivity_metrics:data_collection_bitmap 62" 2831 ] 2832 for cmd in cmds: 2833 ad.adb.shell(cmd, ignore_status=True) 2834 2835 2836def force_connectivity_metrics_upload(ad): 2837 cmd = "cmd jobscheduler run --force com.android.connectivity.metrics %s" 2838 for job_id in [2, 3, 5, 4, 1, 6]: 2839 ad.adb.shell(cmd % job_id, ignore_status=True) 2840 2841 2842def system_file_push(ad, src_file_path, dst_file_path): 2843 """Push system file on a device. 2844 2845 Push system file need to change some system setting and remount. 2846 """ 2847 cmd = "%s %s" % (src_file_path, dst_file_path) 2848 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 2849 skip_sl4a = True if "sl4a.apk" in src_file_path else False 2850 if "Read-only file system" in out: 2851 ad.log.info("Change read-only file system") 2852 adb_disable_verity(ad) 2853 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 2854 if "Read-only file system" in out: 2855 ad.reboot(skip_sl4a) 2856 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 2857 if "error" in out: 2858 ad.log.error("%s failed with %s", cmd, out) 2859 return False 2860 else: 2861 ad.log.info("push %s succeed") 2862 if skip_sl4a: ad.reboot(skip_sl4a) 2863 return True 2864 else: 2865 return True 2866 elif "error" in out: 2867 return False 2868 else: 2869 return True 2870 2871 2872def set_preferred_apn_by_adb(ad, pref_apn_name): 2873 """Select Pref APN 2874 Set Preferred APN on UI using content query/insert 2875 It needs apn name as arg, and it will match with plmn id 2876 """ 2877 try: 2878 plmn_id = get_plmn_by_adb(ad) 2879 out = ad.adb.shell("content query --uri content://telephony/carriers " 2880 "--where \"apn='%s' and numeric='%s'\"" % 2881 (pref_apn_name, plmn_id)) 2882 if "No result found" in out: 2883 ad.log.warning("Cannot find APN %s on device", pref_apn_name) 2884 return False 2885 else: 2886 apn_id = re.search(r'_id=(\d+)', out).group(1) 2887 ad.log.info("APN ID is %s", apn_id) 2888 ad.adb.shell("content insert --uri content:" 2889 "//telephony/carriers/preferapn --bind apn_id:i:%s" % 2890 (apn_id)) 2891 out = ad.adb.shell("content query --uri " 2892 "content://telephony/carriers/preferapn") 2893 if "No result found" in out: 2894 ad.log.error("Failed to set prefer APN %s", pref_apn_name) 2895 return False 2896 elif apn_id == re.search(r'_id=(\d+)', out).group(1): 2897 ad.log.info("Preferred APN set to %s", pref_apn_name) 2898 return True 2899 except Exception as e: 2900 ad.log.error("Exception while setting pref apn %s", e) 2901 return True 2902 2903 2904def check_apm_mode_on_by_serial(ad, serial_id): 2905 try: 2906 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id, 2907 "grep -i airplanemodeon", "cut -f2 -d ' '")) 2908 output = exe_cmd(apm_check_cmd) 2909 if output.decode("utf-8").split("\n")[0] == "true": 2910 return True 2911 else: 2912 return False 2913 except Exception as e: 2914 ad.log.warning("Exception during check apm mode on %s", e) 2915 return True 2916 2917 2918def set_apm_mode_on_by_serial(ad, serial_id): 2919 try: 2920 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id 2921 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id 2922 exe_cmd(cmd1) 2923 exe_cmd(cmd2) 2924 except Exception as e: 2925 ad.log.warning("Exception during set apm mode on %s", e) 2926 return True 2927 2928 2929def print_radio_info(ad, extra_msg=""): 2930 for prop in ("gsm.version.baseband", "persist.radio.ver_info", 2931 "persist.radio.cnv.ver_info"): 2932 output = ad.adb.getprop(prop) 2933 ad.log.info("%s%s = %s", extra_msg, prop, output) 2934 2935 2936def wait_for_state(state_check_func, 2937 state, 2938 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE, 2939 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK, 2940 *args, 2941 **kwargs): 2942 while max_wait_time >= 0: 2943 if state_check_func(*args, **kwargs) == state: 2944 return True 2945 time.sleep(checking_interval) 2946 max_wait_time -= checking_interval 2947 return False 2948 2949 2950def power_off_sim_by_adb(ad, sim_slot_id, 2951 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE): 2952 """Disable pSIM/eSIM SUB by adb command. 2953 2954 Args: 2955 ad: android device object. 2956 sim_slot_id: slot 0 or slot 1. 2957 timeout: wait time for state change. 2958 2959 Returns: 2960 True if success, False otherwise. 2961 """ 2962 release_version = int(ad.adb.getprop("ro.build.version.release")) 2963 if sim_slot_id == 0 and release_version < 12: 2964 ad.log.error( 2965 "The disable pSIM SUB command only support for Android S or higher " 2966 "version, abort test.") 2967 raise signals.TestSkip( 2968 "The disable pSIM SUB command only support for Android S or higher " 2969 "version, abort test.") 2970 try: 2971 if sim_slot_id: 2972 ad.adb.shell("am broadcast -a android.telephony.euicc.action." 2973 "TEST_PROFILE -n com.google.android.euicc/com.android.euicc." 2974 "receiver.ProfileTestReceiver --es 'operation' 'switch' --ei " 2975 "'subscriptionId' -1") 2976 else: 2977 sub_id = get_subid_by_adb(ad, sim_slot_id) 2978 # The command only support for Android S. (b/159605922) 2979 ad.adb.shell( 2980 "cmd phone disable-physical-subscription %d" % sub_id) 2981 except Exception as e: 2982 ad.log.error(e) 2983 return False 2984 while timeout > 0: 2985 if get_subid_by_adb(ad, sim_slot_id) == INVALID_SUB_ID: 2986 return True 2987 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 2988 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 2989 sim_state = ad.adb.getprop("gsm.sim.state").split(",") 2990 ad.log.warning("Fail to power off SIM slot %d, sim_state=%s", 2991 sim_slot_id, sim_state[sim_slot_id]) 2992 return False 2993 2994 2995def power_on_sim_by_adb(ad, sim_slot_id, 2996 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE): 2997 """Enable pSIM/eSIM SUB by adb command. 2998 2999 Args: 3000 ad: android device object. 3001 sim_slot_id: slot 0 or slot 1. 3002 timeout: wait time for state change. 3003 3004 Returns: 3005 True if success, False otherwise. 3006 """ 3007 release_version = int(ad.adb.getprop("ro.build.version.release")) 3008 if sim_slot_id == 0 and release_version < 12: 3009 ad.log.error( 3010 "The enable pSIM SUB command only support for Android S or higher " 3011 "version, abort test.") 3012 raise signals.TestSkip( 3013 "The enable pSIM SUB command only support for Android S or higher " 3014 "version, abort test.") 3015 try: 3016 output = ad.adb.shell( 3017 "dumpsys isub | grep addSubInfoRecord | grep slotIndex=%d" % 3018 sim_slot_id) 3019 pattern = re.compile(r"subId=(\d+)") 3020 sub_id = pattern.findall(output) 3021 sub_id = int(sub_id[-1]) if sub_id else INVALID_SUB_ID 3022 if sim_slot_id: 3023 ad.adb.shell("am broadcast -a android.telephony.euicc.action." 3024 "TEST_PROFILE -n com.google.android.euicc/com.android.euicc." 3025 "receiver.ProfileTestReceiver --es 'operation' 'switch' --ei " 3026 "'subscriptionId' %d" % sub_id) 3027 else: 3028 # The command only support for Android S or higher. (b/159605922) 3029 ad.adb.shell( 3030 "cmd phone enable-physical-subscription %d" % sub_id) 3031 except Exception as e: 3032 ad.log.error(e) 3033 return False 3034 while timeout > 0: 3035 if get_subid_by_adb(ad, sim_slot_id) != INVALID_SUB_ID: 3036 return True 3037 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 3038 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 3039 sim_state = ad.adb.getprop("gsm.sim.state").split(",") 3040 ad.log.warning("Fail to power on SIM slot %d, sim_state=%s", 3041 sim_slot_id, sim_state[sim_slot_id]) 3042 return False 3043 3044 3045def power_off_sim(ad, sim_slot_id=None, 3046 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE): 3047 try: 3048 if sim_slot_id is None: 3049 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN) 3050 verify_func = ad.droid.telephonyGetSimState 3051 verify_args = [] 3052 else: 3053 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, 3054 CARD_POWER_DOWN) 3055 verify_func = ad.droid.telephonyGetSimStateForSlotId 3056 verify_args = [sim_slot_id] 3057 except Exception as e: 3058 ad.log.error(e) 3059 return False 3060 while timeout > 0: 3061 sim_state = verify_func(*verify_args) 3062 if sim_state in ( 3063 SIM_STATE_UNKNOWN, SIM_STATE_ABSENT, SIM_STATE_NOT_READY): 3064 ad.log.info("SIM slot is powered off, SIM state is %s", sim_state) 3065 return True 3066 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 3067 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 3068 ad.log.warning("Fail to power off SIM slot, sim_state=%s", 3069 verify_func(*verify_args)) 3070 return False 3071 3072 3073def power_on_sim(ad, sim_slot_id=None): 3074 try: 3075 if sim_slot_id is None: 3076 ad.droid.telephonySetSimPowerState(CARD_POWER_UP) 3077 verify_func = ad.droid.telephonyGetSimState 3078 verify_args = [] 3079 else: 3080 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP) 3081 verify_func = ad.droid.telephonyGetSimStateForSlotId 3082 verify_args = [sim_slot_id] 3083 except Exception as e: 3084 ad.log.error(e) 3085 return False 3086 if wait_for_state(verify_func, SIM_STATE_READY, 3087 MAX_WAIT_TIME_FOR_STATE_CHANGE, 3088 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args): 3089 ad.log.info("SIM slot is powered on, SIM state is READY") 3090 return True 3091 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED: 3092 ad.log.info("SIM is pin locked") 3093 return True 3094 else: 3095 ad.log.error("Fail to power on SIM slot") 3096 return False 3097 3098 3099def get_device_epoch_time(ad): 3100 return int(1000 * float(ad.adb.shell("date +%s.%N"))) 3101 3102 3103def synchronize_device_time(ad): 3104 ad.adb.shell("put global auto_time 0", ignore_status=True) 3105 try: 3106 ad.adb.droid.setTime(get_current_epoch_time()) 3107 except Exception: 3108 try: 3109 ad.adb.shell("date `date +%m%d%H%M%G.%S`") 3110 except Exception: 3111 pass 3112 try: 3113 ad.adb.shell( 3114 "am broadcast -a android.intent.action.TIME_SET", 3115 ignore_status=True) 3116 except Exception: 3117 pass 3118 3119 3120def revert_default_telephony_setting(ad): 3121 toggle_airplane_mode_by_adb(ad.log, ad, True) 3122 default_data_roaming = int( 3123 ad.adb.getprop("ro.com.android.dataroaming") == 'true') 3124 default_network_preference = int( 3125 ad.adb.getprop("ro.telephony.default_network")) 3126 ad.log.info("Default data roaming %s, network preference %s", 3127 default_data_roaming, default_network_preference) 3128 new_data_roaming = abs(default_data_roaming - 1) 3129 new_network_preference = abs(default_network_preference - 1) 3130 ad.log.info( 3131 "Set data roaming = %s, mobile data = 0, network preference = %s", 3132 new_data_roaming, new_network_preference) 3133 ad.adb.shell("settings put global mobile_data 0") 3134 ad.adb.shell("settings put global data_roaming %s" % new_data_roaming) 3135 ad.adb.shell("settings put global preferred_network_mode %s" % 3136 new_network_preference) 3137 3138 3139def verify_default_telephony_setting(ad): 3140 ad.log.info("carrier_config: %s", dumpsys_carrier_config(ad)) 3141 default_data_roaming = int( 3142 ad.adb.getprop("ro.com.android.dataroaming") == 'true') 3143 default_network_preference = int( 3144 ad.adb.getprop("ro.telephony.default_network")) 3145 ad.log.info("Default data roaming %s, network preference %s", 3146 default_data_roaming, default_network_preference) 3147 data_roaming = int(ad.adb.shell("settings get global data_roaming")) 3148 mobile_data = int(ad.adb.shell("settings get global mobile_data")) 3149 network_preference = int( 3150 ad.adb.shell("settings get global preferred_network_mode")) 3151 airplane_mode = int(ad.adb.shell("settings get global airplane_mode_on")) 3152 result = True 3153 ad.log.info("data_roaming = %s, mobile_data = %s, " 3154 "network_perference = %s, airplane_mode = %s", data_roaming, 3155 mobile_data, network_preference, airplane_mode) 3156 if airplane_mode: 3157 ad.log.error("Airplane mode is on") 3158 result = False 3159 if data_roaming != default_data_roaming: 3160 ad.log.error("Data roaming is %s, expecting %s", data_roaming, 3161 default_data_roaming) 3162 result = False 3163 if not mobile_data: 3164 ad.log.error("Mobile data is off") 3165 result = False 3166 if network_preference != default_network_preference: 3167 ad.log.error("preferred_network_mode is %s, expecting %s", 3168 network_preference, default_network_preference) 3169 result = False 3170 return result 3171 3172 3173def get_carrier_id_version(ad): 3174 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | " \ 3175 "grep -i carrier_list_version") 3176 if out and ":" in out: 3177 version = out.split(':')[1].lstrip() 3178 else: 3179 version = "0" 3180 ad.log.debug("Carrier Config Version is %s", version) 3181 return version 3182 3183 3184def get_carrier_config_version(ad): 3185 out = ad.adb.shell("dumpsys carrier_config | grep version_string") 3186 if out and "-" in out: 3187 version = out.split('-')[1] 3188 else: 3189 version = "0" 3190 ad.log.debug("Carrier Config Version is %s", version) 3191 return version 3192 3193 3194def get_er_db_id_version(ad): 3195 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \ 3196 grep -i \"Database Version\"") 3197 if out and ":" in out: 3198 version = out.split(':', 2)[2].lstrip() 3199 else: 3200 version = "0" 3201 ad.log.debug("Emergency database Version is %s", version) 3202 return version 3203 3204def get_database_content(ad): 3205 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \ 3206 egrep -i \EmergencyNumber:Number-54321") 3207 if out: 3208 return True 3209 result = ad.adb.shell(r"dumpsys activity service TelephonyDebugService | \ 3210 egrep -i \updateOtaEmergencyNumberListDatabaseAndNotify") 3211 ad.log.error("Emergency Number is incorrect. %s ", result) 3212 return False 3213 3214 3215def add_whitelisted_account(ad, user_account,user_password, retries=3): 3216 if not ad.is_apk_installed("com.google.android.tradefed.account"): 3217 ad.log.error("GoogleAccountUtil is not installed") 3218 return False 3219 for _ in range(retries): 3220 ad.ensure_screen_on() 3221 output = ad.adb.shell( 3222 'am instrument -w -e account "%s@gmail.com" -e password ' 3223 '"%s" -e sync true -e wait-for-checkin false ' 3224 'com.google.android.tradefed.account/.AddAccount' % 3225 (user_account, user_password)) 3226 if "result=SUCCESS" in output: 3227 ad.log.info("Google account is added successfully") 3228 return True 3229 ad.log.error("Failed to add google account - %s", output) 3230 return False 3231 3232def install_apk(ad, apk_path, app_package_name): 3233 """Install assigned apk to specific device. 3234 3235 Args: 3236 ad: android device object 3237 apk_path: The path of apk (please refer to the "Resources" section in 3238 go/mhbe-resources for supported file stores.) 3239 app_package_name: package name of the application 3240 3241 Returns: 3242 True if success, False if fail. 3243 """ 3244 ad.log.info("Install %s from %s", app_package_name, apk_path) 3245 ad.adb.install("-r -g %s" % apk_path, timeout=300, ignore_status=True) 3246 time.sleep(3) 3247 if not ad.is_apk_installed(app_package_name): 3248 ad.log.info("%s is not installed.", app_package_name) 3249 return False 3250 if ad.get_apk_version(app_package_name): 3251 ad.log.info("Current version of %s: %s", app_package_name, 3252 ad.get_apk_version(app_package_name)) 3253 return True 3254 3255def install_dialer_apk(ad, dialer_util): 3256 """Install dialer.apk to specific device. 3257 3258 Args: 3259 ad: android device object. 3260 dialer_util: path of dialer.apk 3261 3262 Returns: 3263 True if success, False if fail. 3264 """ 3265 ad.log.info("Install dialer_util %s", dialer_util) 3266 ad.adb.install("-r -g %s" % dialer_util, timeout=300, ignore_status=True) 3267 time.sleep(3) 3268 if not ad.is_apk_installed(DIALER_PACKAGE_NAME): 3269 ad.log.info("%s is not installed", DIALER_PACKAGE_NAME) 3270 return False 3271 if ad.get_apk_version(DIALER_PACKAGE_NAME): 3272 ad.log.info("Current version of %s: %s", DIALER_PACKAGE_NAME, 3273 ad.get_apk_version(DIALER_PACKAGE_NAME)) 3274 return True 3275 3276 3277def install_message_apk(ad, message_util): 3278 """Install message.apk to specific device. 3279 3280 Args: 3281 ad: android device object. 3282 message_util: path of message.apk 3283 3284 Returns: 3285 True if success, False if fail. 3286 """ 3287 ad.log.info("Install message_util %s", message_util) 3288 ad.adb.install("-r -g %s" % message_util, timeout=300, ignore_status=True) 3289 time.sleep(3) 3290 if not ad.is_apk_installed(MESSAGE_PACKAGE_NAME): 3291 ad.log.info("%s is not installed", MESSAGE_PACKAGE_NAME) 3292 return False 3293 if ad.get_apk_version(MESSAGE_PACKAGE_NAME): 3294 ad.log.info("Current version of %s: %s", MESSAGE_PACKAGE_NAME, 3295 ad.get_apk_version(MESSAGE_PACKAGE_NAME)) 3296 return True 3297 3298 3299def install_googleaccountutil_apk(ad, account_util): 3300 ad.log.info("Install account_util %s", account_util) 3301 ad.ensure_screen_on() 3302 ad.adb.install("-r %s" % account_util, timeout=300, ignore_status=True) 3303 time.sleep(3) 3304 if not ad.is_apk_installed("com.google.android.tradefed.account"): 3305 ad.log.info("com.google.android.tradefed.account is not installed") 3306 return False 3307 return True 3308 3309 3310def install_googlefi_apk(ad, fi_util): 3311 ad.log.info("Install fi_util %s", fi_util) 3312 ad.ensure_screen_on() 3313 ad.adb.install("-r -g --user 0 %s" % fi_util, 3314 timeout=300, ignore_status=True) 3315 time.sleep(3) 3316 if not check_fi_apk_installed(ad): 3317 return False 3318 return True 3319 3320 3321def check_fi_apk_installed(ad): 3322 if not ad.is_apk_installed("com.google.android.apps.tycho"): 3323 ad.log.warning("com.google.android.apps.tycho is not installed") 3324 return False 3325 return True 3326 3327 3328def add_google_account(ad, retries=3): 3329 if not ad.is_apk_installed("com.google.android.tradefed.account"): 3330 ad.log.error("GoogleAccountUtil is not installed") 3331 return False 3332 for _ in range(retries): 3333 ad.ensure_screen_on() 3334 output = ad.adb.shell( 3335 'am instrument -w -e account "%s@gmail.com" -e password ' 3336 '"%s" -e sync true -e wait-for-checkin false ' 3337 'com.google.android.tradefed.account/.AddAccount' % 3338 (ad.user_account, ad.user_password)) 3339 if "result=SUCCESS" in output: 3340 ad.log.info("Google account is added successfully") 3341 return True 3342 ad.log.error("Failed to add google account - %s", output) 3343 return False 3344 3345 3346def remove_google_account(ad, retries=3): 3347 if not ad.is_apk_installed("com.google.android.tradefed.account"): 3348 ad.log.error("GoogleAccountUtil is not installed") 3349 return False 3350 for _ in range(retries): 3351 ad.ensure_screen_on() 3352 output = ad.adb.shell( 3353 'am instrument -w ' 3354 'com.google.android.tradefed.account/.RemoveAccounts') 3355 if "result=SUCCESS" in output: 3356 ad.log.info("google account is removed successfully") 3357 return True 3358 ad.log.error("Fail to remove google account due to %s", output) 3359 return False 3360 3361 3362def my_current_screen_content(ad, content): 3363 ad.adb.shell("uiautomator dump --window=WINDOW") 3364 out = ad.adb.shell("cat /sdcard/window_dump.xml | grep -E '%s'" % content) 3365 if not out: 3366 ad.log.warning("NOT FOUND - %s", content) 3367 return False 3368 return True 3369 3370 3371def activate_esim_using_suw(ad): 3372 _START_SUW = ('am start -a android.intent.action.MAIN -n ' 3373 'com.google.android.setupwizard/.SetupWizardTestActivity') 3374 _STOP_SUW = ('am start -a com.android.setupwizard.EXIT') 3375 3376 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False) 3377 ad.adb.shell("settings put system screen_off_timeout 1800000") 3378 ad.ensure_screen_on() 3379 ad.send_keycode("MENU") 3380 ad.send_keycode("HOME") 3381 for _ in range(3): 3382 ad.log.info("Attempt %d - activating eSIM", (_ + 1)) 3383 ad.adb.shell(_START_SUW) 3384 time.sleep(10) 3385 log_screen_shot(ad, "start_suw") 3386 for _ in range(4): 3387 ad.send_keycode("TAB") 3388 time.sleep(0.5) 3389 ad.send_keycode("ENTER") 3390 time.sleep(15) 3391 log_screen_shot(ad, "activate_esim") 3392 get_screen_shot_log(ad) 3393 ad.adb.shell(_STOP_SUW) 3394 time.sleep(5) 3395 current_sim = get_sim_state(ad) 3396 ad.log.info("Current SIM status is %s", current_sim) 3397 if current_sim not in (SIM_STATE_ABSENT, SIM_STATE_UNKNOWN): 3398 break 3399 return True 3400 3401 3402def activate_google_fi_account(ad, retries=10): 3403 _FI_APK = "com.google.android.apps.tycho" 3404 _FI_ACTIVATE_CMD = ('am start -c android.intent.category.DEFAULT -n ' 3405 'com.google.android.apps.tycho/.AccountDetailsActivity --ez ' 3406 'in_setup_wizard false --ez force_show_account_chooser ' 3407 'false') 3408 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False) 3409 ad.adb.shell("settings put system screen_off_timeout 1800000") 3410 page_match_dict = { 3411 "SelectAccount" : "Choose an account to use", 3412 "Setup" : "Activate Google Fi to use your device for calls", 3413 "Switch" : "Switch to the Google Fi mobile network", 3414 "WiFi" : "Fi to download your SIM", 3415 "Connect" : "Connect to the Google Fi mobile network", 3416 "Move" : "Move number", 3417 "Data" : "first turn on mobile data", 3418 "Activate" : "This takes a minute or two, sometimes longer", 3419 "Welcome" : "Welcome to Google Fi", 3420 "Account" : "Your current cycle ends in" 3421 } 3422 page_list = ["Account", "Setup", "WiFi", "Switch", "Connect", 3423 "Activate", "Move", "Welcome", "Data"] 3424 for _ in range(retries): 3425 ad.force_stop_apk(_FI_APK) 3426 ad.ensure_screen_on() 3427 ad.send_keycode("MENU") 3428 ad.send_keycode("HOME") 3429 ad.adb.shell(_FI_ACTIVATE_CMD) 3430 time.sleep(15) 3431 for page in page_list: 3432 if my_current_screen_content(ad, page_match_dict[page]): 3433 ad.log.info("Ready for Step %s", page) 3434 log_screen_shot(ad, "fi_activation_step_%s" % page) 3435 if page in ("Setup", "Switch", "Connect", "WiFi"): 3436 ad.send_keycode("TAB") 3437 ad.send_keycode("TAB") 3438 ad.send_keycode("ENTER") 3439 time.sleep(30) 3440 elif page == "Move" or page == "SelectAccount": 3441 ad.send_keycode("TAB") 3442 ad.send_keycode("ENTER") 3443 time.sleep(5) 3444 elif page == "Welcome": 3445 ad.send_keycode("TAB") 3446 ad.send_keycode("TAB") 3447 ad.send_keycode("TAB") 3448 ad.send_keycode("ENTER") 3449 ad.log.info("Activation SUCCESS using Fi App") 3450 time.sleep(5) 3451 ad.send_keycode("TAB") 3452 ad.send_keycode("TAB") 3453 ad.send_keycode("ENTER") 3454 return True 3455 elif page == "Activate": 3456 time.sleep(60) 3457 if my_current_screen_content(ad, page_match_dict[page]): 3458 time.sleep(60) 3459 elif page == "Account": 3460 return True 3461 elif page == "Data": 3462 ad.log.error("Mobile Data is turned OFF by default") 3463 ad.send_keycode("TAB") 3464 ad.send_keycode("TAB") 3465 ad.send_keycode("ENTER") 3466 else: 3467 ad.log.info("NOT FOUND - Page %s", page) 3468 log_screen_shot(ad, "fi_activation_step_%s_failure" % page) 3469 get_screen_shot_log(ad) 3470 return False 3471 3472 3473def check_google_fi_activated(ad, retries=20): 3474 if check_fi_apk_installed(ad): 3475 _FI_APK = "com.google.android.apps.tycho" 3476 _FI_LAUNCH_CMD = ("am start -n %s/%s.AccountDetailsActivity" \ 3477 % (_FI_APK, _FI_APK)) 3478 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False) 3479 ad.adb.shell("settings put system screen_off_timeout 1800000") 3480 ad.force_stop_apk(_FI_APK) 3481 ad.ensure_screen_on() 3482 ad.send_keycode("HOME") 3483 ad.adb.shell(_FI_LAUNCH_CMD) 3484 time.sleep(10) 3485 if not my_current_screen_content(ad, "Your current cycle ends in"): 3486 ad.log.warning("Fi is not activated") 3487 return False 3488 ad.send_keycode("HOME") 3489 return True 3490 else: 3491 ad.log.info("Fi Apk is not yet installed") 3492 return False 3493 3494 3495def cleanup_configupdater(ad): 3496 cmds = ('rm -rf /data/data/com.google.android.configupdater/shared_prefs', 3497 'rm /data/misc/carrierid/carrier_list.pb', 3498 'setprop persist.telephony.test.carrierid.ota true', 3499 'rm /data/user_de/0/com.android.providers.telephony/shared_prefs' 3500 '/CarrierIdProvider.xml') 3501 for cmd in cmds: 3502 ad.log.info("Cleanup ConfigUpdater - %s", cmd) 3503 ad.adb.shell(cmd, ignore_status=True) 3504 3505 3506def pull_carrier_id_files(ad, carrier_id_path): 3507 os.makedirs(carrier_id_path, exist_ok=True) 3508 ad.log.info("Pull CarrierId Files") 3509 cmds = ('/data/data/com.google.android.configupdater/shared_prefs/', 3510 '/data/misc/carrierid/', 3511 '/data/user_de/0/com.android.providers.telephony/shared_prefs/', 3512 '/data/data/com.android.providers.downloads/databases/downloads.db') 3513 for cmd in cmds: 3514 cmd = cmd + " %s" % carrier_id_path 3515 ad.adb.pull(cmd, timeout=30, ignore_status=True) 3516 3517 3518def bring_up_connectivity_monitor(ad): 3519 monitor_apk = None 3520 for apk in ("com.google.telephonymonitor", 3521 "com.google.android.connectivitymonitor"): 3522 if ad.is_apk_installed(apk): 3523 ad.log.info("apk %s is installed", apk) 3524 monitor_apk = apk 3525 break 3526 if not monitor_apk: 3527 ad.log.info("ConnectivityMonitor|TelephonyMonitor is not installed") 3528 return False 3529 toggle_connectivity_monitor_setting(ad, True) 3530 3531 if not ad.is_apk_running(monitor_apk): 3532 ad.log.info("%s is not running", monitor_apk) 3533 # Reboot 3534 ad.log.info("reboot to bring up %s", monitor_apk) 3535 reboot_device(ad) 3536 for i in range(30): 3537 if ad.is_apk_running(monitor_apk): 3538 ad.log.info("%s is running after reboot", monitor_apk) 3539 return True 3540 else: 3541 ad.log.info( 3542 "%s is not running after reboot. Wait and check again", 3543 monitor_apk) 3544 time.sleep(30) 3545 ad.log.error("%s is not running after reboot", monitor_apk) 3546 return False 3547 else: 3548 ad.log.info("%s is running", monitor_apk) 3549 return True 3550 3551 3552def get_host_ip_address(ad): 3553 cmd = "|".join(("ifconfig", "grep eno1 -A1", "grep inet", "awk '{$1=$1};1'", "cut -d ' ' -f 2")) 3554 destination_ip = exe_cmd(cmd) 3555 destination_ip = (destination_ip.decode("utf-8")).split("\n")[0] 3556 ad.log.info("Host IP is %s", destination_ip) 3557 return destination_ip 3558 3559 3560def load_scone_cat_simulate_data(ad, simulate_data, sub_id=None): 3561 """ Load radio simulate data 3562 ad: android device controller 3563 simulate_data: JSON object of simulate data 3564 sub_id: RIL sub id, should be 0 or 1 3565 """ 3566 ad.log.info("load_scone_cat_simulate_data") 3567 3568 #Check RIL sub id 3569 if sub_id is None or sub_id > 1: 3570 ad.log.error("The value of RIL sub_id should be 0 or 1") 3571 return False 3572 3573 action = "com.google.android.apps.scone.cat.action.SetSimulateData" 3574 3575 #add sub id 3576 simulate_data["SubId"] = sub_id 3577 try: 3578 #dump json 3579 extra = json.dumps(simulate_data) 3580 ad.log.info("send simulate_data=[%s]" % extra) 3581 #send data 3582 ad.adb.shell("am broadcast -a " + action + " --es simulate_data '" + extra + "'") 3583 except Exception as e: 3584 ad.log.error("Exception error to send CAT: %s", e) 3585 return False 3586 3587 return True 3588 3589 3590def load_scone_cat_data_from_file(ad, simulate_file_path, sub_id=None): 3591 """ Load radio simulate data 3592 ad: android device controller 3593 simulate_file_path: JSON file of simulate data 3594 sub_id: RIL sub id, should be 0 or 1 3595 """ 3596 ad.log.info("load_radio_simulate_data_from_file from %s" % simulate_file_path) 3597 radio_simulate_data = {} 3598 3599 #Check RIL sub id 3600 if sub_id is None or sub_id > 1: 3601 ad.log.error("The value of RIL sub_id should be 0 or 1") 3602 raise ValueError 3603 3604 with open(simulate_file_path, 'r') as f: 3605 try: 3606 radio_simulate_data = json.load(f) 3607 except Exception as e: 3608 ad.log.error("Exception error to load %s: %s", f, e) 3609 return False 3610 3611 for item in radio_simulate_data: 3612 result = load_scone_cat_simulate_data(ad, item, sub_id) 3613 if result == False: 3614 ad.log.error("Load CAT command fail") 3615 return False 3616 time.sleep(0.1) 3617 3618 return True 3619 3620 3621def toggle_connectivity_monitor_setting(ad, state=True): 3622 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon") 3623 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting) 3624 current_state = True if monitor_setting == "user_enabled" else False 3625 if current_state == state: 3626 return True 3627 elif state is None: 3628 state = not current_state 3629 expected_monitor_setting = "user_enabled" if state else "disabled" 3630 cmd = "setprop persist.radio.enable_tel_mon %s" % expected_monitor_setting 3631 ad.log.info("Toggle connectivity monitor by %s", cmd) 3632 ad.adb.shell( 3633 "am start -n com.android.settings/.DevelopmentSettings", 3634 ignore_status=True) 3635 ad.adb.shell(cmd) 3636 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon") 3637 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting) 3638 return monitor_setting == expected_monitor_setting 3639 3640 3641def get_rx_tx_power_levels(log, ad): 3642 """ Obtains Rx and Tx power levels from the MDS application. 3643 3644 The method requires the MDS app to be installed in the DUT. 3645 3646 Args: 3647 log: logger object 3648 ad: an android device 3649 3650 Return: 3651 A tuple where the first element is an array array with the RSRP value 3652 in Rx chain, and the second element is the transmitted power in dBm. 3653 Values for invalid Rx / Tx chains are set to None. 3654 """ 3655 cmd = ('am instrument -w -e request "80 00 e8 03 00 08 00 00 00" -e ' 3656 'response wait "com.google.mdstest/com.google.mdstest.instrument.' 3657 'ModemCommandInstrumentation"') 3658 output = ad.adb.shell(cmd) 3659 3660 if 'result=SUCCESS' not in output: 3661 raise RuntimeError('Could not obtain Tx/Rx power levels from MDS. Is ' 3662 'the MDS app installed?') 3663 3664 response = re.search(r"(?<=response=).+", output) 3665 3666 if not response: 3667 raise RuntimeError('Invalid response from the MDS app:\n' + output) 3668 3669 # Obtain a list of bytes in hex format from the response string 3670 response_hex = response.group(0).split(' ') 3671 3672 def get_bool(pos): 3673 """ Obtain a boolean variable from the byte array. """ 3674 return response_hex[pos] == '01' 3675 3676 def get_int32(pos): 3677 """ Obtain an int from the byte array. Bytes are printed in 3678 little endian format.""" 3679 return struct.unpack( 3680 '<i', bytearray.fromhex(''.join(response_hex[pos:pos + 4])))[0] 3681 3682 rx_power = [] 3683 RX_CHAINS = 4 3684 3685 for i in range(RX_CHAINS): 3686 # Calculate starting position for the Rx chain data structure 3687 start = 12 + i * 22 3688 3689 # The first byte in the data structure indicates if the rx chain is 3690 # valid. 3691 if get_bool(start): 3692 rx_power.append(get_int32(start + 2) / 10) 3693 else: 3694 rx_power.append(None) 3695 3696 # Calculate the position for the tx chain data structure 3697 tx_pos = 12 + RX_CHAINS * 22 3698 3699 tx_valid = get_bool(tx_pos) 3700 if tx_valid: 3701 tx_power = get_int32(tx_pos + 2) / -10 3702 else: 3703 tx_power = None 3704 3705 return rx_power, tx_power 3706 3707 3708def set_time_sync_from_network(ad, action): 3709 if (action == 'enable'): 3710 ad.log.info('Enabling sync time from network.') 3711 ad.adb.shell('settings put global auto_time 1') 3712 3713 elif (action == 'disable'): 3714 ad.log.info('Disabling sync time from network.') 3715 ad.adb.shell('settings put global auto_time 0') 3716 3717 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK) 3718 3719 3720def datetime_handle(ad, action, set_datetime_value='', get_year=False): 3721 get_value = '' 3722 if (action == 'get'): 3723 if (get_year): 3724 datetime_string = ad.adb.shell('date') 3725 datetime_list = datetime_string.split() 3726 try: 3727 get_value = datetime_list[5] 3728 except Exception as e: 3729 ad.log.error("Fail to get year from datetime: %s. " \ 3730 "Exception error: %s", datetime_list 3731 , str(e)) 3732 raise signals.TestSkip("Fail to get year from datetime" \ 3733 ", the format is changed. Skip the test.") 3734 else: 3735 get_value = ad.adb.shell('date') 3736 3737 elif (action == 'set'): 3738 ad.adb.shell('date %s' % set_datetime_value) 3739 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK) 3740 ad.adb.shell('am broadcast -a android.intent.action.TIME_SET') 3741 3742 return get_value 3743 3744 3745def change_voice_subid_temporarily(ad, sub_id, state_check_func, params=None): 3746 result = False 3747 voice_sub_id_changed = False 3748 current_sub_id = get_incoming_voice_sub_id(ad) 3749 if current_sub_id != sub_id: 3750 set_incoming_voice_sub_id(ad, sub_id) 3751 voice_sub_id_changed = True 3752 3753 if not params: 3754 if state_check_func(): 3755 result = True 3756 else: 3757 if state_check_func(*params): 3758 result = True 3759 3760 if voice_sub_id_changed: 3761 set_incoming_voice_sub_id(ad, current_sub_id) 3762 3763 return result 3764 3765 3766def check_voice_network_type(ads, voice_init=True): 3767 """ 3768 Args: 3769 ad: Android device object 3770 voice_init: check voice network type before initiate call 3771 Return: 3772 voice_network_list: Network Type for all android devices 3773 """ 3774 voice_network_list = [] 3775 for ad in ads: 3776 voice_network_list.append(ad.droid.telephonyGetCurrentVoiceNetworkType()) 3777 if voice_init: 3778 ad.log.debug("Voice Network Type Before Call is %s", 3779 ad.droid.telephonyGetCurrentVoiceNetworkType()) 3780 else: 3781 ad.log.debug("Voice Network Type During Call is %s", 3782 ad.droid.telephonyGetCurrentVoiceNetworkType()) 3783 return voice_network_list 3784 3785 3786def cycle_airplane_mode(ad): 3787 """Turn on APM and then off.""" 3788 # APM toggle 3789 if not toggle_airplane_mode(ad.log, ad, True): 3790 ad.log.info("Failed to turn on airplane mode.") 3791 return False 3792 if not toggle_airplane_mode(ad.log, ad, False): 3793 ad.log.info("Failed to turn off airplane mode.") 3794 return False 3795 return True