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