1#!/usr/bin/env python3 2# 3# Copyright 2016 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from future import standard_library 18standard_library.install_aliases() 19 20import concurrent.futures 21import json 22import logging 23import re 24import os 25import urllib.parse 26import time 27 28from acts import signals 29from acts import utils 30from queue import Empty 31from acts.asserts import abort_all 32from acts.asserts import fail 33from acts.controllers.adb import AdbError 34from acts.controllers.android_device import list_adb_devices 35from acts.controllers.android_device import list_fastboot_devices 36from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH 37from acts.controllers.android_device import SL4A_APK_NAME 38from acts.libs.proc import job 39from acts.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult 40from acts.test_utils.tel.tel_defines import CarrierConfigs 41from acts.test_utils.tel.tel_defines import AOSP_PREFIX 42from acts.test_utils.tel.tel_defines import CARD_POWER_DOWN 43from acts.test_utils.tel.tel_defines import CARD_POWER_UP 44from acts.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE 45from acts.test_utils.tel.tel_defines import CAPABILITY_VOLTE 46from acts.test_utils.tel.tel_defines import CAPABILITY_VOLTE_PROVISIONING 47from acts.test_utils.tel.tel_defines import CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING 48from acts.test_utils.tel.tel_defines import CAPABILITY_VT 49from acts.test_utils.tel.tel_defines import CAPABILITY_WFC 50from acts.test_utils.tel.tel_defines import CAPABILITY_WFC_MODE_CHANGE 51from acts.test_utils.tel.tel_defines import CARRIER_UNKNOWN 52from acts.test_utils.tel.tel_defines import CARRIER_FRE 53from acts.test_utils.tel.tel_defines import COUNTRY_CODE_LIST 54from acts.test_utils.tel.tel_defines import DATA_STATE_CONNECTED 55from acts.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED 56from acts.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE 57from acts.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE 58from acts.test_utils.tel.tel_defines import GEN_4G 59from acts.test_utils.tel.tel_defines import GEN_UNKNOWN 60from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND 61from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 62from acts.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX 63from acts.test_utils.tel.tel_defines import INVALID_SUB_ID 64from acts.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL 65from acts.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME 66from acts.test_utils.tel.tel_defines import \ 67 MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT 68from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT 69from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP 70from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION 71from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING 72from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 73from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE 74from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT 75from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION 76from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE 77from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS 78from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING 79from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT 80from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED 81from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED 82from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED 83from acts.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL 84from acts.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL 85from acts.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY 86from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY 87from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL 88from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI 89from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 90from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 91from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT 92from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT 93from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT 94from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT 95from acts.test_utils.tel.tel_defines import RAT_FAMILY_GSM 96from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE 97from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN 98from acts.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA 99from acts.test_utils.tel.tel_defines import RAT_1XRTT 100from acts.test_utils.tel.tel_defines import RAT_UNKNOWN 101from acts.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY 102from acts.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE 103from acts.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING 104from acts.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE 105from acts.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF 106from acts.test_utils.tel.tel_defines import SIM_STATE_ABSENT 107from acts.test_utils.tel.tel_defines import SIM_STATE_LOADED 108from acts.test_utils.tel.tel_defines import SIM_STATE_NOT_READY 109from acts.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED 110from acts.test_utils.tel.tel_defines import SIM_STATE_READY 111from acts.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN 112from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE 113from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK 114from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING 115from acts.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT 116from acts.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH 117from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 118from acts.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK 119from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE 120from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID 121from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 122from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL 123from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL 124from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE 125from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED 126from acts.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED 127from acts.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY 128from acts.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED 129from acts.test_utils.tel.tel_defines import TYPE_MOBILE 130from acts.test_utils.tel.tel_defines import TYPE_WIFI 131from acts.test_utils.tel.tel_defines import EventCallStateChanged 132from acts.test_utils.tel.tel_defines import EventConnectivityChanged 133from acts.test_utils.tel.tel_defines import EventDataConnectionStateChanged 134from acts.test_utils.tel.tel_defines import EventDataSmsReceived 135from acts.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged 136from acts.test_utils.tel.tel_defines import EventServiceStateChanged 137from acts.test_utils.tel.tel_defines import EventMmsSentFailure 138from acts.test_utils.tel.tel_defines import EventMmsSentSuccess 139from acts.test_utils.tel.tel_defines import EventMmsDownloaded 140from acts.test_utils.tel.tel_defines import EventSmsReceived 141from acts.test_utils.tel.tel_defines import EventSmsDeliverFailure 142from acts.test_utils.tel.tel_defines import EventSmsDeliverSuccess 143from acts.test_utils.tel.tel_defines import EventSmsSentFailure 144from acts.test_utils.tel.tel_defines import EventSmsSentSuccess 145from acts.test_utils.tel.tel_defines import CallStateContainer 146from acts.test_utils.tel.tel_defines import DataConnectionStateContainer 147from acts.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer 148from acts.test_utils.tel.tel_defines import NetworkCallbackContainer 149from acts.test_utils.tel.tel_defines import ServiceStateContainer 150from acts.test_utils.tel.tel_defines import CARRIER_VZW, CARRIER_ATT, \ 151 CARRIER_BELL, CARRIER_ROGERS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_TELUS 152from acts.test_utils.tel.tel_lookup_tables import \ 153 connection_type_from_type_string 154from acts.test_utils.tel.tel_lookup_tables import is_valid_rat 155from acts.test_utils.tel.tel_lookup_tables import get_allowable_network_preference 156from acts.test_utils.tel.tel_lookup_tables import \ 157 get_voice_mail_count_check_function 158from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number 159from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit 160from acts.test_utils.tel.tel_lookup_tables import \ 161 network_preference_for_generation 162from acts.test_utils.tel.tel_lookup_tables import \ 163 operator_name_from_network_name 164from acts.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id 165from acts.test_utils.tel.tel_lookup_tables import \ 166 rat_families_for_network_preference 167from acts.test_utils.tel.tel_lookup_tables import rat_family_for_generation 168from acts.test_utils.tel.tel_lookup_tables import rat_family_from_rat 169from acts.test_utils.tel.tel_lookup_tables import rat_generation_from_rat 170from acts.test_utils.tel.tel_subscription_utils import \ 171 get_default_data_sub_id, get_subid_from_slot_index 172from acts.test_utils.tel.tel_subscription_utils import \ 173 get_outgoing_message_sub_id 174from acts.test_utils.tel.tel_subscription_utils import \ 175 get_outgoing_voice_sub_id 176from acts.test_utils.tel.tel_subscription_utils import \ 177 get_incoming_voice_sub_id 178from acts.test_utils.tel.tel_subscription_utils import \ 179 get_incoming_message_sub_id 180from acts.test_utils.tel.tel_subscription_utils import \ 181 set_subid_for_outgoing_call 182from acts.test_utils.wifi import wifi_test_utils 183from acts.test_utils.wifi import wifi_constants 184from acts.utils import adb_shell_ping 185from acts.utils import load_config 186from acts.utils import create_dir 187from acts.utils import start_standing_subprocess 188from acts.utils import stop_standing_subprocess 189from acts.logger import epoch_to_log_line_timestamp 190from acts.logger import normalize_log_line_timestamp 191from acts.utils import get_current_epoch_time 192from acts.utils import exe_cmd 193 194 195WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY 196WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY 197WIFI_CONFIG_APBAND_2G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_2G 198WIFI_CONFIG_APBAND_5G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_5G 199WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO 200log = logging 201STORY_LINE = "+19523521350" 202CallResult = TelephonyVoiceTestResult.CallResult.Value 203 204 205class TelTestUtilsError(Exception): 206 pass 207 208 209class TelResultWrapper(object): 210 """Test results wrapper for Telephony test utils. 211 212 In order to enable metrics reporting without refactoring 213 all of the test utils this class is used to keep the 214 current return boolean scheme in tact. 215 """ 216 217 def __init__(self, result_value): 218 self._result_value = result_value 219 220 @property 221 def result_value(self): 222 return self._result_value 223 224 @result_value.setter 225 def result_value(self, result_value): 226 self._result_value = result_value 227 228 def __bool__(self): 229 return self._result_value == CallResult('SUCCESS') 230 231 232def abort_all_tests(log, msg): 233 log.error("Aborting all ongoing tests due to: %s.", msg) 234 abort_all(msg) 235 236 237def get_phone_number_by_adb(ad): 238 return phone_number_formatter( 239 ad.adb.shell("service call iphonesubinfo 13")) 240 241 242def get_iccid_by_adb(ad): 243 return ad.adb.shell("service call iphonesubinfo 11") 244 245 246def get_operator_by_adb(ad): 247 operator = ad.adb.getprop("gsm.sim.operator.alpha") 248 if "," in operator: 249 operator = operator.strip()[0] 250 return operator 251 252 253def get_plmn_by_adb(ad): 254 plmn_id = ad.adb.getprop("gsm.sim.operator.numeric") 255 if "," in plmn_id: 256 plmn_id = plmn_id.strip()[0] 257 return plmn_id 258 259 260def get_sub_id_by_adb(ad): 261 return ad.adb.shell("service call iphonesubinfo 5") 262 263 264def setup_droid_properties_by_adb(log, ad, sim_filename=None): 265 266 sim_data = None 267 if sim_filename: 268 try: 269 sim_data = load_config(sim_filename) 270 except Exception: 271 log.warning("Failed to load %s!", sim_filename) 272 273 sub_id = get_sub_id_by_adb(ad) 274 iccid = get_iccid_by_adb(ad) 275 ad.log.info("iccid = %s", iccid) 276 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"): 277 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"]) 278 else: 279 phone_number = get_phone_number_by_adb(ad) 280 if not phone_number and hasattr(ad, phone_number): 281 phone_number = ad.phone_number 282 if not phone_number: 283 ad.log.error("Failed to find valid phone number for %s", iccid) 284 abort_all_tests(ad.log, "Failed to find valid phone number for %s") 285 sub_record = { 286 'phone_num': phone_number, 287 'iccid': get_iccid_by_adb(ad), 288 'sim_operator_name': get_operator_by_adb(ad), 289 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad)) 290 } 291 device_props = {'subscription': {sub_id: sub_record}} 292 ad.log.info("subId %s SIM record: %s", sub_id, sub_record) 293 setattr(ad, 'telephony', device_props) 294 295 296def setup_droid_properties(log, ad, sim_filename=None, cbrs_esim=False): 297 298 if ad.skip_sl4a: 299 return setup_droid_properties_by_adb( 300 log, ad, sim_filename=sim_filename) 301 refresh_droid_config(log, ad, cbrs_esim) 302 device_props = {} 303 device_props['subscription'] = {} 304 305 sim_data = {} 306 if sim_filename: 307 try: 308 sim_data = load_config(sim_filename) 309 except Exception: 310 log.warning("Failed to load %s!", sim_filename) 311 if not ad.telephony["subscription"]: 312 abort_all_tests(ad.log, "No valid subscription") 313 ad.log.debug("Subscription DB %s", ad.telephony["subscription"]) 314 result = True 315 active_sub_id = get_outgoing_voice_sub_id(ad) 316 for sub_id, sub_info in ad.telephony["subscription"].items(): 317 ad.log.debug("Loop for Subid %s", sub_id) 318 sub_info["operator"] = get_operator_name(log, ad, sub_id) 319 iccid = sub_info["iccid"] 320 if not iccid: 321 ad.log.warning("Unable to find ICC-ID for subscriber %s", sub_id) 322 continue 323 if sub_info.get("phone_num"): 324 if iccid in sim_data and sim_data[iccid].get("phone_num"): 325 if not check_phone_number_match(sim_data[iccid]["phone_num"], 326 sub_info["phone_num"]): 327 ad.log.warning( 328 "phone_num %s in sim card data file for iccid %s" 329 " do not match phone_num %s from subscription", 330 sim_data[iccid]["phone_num"], iccid, 331 sub_info["phone_num"]) 332 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 333 else: 334 if iccid in sim_data and sim_data[iccid].get("phone_num"): 335 sub_info["phone_num"] = sim_data[iccid]["phone_num"] 336 elif sub_id == active_sub_id: 337 phone_number = get_phone_number_by_secret_code( 338 ad, sub_info["sim_operator_name"]) 339 if phone_number: 340 sub_info["phone_num"] = phone_number 341 elif getattr(ad, "phone_num", None): 342 sub_info["phone_num"] = ad.phone_number 343 if (not sub_info.get("phone_num")) and sub_id == active_sub_id: 344 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info) 345 ad.log.error( 346 "Unable to retrieve phone number for sub %s with iccid" 347 " %s from device or testbed config or sim card file %s", 348 sub_id, iccid, sim_filename) 349 result = False 350 if not hasattr( 351 ad, 'roaming' 352 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and sub_info["sim_operator_name"].strip( 353 ) not in sub_info["network_operator_name"].strip(): 354 ad.log.info("roaming is not enabled, enable it") 355 setattr(ad, 'roaming', True) 356 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items())) 357 get_phone_capability(ad) 358 data_roaming = getattr(ad, 'roaming', False) 359 if get_cell_data_roaming_state_by_adb(ad) != data_roaming: 360 set_cell_data_roaming_state_by_adb(ad, data_roaming) 361 # Setup VoWiFi MDN for Verizon. b/33187374 362 if not result: 363 abort_all_tests(ad.log, "Failed to find valid phone number") 364 365 ad.log.debug("telephony = %s", ad.telephony) 366 367 368def refresh_droid_config(log, ad, cbrs_esim=False): 369 """ Update Android Device telephony records for each sub_id. 370 371 Args: 372 log: log object 373 ad: android device object 374 cbrs_esim: special case for cbrs feature 375 376 Returns: 377 None 378 """ 379 if not getattr(ad, 'telephony', {}): 380 setattr(ad, 'telephony', {"subscription": {}}) 381 droid = ad.droid 382 sub_info_list = droid.subscriptionGetAllSubInfoList() 383 ad.log.info("SubInfoList is %s", sub_info_list) 384 if cbrs_esim: 385 ad.log.info("CBRS testing detected, removing it form SubInfoList") 386 if len(sub_info_list) > 1: 387 # Check for Display Name 388 index_to_delete = -1 389 for i, oper in enumerate(d['displayName'] for d in sub_info_list): 390 ad.log.info("Index %d Display %s", i, oper) 391 if "Google" in oper: 392 index_to_delete = i 393 elif sub_info_list[i]['simSlotIndex'] != -1: 394 ad.log.info("Workaround for b/122979645, setting default" \ 395 " Voice Sub ID to %s", sub_info_list[i]['subscriptionId']) 396 set_subid_for_outgoing_call(ad, 397 sub_info_list[i]['subscriptionId']) 398 del sub_info_list[index_to_delete] 399 ad.log.info("Updated SubInfoList is %s", sub_info_list) 400 active_sub_id = get_outgoing_voice_sub_id(ad) 401 for sub_info in sub_info_list: 402 sub_id = sub_info["subscriptionId"] 403 sim_slot = sub_info["simSlotIndex"] 404 405 if sim_slot != INVALID_SIM_SLOT_INDEX: 406 if sub_id not in ad.telephony["subscription"]: 407 ad.telephony["subscription"][sub_id] = {} 408 sub_record = ad.telephony["subscription"][sub_id] 409 if sub_info.get("iccId"): 410 sub_record["iccid"] = sub_info["iccId"] 411 else: 412 sub_record[ 413 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription( 414 sub_id) 415 sub_record["sim_slot"] = sim_slot 416 if sub_info.get("mcc"): 417 sub_record["mcc"] = sub_info["mcc"] 418 if sub_info.get("mnc"): 419 sub_record["mnc"] = sub_info["mnc"] 420 if sub_info.get("displayName"): 421 sub_record["display_name"] = sub_info["displayName"] 422 try: 423 sub_record[ 424 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription( 425 sub_id) 426 except: 427 if not sub_record.get("phone_type"): 428 sub_record["phone_type"] = droid.telephonyGetPhoneType() 429 sub_record[ 430 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription( 431 sub_id) 432 sub_record[ 433 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription( 434 sub_id) 435 sub_record[ 436 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription( 437 sub_id) 438 sub_record[ 439 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription( 440 sub_id) 441 sub_record[ 442 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription( 443 sub_id) 444 if active_sub_id == sub_id: 445 try: 446 sub_record[ 447 "carrier_id"] = ad.droid.telephonyGetSimCarrierId() 448 sub_record[ 449 "carrier_id_name"] = ad.droid.telephonyGetSimCarrierIdName( 450 ) 451 except: 452 ad.log.info("Carrier ID is not supported") 453 if not sub_info.get("number"): 454 sub_info[ 455 "number"] = droid.telephonyGetLine1NumberForSubscription( 456 sub_id) 457 if sub_info.get("number"): 458 if sub_record.get("phone_num"): 459 # Use the phone number provided in sim info file by default 460 # as the sub_info["number"] may not be formatted in a 461 # dialable number 462 if not check_phone_number_match(sub_info["number"], 463 sub_record["phone_num"]): 464 ad.log.info( 465 "Subscriber phone number changed from %s to %s", 466 sub_record["phone_num"], sub_info["number"]) 467 sub_record["phone_num"] = sub_info["number"] 468 else: 469 sub_record["phone_num"] = phone_number_formatter( 470 sub_info["number"]) 471 #ad.telephony['subscription'][sub_id] = sub_record 472 ad.log.info("SubId %s info: %s", sub_id, sorted( 473 sub_record.items())) 474 475 476def get_phone_number_by_secret_code(ad, operator): 477 if "T-Mobile" in operator: 478 ad.droid.telecomDialNumber("#686#") 479 ad.send_keycode("ENTER") 480 for _ in range(12): 481 output = ad.search_logcat("mobile number") 482 if output: 483 result = re.findall(r"mobile number is (\S+)", 484 output[-1]["log_message"]) 485 ad.send_keycode("BACK") 486 return result[0] 487 else: 488 time.sleep(5) 489 return "" 490 491 492def get_user_config_profile(ad): 493 return { 494 "Airplane Mode": 495 ad.droid.connectivityCheckAirplaneMode(), 496 "IMS Registered": 497 ad.droid.telephonyIsImsRegistered(), 498 "Preferred Network Type": 499 ad.droid.telephonyGetPreferredNetworkTypes(), 500 "VoLTE Platform Enabled": 501 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(), 502 "VoLTE Enabled": 503 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser(), 504 "VoLTE Available": 505 ad.droid.telephonyIsVolteAvailable(), 506 "VT Available": 507 ad.droid.telephonyIsVideoCallingAvailable(), 508 "VT Enabled": 509 ad.droid.imsIsVtEnabledByUser(), 510 "VT Platform Enabled": 511 ad.droid.imsIsVtEnabledByPlatform(), 512 "WFC Available": 513 ad.droid.telephonyIsWifiCallingAvailable(), 514 "WFC Enabled": 515 ad.droid.imsIsWfcEnabledByUser(), 516 "WFC Platform Enabled": 517 ad.droid.imsIsWfcEnabledByPlatform(), 518 "WFC Mode": 519 ad.droid.imsGetWfcMode() 520 } 521 522 523def get_slot_index_from_subid(log, ad, sub_id): 524 try: 525 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id) 526 return info['simSlotIndex'] 527 except KeyError: 528 return INVALID_SIM_SLOT_INDEX 529 530 531def get_num_active_sims(log, ad): 532 """ Get the number of active SIM cards by counting slots 533 534 Args: 535 ad: android_device object. 536 537 Returns: 538 result: The number of loaded (physical) SIM cards 539 """ 540 # using a dictionary as a cheap way to prevent double counting 541 # in the situation where multiple subscriptions are on the same SIM. 542 # yes, this is a corner corner case. 543 valid_sims = {} 544 subInfo = ad.droid.subscriptionGetAllSubInfoList() 545 for info in subInfo: 546 ssidx = info['simSlotIndex'] 547 if ssidx == INVALID_SIM_SLOT_INDEX: 548 continue 549 valid_sims[ssidx] = True 550 return len(valid_sims.keys()) 551 552 553def toggle_airplane_mode_by_adb(log, ad, new_state=None): 554 """ Toggle the state of airplane mode. 555 556 Args: 557 log: log handler. 558 ad: android_device object. 559 new_state: Airplane mode state to set to. 560 If None, opposite of the current state. 561 strict_checking: Whether to turn on strict checking that checks all features. 562 563 Returns: 564 result: True if operation succeed. False if error happens. 565 """ 566 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on"))) 567 if new_state == cur_state: 568 ad.log.info("Airplane mode already in %s", new_state) 569 return True 570 elif new_state is None: 571 new_state = not cur_state 572 ad.log.info("Change airplane mode from %s to %s", cur_state, new_state) 573 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state)) 574 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE") 575 return True 576 577 578def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True): 579 """ Toggle the state of airplane mode. 580 581 Args: 582 log: log handler. 583 ad: android_device object. 584 new_state: Airplane mode state to set to. 585 If None, opposite of the current state. 586 strict_checking: Whether to turn on strict checking that checks all features. 587 588 Returns: 589 result: True if operation succeed. False if error happens. 590 """ 591 if ad.skip_sl4a: 592 return toggle_airplane_mode_by_adb(log, ad, new_state) 593 else: 594 return toggle_airplane_mode_msim( 595 log, ad, new_state, strict_checking=strict_checking) 596 597 598def get_telephony_signal_strength(ad): 599 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0, 600 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160, 601 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0, 602 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0, 603 # 'lteDbm': -112, 'gsmSignalStrength': 99} 604 try: 605 signal_strength = ad.droid.telephonyGetSignalStrength() 606 if not signal_strength: 607 signal_strength = {} 608 except Exception as e: 609 ad.log.error(e) 610 signal_strength = {} 611 return signal_strength 612 613 614def get_wifi_signal_strength(ad): 615 signal_strength = ad.droid.wifiGetConnectionInfo()['rssi'] 616 ad.log.info("WiFi Signal Strength is %s" % signal_strength) 617 return signal_strength 618 619 620def get_lte_rsrp(ad): 621 try: 622 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"): 623 out = ad.adb.shell( 624 "dumpsys telephony.registry | grep -i signalstrength") 625 if out: 626 lte_rsrp = out.split()[9] 627 if lte_rsrp: 628 ad.log.info("lte_rsrp: %s ", lte_rsrp) 629 return lte_rsrp 630 else: 631 out = ad.adb.shell( 632 "dumpsys telephony.registry |grep -i primary=CellSignalStrengthLte") 633 if out: 634 lte_cell_info = out.split('mLte=')[1] 635 lte_rsrp = re.match(r'.*rsrp=(\S+).*', lte_cell_info).group(1) 636 if lte_rsrp: 637 ad.log.info("lte_rsrp: %s ", lte_rsrp) 638 return lte_rsrp 639 except Exception as e: 640 ad.log.error(e) 641 return None 642 643 644def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL): 645 data_stall_detected = False 646 time_var = 1 647 try: 648 while (time_var < wait_time): 649 out = ad.adb.shell("dumpsys network_stack " \ 650 "| grep \"Suspecting data stall\"", 651 ignore_status=True) 652 ad.log.debug("Output is %s", out) 653 if out: 654 ad.log.info("NetworkMonitor detected - %s", out) 655 data_stall_detected = True 656 break 657 time.sleep(30) 658 time_var += 30 659 except Exception as e: 660 ad.log.error(e) 661 return data_stall_detected 662 663 664def check_network_validation_fail(ad, begin_time=None, 665 wait_time=WAIT_TIME_FOR_NW_VALID_FAIL): 666 network_validation_fail = False 667 time_var = 1 668 try: 669 while (time_var < wait_time): 670 time_var += 30 671 nw_valid = ad.search_logcat("validation failed", 672 begin_time) 673 if nw_valid: 674 ad.log.info("Validation Failed received here - %s", 675 nw_valid[0]["log_message"]) 676 network_validation_fail = True 677 break 678 time.sleep(30) 679 except Exception as e: 680 ad.log.error(e) 681 return network_validation_fail 682 683 684def check_data_stall_recovery(ad, begin_time=None, 685 wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY): 686 data_stall_recovery = False 687 time_var = 1 688 try: 689 while (time_var < wait_time): 690 time_var += 30 691 recovery = ad.search_logcat("doRecovery() cleanup all connections", 692 begin_time) 693 if recovery: 694 ad.log.info("Recovery Performed here - %s", 695 recovery[-1]["log_message"]) 696 data_stall_recovery = True 697 break 698 time.sleep(30) 699 except Exception as e: 700 ad.log.error(e) 701 return data_stall_recovery 702 703 704def break_internet_except_sl4a_port(ad, sl4a_port): 705 ad.log.info("Breaking internet using iptables rules") 706 ad.adb.shell("iptables -I INPUT 1 -p tcp --dport %s -j ACCEPT" % sl4a_port, 707 ignore_status=True) 708 ad.adb.shell("iptables -I INPUT 2 -p tcp --sport %s -j ACCEPT" % sl4a_port, 709 ignore_status=True) 710 ad.adb.shell("iptables -I INPUT 3 -j DROP", ignore_status=True) 711 ad.adb.shell("ip6tables -I INPUT -j DROP", ignore_status=True) 712 return True 713 714 715def resume_internet_with_sl4a_port(ad, sl4a_port): 716 ad.log.info("Bring internet back using iptables rules") 717 ad.adb.shell("iptables -D INPUT -p tcp --dport %s -j ACCEPT" % sl4a_port, 718 ignore_status=True) 719 ad.adb.shell("iptables -D INPUT -p tcp --sport %s -j ACCEPT" % sl4a_port, 720 ignore_status=True) 721 ad.adb.shell("iptables -D INPUT -j DROP", ignore_status=True) 722 ad.adb.shell("ip6tables -D INPUT -j DROP", ignore_status=True) 723 return True 724 725 726def test_data_browsing_success_using_sl4a(log, ad): 727 result = True 728 web_page_list = ['https://www.google.com', 'https://www.yahoo.com', 729 'https://www.amazon.com', 'https://www.nike.com', 730 'https://www.facebook.com'] 731 for website in web_page_list: 732 if not verify_http_connection(log, ad, website, retry=0): 733 ad.log.error("Failed to browse %s successfully!", website) 734 result = False 735 return result 736 737 738def test_data_browsing_failure_using_sl4a(log, ad): 739 result = True 740 web_page_list = ['https://www.youtube.com', 'https://www.cnn.com', 741 'https://www.att.com', 'https://www.nbc.com', 742 'https://www.verizonwireless.com'] 743 for website in web_page_list: 744 if not verify_http_connection(log, ad, website, retry=0, 745 expected_state=False): 746 ad.log.error("Browsing to %s worked!", website) 747 result = False 748 return result 749 750 751def is_expected_event(event_to_check, events_list): 752 """ check whether event is present in the event list 753 754 Args: 755 event_to_check: event to be checked. 756 events_list: list of events 757 Returns: 758 result: True if event present in the list. False if not. 759 """ 760 for event in events_list: 761 if event in event_to_check['name']: 762 return True 763 return False 764 765 766def is_sim_ready(log, ad, sim_slot_id=None): 767 """ check whether SIM is ready. 768 769 Args: 770 ad: android_device object. 771 sim_slot_id: check the SIM status for sim_slot_id 772 This is optional. If this is None, check default SIM. 773 774 Returns: 775 result: True if all SIMs are ready. False if not. 776 """ 777 if sim_slot_id is None: 778 status = ad.droid.telephonyGetSimState() 779 else: 780 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id) 781 if status != SIM_STATE_READY: 782 ad.log.info("Sim state is %s, not ready", status) 783 return False 784 return True 785 786 787def is_sim_ready_by_adb(log, ad): 788 state = ad.adb.getprop("gsm.sim.state") 789 ad.log.info("gsm.sim.state = %s", state) 790 return state == SIM_STATE_READY or state == SIM_STATE_LOADED 791 792 793def wait_for_sim_ready_by_adb(log, ad, wait_time=90): 794 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb) 795 796 797def is_sims_ready_by_adb(log, ad): 798 states = list(ad.adb.getprop("gsm.sim.state").split(",")) 799 ad.log.info("gsm.sim.state = %s", states) 800 for state in states: 801 if state != SIM_STATE_READY and state != SIM_STATE_LOADED: 802 return False 803 return True 804 805 806def wait_for_sims_ready_by_adb(log, ad, wait_time=90): 807 return _wait_for_droid_in_state(log, ad, wait_time, is_sims_ready_by_adb) 808 809 810def get_service_state_by_adb(log, ad): 811 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState") 812 if "mVoiceRegState" in output: 813 result = re.search(r"mVoiceRegState=(\S+)\((\S+)\)", output) 814 if result: 815 ad.log.info("mVoiceRegState is %s %s", result.group(1), 816 result.group(2)) 817 return result.group(2) 818 else: 819 result = re.search(r"mServiceState=(\S+)", output) 820 if result: 821 ad.log.info("mServiceState=%s %s", result.group(1), 822 SERVICE_STATE_MAPPING[result.group(1)]) 823 return SERVICE_STATE_MAPPING[result.group(1)] 824 825 826def _is_expecting_event(event_recv_list): 827 """ check for more event is expected in event list 828 829 Args: 830 event_recv_list: list of events 831 Returns: 832 result: True if more events are expected. False if not. 833 """ 834 for state in event_recv_list: 835 if state is False: 836 return True 837 return False 838 839 840def _set_event_list(event_recv_list, sub_id_list, sub_id, value): 841 """ set received event in expected event list 842 843 Args: 844 event_recv_list: list of received events 845 sub_id_list: subscription ID list 846 sub_id: subscription id of current event 847 value: True or False 848 Returns: 849 None. 850 """ 851 for i in range(len(sub_id_list)): 852 if sub_id_list[i] == sub_id: 853 event_recv_list[i] = value 854 855 856def _wait_for_bluetooth_in_state(log, ad, state, max_wait): 857 # FIXME: These event names should be defined in a common location 858 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn' 859 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff' 860 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT) 861 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT) 862 863 ad.droid.bluetoothStartListeningForAdapterStateChange() 864 try: 865 bt_state = ad.droid.bluetoothCheckState() 866 if bt_state == state: 867 return True 868 if max_wait <= 0: 869 ad.log.error("Time out: bluetooth state still %s, expecting %s", 870 bt_state, state) 871 return False 872 873 event = { 874 False: _BLUETOOTH_STATE_OFF_EVENT, 875 True: _BLUETOOTH_STATE_ON_EVENT 876 }[state] 877 event = ad.ed.pop_event(event, max_wait) 878 ad.log.info("Got event %s", event['name']) 879 return True 880 except Empty: 881 ad.log.error("Time out: bluetooth state still in %s, expecting %s", 882 bt_state, state) 883 return False 884 finally: 885 ad.droid.bluetoothStopListeningForAdapterStateChange() 886 887 888# TODO: replace this with an event-based function 889def _wait_for_wifi_in_state(log, ad, state, max_wait): 890 return _wait_for_droid_in_state(log, ad, max_wait, 891 lambda log, ad, state: \ 892 (True if ad.droid.wifiCheckState() == state else False), 893 state) 894 895 896def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True): 897 """ Toggle the state of airplane mode. 898 899 Args: 900 log: log handler. 901 ad: android_device object. 902 new_state: Airplane mode state to set to. 903 If None, opposite of the current state. 904 strict_checking: Whether to turn on strict checking that checks all features. 905 906 Returns: 907 result: True if operation succeed. False if error happens. 908 """ 909 910 cur_state = ad.droid.connectivityCheckAirplaneMode() 911 if cur_state == new_state: 912 ad.log.info("Airplane mode already in %s", new_state) 913 return True 914 elif new_state is None: 915 new_state = not cur_state 916 ad.log.info("Toggle APM mode, from current tate %s to %s", cur_state, 917 new_state) 918 919 sub_id_list = [] 920 active_sub_info = ad.droid.subscriptionGetAllSubInfoList() 921 for info in active_sub_info: 922 sub_id_list.append(info['subscriptionId']) 923 924 ad.ed.clear_all_events() 925 time.sleep(0.1) 926 service_state_list = [] 927 if new_state: 928 service_state_list.append(SERVICE_STATE_POWER_OFF) 929 ad.log.info("Turn on airplane mode") 930 931 else: 932 # If either one of these 3 events show up, it should be OK. 933 # Normal SIM, phone in service 934 service_state_list.append(SERVICE_STATE_IN_SERVICE) 935 # NO SIM, or Dead SIM, or no Roaming coverage. 936 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE) 937 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY) 938 ad.log.info("Turn off airplane mode") 939 940 for sub_id in sub_id_list: 941 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription( 942 sub_id) 943 944 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT 945 ad.droid.connectivityToggleAirplaneMode(new_state) 946 947 try: 948 try: 949 event = ad.ed.wait_for_event( 950 EventServiceStateChanged, 951 is_event_match_for_list, 952 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT, 953 field=ServiceStateContainer.SERVICE_STATE, 954 value_list=service_state_list) 955 ad.log.info("Got event %s", event) 956 except Empty: 957 ad.log.warning("Did not get expected service state change to %s", 958 service_state_list) 959 finally: 960 for sub_id in sub_id_list: 961 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription( 962 sub_id) 963 except Exception as e: 964 ad.log.error(e) 965 966 # APM on (new_state=True) will turn off bluetooth but may not turn it on 967 try: 968 if new_state and not _wait_for_bluetooth_in_state( 969 log, ad, False, timeout_time - time.time()): 970 ad.log.error( 971 "Failed waiting for bluetooth during airplane mode toggle") 972 if strict_checking: return False 973 except Exception as e: 974 ad.log.error("Failed to check bluetooth state due to %s", e) 975 if strict_checking: 976 raise 977 978 # APM on (new_state=True) will turn off wifi but may not turn it on 979 if new_state and not _wait_for_wifi_in_state(log, ad, False, 980 timeout_time - time.time()): 981 ad.log.error("Failed waiting for wifi during airplane mode toggle on") 982 if strict_checking: return False 983 984 if ad.droid.connectivityCheckAirplaneMode() != new_state: 985 ad.log.error("Set airplane mode to %s failed", new_state) 986 return False 987 return True 988 989 990def wait_and_answer_call(log, 991 ad, 992 incoming_number=None, 993 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 994 caller=None, 995 video_state=None): 996 """Wait for an incoming call on default voice subscription and 997 accepts the call. 998 999 Args: 1000 ad: android device object. 1001 incoming_number: Expected incoming number. 1002 Optional. Default is None 1003 incall_ui_display: after answer the call, bring in-call UI to foreground or 1004 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1005 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1006 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1007 else, do nothing. 1008 1009 Returns: 1010 True: if incoming call is received and answered successfully. 1011 False: for errors 1012 """ 1013 return wait_and_answer_call_for_subscription( 1014 log, 1015 ad, 1016 get_incoming_voice_sub_id(ad), 1017 incoming_number, 1018 incall_ui_display=incall_ui_display, 1019 caller=caller, 1020 video_state=video_state) 1021 1022 1023def _wait_for_ringing_event(log, ad, wait_time): 1024 """Wait for ringing event. 1025 1026 Args: 1027 log: log object. 1028 ad: android device object. 1029 wait_time: max time to wait for ringing event. 1030 1031 Returns: 1032 event_ringing if received ringing event. 1033 otherwise return None. 1034 """ 1035 event_ringing = None 1036 1037 try: 1038 event_ringing = ad.ed.wait_for_event( 1039 EventCallStateChanged, 1040 is_event_match, 1041 timeout=wait_time, 1042 field=CallStateContainer.CALL_STATE, 1043 value=TELEPHONY_STATE_RINGING) 1044 ad.log.info("Receive ringing event") 1045 except Empty: 1046 ad.log.info("No Ringing Event") 1047 finally: 1048 return event_ringing 1049 1050 1051def wait_for_ringing_call(log, ad, incoming_number=None): 1052 """Wait for an incoming call on default voice subscription and 1053 accepts the call. 1054 1055 Args: 1056 log: log object. 1057 ad: android device object. 1058 incoming_number: Expected incoming number. 1059 Optional. Default is None 1060 1061 Returns: 1062 True: if incoming call is received and answered successfully. 1063 False: for errors 1064 """ 1065 return wait_for_ringing_call_for_subscription( 1066 log, ad, get_incoming_voice_sub_id(ad), incoming_number) 1067 1068 1069def wait_for_ringing_call_for_subscription( 1070 log, 1071 ad, 1072 sub_id, 1073 incoming_number=None, 1074 caller=None, 1075 event_tracking_started=False, 1076 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 1077 interval=WAIT_TIME_BETWEEN_STATE_CHECK): 1078 """Wait for an incoming call on specified subscription. 1079 1080 Args: 1081 log: log object. 1082 ad: android device object. 1083 sub_id: subscription ID 1084 incoming_number: Expected incoming number. Default is None 1085 event_tracking_started: True if event tracking already state outside 1086 timeout: time to wait for ring 1087 interval: checking interval 1088 1089 Returns: 1090 True: if incoming call is received and answered successfully. 1091 False: for errors 1092 """ 1093 if not event_tracking_started: 1094 ad.ed.clear_events(EventCallStateChanged) 1095 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1096 ring_event_received = False 1097 end_time = time.time() + timeout 1098 try: 1099 while time.time() < end_time: 1100 if not ring_event_received: 1101 event_ringing = _wait_for_ringing_event(log, ad, interval) 1102 if event_ringing: 1103 if incoming_number and not check_phone_number_match( 1104 event_ringing['data'] 1105 [CallStateContainer.INCOMING_NUMBER], incoming_number): 1106 ad.log.error( 1107 "Incoming Number not match. Expected number:%s, actual number:%s", 1108 incoming_number, event_ringing['data'][ 1109 CallStateContainer.INCOMING_NUMBER]) 1110 return False 1111 ring_event_received = True 1112 telephony_state = ad.droid.telephonyGetCallStateForSubscription( 1113 sub_id) 1114 telecom_state = ad.droid.telecomGetCallState() 1115 if telephony_state == TELEPHONY_STATE_RINGING and ( 1116 telecom_state == TELEPHONY_STATE_RINGING): 1117 ad.log.info("callee is in telephony and telecom RINGING state") 1118 if caller: 1119 if caller.droid.telecomIsInCall(): 1120 caller.log.info("Caller telecom is in call state") 1121 return True 1122 else: 1123 caller.log.info("Caller telecom is NOT in call state") 1124 else: 1125 return True 1126 else: 1127 ad.log.info( 1128 "telephony in %s, telecom in %s, expecting RINGING state", 1129 telephony_state, telecom_state) 1130 time.sleep(interval) 1131 finally: 1132 if not event_tracking_started: 1133 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 1134 sub_id) 1135 1136 1137def wait_for_call_offhook_for_subscription( 1138 log, 1139 ad, 1140 sub_id, 1141 event_tracking_started=False, 1142 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT, 1143 interval=WAIT_TIME_BETWEEN_STATE_CHECK): 1144 """Wait for an incoming call on specified subscription. 1145 1146 Args: 1147 log: log object. 1148 ad: android device object. 1149 sub_id: subscription ID 1150 timeout: time to wait for ring 1151 interval: checking interval 1152 1153 Returns: 1154 True: if incoming call is received and answered successfully. 1155 False: for errors 1156 """ 1157 if not event_tracking_started: 1158 ad.ed.clear_events(EventCallStateChanged) 1159 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1160 offhook_event_received = False 1161 end_time = time.time() + timeout 1162 try: 1163 while time.time() < end_time: 1164 if not offhook_event_received: 1165 if wait_for_call_offhook_event(log, ad, sub_id, True, 1166 interval): 1167 offhook_event_received = True 1168 telephony_state = ad.droid.telephonyGetCallStateForSubscription( 1169 sub_id) 1170 telecom_state = ad.droid.telecomGetCallState() 1171 if telephony_state == TELEPHONY_STATE_OFFHOOK and ( 1172 telecom_state == TELEPHONY_STATE_OFFHOOK): 1173 ad.log.info("telephony and telecom are in OFFHOOK state") 1174 return True 1175 else: 1176 ad.log.info( 1177 "telephony in %s, telecom in %s, expecting OFFHOOK state", 1178 telephony_state, telecom_state) 1179 if offhook_event_received: 1180 time.sleep(interval) 1181 finally: 1182 if not event_tracking_started: 1183 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 1184 sub_id) 1185 1186 1187def wait_for_call_offhook_event( 1188 log, 1189 ad, 1190 sub_id, 1191 event_tracking_started=False, 1192 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT): 1193 """Wait for an incoming call on specified subscription. 1194 1195 Args: 1196 log: log object. 1197 ad: android device object. 1198 event_tracking_started: True if event tracking already state outside 1199 timeout: time to wait for event 1200 1201 Returns: 1202 True: if call offhook event is received. 1203 False: if call offhook event is not received. 1204 """ 1205 if not event_tracking_started: 1206 ad.ed.clear_events(EventCallStateChanged) 1207 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1208 try: 1209 ad.ed.wait_for_event( 1210 EventCallStateChanged, 1211 is_event_match, 1212 timeout=timeout, 1213 field=CallStateContainer.CALL_STATE, 1214 value=TELEPHONY_STATE_OFFHOOK) 1215 ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK) 1216 except Empty: 1217 ad.log.info("No event for call state change to OFFHOOK") 1218 return False 1219 finally: 1220 if not event_tracking_started: 1221 ad.droid.telephonyStopTrackingCallStateChangeForSubscription( 1222 sub_id) 1223 return True 1224 1225 1226def wait_and_answer_call_for_subscription( 1227 log, 1228 ad, 1229 sub_id, 1230 incoming_number=None, 1231 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 1232 timeout=MAX_WAIT_TIME_CALLEE_RINGING, 1233 caller=None, 1234 video_state=None): 1235 """Wait for an incoming call on specified subscription and 1236 accepts the call. 1237 1238 Args: 1239 log: log object. 1240 ad: android device object. 1241 sub_id: subscription ID 1242 incoming_number: Expected incoming number. 1243 Optional. Default is None 1244 incall_ui_display: after answer the call, bring in-call UI to foreground or 1245 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 1246 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 1247 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 1248 else, do nothing. 1249 1250 Returns: 1251 True: if incoming call is received and answered successfully. 1252 False: for errors 1253 """ 1254 ad.ed.clear_events(EventCallStateChanged) 1255 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1256 try: 1257 if not wait_for_ringing_call_for_subscription( 1258 log, 1259 ad, 1260 sub_id, 1261 incoming_number=incoming_number, 1262 caller=caller, 1263 event_tracking_started=True, 1264 timeout=timeout): 1265 ad.log.info("Incoming call ringing check failed.") 1266 return False 1267 ad.log.info("Accept the ring call") 1268 ad.droid.telecomAcceptRingingCall(video_state) 1269 1270 if wait_for_call_offhook_for_subscription( 1271 log, ad, sub_id, event_tracking_started=True): 1272 return True 1273 else: 1274 ad.log.error("Could not answer the call.") 1275 return False 1276 except Exception as e: 1277 log.error(e) 1278 return False 1279 finally: 1280 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 1281 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 1282 ad.droid.telecomShowInCallScreen() 1283 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 1284 ad.droid.showHomeScreen() 1285 1286 1287def wait_and_reject_call(log, 1288 ad, 1289 incoming_number=None, 1290 delay_reject=WAIT_TIME_REJECT_CALL, 1291 reject=True): 1292 """Wait for an incoming call on default voice subscription and 1293 reject the call. 1294 1295 Args: 1296 log: log object. 1297 ad: android device object. 1298 incoming_number: Expected incoming number. 1299 Optional. Default is None 1300 delay_reject: time to wait before rejecting the call 1301 Optional. Default is WAIT_TIME_REJECT_CALL 1302 1303 Returns: 1304 True: if incoming call is received and reject successfully. 1305 False: for errors 1306 """ 1307 return wait_and_reject_call_for_subscription(log, ad, 1308 get_incoming_voice_sub_id(ad), 1309 incoming_number, delay_reject, 1310 reject) 1311 1312 1313def wait_and_reject_call_for_subscription(log, 1314 ad, 1315 sub_id, 1316 incoming_number=None, 1317 delay_reject=WAIT_TIME_REJECT_CALL, 1318 reject=True): 1319 """Wait for an incoming call on specific subscription and 1320 reject the call. 1321 1322 Args: 1323 log: log object. 1324 ad: android device object. 1325 sub_id: subscription ID 1326 incoming_number: Expected incoming number. 1327 Optional. Default is None 1328 delay_reject: time to wait before rejecting the call 1329 Optional. Default is WAIT_TIME_REJECT_CALL 1330 1331 Returns: 1332 True: if incoming call is received and reject successfully. 1333 False: for errors 1334 """ 1335 1336 if not wait_for_ringing_call_for_subscription(log, ad, sub_id, 1337 incoming_number): 1338 ad.log.error( 1339 "Could not reject a call: incoming call in ringing check failed.") 1340 return False 1341 1342 ad.ed.clear_events(EventCallStateChanged) 1343 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1344 if reject is True: 1345 # Delay between ringing and reject. 1346 time.sleep(delay_reject) 1347 is_find = False 1348 # Loop the call list and find the matched one to disconnect. 1349 for call in ad.droid.telecomCallGetCallIds(): 1350 if check_phone_number_match( 1351 get_number_from_tel_uri(get_call_uri(ad, call)), 1352 incoming_number): 1353 ad.droid.telecomCallDisconnect(call) 1354 ad.log.info("Callee reject the call") 1355 is_find = True 1356 if is_find is False: 1357 ad.log.error("Callee did not find matching call to reject.") 1358 return False 1359 else: 1360 # don't reject on callee. Just ignore the incoming call. 1361 ad.log.info("Callee received incoming call. Ignore it.") 1362 try: 1363 ad.ed.wait_for_event( 1364 EventCallStateChanged, 1365 is_event_match_for_list, 1366 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 1367 field=CallStateContainer.CALL_STATE, 1368 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK]) 1369 except Empty: 1370 ad.log.error("No onCallStateChangedIdle event received.") 1371 return False 1372 finally: 1373 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 1374 return True 1375 1376 1377def hangup_call(log, ad): 1378 """Hang up ongoing active call. 1379 1380 Args: 1381 log: log object. 1382 ad: android device object. 1383 1384 Returns: 1385 True: if all calls are cleared 1386 False: for errors 1387 """ 1388 # short circuit in case no calls are active 1389 if not ad.droid.telecomIsInCall(): 1390 return True 1391 ad.ed.clear_events(EventCallStateChanged) 1392 ad.droid.telephonyStartTrackingCallState() 1393 ad.log.info("Hangup call.") 1394 ad.droid.telecomEndCall() 1395 1396 try: 1397 ad.ed.wait_for_event( 1398 EventCallStateChanged, 1399 is_event_match, 1400 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT, 1401 field=CallStateContainer.CALL_STATE, 1402 value=TELEPHONY_STATE_IDLE) 1403 except Empty: 1404 ad.log.warning("Call state IDLE event is not received after hang up.") 1405 finally: 1406 ad.droid.telephonyStopTrackingCallStateChange() 1407 if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1): 1408 ad.log.error("Telecom is in call, hangup call failed.") 1409 return False 1410 return True 1411 1412 1413def disconnect_call_by_id(log, ad, call_id): 1414 """Disconnect call by call id. 1415 """ 1416 ad.droid.telecomCallDisconnect(call_id) 1417 return True 1418 1419 1420def _phone_number_remove_prefix(number): 1421 """Remove the country code and other prefix from the input phone number. 1422 Currently only handle phone number with the following formats: 1423 (US phone number format) 1424 +1abcxxxyyyy 1425 1abcxxxyyyy 1426 abcxxxyyyy 1427 abc xxx yyyy 1428 abc.xxx.yyyy 1429 abc-xxx-yyyy 1430 (EEUK phone number format) 1431 +44abcxxxyyyy 1432 0abcxxxyyyy 1433 1434 Args: 1435 number: input phone number 1436 1437 Returns: 1438 Phone number without country code or prefix 1439 """ 1440 if number is None: 1441 return None, None 1442 for country_code in COUNTRY_CODE_LIST: 1443 if number.startswith(country_code): 1444 return number[len(country_code):], country_code 1445 if number[0] == "1" or number[0] == "0": 1446 return number[1:], None 1447 return number, None 1448 1449 1450def check_phone_number_match(number1, number2): 1451 """Check whether two input phone numbers match or not. 1452 1453 Compare the two input phone numbers. 1454 If they match, return True; otherwise, return False. 1455 Currently only handle phone number with the following formats: 1456 (US phone number format) 1457 +1abcxxxyyyy 1458 1abcxxxyyyy 1459 abcxxxyyyy 1460 abc xxx yyyy 1461 abc.xxx.yyyy 1462 abc-xxx-yyyy 1463 (EEUK phone number format) 1464 +44abcxxxyyyy 1465 0abcxxxyyyy 1466 1467 There are some scenarios we can not verify, one example is: 1468 number1 = +15555555555, number2 = 5555555555 1469 (number2 have no country code) 1470 1471 Args: 1472 number1: 1st phone number to be compared. 1473 number2: 2nd phone number to be compared. 1474 1475 Returns: 1476 True if two phone numbers match. Otherwise False. 1477 """ 1478 number1 = phone_number_formatter(number1) 1479 number2 = phone_number_formatter(number2) 1480 # Handle extra country code attachment when matching phone number 1481 if number1[-7:] in number2 or number2[-7:] in number1: 1482 return True 1483 else: 1484 logging.info("phone number1 %s and number2 %s does not match" % 1485 (number1, number2)) 1486 return False 1487 1488 1489def initiate_call(log, 1490 ad, 1491 callee_number, 1492 emergency=False, 1493 timeout=MAX_WAIT_TIME_CALL_INITIATION, 1494 checking_interval=5, 1495 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 1496 video=False): 1497 """Make phone call from caller to callee. 1498 1499 Args: 1500 ad_caller: Caller android device object. 1501 callee_number: Callee phone number. 1502 emergency : specify the call is emergency. 1503 Optional. Default value is False. 1504 incall_ui_display: show the dialer UI foreground or backgroud 1505 video: whether to initiate as video call 1506 1507 Returns: 1508 result: if phone call is placed successfully. 1509 """ 1510 ad.ed.clear_events(EventCallStateChanged) 1511 sub_id = get_outgoing_voice_sub_id(ad) 1512 begin_time = get_device_epoch_time(ad) 1513 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id) 1514 try: 1515 # Make a Call 1516 ad.log.info("Make a phone call to %s", callee_number) 1517 if emergency: 1518 ad.droid.telecomCallEmergencyNumber(callee_number) 1519 else: 1520 ad.droid.telecomCallNumber(callee_number, video) 1521 1522 # Verify OFFHOOK state 1523 if not wait_for_call_offhook_for_subscription( 1524 log, ad, sub_id, event_tracking_started=True): 1525 ad.log.info("sub_id %s not in call offhook state", sub_id) 1526 last_call_drop_reason(ad, begin_time=begin_time) 1527 return False 1528 else: 1529 return True 1530 finally: 1531 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id) 1532 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND: 1533 ad.droid.telecomShowInCallScreen() 1534 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND: 1535 ad.droid.showHomeScreen() 1536 1537 1538def dial_phone_number(ad, callee_number): 1539 for number in str(callee_number): 1540 if number == "#": 1541 ad.send_keycode("POUND") 1542 elif number == "*": 1543 ad.send_keycode("STAR") 1544 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]: 1545 ad.send_keycode("%s" % number) 1546 1547 1548def get_call_state_by_adb(ad): 1549 return ad.adb.shell("dumpsys telephony.registry | grep mCallState") 1550 1551 1552def check_call_state_connected_by_adb(ad): 1553 return "2" in get_call_state_by_adb(ad) 1554 1555 1556def check_call_state_idle_by_adb(ad): 1557 return "0" in get_call_state_by_adb(ad) 1558 1559 1560def check_call_state_ring_by_adb(ad): 1561 return "1" in get_call_state_by_adb(ad) 1562 1563 1564def get_incoming_call_number_by_adb(ad): 1565 output = ad.adb.shell( 1566 "dumpsys telephony.registry | grep mCallIncomingNumber") 1567 return re.search(r"mCallIncomingNumber=(.*)", output).group(1) 1568 1569 1570def emergency_dialer_call_by_keyevent(ad, callee_number): 1571 for i in range(3): 1572 if "EmergencyDialer" in ad.get_my_current_focus_window(): 1573 ad.log.info("EmergencyDialer is the current focus window") 1574 break 1575 elif i <= 2: 1576 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 1577 time.sleep(1) 1578 else: 1579 ad.log.error("Unable to bring up EmergencyDialer") 1580 return False 1581 ad.log.info("Make a phone call to %s", callee_number) 1582 dial_phone_number(ad, callee_number) 1583 ad.send_keycode("CALL") 1584 1585 1586def initiate_emergency_dialer_call_by_adb( 1587 log, 1588 ad, 1589 callee_number, 1590 timeout=MAX_WAIT_TIME_CALL_INITIATION, 1591 checking_interval=5): 1592 """Make emergency call by EmergencyDialer. 1593 1594 Args: 1595 ad: Caller android device object. 1596 callee_number: Callee phone number. 1597 emergency : specify the call is emergency. 1598 Optional. Default value is False. 1599 1600 Returns: 1601 result: if phone call is placed successfully. 1602 """ 1603 try: 1604 # Make a Call 1605 ad.wakeup_screen() 1606 ad.send_keycode("MENU") 1607 ad.log.info("Call %s", callee_number) 1608 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL") 1609 ad.adb.shell( 1610 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" % 1611 callee_number) 1612 if not timeout: return True 1613 ad.log.info("Check call state") 1614 # Verify Call State 1615 elapsed_time = 0 1616 while elapsed_time < timeout: 1617 time.sleep(checking_interval) 1618 elapsed_time += checking_interval 1619 if check_call_state_connected_by_adb(ad): 1620 ad.log.info("Call to %s is connected", callee_number) 1621 return True 1622 if check_call_state_idle_by_adb(ad): 1623 ad.log.info("Call to %s failed", callee_number) 1624 return False 1625 ad.log.info("Make call to %s failed", callee_number) 1626 return False 1627 except Exception as e: 1628 ad.log.error("initiate emergency call failed with error %s", e) 1629 1630 1631def hangup_call_by_adb(ad): 1632 """Make emergency call by EmergencyDialer. 1633 1634 Args: 1635 ad: Caller android device object. 1636 callee_number: Callee phone number. 1637 """ 1638 ad.log.info("End call by adb") 1639 ad.send_keycode("ENDCALL") 1640 1641 1642def dumpsys_all_call_info(ad): 1643 """ Get call information by dumpsys telecom. """ 1644 output = ad.adb.shell("dumpsys telecom") 1645 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL) 1646 calls_info = [] 1647 for call in calls: 1648 call_info = {} 1649 for attr in ("startTime", "endTime", "direction", "isInterrupted", 1650 "callTechnologies", "callTerminationsReason", 1651 "connectionService", "isVideoCall", "callProperties"): 1652 match = re.search(r"%s: (.*)" % attr, call) 1653 if match: 1654 if attr in ("startTime", "endTime"): 1655 call_info[attr] = epoch_to_log_line_timestamp( 1656 int(match.group(1))) 1657 else: 1658 call_info[attr] = match.group(1) 1659 call_info["inCallServices"] = re.findall(r"name: (.*)", call) 1660 calls_info.append(call_info) 1661 ad.log.debug("calls_info = %s", calls_info) 1662 return calls_info 1663 1664 1665def dumpsys_last_call_info(ad): 1666 """ Get call information by dumpsys telecom. """ 1667 num = dumpsys_last_call_number(ad) 1668 output = ad.adb.shell("dumpsys telecom") 1669 result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL) 1670 call_info = {"TC": num} 1671 if result: 1672 result = result.group(1) 1673 for attr in ("startTime", "endTime", "direction", "isInterrupted", 1674 "callTechnologies", "callTerminationsReason", 1675 "isVideoCall", "callProperties"): 1676 match = re.search(r"%s: (.*)" % attr, result) 1677 if match: 1678 if attr in ("startTime", "endTime"): 1679 call_info[attr] = epoch_to_log_line_timestamp( 1680 int(match.group(1))) 1681 else: 1682 call_info[attr] = match.group(1) 1683 ad.log.debug("call_info = %s", call_info) 1684 return call_info 1685 1686 1687def dumpsys_last_call_number(ad): 1688 output = ad.adb.shell("dumpsys telecom") 1689 call_nums = re.findall("Call TC@(\d+):", output) 1690 if not call_nums: 1691 return 0 1692 else: 1693 return int(call_nums[-1]) 1694 1695 1696def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5): 1697 for i in range(retries): 1698 if dumpsys_last_call_number(ad) > last_tc_number: 1699 call_info = dumpsys_last_call_info(ad) 1700 ad.log.info("New call info = %s", sorted(call_info.items())) 1701 return call_info 1702 else: 1703 time.sleep(interval) 1704 ad.log.error("New call is not in sysdump telecom") 1705 return {} 1706 1707 1708def dumpsys_carrier_config(ad): 1709 output = ad.adb.shell("dumpsys carrier_config") 1710 configs = {} 1711 attrs = [attr for attr in dir(CarrierConfigs) if not attr.startswith("__")] 1712 for attr in attrs: 1713 attr_string = getattr(CarrierConfigs, attr) 1714 values = re.findall(r"%s = (\S+)" % attr_string, output) 1715 if values: 1716 value = values[-1] 1717 if value == "true": 1718 configs[attr_string] = True 1719 elif value == "false": 1720 configs[attr_string] = False 1721 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT: 1722 if value == "0": 1723 configs[attr_string] = WFC_MODE_WIFI_ONLY 1724 elif value == "1": 1725 configs[attr_string] = WFC_MODE_CELLULAR_PREFERRED 1726 elif value == "2": 1727 configs[attr_string] = WFC_MODE_WIFI_PREFERRED 1728 else: 1729 try: 1730 configs[attr_string] = int(value) 1731 except Exception: 1732 configs[attr_string] = value 1733 else: 1734 configs[attr_string] = None 1735 return configs 1736 1737 1738def get_phone_capability(ad): 1739 # TODO: add sub_id based carrier_config: 1740 carrier_configs = dumpsys_carrier_config(ad) 1741 capabilities = [] 1742 if carrier_configs[CarrierConfigs.VOLTE_AVAILABLE_BOOL]: 1743 capabilities.append(CAPABILITY_VOLTE) 1744 if carrier_configs[CarrierConfigs.WFC_IMS_AVAILABLE_BOOL]: 1745 capabilities.append(CAPABILITY_WFC) 1746 if carrier_configs[CarrierConfigs.EDITABLE_WFC_MODE_BOOL]: 1747 capabilities.append(CAPABILITY_WFC_MODE_CHANGE) 1748 if carrier_configs[CarrierConfigs.SUPPORT_CONFERENCE_CALL_BOOL]: 1749 capabilities.append(CAPABILITY_CONFERENCE) 1750 if carrier_configs[CarrierConfigs.VT_AVAILABLE_BOOL]: 1751 capabilities.append(CAPABILITY_VT) 1752 if carrier_configs[CarrierConfigs.VOLTE_PROVISIONED_BOOL]: 1753 capabilities.append(CAPABILITY_VOLTE_PROVISIONING) 1754 if carrier_configs[CarrierConfigs.VOLTE_OVERRIDE_WFC_BOOL]: 1755 capabilities.append(CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING) 1756 ad.log.info("Capabilities: %s", capabilities) 1757 if not getattr(ad, 'telephony', {}): 1758 setattr(ad, 'telephony', {"capabilities": capabilities}) 1759 else: 1760 ad.telephony["capabilities"] = capabilities 1761 if CAPABILITY_WFC not in capabilities: 1762 wfc_modes = [] 1763 else: 1764 if carrier_configs.get(CarrierConfigs.EDITABLE_WFC_MODE_BOOL, False): 1765 wfc_modes = [WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_WIFI_PREFERRED] 1766 else: 1767 wfc_modes = [ 1768 carrier_configs.get(CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, 1769 WFC_MODE_CELLULAR_PREFERRED) 1770 ] 1771 if carrier_configs.get(CarrierConfigs.WFC_SUPPORTS_WIFI_ONLY_BOOL, 1772 False) and WFC_MODE_WIFI_ONLY not in wfc_modes: 1773 wfc_modes.append(WFC_MODE_WIFI_ONLY) 1774 ad.telephony["wfc_modes"] = wfc_modes 1775 if wfc_modes: 1776 ad.log.info("Supported WFC modes: %s", wfc_modes) 1777 1778 1779def call_reject(log, ad_caller, ad_callee, reject=True): 1780 """Caller call Callee, then reject on callee. 1781 1782 1783 """ 1784 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId() 1785 subid_callee = ad_callee.incoming_voice_sub_id 1786 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller, 1787 subid_callee) 1788 return call_reject_for_subscription(log, ad_caller, ad_callee, 1789 subid_caller, subid_callee, reject) 1790 1791 1792def call_reject_for_subscription(log, 1793 ad_caller, 1794 ad_callee, 1795 subid_caller, 1796 subid_callee, 1797 reject=True): 1798 """ 1799 """ 1800 1801 caller_number = ad_caller.telephony['subscription'][subid_caller][ 1802 'phone_num'] 1803 callee_number = ad_callee.telephony['subscription'][subid_callee][ 1804 'phone_num'] 1805 1806 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 1807 if not initiate_call(log, ad_caller, callee_number): 1808 ad_caller.log.error("Initiate call failed") 1809 return False 1810 1811 if not wait_and_reject_call_for_subscription( 1812 log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL, 1813 reject): 1814 ad_callee.log.error("Reject call fail.") 1815 return False 1816 # Check if incoming call is cleared on callee or not. 1817 if ad_callee.droid.telephonyGetCallStateForSubscription( 1818 subid_callee) == TELEPHONY_STATE_RINGING: 1819 ad_callee.log.error("Incoming call is not cleared") 1820 return False 1821 # Hangup on caller 1822 hangup_call(log, ad_caller) 1823 return True 1824 1825 1826def call_reject_leave_message(log, 1827 ad_caller, 1828 ad_callee, 1829 verify_caller_func=None, 1830 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 1831 """On default voice subscription, Call from caller to callee, 1832 reject on callee, caller leave a voice mail. 1833 1834 1. Caller call Callee. 1835 2. Callee reject incoming call. 1836 3. Caller leave a voice mail. 1837 4. Verify callee received the voice mail notification. 1838 1839 Args: 1840 ad_caller: caller android device object. 1841 ad_callee: callee android device object. 1842 verify_caller_func: function to verify caller is in correct state while in-call. 1843 This is optional, default is None. 1844 wait_time_in_call: time to wait when leaving a voice mail. 1845 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 1846 1847 Returns: 1848 True: if voice message is received on callee successfully. 1849 False: for errors 1850 """ 1851 subid_caller = get_outgoing_voice_sub_id(ad_caller) 1852 subid_callee = get_incoming_voice_sub_id(ad_callee) 1853 return call_reject_leave_message_for_subscription( 1854 log, ad_caller, ad_callee, subid_caller, subid_callee, 1855 verify_caller_func, wait_time_in_call) 1856 1857 1858def call_reject_leave_message_for_subscription( 1859 log, 1860 ad_caller, 1861 ad_callee, 1862 subid_caller, 1863 subid_callee, 1864 verify_caller_func=None, 1865 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL): 1866 """On specific voice subscription, Call from caller to callee, 1867 reject on callee, caller leave a voice mail. 1868 1869 1. Caller call Callee. 1870 2. Callee reject incoming call. 1871 3. Caller leave a voice mail. 1872 4. Verify callee received the voice mail notification. 1873 1874 Args: 1875 ad_caller: caller android device object. 1876 ad_callee: callee android device object. 1877 subid_caller: caller's subscription id. 1878 subid_callee: callee's subscription id. 1879 verify_caller_func: function to verify caller is in correct state while in-call. 1880 This is optional, default is None. 1881 wait_time_in_call: time to wait when leaving a voice mail. 1882 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL 1883 1884 Returns: 1885 True: if voice message is received on callee successfully. 1886 False: for errors 1887 """ 1888 1889 # Currently this test utility only works for TMO and ATT and SPT. 1890 # It does not work for VZW (see b/21559800) 1891 # "with VVM TelephonyManager APIs won't work for vm" 1892 1893 caller_number = ad_caller.telephony['subscription'][subid_caller][ 1894 'phone_num'] 1895 callee_number = ad_callee.telephony['subscription'][subid_callee][ 1896 'phone_num'] 1897 1898 ad_caller.log.info("Call from %s to %s", caller_number, callee_number) 1899 1900 try: 1901 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 1902 subid_callee) 1903 ad_callee.log.info("voice mail count is %s", voice_mail_count_before) 1904 # -1 means there are unread voice mail, but the count is unknown 1905 # 0 means either this API not working (VZW) or no unread voice mail. 1906 if voice_mail_count_before != 0: 1907 log.warning("--Pending new Voice Mail, please clear on phone.--") 1908 1909 if not initiate_call(log, ad_caller, callee_number): 1910 ad_caller.log.error("Initiate call failed.") 1911 return False 1912 1913 if not wait_and_reject_call_for_subscription( 1914 log, ad_callee, subid_callee, incoming_number=caller_number): 1915 ad_callee.log.error("Reject call fail.") 1916 return False 1917 1918 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription( 1919 subid_callee) 1920 1921 # ensure that all internal states are updated in telecom 1922 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 1923 ad_callee.ed.clear_events(EventCallStateChanged) 1924 1925 if verify_caller_func and not verify_caller_func(log, ad_caller): 1926 ad_caller.log.error("Caller not in correct state!") 1927 return False 1928 1929 # TODO: b/26293512 Need to play some sound to leave message. 1930 # Otherwise carrier voice mail server may drop this voice mail. 1931 time.sleep(wait_time_in_call) 1932 1933 if not verify_caller_func: 1934 caller_state_result = ad_caller.droid.telecomIsInCall() 1935 else: 1936 caller_state_result = verify_caller_func(log, ad_caller) 1937 if not caller_state_result: 1938 ad_caller.log.error("Caller not in correct state after %s seconds", 1939 wait_time_in_call) 1940 1941 if not hangup_call(log, ad_caller): 1942 ad_caller.log.error("Error in Hanging-Up Call") 1943 return False 1944 1945 ad_callee.log.info("Wait for voice mail indicator on callee.") 1946 try: 1947 event = ad_callee.ed.wait_for_event( 1948 EventMessageWaitingIndicatorChanged, 1949 _is_on_message_waiting_event_true) 1950 ad_callee.log.info("Got event %s", event) 1951 except Empty: 1952 ad_callee.log.warning("No expected event %s", 1953 EventMessageWaitingIndicatorChanged) 1954 return False 1955 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription( 1956 subid_callee) 1957 ad_callee.log.info( 1958 "telephonyGetVoiceMailCount output - before: %s, after: %s", 1959 voice_mail_count_before, voice_mail_count_after) 1960 1961 # voice_mail_count_after should: 1962 # either equals to (voice_mail_count_before + 1) [For ATT and SPT] 1963 # or equals to -1 [For TMO] 1964 # -1 means there are unread voice mail, but the count is unknown 1965 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before, 1966 voice_mail_count_after): 1967 log.error("before and after voice mail count is not incorrect.") 1968 return False 1969 finally: 1970 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription( 1971 subid_callee) 1972 return True 1973 1974 1975def call_voicemail_erase_all_pending_voicemail(log, ad): 1976 """Script for phone to erase all pending voice mail. 1977 This script only works for TMO and ATT and SPT currently. 1978 This script only works if phone have already set up voice mail options, 1979 and phone should disable password protection for voice mail. 1980 1981 1. If phone don't have pending voice message, return True. 1982 2. Dial voice mail number. 1983 For TMO, the number is '123' 1984 For ATT, the number is phone's number 1985 For SPT, the number is phone's number 1986 3. Wait for voice mail connection setup. 1987 4. Wait for voice mail play pending voice message. 1988 5. Send DTMF to delete one message. 1989 The digit is '7'. 1990 6. Repeat steps 4 and 5 until voice mail server drop this call. 1991 (No pending message) 1992 6. Check telephonyGetVoiceMailCount result. it should be 0. 1993 1994 Args: 1995 log: log object 1996 ad: android device object 1997 Returns: 1998 False if error happens. True is succeed. 1999 """ 2000 log.info("Erase all pending voice mail.") 2001 count = ad.droid.telephonyGetVoiceMailCount() 2002 if count == 0: 2003 ad.log.info("No Pending voice mail.") 2004 return True 2005 if count == -1: 2006 ad.log.info("There is pending voice mail, but the count is unknown") 2007 count = MAX_SAVED_VOICE_MAIL 2008 else: 2009 ad.log.info("There are %s voicemails", count) 2010 2011 voice_mail_number = get_voice_mail_number(log, ad) 2012 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad)) 2013 if not initiate_call(log, ad, voice_mail_number): 2014 log.error("Initiate call to voice mail failed.") 2015 return False 2016 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 2017 callId = ad.droid.telecomCallGetCallIds()[0] 2018 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 2019 while (is_phone_in_call(log, ad) and (count > 0)): 2020 ad.log.info("Press %s to delete voice mail.", delete_digit) 2021 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit) 2022 ad.droid.telecomCallStopDtmfTone(callId) 2023 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE) 2024 count -= 1 2025 if is_phone_in_call(log, ad): 2026 hangup_call(log, ad) 2027 2028 # wait for telephonyGetVoiceMailCount to update correct result 2029 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT 2030 while ((remaining_time > 0) 2031 and (ad.droid.telephonyGetVoiceMailCount() != 0)): 2032 time.sleep(1) 2033 remaining_time -= 1 2034 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount() 2035 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count) 2036 return (current_voice_mail_count == 0) 2037 2038 2039def _is_on_message_waiting_event_true(event): 2040 """Private function to return if the received EventMessageWaitingIndicatorChanged 2041 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True. 2042 """ 2043 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING] 2044 2045 2046def call_setup_teardown(log, 2047 ad_caller, 2048 ad_callee, 2049 ad_hangup=None, 2050 verify_caller_func=None, 2051 verify_callee_func=None, 2052 wait_time_in_call=WAIT_TIME_IN_CALL, 2053 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 2054 dialing_number_length=None, 2055 video_state=None, 2056 slot_id_callee=None): 2057 """ Call process, including make a phone call from caller, 2058 accept from callee, and hang up. The call is on default voice subscription 2059 2060 In call process, call from <droid_caller> to <droid_callee>, 2061 accept the call, (optional)then hang up from <droid_hangup>. 2062 2063 Args: 2064 ad_caller: Caller Android Device Object. 2065 ad_callee: Callee Android Device Object. 2066 ad_hangup: Android Device Object end the phone call. 2067 Optional. Default value is None, and phone call will continue. 2068 verify_call_mode_caller: func_ptr to verify caller in correct mode 2069 Optional. Default is None 2070 verify_call_mode_caller: func_ptr to verify caller in correct mode 2071 Optional. Default is None 2072 incall_ui_display: after answer the call, bring in-call UI to foreground or 2073 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 2074 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 2075 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 2076 else, do nothing. 2077 dialing_number_length: the number of digits used for dialing 2078 slot_id_callee : the slot if of the callee to call to 2079 2080 Returns: 2081 True if call process without any error. 2082 False if error happened. 2083 2084 """ 2085 subid_caller = get_outgoing_voice_sub_id(ad_caller) 2086 if slot_id_callee is None: 2087 subid_callee = get_incoming_voice_sub_id(ad_callee) 2088 else: 2089 subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee) 2090 2091 return call_setup_teardown_for_subscription( 2092 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup, 2093 verify_caller_func, verify_callee_func, wait_time_in_call, 2094 incall_ui_display, dialing_number_length, video_state) 2095 2096 2097def call_setup_teardown_for_subscription( 2098 log, 2099 ad_caller, 2100 ad_callee, 2101 subid_caller, 2102 subid_callee, 2103 ad_hangup=None, 2104 verify_caller_func=None, 2105 verify_callee_func=None, 2106 wait_time_in_call=WAIT_TIME_IN_CALL, 2107 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 2108 dialing_number_length=None, 2109 video_state=None): 2110 """ Call process, including make a phone call from caller, 2111 accept from callee, and hang up. The call is on specified subscription 2112 2113 In call process, call from <droid_caller> to <droid_callee>, 2114 accept the call, (optional)then hang up from <droid_hangup>. 2115 2116 Args: 2117 ad_caller: Caller Android Device Object. 2118 ad_callee: Callee Android Device Object. 2119 subid_caller: Caller subscription ID 2120 subid_callee: Callee subscription ID 2121 ad_hangup: Android Device Object end the phone call. 2122 Optional. Default value is None, and phone call will continue. 2123 verify_call_mode_caller: func_ptr to verify caller in correct mode 2124 Optional. Default is None 2125 verify_call_mode_caller: func_ptr to verify caller in correct mode 2126 Optional. Default is None 2127 incall_ui_display: after answer the call, bring in-call UI to foreground or 2128 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 2129 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 2130 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 2131 else, do nothing. 2132 2133 Returns: 2134 TelResultWrapper which will evaluate as False if error. 2135 2136 """ 2137 CHECK_INTERVAL = 5 2138 begin_time = get_current_epoch_time() 2139 if not verify_caller_func: 2140 verify_caller_func = is_phone_in_call 2141 if not verify_callee_func: 2142 verify_callee_func = is_phone_in_call 2143 2144 caller_number = ad_caller.telephony['subscription'][subid_caller][ 2145 'phone_num'] 2146 callee_number = ad_callee.telephony['subscription'][subid_callee][ 2147 'phone_num'] 2148 if dialing_number_length: 2149 skip_test = False 2150 trunc_position = 0 - int(dialing_number_length) 2151 try: 2152 caller_area_code = caller_number[:trunc_position] 2153 callee_area_code = callee_number[:trunc_position] 2154 callee_dial_number = callee_number[trunc_position:] 2155 except: 2156 skip_test = True 2157 if caller_area_code != callee_area_code: 2158 skip_test = True 2159 if skip_test: 2160 msg = "Cannot make call from %s to %s by %s digits" % ( 2161 caller_number, callee_number, dialing_number_length) 2162 ad_caller.log.info(msg) 2163 raise signals.TestSkip(msg) 2164 else: 2165 callee_number = callee_dial_number 2166 2167 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS')) 2168 msg = "Call from %s to %s" % (caller_number, callee_number) 2169 if video_state: 2170 msg = "Video %s" % msg 2171 video = True 2172 else: 2173 video = False 2174 if ad_hangup: 2175 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call) 2176 ad_caller.log.info(msg) 2177 2178 for ad in (ad_caller, ad_callee): 2179 call_ids = ad.droid.telecomCallGetCallIds() 2180 setattr(ad, "call_ids", call_ids) 2181 if call_ids: 2182 ad.log.info("Pre-exist CallId %s before making call", call_ids) 2183 try: 2184 if not initiate_call( 2185 log, 2186 ad_caller, 2187 callee_number, 2188 incall_ui_display=incall_ui_display, 2189 video=video): 2190 ad_caller.log.error("Initiate call failed.") 2191 tel_result_wrapper.result_value = CallResult('INITIATE_FAILED') 2192 return tel_result_wrapper 2193 else: 2194 ad_caller.log.info("Caller initate call successfully") 2195 if not wait_and_answer_call_for_subscription( 2196 log, 2197 ad_callee, 2198 subid_callee, 2199 incoming_number=caller_number, 2200 caller=ad_caller, 2201 incall_ui_display=incall_ui_display, 2202 video_state=video_state): 2203 ad_callee.log.error("Answer call fail.") 2204 tel_result_wrapper.result_value = CallResult( 2205 'NO_RING_EVENT_OR_ANSWER_FAILED') 2206 return tel_result_wrapper 2207 else: 2208 ad_callee.log.info("Callee answered the call successfully") 2209 2210 for ad, call_func in zip([ad_caller, ad_callee], 2211 [verify_caller_func, verify_callee_func]): 2212 call_ids = ad.droid.telecomCallGetCallIds() 2213 new_call_ids = set(call_ids) - set(ad.call_ids) 2214 if not new_call_ids: 2215 ad.log.error( 2216 "No new call ids are found after call establishment") 2217 ad.log.error("telecomCallGetCallIds returns %s", 2218 ad.droid.telecomCallGetCallIds()) 2219 tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND') 2220 for new_call_id in new_call_ids: 2221 if not wait_for_in_call_active(ad, call_id=new_call_id): 2222 tel_result_wrapper.result_value = CallResult( 2223 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT') 2224 else: 2225 ad.log.info("callProperties = %s", 2226 ad.droid.telecomCallGetProperties(new_call_id)) 2227 2228 if not ad.droid.telecomCallGetAudioState(): 2229 ad.log.error("Audio is not in call state") 2230 tel_result_wrapper.result_value = CallResult( 2231 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT') 2232 2233 if call_func(log, ad): 2234 ad.log.info("Call is in %s state", call_func.__name__) 2235 else: 2236 ad.log.error("Call is not in %s state, voice in RAT %s", 2237 call_func.__name__, 2238 ad.droid.telephonyGetCurrentVoiceNetworkType()) 2239 tel_result_wrapper.result_value = CallResult( 2240 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT') 2241 if not tel_result_wrapper: 2242 return tel_result_wrapper 2243 elapsed_time = 0 2244 while (elapsed_time < wait_time_in_call): 2245 CHECK_INTERVAL = min(CHECK_INTERVAL, 2246 wait_time_in_call - elapsed_time) 2247 time.sleep(CHECK_INTERVAL) 2248 elapsed_time += CHECK_INTERVAL 2249 time_message = "at <%s>/<%s> second." % (elapsed_time, 2250 wait_time_in_call) 2251 for ad, call_func in [(ad_caller, verify_caller_func), 2252 (ad_callee, verify_callee_func)]: 2253 if not call_func(log, ad): 2254 ad.log.error( 2255 "NOT in correct %s state at %s, voice in RAT %s", 2256 call_func.__name__, time_message, 2257 ad.droid.telephonyGetCurrentVoiceNetworkType()) 2258 tel_result_wrapper.result_value = CallResult( 2259 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED') 2260 else: 2261 ad.log.info("In correct %s state at %s", 2262 call_func.__name__, time_message) 2263 if not ad.droid.telecomCallGetAudioState(): 2264 ad.log.error("Audio is not in call state at %s", 2265 time_message) 2266 tel_result_wrapper.result_value = CallResult( 2267 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED') 2268 if not tel_result_wrapper: 2269 return tel_result_wrapper 2270 2271 if ad_hangup: 2272 if not hangup_call(log, ad_hangup): 2273 ad_hangup.log.info("Failed to hang up the call") 2274 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL') 2275 return tel_result_wrapper 2276 finally: 2277 if not tel_result_wrapper: 2278 for ad in (ad_caller, ad_callee): 2279 last_call_drop_reason(ad, begin_time) 2280 try: 2281 if ad.droid.telecomIsInCall(): 2282 ad.log.info("In call. End now.") 2283 ad.droid.telecomEndCall() 2284 except Exception as e: 2285 log.error(str(e)) 2286 if ad_hangup or not tel_result_wrapper: 2287 for ad in (ad_caller, ad_callee): 2288 if not wait_for_call_id_clearing( 2289 ad, getattr(ad, "caller_ids", [])): 2290 tel_result_wrapper.result_value = CallResult( 2291 'CALL_ID_CLEANUP_FAIL') 2292 return tel_result_wrapper 2293 2294 2295def wait_for_call_id_clearing(ad, 2296 previous_ids, 2297 timeout=MAX_WAIT_TIME_CALL_DROP): 2298 while timeout > 0: 2299 new_call_ids = ad.droid.telecomCallGetCallIds() 2300 if len(new_call_ids) <= len(previous_ids): 2301 return True 2302 time.sleep(5) 2303 timeout = timeout - 5 2304 ad.log.error("Call id clearing failed. Before: %s; After: %s", 2305 previous_ids, new_call_ids) 2306 return False 2307 2308 2309def last_call_drop_reason(ad, begin_time=None): 2310 reasons = ad.search_logcat( 2311 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time) 2312 reason_string = "" 2313 if reasons: 2314 log_msg = "Logcat call drop reasons:" 2315 for reason in reasons: 2316 log_msg = "%s\n\t%s" % (log_msg, reason["log_message"]) 2317 if "ril reason str" in reason["log_message"]: 2318 reason_string = reason["log_message"].split(":")[-1].strip() 2319 ad.log.info(log_msg) 2320 reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION", 2321 begin_time) 2322 if reasons: 2323 ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen") 2324 ad.log.info("last call dumpsys: %s", 2325 sorted(dumpsys_last_call_info(ad).items())) 2326 return reason_string 2327 2328 2329def phone_number_formatter(input_string, formatter=None): 2330 """Get expected format of input phone number string. 2331 2332 Args: 2333 input_string: (string) input phone number. 2334 The input could be 10/11/12 digital, with or without " "/"-"/"." 2335 formatter: (int) expected format, this could be 7/10/11/12 2336 if formatter is 7: output string would be 7 digital number. 2337 if formatter is 10: output string would be 10 digital (standard) number. 2338 if formatter is 11: output string would be "1" + 10 digital number. 2339 if formatter is 12: output string would be "+1" + 10 digital number. 2340 2341 Returns: 2342 If no error happen, return phone number in expected format. 2343 Else, return None. 2344 """ 2345 if not input_string: 2346 return "" 2347 # make sure input_string is 10 digital 2348 # Remove white spaces, dashes, dots 2349 input_string = input_string.replace(" ", "").replace("-", "").replace( 2350 ".", "").lstrip("0") 2351 if not formatter: 2352 return input_string 2353 # Remove "1" or "+1"from front 2354 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT 2355 and input_string[0] == "1"): 2356 input_string = input_string[1:] 2357 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT 2358 and input_string[0:2] == "+1"): 2359 input_string = input_string[2:] 2360 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT 2361 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT): 2362 return input_string 2363 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 2364 return None 2365 # change input_string according to format 2366 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT: 2367 input_string = "+1" + input_string 2368 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT: 2369 input_string = "1" + input_string 2370 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT: 2371 input_string = input_string 2372 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT: 2373 input_string = input_string[3:] 2374 else: 2375 return None 2376 return input_string 2377 2378 2379def get_internet_connection_type(log, ad): 2380 """Get current active connection type name. 2381 2382 Args: 2383 log: Log object. 2384 ad: Android Device Object. 2385 Returns: 2386 current active connection type name. 2387 """ 2388 if not ad.droid.connectivityNetworkIsConnected(): 2389 return 'none' 2390 return connection_type_from_type_string( 2391 ad.droid.connectivityNetworkGetActiveConnectionTypeName()) 2392 2393 2394def verify_http_connection(log, 2395 ad, 2396 url="https://www.google.com", 2397 retry=5, 2398 retry_interval=15, 2399 expected_state=True): 2400 """Make ping request and return status. 2401 2402 Args: 2403 log: log object 2404 ad: Android Device Object. 2405 url: Optional. The ping request will be made to this URL. 2406 Default Value is "http://www.google.com/". 2407 2408 """ 2409 if not getattr(ad, "data_droid", None): 2410 ad.data_droid, ad.data_ed = ad.get_droid() 2411 ad.data_ed.start() 2412 else: 2413 try: 2414 if not ad.data_droid.is_live: 2415 ad.data_droid, ad.data_ed = ad.get_droid() 2416 ad.data_ed.start() 2417 except Exception: 2418 ad.log.info("Start new sl4a session for file download") 2419 ad.data_droid, ad.data_ed = ad.get_droid() 2420 ad.data_ed.start() 2421 for i in range(0, retry + 1): 2422 try: 2423 http_response = ad.data_droid.httpPing(url) 2424 except Exception as e: 2425 ad.log.info("httpPing with %s", e) 2426 http_response = None 2427 if (expected_state and http_response) or (not expected_state 2428 and not http_response): 2429 ad.log.info("Http ping response for %s meet expected %s", url, 2430 expected_state) 2431 return True 2432 if i < retry: 2433 time.sleep(retry_interval) 2434 ad.log.error("Http ping to %s is %s after %s second, expecting %s", url, 2435 http_response, i * retry_interval, expected_state) 2436 return False 2437 2438 2439def _generate_file_directory_and_file_name(url, out_path): 2440 file_name = url.split("/")[-1] 2441 if not out_path: 2442 file_directory = "/sdcard/Download/" 2443 elif not out_path.endswith("/"): 2444 file_directory, file_name = os.path.split(out_path) 2445 else: 2446 file_directory = out_path 2447 return file_directory, file_name 2448 2449 2450def _check_file_existance(ad, file_path, expected_file_size=None): 2451 """Check file existance by file_path. If expected_file_size 2452 is provided, then also check if the file meet the file size requirement. 2453 """ 2454 out = None 2455 try: 2456 out = ad.adb.shell('stat -c "%%s" %s' % file_path) 2457 except AdbError: 2458 pass 2459 # Handle some old version adb returns error message "No such" into std_out 2460 if out and "No such" not in out: 2461 if expected_file_size: 2462 file_size = int(out) 2463 if file_size >= expected_file_size: 2464 ad.log.info("File %s of size %s exists", file_path, file_size) 2465 return True 2466 else: 2467 ad.log.info("File %s is of size %s, does not meet expected %s", 2468 file_path, file_size, expected_file_size) 2469 return False 2470 else: 2471 ad.log.info("File %s exists", file_path) 2472 return True 2473 else: 2474 ad.log.info("File %s does not exist.", file_path) 2475 return False 2476 2477 2478def check_curl_availability(ad): 2479 if not hasattr(ad, "curl_capable"): 2480 try: 2481 out = ad.adb.shell("/data/curl --version") 2482 if not out or "not found" in out: 2483 setattr(ad, "curl_capable", False) 2484 ad.log.info("curl is unavailable, use chrome to download file") 2485 else: 2486 setattr(ad, "curl_capable", True) 2487 except Exception: 2488 setattr(ad, "curl_capable", False) 2489 ad.log.info("curl is unavailable, use chrome to download file") 2490 return ad.curl_capable 2491 2492 2493def start_youtube_video(ad, url="https://www.youtube.com/watch?v=pSJoP0LR8CQ"): 2494 ad.log.info("Open an youtube video") 2495 ad.ensure_screen_on() 2496 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url) 2497 if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1): 2498 ad.log.info("Started a video in youtube, audio is in MUSIC state") 2499 return True 2500 else: 2501 ad.unlock_screen() 2502 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url) 2503 if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1): 2504 ad.log.info("Started a video in youtube, audio is in MUSIC state") 2505 return True 2506 else: 2507 ad.log.warning( 2508 "Started a video in youtube, but audio is not in MUSIC state") 2509 return False 2510 2511 2512def active_file_download_task(log, ad, file_name="5MB", method="curl"): 2513 # files available for download on the same website: 2514 # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip 2515 # download file by adb command, as phone call will use sl4a 2516 file_size_map = { 2517 '5MB': 5000000, 2518 '10MB': 10000000, 2519 '20MB': 20000000, 2520 '50MB': 50000000, 2521 '100MB': 100000000, 2522 '200MB': 200000000, 2523 '512MB': 512000000 2524 } 2525 url_map = { 2526 "5MB": [ 2527 "http://146.148.91.8/download/5MB.zip", 2528 "http://212.183.159.230/5MB.zip", 2529 "http://ipv4.download.thinkbroadband.com/5MB.zip" 2530 ], 2531 "10MB": [ 2532 "http://146.148.91.8/download/10MB.zip", 2533 "http://212.183.159.230/10MB.zip", 2534 "http://ipv4.download.thinkbroadband.com/10MB.zip", 2535 "http://lax.futurehosting.com/test.zip", 2536 "http://ovh.net/files/10Mio.dat" 2537 ], 2538 "20MB": [ 2539 "http://146.148.91.8/download/20MB.zip", 2540 "http://212.183.159.230/20MB.zip", 2541 "http://ipv4.download.thinkbroadband.com/20MB.zip" 2542 ], 2543 "50MB": [ 2544 "http://146.148.91.8/download/50MB.zip", 2545 "http://212.183.159.230/50MB.zip", 2546 "http://ipv4.download.thinkbroadband.com/50MB.zip" 2547 ], 2548 "100MB": [ 2549 "http://146.148.91.8/download/100MB.zip", 2550 "http://212.183.159.230/100MB.zip", 2551 "http://ipv4.download.thinkbroadband.com/100MB.zip", 2552 "http://speedtest-ca.turnkeyinternet.net/100mb.bin", 2553 "http://ovh.net/files/100Mio.dat", 2554 "http://lax.futurehosting.com/test100.zip" 2555 ], 2556 "200MB": [ 2557 "http://146.148.91.8/download/200MB.zip", 2558 "http://212.183.159.230/200MB.zip", 2559 "http://ipv4.download.thinkbroadband.com/200MB.zip" 2560 ], 2561 "512MB": [ 2562 "http://146.148.91.8/download/512MB.zip", 2563 "http://212.183.159.230/512MB.zip", 2564 "http://ipv4.download.thinkbroadband.com/512MB.zip" 2565 ] 2566 } 2567 2568 file_size = file_size_map.get(file_name) 2569 file_urls = url_map.get(file_name) 2570 file_url = None 2571 for url in file_urls: 2572 url_splits = url.split("/") 2573 if verify_http_connection(log, ad, url=url, retry=1): 2574 output_path = "/sdcard/Download/%s" % url_splits[-1] 2575 file_url = url 2576 break 2577 if not file_url: 2578 ad.log.error("No url is available to download %s", file_name) 2579 return False 2580 timeout = min(max(file_size / 100000, 600), 3600) 2581 if method == "sl4a": 2582 return (http_file_download_by_sl4a, (ad, file_url, output_path, 2583 file_size, True, timeout)) 2584 if method == "curl" and check_curl_availability(ad): 2585 return (http_file_download_by_curl, (ad, file_url, output_path, 2586 file_size, True, timeout)) 2587 elif method == "sl4a" or method == "curl": 2588 return (http_file_download_by_sl4a, (ad, file_url, output_path, 2589 file_size, True, timeout)) 2590 else: 2591 return (http_file_download_by_chrome, (ad, file_url, file_size, True, 2592 timeout)) 2593 2594 2595def active_file_download_test(log, ad, file_name="5MB", method="sl4a"): 2596 task = active_file_download_task(log, ad, file_name, method=method) 2597 if not task: 2598 return False 2599 return task[0](*task[1]) 2600 2601 2602def verify_internet_connection_by_ping(log, 2603 ad, 2604 retries=1, 2605 expected_state=True, 2606 timeout=60): 2607 """Verify internet connection by ping test. 2608 2609 Args: 2610 log: log object 2611 ad: Android Device Object. 2612 2613 """ 2614 begin_time = get_current_epoch_time() 2615 ip_addr = "54.230.144.105" 2616 for dest in ("www.google.com", "www.amazon.com", ip_addr): 2617 for i in range(retries): 2618 ad.log.info("Ping %s - attempt %d", dest, i + 1) 2619 result = adb_shell_ping( 2620 ad, count=5, timeout=timeout, loss_tolerance=40, dest_ip=dest) 2621 if result == expected_state: 2622 ad.log.info( 2623 "Internet connection by pinging to %s is %s as expected", 2624 dest, expected_state) 2625 if dest == ip_addr: 2626 ad.log.warning("Suspect dns failure") 2627 ad.log.info("DNS config: %s", 2628 ad.adb.shell("getprop | grep dns").replace( 2629 "\n", " ")) 2630 return False 2631 return True 2632 else: 2633 ad.log.warning( 2634 "Internet connection test by pinging %s is %s, expecting %s", 2635 dest, result, expected_state) 2636 if get_current_epoch_time() - begin_time < timeout * 1000: 2637 time.sleep(5) 2638 ad.log.error("Ping test doesn't meet expected %s", expected_state) 2639 return False 2640 2641 2642def verify_internet_connection(log, ad, retries=3, expected_state=True): 2643 """Verify internet connection by ping test and http connection. 2644 2645 Args: 2646 log: log object 2647 ad: Android Device Object. 2648 2649 """ 2650 if ad.droid.connectivityNetworkIsConnected() != expected_state: 2651 ad.log.info("NetworkIsConnected = %s, expecting %s", 2652 not expected_state, expected_state) 2653 if verify_internet_connection_by_ping( 2654 log, ad, retries=retries, expected_state=expected_state): 2655 return True 2656 for url in ("https://www.google.com", "https://www.amazon.com"): 2657 if verify_http_connection( 2658 log, ad, url=url, retry=retries, 2659 expected_state=expected_state): 2660 return True 2661 ad.log.info("DNS config: %s", " ".join( 2662 ad.adb.shell("getprop | grep dns").split())) 2663 ad.log.info("Interface info:\n%s", ad.adb.shell("ifconfig")) 2664 ad.log.info("NetworkAgentInfo: %s", 2665 ad.adb.shell("dumpsys connectivity | grep NetworkAgentInfo")) 2666 return False 2667 2668 2669def iperf_test_by_adb(log, 2670 ad, 2671 iperf_server, 2672 port_num=None, 2673 reverse=False, 2674 timeout=180, 2675 limit_rate=None, 2676 omit=10, 2677 ipv6=False, 2678 rate_dict=None, 2679 blocking=True, 2680 log_file_path=None): 2681 """Iperf test by adb. 2682 2683 Args: 2684 log: log object 2685 ad: Android Device Object. 2686 iperf_Server: The iperf host url". 2687 port_num: TCP/UDP server port 2688 timeout: timeout for file download to complete. 2689 limit_rate: iperf bandwidth option. None by default 2690 omit: the omit option provided in iperf command. 2691 """ 2692 iperf_option = "-t %s -O %s -J" % (timeout, omit) 2693 if limit_rate: iperf_option += " -b %s" % limit_rate 2694 if port_num: iperf_option += " -p %s" % port_num 2695 if ipv6: iperf_option += " -6" 2696 if reverse: iperf_option += " -R" 2697 try: 2698 if log_file_path: 2699 ad.adb.shell("rm %s" % log_file_path, ignore_status=True) 2700 ad.log.info("Running adb iperf test with server %s", iperf_server) 2701 if not blocking: 2702 ad.run_iperf_client_nb( 2703 iperf_server, 2704 iperf_option, 2705 timeout=timeout + 60, 2706 log_file_path=log_file_path) 2707 return True 2708 result, data = ad.run_iperf_client( 2709 iperf_server, iperf_option, timeout=timeout + 60) 2710 ad.log.info("Iperf test result with server %s is %s", iperf_server, 2711 result) 2712 if result: 2713 data_json = json.loads(''.join(data)) 2714 tx_rate = data_json['end']['sum_sent']['bits_per_second'] 2715 rx_rate = data_json['end']['sum_received']['bits_per_second'] 2716 ad.log.info( 2717 'iPerf3 upload speed is %sbps, download speed is %sbps', 2718 tx_rate, rx_rate) 2719 if rate_dict is not None: 2720 rate_dict["Uplink"] = tx_rate 2721 rate_dict["Downlink"] = rx_rate 2722 return result 2723 except Exception as e: 2724 ad.log.warning("Fail to run iperf test with exception %s", e) 2725 return False 2726 2727 2728def http_file_download_by_curl(ad, 2729 url, 2730 out_path=None, 2731 expected_file_size=None, 2732 remove_file_after_check=True, 2733 timeout=3600, 2734 limit_rate=None, 2735 retry=3): 2736 """Download http file by adb curl. 2737 2738 Args: 2739 ad: Android Device Object. 2740 url: The url that file to be downloaded from". 2741 out_path: Optional. Where to download file to. 2742 out_path is /sdcard/Download/ by default. 2743 expected_file_size: Optional. Provided if checking the download file meet 2744 expected file size in unit of byte. 2745 remove_file_after_check: Whether to remove the downloaded file after 2746 check. 2747 timeout: timeout for file download to complete. 2748 limit_rate: download rate in bps. None, if do not apply rate limit. 2749 retry: the retry request times provided in curl command. 2750 """ 2751 file_directory, file_name = _generate_file_directory_and_file_name( 2752 url, out_path) 2753 file_path = os.path.join(file_directory, file_name) 2754 curl_cmd = "/data/curl" 2755 if limit_rate: 2756 curl_cmd += " --limit-rate %s" % limit_rate 2757 if retry: 2758 curl_cmd += " --retry %s" % retry 2759 curl_cmd += " --url %s > %s" % (url, file_path) 2760 try: 2761 ad.log.info("Download %s to %s by adb shell command %s", url, 2762 file_path, curl_cmd) 2763 2764 ad.adb.shell(curl_cmd, timeout=timeout) 2765 if _check_file_existance(ad, file_path, expected_file_size): 2766 ad.log.info("%s is downloaded to %s successfully", url, file_path) 2767 return True 2768 else: 2769 ad.log.warning("Fail to download %s", url) 2770 return False 2771 except Exception as e: 2772 ad.log.warning("Download %s failed with exception %s", url, e) 2773 for cmd in ("ls -lh /data/local/tmp/tcpdump/", 2774 "ls -lh /sdcard/Download/", 2775 "ls -lh /data/vendor/radio/diag_logs/logs/", 2776 "df -h", 2777 "du -d 4 -h /data"): 2778 out = ad.adb.shell(cmd) 2779 ad.log.debug("%s", out) 2780 return False 2781 finally: 2782 if remove_file_after_check: 2783 ad.log.info("Remove the downloaded file %s", file_path) 2784 ad.adb.shell("rm %s" % file_path, ignore_status=True) 2785 2786 2787def open_url_by_adb(ad, url): 2788 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url) 2789 2790 2791def http_file_download_by_chrome(ad, 2792 url, 2793 expected_file_size=None, 2794 remove_file_after_check=True, 2795 timeout=3600): 2796 """Download http file by chrome. 2797 2798 Args: 2799 ad: Android Device Object. 2800 url: The url that file to be downloaded from". 2801 expected_file_size: Optional. Provided if checking the download file meet 2802 expected file size in unit of byte. 2803 remove_file_after_check: Whether to remove the downloaded file after 2804 check. 2805 timeout: timeout for file download to complete. 2806 """ 2807 chrome_apk = "com.android.chrome" 2808 file_directory, file_name = _generate_file_directory_and_file_name( 2809 url, "/sdcard/Download/") 2810 file_path = os.path.join(file_directory, file_name) 2811 # Remove pre-existing file 2812 ad.force_stop_apk(chrome_apk) 2813 file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name) 2814 ad.adb.shell("rm -f %s" % file_to_be_delete) 2815 ad.adb.shell("rm -rf /sdcard/Download/.*") 2816 ad.adb.shell("rm -f /sdcard/Download/.*") 2817 data_accounting = { 2818 "total_rx_bytes": ad.droid.getTotalRxBytes(), 2819 "mobile_rx_bytes": ad.droid.getMobileRxBytes(), 2820 "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None), 2821 "chrome_mobile_data_usage": get_mobile_data_usage( 2822 ad, None, chrome_apk) 2823 } 2824 ad.log.info("Before downloading: %s", data_accounting) 2825 ad.log.info("Download %s with timeout %s", url, timeout) 2826 ad.ensure_screen_on() 2827 open_url_by_adb(ad, url) 2828 elapse_time = 0 2829 result = True 2830 while elapse_time < timeout: 2831 time.sleep(30) 2832 if _check_file_existance(ad, file_path, expected_file_size): 2833 ad.log.info("%s is downloaded successfully", url) 2834 if remove_file_after_check: 2835 ad.log.info("Remove the downloaded file %s", file_path) 2836 ad.adb.shell("rm -f %s" % file_to_be_delete) 2837 ad.adb.shell("rm -rf /sdcard/Download/.*") 2838 ad.adb.shell("rm -f /sdcard/Download/.*") 2839 #time.sleep(30) 2840 new_data_accounting = { 2841 "mobile_rx_bytes": 2842 ad.droid.getMobileRxBytes(), 2843 "subscriber_mobile_data_usage": 2844 get_mobile_data_usage(ad, None, None), 2845 "chrome_mobile_data_usage": 2846 get_mobile_data_usage(ad, None, chrome_apk) 2847 } 2848 ad.log.info("After downloading: %s", new_data_accounting) 2849 accounting_diff = { 2850 key: value - data_accounting[key] 2851 for key, value in new_data_accounting.items() 2852 } 2853 ad.log.info("Data accounting difference: %s", accounting_diff) 2854 if getattr(ad, "on_mobile_data", False): 2855 for key, value in accounting_diff.items(): 2856 if value < expected_file_size: 2857 ad.log.warning("%s diff is %s less than %s", key, 2858 value, expected_file_size) 2859 ad.data_accounting["%s_failure" % key] += 1 2860 else: 2861 for key, value in accounting_diff.items(): 2862 if value >= expected_file_size: 2863 ad.log.error("%s diff is %s. File download is " 2864 "consuming mobile data", key, value) 2865 result = False 2866 return result 2867 elif _check_file_existance(ad, "%s.crdownload" % file_path): 2868 ad.log.info("Chrome is downloading %s", url) 2869 elif elapse_time < 60: 2870 # download not started, retry download wit chrome again 2871 open_url_by_adb(ad, url) 2872 else: 2873 ad.log.error("Unable to download file from %s", url) 2874 break 2875 elapse_time += 30 2876 ad.log.warning("Fail to download file from %s", url) 2877 ad.force_stop_apk("com.android.chrome") 2878 ad.adb.shell("rm -f %s" % file_to_be_delete) 2879 ad.adb.shell("rm -rf /sdcard/Download/.*") 2880 ad.adb.shell("rm -f /sdcard/Download/.*") 2881 return False 2882 2883 2884def http_file_download_by_sl4a(ad, 2885 url, 2886 out_path=None, 2887 expected_file_size=None, 2888 remove_file_after_check=True, 2889 timeout=300): 2890 """Download http file by sl4a RPC call. 2891 2892 Args: 2893 ad: Android Device Object. 2894 url: The url that file to be downloaded from". 2895 out_path: Optional. Where to download file to. 2896 out_path is /sdcard/Download/ by default. 2897 expected_file_size: Optional. Provided if checking the download file meet 2898 expected file size in unit of byte. 2899 remove_file_after_check: Whether to remove the downloaded file after 2900 check. 2901 timeout: timeout for file download to complete. 2902 """ 2903 file_folder, file_name = _generate_file_directory_and_file_name( 2904 url, out_path) 2905 file_path = os.path.join(file_folder, file_name) 2906 ad.adb.shell("rm -f %s" % file_path) 2907 accounting_apk = SL4A_APK_NAME 2908 result = True 2909 try: 2910 if not getattr(ad, "data_droid", None): 2911 ad.data_droid, ad.data_ed = ad.get_droid() 2912 ad.data_ed.start() 2913 else: 2914 try: 2915 if not ad.data_droid.is_live: 2916 ad.data_droid, ad.data_ed = ad.get_droid() 2917 ad.data_ed.start() 2918 except Exception: 2919 ad.log.info("Start new sl4a session for file download") 2920 ad.data_droid, ad.data_ed = ad.get_droid() 2921 ad.data_ed.start() 2922 data_accounting = { 2923 "mobile_rx_bytes": 2924 ad.droid.getMobileRxBytes(), 2925 "subscriber_mobile_data_usage": 2926 get_mobile_data_usage(ad, None, None), 2927 "sl4a_mobile_data_usage": 2928 get_mobile_data_usage(ad, None, accounting_apk) 2929 } 2930 ad.log.info("Before downloading: %s", data_accounting) 2931 ad.log.info("Download file from %s to %s by sl4a RPC call", url, 2932 file_path) 2933 try: 2934 ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout) 2935 except Exception as e: 2936 ad.log.warning("SL4A file download error: %s", e) 2937 for cmd in ("ls -lh /data/local/tmp/tcpdump/", 2938 "ls -lh /sdcard/Download/", 2939 "ls -lh /data/vendor/radio/diag_logs/logs/", 2940 "df -h", 2941 "du -d 4 -h /data"): 2942 out = ad.adb.shell(cmd) 2943 ad.log.debug("%s", out) 2944 ad.data_droid.terminate() 2945 return False 2946 if _check_file_existance(ad, file_path, expected_file_size): 2947 ad.log.info("%s is downloaded successfully", url) 2948 new_data_accounting = { 2949 "mobile_rx_bytes": 2950 ad.droid.getMobileRxBytes(), 2951 "subscriber_mobile_data_usage": 2952 get_mobile_data_usage(ad, None, None), 2953 "sl4a_mobile_data_usage": 2954 get_mobile_data_usage(ad, None, accounting_apk) 2955 } 2956 ad.log.info("After downloading: %s", new_data_accounting) 2957 accounting_diff = { 2958 key: value - data_accounting[key] 2959 for key, value in new_data_accounting.items() 2960 } 2961 ad.log.info("Data accounting difference: %s", accounting_diff) 2962 if getattr(ad, "on_mobile_data", False): 2963 for key, value in accounting_diff.items(): 2964 if value < expected_file_size: 2965 ad.log.warning("%s diff is %s less than %s", key, 2966 value, expected_file_size) 2967 ad.data_accounting["%s_failure"] += 1 2968 else: 2969 for key, value in accounting_diff.items(): 2970 if value >= expected_file_size: 2971 ad.log.error("%s diff is %s. File download is " 2972 "consuming mobile data", key, value) 2973 result = False 2974 return result 2975 else: 2976 ad.log.warning("Fail to download %s", url) 2977 return False 2978 except Exception as e: 2979 ad.log.error("Download %s failed with exception %s", url, e) 2980 raise 2981 finally: 2982 if remove_file_after_check: 2983 ad.log.info("Remove the downloaded file %s", file_path) 2984 ad.adb.shell("rm %s" % file_path, ignore_status=True) 2985 2986 2987def get_mobile_data_usage(ad, sid=None, apk=None): 2988 if not sid: 2989 sid = ad.droid.subscriptionGetDefaultSubId() 2990 current_time = int(time.time() * 1000) 2991 begin_time = current_time - 10 * 24 * 60 * 60 * 1000 2992 end_time = current_time + 10 * 24 * 60 * 60 * 1000 2993 2994 if apk: 2995 uid = ad.get_apk_uid(apk) 2996 ad.log.info("apk %s uid = %s", apk, uid) 2997 try: 2998 usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid) 2999 ad.log.info("Mobile data usage info for uid %s = %s", uid, 3000 usage_info) 3001 return usage_info["UsageLevel"] 3002 except: 3003 try: 3004 return ad.droid.connectivityQueryDetailsForUid( 3005 TYPE_MOBILE, 3006 ad.droid.telephonyGetSubscriberIdForSubscription(sid), 3007 begin_time, end_time, uid) 3008 except: 3009 return ad.droid.connectivityQueryDetailsForUid( 3010 ad.droid.telephonyGetSubscriberIdForSubscription(sid), 3011 begin_time, end_time, uid) 3012 else: 3013 try: 3014 usage_info = ad.droid.getMobileDataUsageInfo(sid) 3015 ad.log.info("Mobile data usage info = %s", usage_info) 3016 return usage_info["UsageLevel"] 3017 except: 3018 try: 3019 return ad.droid.connectivityQuerySummaryForDevice( 3020 TYPE_MOBILE, 3021 ad.droid.telephonyGetSubscriberIdForSubscription(sid), 3022 begin_time, end_time) 3023 except: 3024 return ad.droid.connectivityQuerySummaryForDevice( 3025 ad.droid.telephonyGetSubscriberIdForSubscription(sid), 3026 begin_time, end_time) 3027 3028 3029def set_mobile_data_usage_limit(ad, limit, subscriber_id=None): 3030 if not subscriber_id: 3031 subscriber_id = ad.droid.telephonyGetSubscriberId() 3032 ad.log.info("Set subscriber mobile data usage limit to %s", limit) 3033 ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit) 3034 try: 3035 ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit)) 3036 except: 3037 ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit) 3038 3039 3040def remove_mobile_data_usage_limit(ad, subscriber_id=None): 3041 if not subscriber_id: 3042 subscriber_id = ad.droid.telephonyGetSubscriberId() 3043 ad.log.debug("Remove subscriber mobile data usage limit") 3044 ad.droid.logV( 3045 "Setting subscriber mobile data usage limit to -1, unlimited") 3046 try: 3047 ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1") 3048 except: 3049 ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1) 3050 3051 3052def trigger_modem_crash(ad, timeout=120): 3053 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem" 3054 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd) 3055 ad.adb.shell(cmd) 3056 time.sleep(timeout) 3057 return True 3058 3059 3060def trigger_modem_crash_by_modem(ad, timeout=120): 3061 begin_time = get_device_epoch_time(ad) 3062 ad.adb.shell( 3063 "setprop persist.vendor.sys.modem.diag.mdlog false", 3064 ignore_status=True) 3065 # Legacy pixels use persist.sys.modem.diag.mdlog. 3066 ad.adb.shell( 3067 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 3068 disable_qxdm_logger(ad) 3069 cmd = ('am instrument -w -e request "4b 25 03 00" ' 3070 '"com.google.mdstest/com.google.mdstest.instrument.' 3071 'ModemCommandInstrumentation"') 3072 ad.log.info("Crash modem by %s", cmd) 3073 ad.adb.shell(cmd, ignore_status=True) 3074 time.sleep(timeout) # sleep time for sl4a stability 3075 reasons = ad.search_logcat("modem subsystem failure reason", begin_time) 3076 if reasons: 3077 ad.log.info("Modem crash is triggered successfully") 3078 ad.log.info(reasons[-1]["log_message"]) 3079 return True 3080 else: 3081 ad.log.warning("There is no modem subsystem failure reason logcat") 3082 return False 3083 3084 3085def phone_switch_to_msim_mode(ad, retries=3, timeout=60): 3086 result = False 3087 if not ad.is_apk_installed("com.google.mdstest"): 3088 raise signals.TestSkipClass("mdstest is not installed") 3089 mode = ad.droid.telephonyGetPhoneCount() 3090 if mode == 2: 3091 ad.log.info("Device already in MSIM mode") 3092 return True 3093 for i in range(retries): 3094 ad.adb.shell( 3095 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) 3096 ad.adb.shell( 3097 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 3098 disable_qxdm_logger(ad) 3099 cmd = ('am instrument -w -e request "WriteEFS" -e item ' 3100 '"/google/pixel_multisim_config" -e data "02 00 00 00" ' 3101 '"com.google.mdstest/com.google.mdstest.instrument.' 3102 'ModemConfigInstrumentation"') 3103 ad.log.info("Switch to MSIM mode by using %s", cmd) 3104 ad.adb.shell(cmd, ignore_status=True) 3105 time.sleep(timeout) 3106 ad.adb.shell("setprop persist.radio.multisim.config dsds") 3107 reboot_device(ad) 3108 # Verify if device is really in msim mode 3109 mode = ad.droid.telephonyGetPhoneCount() 3110 if mode == 2: 3111 ad.log.info("Device correctly switched to MSIM mode") 3112 result = True 3113 break 3114 else: 3115 ad.log.warning("Attempt %d - failed to switch to MSIM", (i + 1)) 3116 return result 3117 3118 3119def phone_switch_to_ssim_mode(ad, retries=3, timeout=30): 3120 result = False 3121 if not ad.is_apk_installed("com.google.mdstest"): 3122 raise signals.TestSkipClass("mdstest is not installed") 3123 mode = ad.droid.telephonyGetPhoneCount() 3124 if mode == 1: 3125 ad.log.info("Device already in SSIM mode") 3126 return True 3127 for i in range(retries): 3128 ad.adb.shell( 3129 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) 3130 ad.adb.shell( 3131 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) 3132 disable_qxdm_logger(ad) 3133 cmds = ('am instrument -w -e request "WriteEFS" -e item ' 3134 '"/google/pixel_multisim_config" -e data "01 00 00 00" ' 3135 '"com.google.mdstest/com.google.mdstest.instrument.' 3136 'ModemConfigInstrumentation"', 3137 'am instrument -w -e request "WriteEFS" -e item "/nv/item_files' 3138 '/modem/uim/uimdrv/uim_extended_slot_mapping_config" -e data ' 3139 '"00 01 02 01" "com.google.mdstest/com.google.mdstest.' 3140 'instrument.ModemConfigInstrumentation"') 3141 for cmd in cmds: 3142 ad.log.info("Switch to SSIM mode by using %s", cmd) 3143 ad.adb.shell(cmd, ignore_status=True) 3144 time.sleep(timeout) 3145 ad.adb.shell("setprop persist.radio.multisim.config ssss") 3146 reboot_device(ad) 3147 # Verify if device is really in ssim mode 3148 mode = ad.droid.telephonyGetPhoneCount() 3149 if mode == 1: 3150 ad.log.info("Device correctly switched to SSIM mode") 3151 result = True 3152 break 3153 else: 3154 ad.log.warning("Attempt %d - failed to switch to SSIM", (i + 1)) 3155 return result 3156 3157 3158def lock_lte_band_by_mds(ad, band): 3159 disable_qxdm_logger(ad) 3160 ad.log.info("Write band %s locking to efs file", band) 3161 if band == "4": 3162 item_string = ( 3163 "4B 13 26 00 08 00 00 00 40 00 08 00 0B 00 08 00 00 00 00 00 00 00 " 3164 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D " 3165 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00") 3166 elif band == "13": 3167 item_string = ( 3168 "4B 13 26 00 08 00 00 00 40 00 08 00 0A 00 00 10 00 00 00 00 00 00 " 3169 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D " 3170 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00") 3171 else: 3172 ad.log.error("Band %s is not supported", band) 3173 return False 3174 cmd = ('am instrument -w -e request "%s" com.google.mdstest/com.google.' 3175 'mdstest.instrument.ModemCommandInstrumentation') 3176 for _ in range(3): 3177 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True): 3178 break 3179 else: 3180 ad.log.error("Fail to write band by %s" % (cmd % item_string)) 3181 return False 3182 3183 # EFS Sync 3184 item_string = "4B 13 30 00 2A 00 2F 00" 3185 3186 for _ in range(3): 3187 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True): 3188 break 3189 else: 3190 ad.log.error("Fail to sync efs by %s" % (cmd % item_string)) 3191 return False 3192 time.sleep(5) 3193 reboot_device(ad) 3194 3195 3196def _connection_state_change(_event, target_state, connection_type): 3197 if connection_type: 3198 if 'TypeName' not in _event['data']: 3199 return False 3200 connection_type_string_in_event = _event['data']['TypeName'] 3201 cur_type = connection_type_from_type_string( 3202 connection_type_string_in_event) 3203 if cur_type != connection_type: 3204 log.info( 3205 "_connection_state_change expect: %s, received: %s <type %s>", 3206 connection_type, connection_type_string_in_event, cur_type) 3207 return False 3208 3209 if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state: 3210 return True 3211 return False 3212 3213 3214def wait_for_cell_data_connection( 3215 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 3216 """Wait for data connection status to be expected value for default 3217 data subscription. 3218 3219 Wait for the data connection status to be DATA_STATE_CONNECTED 3220 or DATA_STATE_DISCONNECTED. 3221 3222 Args: 3223 log: Log object. 3224 ad: Android Device Object. 3225 state: Expected status: True or False. 3226 If True, it will wait for status to be DATA_STATE_CONNECTED. 3227 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 3228 timeout_value: wait for cell data timeout value. 3229 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 3230 3231 Returns: 3232 True if success. 3233 False if failed. 3234 """ 3235 sub_id = get_default_data_sub_id(ad) 3236 return wait_for_cell_data_connection_for_subscription( 3237 log, ad, sub_id, state, timeout_value) 3238 3239 3240def _is_data_connection_state_match(log, ad, expected_data_connection_state): 3241 return (expected_data_connection_state == 3242 ad.droid.telephonyGetDataConnectionState()) 3243 3244 3245def _is_network_connected_state_match(log, ad, 3246 expected_network_connected_state): 3247 return (expected_network_connected_state == 3248 ad.droid.connectivityNetworkIsConnected()) 3249 3250 3251def wait_for_cell_data_connection_for_subscription( 3252 log, 3253 ad, 3254 sub_id, 3255 state, 3256 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 3257 """Wait for data connection status to be expected value for specified 3258 subscrption id. 3259 3260 Wait for the data connection status to be DATA_STATE_CONNECTED 3261 or DATA_STATE_DISCONNECTED. 3262 3263 Args: 3264 log: Log object. 3265 ad: Android Device Object. 3266 sub_id: subscription Id 3267 state: Expected status: True or False. 3268 If True, it will wait for status to be DATA_STATE_CONNECTED. 3269 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 3270 timeout_value: wait for cell data timeout value. 3271 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 3272 3273 Returns: 3274 True if success. 3275 False if failed. 3276 """ 3277 state_str = { 3278 True: DATA_STATE_CONNECTED, 3279 False: DATA_STATE_DISCONNECTED 3280 }[state] 3281 3282 data_state = ad.droid.telephonyGetDataConnectionState() 3283 if not state and ad.droid.telephonyGetDataConnectionState() == state_str: 3284 return True 3285 3286 ad.ed.clear_events(EventDataConnectionStateChanged) 3287 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription( 3288 sub_id) 3289 ad.droid.connectivityStartTrackingConnectivityStateChange() 3290 try: 3291 ad.log.info("User data enabled for sub_id %s: %s", sub_id, 3292 ad.droid.telephonyIsDataEnabledForSubscription(sub_id)) 3293 data_state = ad.droid.telephonyGetDataConnectionState() 3294 ad.log.info("Data connection state is %s", data_state) 3295 ad.log.info("Network is connected: %s", 3296 ad.droid.connectivityNetworkIsConnected()) 3297 if data_state == state_str: 3298 return _wait_for_nw_data_connection( 3299 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 3300 3301 try: 3302 ad.ed.wait_for_event( 3303 EventDataConnectionStateChanged, 3304 is_event_match, 3305 timeout=timeout_value, 3306 field=DataConnectionStateContainer.DATA_CONNECTION_STATE, 3307 value=state_str) 3308 except Empty: 3309 ad.log.info("No expected event EventDataConnectionStateChanged %s", 3310 state_str) 3311 3312 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 3313 # data connection state. 3314 # Otherwise, the network state will not be correct. 3315 # The bug is tracked here: b/20921915 3316 3317 # Previously we use _is_data_connection_state_match, 3318 # but telephonyGetDataConnectionState sometimes return wrong value. 3319 # The bug is tracked here: b/22612607 3320 # So we use _is_network_connected_state_match. 3321 3322 if _wait_for_droid_in_state(log, ad, timeout_value, 3323 _is_network_connected_state_match, state): 3324 return _wait_for_nw_data_connection( 3325 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value) 3326 else: 3327 return False 3328 3329 finally: 3330 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription( 3331 sub_id) 3332 3333 3334def wait_for_wifi_data_connection( 3335 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 3336 """Wait for data connection status to be expected value and connection is by WiFi. 3337 3338 Args: 3339 log: Log object. 3340 ad: Android Device Object. 3341 state: Expected status: True or False. 3342 If True, it will wait for status to be DATA_STATE_CONNECTED. 3343 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 3344 timeout_value: wait for network data timeout value. 3345 This is optional, default value is MAX_WAIT_TIME_NW_SELECTION 3346 3347 Returns: 3348 True if success. 3349 False if failed. 3350 """ 3351 ad.log.info("wait_for_wifi_data_connection") 3352 return _wait_for_nw_data_connection( 3353 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value) 3354 3355 3356def wait_for_data_connection( 3357 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 3358 """Wait for data connection status to be expected value. 3359 3360 Wait for the data connection status to be DATA_STATE_CONNECTED 3361 or DATA_STATE_DISCONNECTED. 3362 3363 Args: 3364 log: Log object. 3365 ad: Android Device Object. 3366 state: Expected status: True or False. 3367 If True, it will wait for status to be DATA_STATE_CONNECTED. 3368 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 3369 timeout_value: wait for network data timeout value. 3370 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 3371 3372 Returns: 3373 True if success. 3374 False if failed. 3375 """ 3376 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value) 3377 3378 3379def _wait_for_nw_data_connection( 3380 log, 3381 ad, 3382 is_connected, 3383 connection_type=None, 3384 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE): 3385 """Wait for data connection status to be expected value. 3386 3387 Wait for the data connection status to be DATA_STATE_CONNECTED 3388 or DATA_STATE_DISCONNECTED. 3389 3390 Args: 3391 log: Log object. 3392 ad: Android Device Object. 3393 is_connected: Expected connection status: True or False. 3394 If True, it will wait for status to be DATA_STATE_CONNECTED. 3395 If False, it will wait for status ti be DATA_STATE_DISCONNECTED. 3396 connection_type: expected connection type. 3397 This is optional, if it is None, then any connection type will return True. 3398 timeout_value: wait for network data timeout value. 3399 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE 3400 3401 Returns: 3402 True if success. 3403 False if failed. 3404 """ 3405 ad.ed.clear_events(EventConnectivityChanged) 3406 ad.droid.connectivityStartTrackingConnectivityStateChange() 3407 try: 3408 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected() 3409 if is_connected == cur_data_connection_state: 3410 current_type = get_internet_connection_type(log, ad) 3411 ad.log.info("current data connection type: %s", current_type) 3412 if not connection_type: 3413 return True 3414 else: 3415 if not is_connected and current_type != connection_type: 3416 ad.log.info("data connection not on %s!", connection_type) 3417 return True 3418 elif is_connected and current_type == connection_type: 3419 ad.log.info("data connection on %s as expected", 3420 connection_type) 3421 return True 3422 else: 3423 ad.log.info("current data connection state: %s target: %s", 3424 cur_data_connection_state, is_connected) 3425 3426 try: 3427 event = ad.ed.wait_for_event( 3428 EventConnectivityChanged, _connection_state_change, 3429 timeout_value, is_connected, connection_type) 3430 ad.log.info("Got event: %s", event) 3431 except Empty: 3432 pass 3433 3434 log.info( 3435 "_wait_for_nw_data_connection: check connection after wait event.") 3436 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for 3437 # data connection state. 3438 # Otherwise, the network state will not be correct. 3439 # The bug is tracked here: b/20921915 3440 if _wait_for_droid_in_state(log, ad, timeout_value, 3441 _is_network_connected_state_match, 3442 is_connected): 3443 current_type = get_internet_connection_type(log, ad) 3444 ad.log.info("current data connection type: %s", current_type) 3445 if not connection_type: 3446 return True 3447 else: 3448 if not is_connected and current_type != connection_type: 3449 ad.log.info("data connection not on %s", connection_type) 3450 return True 3451 elif is_connected and current_type == connection_type: 3452 ad.log.info("after event wait, data connection on %s", 3453 connection_type) 3454 return True 3455 else: 3456 return False 3457 else: 3458 return False 3459 except Exception as e: 3460 ad.log.error("Exception error %s", str(e)) 3461 return False 3462 finally: 3463 ad.droid.connectivityStopTrackingConnectivityStateChange() 3464 3465 3466def get_cell_data_roaming_state_by_adb(ad): 3467 """Get Cell Data Roaming state. True for enabled, False for disabled""" 3468 adb_str = {"1": True, "0": False} 3469 out = ad.adb.shell("settings get global data_roaming") 3470 return adb_str[out] 3471 3472 3473def get_cell_data_roaming_state_by_adb(ad): 3474 """Get Cell Data Roaming state. True for enabled, False for disabled""" 3475 state_mapping = {"1": True, "0": False} 3476 return state_mapping[ad.adb.shell("settings get global data_roaming")] 3477 3478 3479def set_cell_data_roaming_state_by_adb(ad, state): 3480 """Set Cell Data Roaming state.""" 3481 state_mapping = {True: "1", False: "0"} 3482 ad.log.info("Set data roaming to %s", state) 3483 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state]) 3484 3485 3486def toggle_cell_data_roaming(ad, state): 3487 """Enable cell data roaming for default data subscription. 3488 3489 Wait for the data roaming status to be DATA_STATE_CONNECTED 3490 or DATA_STATE_DISCONNECTED. 3491 3492 Args: 3493 log: Log object. 3494 ad: Android Device Object. 3495 state: True or False for enable or disable cell data roaming. 3496 3497 Returns: 3498 True if success. 3499 False if failed. 3500 """ 3501 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state] 3502 action_str = {True: "Enable", False: "Disable"}[state] 3503 if ad.droid.connectivityCheckDataRoamingMode() == state: 3504 ad.log.info("Data roaming is already in state %s", state) 3505 return True 3506 if not ad.droid.connectivitySetDataRoaming(state_int): 3507 ad.error.info("Fail to config data roaming into state %s", state) 3508 return False 3509 if ad.droid.connectivityCheckDataRoamingMode() == state: 3510 ad.log.info("Data roaming is configured into state %s", state) 3511 return True 3512 else: 3513 ad.log.error("Data roaming is not configured into state %s", state) 3514 return False 3515 3516 3517def verify_incall_state(log, ads, expected_status): 3518 """Verify phones in incall state or not. 3519 3520 Verify if all phones in the array <ads> are in <expected_status>. 3521 3522 Args: 3523 log: Log object. 3524 ads: Array of Android Device Object. All droid in this array will be tested. 3525 expected_status: If True, verify all Phones in incall state. 3526 If False, verify all Phones not in incall state. 3527 3528 """ 3529 result = True 3530 for ad in ads: 3531 if ad.droid.telecomIsInCall() is not expected_status: 3532 ad.log.error("InCall status:%s, expected:%s", 3533 ad.droid.telecomIsInCall(), expected_status) 3534 result = False 3535 return result 3536 3537 3538def verify_active_call_number(log, ad, expected_number): 3539 """Verify the number of current active call. 3540 3541 Verify if the number of current active call in <ad> is 3542 equal to <expected_number>. 3543 3544 Args: 3545 ad: Android Device Object. 3546 expected_number: Expected active call number. 3547 """ 3548 calls = ad.droid.telecomCallGetCallIds() 3549 if calls is None: 3550 actual_number = 0 3551 else: 3552 actual_number = len(calls) 3553 if actual_number != expected_number: 3554 ad.log.error("Active Call number is %s, expecting", actual_number, 3555 expected_number) 3556 return False 3557 return True 3558 3559 3560def num_active_calls(log, ad): 3561 """Get the count of current active calls. 3562 3563 Args: 3564 log: Log object. 3565 ad: Android Device Object. 3566 3567 Returns: 3568 Count of current active calls. 3569 """ 3570 calls = ad.droid.telecomCallGetCallIds() 3571 return len(calls) if calls else 0 3572 3573 3574def toggle_volte(log, ad, new_state=None): 3575 """Toggle enable/disable VoLTE for default voice subscription. 3576 3577 Args: 3578 ad: Android device object. 3579 new_state: VoLTE mode state to set to. 3580 True for enable, False for disable. 3581 If None, opposite of the current state. 3582 3583 Raises: 3584 TelTestUtilsError if platform does not support VoLTE. 3585 """ 3586 return toggle_volte_for_subscription( 3587 log, ad, get_outgoing_voice_sub_id(ad), new_state) 3588 3589 3590def toggle_volte_for_subscription(log, ad, sub_id, new_state=None): 3591 """Toggle enable/disable VoLTE for specified voice subscription. 3592 3593 Args: 3594 ad: Android device object. 3595 sub_id: subscription ID 3596 new_state: VoLTE mode state to set to. 3597 True for enable, False for disable. 3598 If None, opposite of the current state. 3599 3600 """ 3601 # TODO: b/26293960 No framework API available to set IMS by SubId. 3602 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(): 3603 ad.log.info("Enhanced 4G Lte Mode Setting is not enabled by platform.") 3604 return False 3605 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() 3606 if new_state is None: 3607 new_state = not current_state 3608 if new_state != current_state: 3609 ad.log.info("Toggle Enhanced 4G LTE Mode from %s to %s", current_state, 3610 new_state) 3611 ad.droid.imsSetEnhanced4gMode(new_state) 3612 return True 3613 3614 3615def toggle_wfc(log, ad, new_state=None): 3616 """ Toggle WFC enable/disable""" 3617 if not ad.droid.imsIsWfcEnabledByPlatform(): 3618 ad.log.info("WFC is not enabled by platform") 3619 return False 3620 current_state = ad.droid.imsIsWfcEnabledByUser() 3621 if current_state == None: 3622 new_state = not current_state 3623 if new_state != current_state: 3624 ad.log.info("Toggle WFC user enabled from %s to %s", current_state, 3625 new_state) 3626 ad.droid.imsSetWfcSetting(new_state) 3627 return True 3628 3629 3630def wait_for_enhanced_4g_lte_setting(log, 3631 ad, 3632 max_time=MAX_WAIT_TIME_FOR_STATE_CHANGE): 3633 """Wait for android device to enable enhance 4G LTE setting. 3634 3635 Args: 3636 log: log object. 3637 ad: android device. 3638 max_time: maximal wait time. 3639 3640 Returns: 3641 Return True if device report VoLTE enabled bit true within max_time. 3642 Return False if timeout. 3643 """ 3644 return wait_for_state( 3645 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform, 3646 True, 3647 max_wait_time=max_time) 3648 3649 3650def set_wfc_mode(log, ad, wfc_mode): 3651 """Set WFC enable/disable and mode. 3652 3653 Args: 3654 log: Log object 3655 ad: Android device object. 3656 wfc_mode: WFC mode to set to. 3657 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED, 3658 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED. 3659 3660 Returns: 3661 True if success. False if ad does not support WFC or error happened. 3662 """ 3663 if wfc_mode != WFC_MODE_DISABLED and wfc_mode not in ad.telephony.get( 3664 "wfc_modes", []): 3665 ad.log.error("WFC mode %s is not supported", wfc_mode) 3666 raise signals.TestSkip("WFC mode %s is not supported" % wfc_mode) 3667 try: 3668 ad.log.info("Set wfc mode to %s", wfc_mode) 3669 if wfc_mode != WFC_MODE_DISABLED: 3670 start_adb_tcpdump(ad, interface="wlan0", mask="all") 3671 if not ad.droid.imsIsWfcEnabledByPlatform(): 3672 if wfc_mode == WFC_MODE_DISABLED: 3673 return True 3674 else: 3675 ad.log.error("WFC not supported by platform.") 3676 return False 3677 ad.droid.imsSetWfcMode(wfc_mode) 3678 mode = ad.droid.imsGetWfcMode() 3679 if mode != wfc_mode: 3680 ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode) 3681 return False 3682 except Exception as e: 3683 log.error(e) 3684 return False 3685 return True 3686 3687 3688def activate_wfc_on_device(log, ad): 3689 """ Activates WiFi calling on device. 3690 3691 Required for certain network operators. 3692 3693 Args: 3694 log: Log object 3695 ad: Android device object 3696 3697 """ 3698 activate_wfc_on_device_for_subscription(log, ad, 3699 ad.droid.subscriptionGetDefaultSubId()) 3700 3701 3702def activate_wfc_on_device_for_subscription(log, ad, sub_id): 3703 """ Activates WiFi calling on device for a subscription. 3704 3705 Args: 3706 log: Log object 3707 ad: Android device object 3708 sub_id: Subscription id (integer) 3709 3710 """ 3711 if not sub_id or INVALID_SUB_ID == sub_id: 3712 ad.log.error("Subscription id invalid") 3713 return 3714 operator_name = get_operator_name(log, ad, sub_id) 3715 if operator_name in (CARRIER_VZW, CARRIER_ATT, CARRIER_BELL, CARRIER_ROGERS, 3716 CARRIER_TELUS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_FRE): 3717 ad.log.info("Activating WFC on operator : %s", operator_name) 3718 if not ad.is_apk_installed("com.google.android.wfcactivation"): 3719 ad.log.error("WFC Activation Failed, wfc activation apk not installed") 3720 return 3721 wfc_activate_cmd ="am start --ei EXTRA_LAUNCH_CARRIER_APP 0 --ei " \ 3722 "android.telephony.extra.SUBSCRIPTION_INDEX {} -n ".format(sub_id) 3723 if CARRIER_ATT == operator_name: 3724 ad.adb.shell("setprop dbg.att.force_wfc_nv_enabled true") 3725 wfc_activate_cmd = wfc_activate_cmd+\ 3726 "\"com.google.android.wfcactivation/" \ 3727 ".WfcActivationActivity\"" 3728 elif CARRIER_VZW == operator_name: 3729 ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true") 3730 wfc_activate_cmd = wfc_activate_cmd + \ 3731 "\"com.google.android.wfcactivation/" \ 3732 ".VzwEmergencyAddressActivity\"" 3733 else: 3734 wfc_activate_cmd = wfc_activate_cmd+ \ 3735 "\"com.google.android.wfcactivation/" \ 3736 ".can.WfcActivationCanadaActivity\"" 3737 ad.adb.shell(wfc_activate_cmd) 3738 3739 3740def toggle_video_calling(log, ad, new_state=None): 3741 """Toggle enable/disable Video calling for default voice subscription. 3742 3743 Args: 3744 ad: Android device object. 3745 new_state: Video mode state to set to. 3746 True for enable, False for disable. 3747 If None, opposite of the current state. 3748 3749 Raises: 3750 TelTestUtilsError if platform does not support Video calling. 3751 """ 3752 if not ad.droid.imsIsVtEnabledByPlatform(): 3753 if new_state is not False: 3754 raise TelTestUtilsError("VT not supported by platform.") 3755 # if the user sets VT false and it's unavailable we just let it go 3756 return False 3757 3758 current_state = ad.droid.imsIsVtEnabledByUser() 3759 if new_state is None: 3760 new_state = not current_state 3761 if new_state != current_state: 3762 ad.droid.imsSetVtSetting(new_state) 3763 return True 3764 3765 3766def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args, 3767 **kwargs): 3768 while max_time >= 0: 3769 if state_check_func(log, ad, *args, **kwargs): 3770 return True 3771 3772 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 3773 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 3774 3775 return False 3776 3777 3778def _wait_for_droid_in_state_for_subscription( 3779 log, ad, sub_id, max_time, state_check_func, *args, **kwargs): 3780 while max_time >= 0: 3781 if state_check_func(log, ad, sub_id, *args, **kwargs): 3782 return True 3783 3784 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 3785 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 3786 3787 return False 3788 3789 3790def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args, 3791 **kwargs): 3792 while max_time > 0: 3793 success = True 3794 for ad in ads: 3795 if not state_check_func(log, ad, *args, **kwargs): 3796 success = False 3797 break 3798 if success: 3799 return True 3800 3801 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 3802 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK 3803 3804 return False 3805 3806 3807def is_phone_in_call(log, ad): 3808 """Return True if phone in call. 3809 3810 Args: 3811 log: log object. 3812 ad: android device. 3813 """ 3814 try: 3815 return ad.droid.telecomIsInCall() 3816 except: 3817 return "mCallState=2" in ad.adb.shell( 3818 "dumpsys telephony.registry | grep mCallState") 3819 3820 3821def is_phone_not_in_call(log, ad): 3822 """Return True if phone not in call. 3823 3824 Args: 3825 log: log object. 3826 ad: android device. 3827 """ 3828 in_call = ad.droid.telecomIsInCall() 3829 call_state = ad.droid.telephonyGetCallState() 3830 if in_call: 3831 ad.log.info("Device is In Call") 3832 if call_state != TELEPHONY_STATE_IDLE: 3833 ad.log.info("Call_state is %s, not %s", call_state, 3834 TELEPHONY_STATE_IDLE) 3835 return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE)) 3836 3837 3838def wait_for_droid_in_call(log, ad, max_time): 3839 """Wait for android to be in call state. 3840 3841 Args: 3842 log: log object. 3843 ad: android device. 3844 max_time: maximal wait time. 3845 3846 Returns: 3847 If phone become in call state within max_time, return True. 3848 Return False if timeout. 3849 """ 3850 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call) 3851 3852 3853def is_phone_in_call_active(ad, call_id=None): 3854 """Return True if phone in active call. 3855 3856 Args: 3857 log: log object. 3858 ad: android device. 3859 call_id: the call id 3860 """ 3861 if ad.droid.telecomIsInCall(): 3862 if not call_id: 3863 call_id = ad.droid.telecomCallGetCallIds()[0] 3864 call_state = ad.droid.telecomCallGetCallState(call_id) 3865 ad.log.info("%s state is %s", call_id, call_state) 3866 return call_state == "ACTIVE" 3867 else: 3868 ad.log.info("Not in telecomIsInCall") 3869 return False 3870 3871 3872def wait_for_in_call_active(ad, 3873 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT, 3874 interval=WAIT_TIME_BETWEEN_STATE_CHECK, 3875 call_id=None): 3876 """Wait for call reach active state. 3877 3878 Args: 3879 log: log object. 3880 ad: android device. 3881 call_id: the call id 3882 """ 3883 if not call_id: 3884 call_id = ad.droid.telecomCallGetCallIds()[0] 3885 args = [ad, call_id] 3886 if not wait_for_state(is_phone_in_call_active, True, timeout, interval, 3887 *args): 3888 ad.log.error("Call did not reach ACTIVE state") 3889 return False 3890 else: 3891 return True 3892 3893 3894def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING): 3895 """Wait for android to be in telecom ringing state. 3896 3897 Args: 3898 log: log object. 3899 ad: android device. 3900 max_time: maximal wait time. This is optional. 3901 Default Value is MAX_WAIT_TIME_TELECOM_RINGING. 3902 3903 Returns: 3904 If phone become in telecom ringing state within max_time, return True. 3905 Return False if timeout. 3906 """ 3907 return _wait_for_droid_in_state( 3908 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging()) 3909 3910 3911def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP): 3912 """Wait for android to be not in call state. 3913 3914 Args: 3915 log: log object. 3916 ad: android device. 3917 max_time: maximal wait time. 3918 3919 Returns: 3920 If phone become not in call state within max_time, return True. 3921 Return False if timeout. 3922 """ 3923 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call) 3924 3925 3926def _is_attached(log, ad, voice_or_data): 3927 return _is_attached_for_subscription( 3928 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 3929 3930 3931def _is_attached_for_subscription(log, ad, sub_id, voice_or_data): 3932 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data) 3933 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat, 3934 voice_or_data) 3935 return rat != RAT_UNKNOWN 3936 3937 3938def is_voice_attached(log, ad): 3939 return _is_attached_for_subscription( 3940 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE) 3941 3942 3943def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION): 3944 """Wait for android device to attach on voice. 3945 3946 Args: 3947 log: log object. 3948 ad: android device. 3949 max_time: maximal wait time. 3950 3951 Returns: 3952 Return True if device attach voice within max_time. 3953 Return False if timeout. 3954 """ 3955 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 3956 NETWORK_SERVICE_VOICE) 3957 3958 3959def wait_for_voice_attach_for_subscription( 3960 log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION): 3961 """Wait for android device to attach on voice in subscription id. 3962 3963 Args: 3964 log: log object. 3965 ad: android device. 3966 sub_id: subscription id. 3967 max_time: maximal wait time. 3968 3969 Returns: 3970 Return True if device attach voice within max_time. 3971 Return False if timeout. 3972 """ 3973 if not _wait_for_droid_in_state_for_subscription( 3974 log, ad, sub_id, max_time, _is_attached_for_subscription, 3975 NETWORK_SERVICE_VOICE): 3976 return False 3977 3978 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not 3979 # receive incoming call immediately. 3980 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT: 3981 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH) 3982 return True 3983 3984 3985def wait_for_data_attach(log, ad, max_time): 3986 """Wait for android device to attach on data. 3987 3988 Args: 3989 log: log object. 3990 ad: android device. 3991 max_time: maximal wait time. 3992 3993 Returns: 3994 Return True if device attach data within max_time. 3995 Return False if timeout. 3996 """ 3997 return _wait_for_droid_in_state(log, ad, max_time, _is_attached, 3998 NETWORK_SERVICE_DATA) 3999 4000 4001def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time): 4002 """Wait for android device to attach on data in subscription id. 4003 4004 Args: 4005 log: log object. 4006 ad: android device. 4007 sub_id: subscription id. 4008 max_time: maximal wait time. 4009 4010 Returns: 4011 Return True if device attach data within max_time. 4012 Return False if timeout. 4013 """ 4014 return _wait_for_droid_in_state_for_subscription( 4015 log, ad, sub_id, max_time, _is_attached_for_subscription, 4016 NETWORK_SERVICE_DATA) 4017 4018 4019def is_ims_registered(log, ad): 4020 """Return True if IMS registered. 4021 4022 Args: 4023 log: log object. 4024 ad: android device. 4025 4026 Returns: 4027 Return True if IMS registered. 4028 Return False if IMS not registered. 4029 """ 4030 return ad.droid.telephonyIsImsRegistered() 4031 4032 4033def wait_for_ims_registered(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): 4034 """Wait for android device to register on ims. 4035 4036 Args: 4037 log: log object. 4038 ad: android device. 4039 max_time: maximal wait time. 4040 4041 Returns: 4042 Return True if device register ims successfully within max_time. 4043 Return False if timeout. 4044 """ 4045 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered) 4046 4047 4048def is_volte_enabled(log, ad): 4049 """Return True if VoLTE feature bit is True. 4050 4051 Args: 4052 log: log object. 4053 ad: android device. 4054 4055 Returns: 4056 Return True if VoLTE feature bit is True and IMS registered. 4057 Return False if VoLTE feature bit is False or IMS not registered. 4058 """ 4059 if not is_ims_registered(log, ad): 4060 ad.log.info("IMS is not registered.") 4061 return False 4062 if not ad.droid.telephonyIsVolteAvailable(): 4063 ad.log.info("IMS is registered, IsVolteCallingAvailble is False") 4064 return False 4065 else: 4066 ad.log.info("IMS is registered, IsVolteCallingAvailble is True") 4067 return True 4068 4069 4070def is_video_enabled(log, ad): 4071 """Return True if Video Calling feature bit is True. 4072 4073 Args: 4074 log: log object. 4075 ad: android device. 4076 4077 Returns: 4078 Return True if Video Calling feature bit is True and IMS registered. 4079 Return False if Video Calling feature bit is False or IMS not registered. 4080 """ 4081 video_status = ad.droid.telephonyIsVideoCallingAvailable() 4082 if video_status is True and is_ims_registered(log, ad) is False: 4083 ad.log.error( 4084 "Error! Video Call is Available, but IMS is not registered.") 4085 return False 4086 return video_status 4087 4088 4089def wait_for_volte_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED): 4090 """Wait for android device to report VoLTE enabled bit true. 4091 4092 Args: 4093 log: log object. 4094 ad: android device. 4095 max_time: maximal wait time. 4096 4097 Returns: 4098 Return True if device report VoLTE enabled bit true within max_time. 4099 Return False if timeout. 4100 """ 4101 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled) 4102 4103 4104def wait_for_video_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED): 4105 """Wait for android device to report Video Telephony enabled bit true. 4106 4107 Args: 4108 log: log object. 4109 ad: android device. 4110 max_time: maximal wait time. 4111 4112 Returns: 4113 Return True if device report Video Telephony enabled bit true within max_time. 4114 Return False if timeout. 4115 """ 4116 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled) 4117 4118 4119def is_wfc_enabled(log, ad): 4120 """Return True if WiFi Calling feature bit is True. 4121 4122 Args: 4123 log: log object. 4124 ad: android device. 4125 4126 Returns: 4127 Return True if WiFi Calling feature bit is True and IMS registered. 4128 Return False if WiFi Calling feature bit is False or IMS not registered. 4129 """ 4130 if not is_ims_registered(log, ad): 4131 ad.log.info("IMS is not registered.") 4132 return False 4133 if not ad.droid.telephonyIsWifiCallingAvailable(): 4134 ad.log.info("IMS is registered, IsWifiCallingAvailble is False") 4135 return False 4136 else: 4137 ad.log.info("IMS is registered, IsWifiCallingAvailble is True") 4138 return True 4139 4140 4141def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): 4142 """Wait for android device to report WiFi Calling enabled bit true. 4143 4144 Args: 4145 log: log object. 4146 ad: android device. 4147 max_time: maximal wait time. 4148 Default value is MAX_WAIT_TIME_WFC_ENABLED. 4149 4150 Returns: 4151 Return True if device report WiFi Calling enabled bit true within max_time. 4152 Return False if timeout. 4153 """ 4154 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled) 4155 4156 4157def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED): 4158 """Wait for android device to report WiFi Calling enabled bit false. 4159 4160 Args: 4161 log: log object. 4162 ad: android device. 4163 max_time: maximal wait time. 4164 Default value is MAX_WAIT_TIME_WFC_DISABLED. 4165 4166 Returns: 4167 Return True if device report WiFi Calling enabled bit false within max_time. 4168 Return False if timeout. 4169 """ 4170 return _wait_for_droid_in_state( 4171 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad)) 4172 4173 4174def get_phone_number(log, ad): 4175 """Get phone number for default subscription 4176 4177 Args: 4178 log: log object. 4179 ad: Android device object. 4180 4181 Returns: 4182 Phone number. 4183 """ 4184 return get_phone_number_for_subscription(log, ad, 4185 get_outgoing_voice_sub_id(ad)) 4186 4187 4188def get_phone_number_for_subscription(log, ad, subid): 4189 """Get phone number for subscription 4190 4191 Args: 4192 log: log object. 4193 ad: Android device object. 4194 subid: subscription id. 4195 4196 Returns: 4197 Phone number. 4198 """ 4199 number = None 4200 try: 4201 number = ad.telephony['subscription'][subid]['phone_num'] 4202 except KeyError: 4203 number = ad.droid.telephonyGetLine1NumberForSubscription(subid) 4204 return number 4205 4206 4207def set_phone_number(log, ad, phone_num): 4208 """Set phone number for default subscription 4209 4210 Args: 4211 log: log object. 4212 ad: Android device object. 4213 phone_num: phone number string. 4214 4215 Returns: 4216 True if success. 4217 """ 4218 return set_phone_number_for_subscription(log, ad, 4219 get_outgoing_voice_sub_id(ad), 4220 phone_num) 4221 4222 4223def set_phone_number_for_subscription(log, ad, subid, phone_num): 4224 """Set phone number for subscription 4225 4226 Args: 4227 log: log object. 4228 ad: Android device object. 4229 subid: subscription id. 4230 phone_num: phone number string. 4231 4232 Returns: 4233 True if success. 4234 """ 4235 try: 4236 ad.telephony['subscription'][subid]['phone_num'] = phone_num 4237 except Exception: 4238 return False 4239 return True 4240 4241 4242def get_operator_name(log, ad, subId=None): 4243 """Get operator name (e.g. vzw, tmo) of droid. 4244 4245 Args: 4246 ad: Android device object. 4247 sub_id: subscription ID 4248 Optional, default is None 4249 4250 Returns: 4251 Operator name. 4252 """ 4253 try: 4254 if subId is not None: 4255 result = operator_name_from_plmn_id( 4256 ad.droid.telephonyGetNetworkOperatorForSubscription(subId)) 4257 else: 4258 result = operator_name_from_plmn_id( 4259 ad.droid.telephonyGetNetworkOperator()) 4260 except KeyError: 4261 try: 4262 if subId is not None: 4263 result = ad.droid.telephonyGetNetworkOperatorNameForSubscription( 4264 subId) 4265 else: 4266 result = ad.droid.telephonyGetNetworkOperatorName() 4267 result = operator_name_from_network_name(result) 4268 except Exception: 4269 result = CARRIER_UNKNOWN 4270 ad.log.info("Operator Name is %s", result) 4271 return result 4272 4273 4274def get_model_name(ad): 4275 """Get android device model name 4276 4277 Args: 4278 ad: Android device object 4279 4280 Returns: 4281 model name string 4282 """ 4283 # TODO: Create translate table. 4284 model = ad.model 4285 if (model.startswith(AOSP_PREFIX)): 4286 model = model[len(AOSP_PREFIX):] 4287 return model 4288 4289 4290def is_sms_match(event, phonenumber_tx, text): 4291 """Return True if 'text' equals to event['data']['Text'] 4292 and phone number match. 4293 4294 Args: 4295 event: Event object to verify. 4296 phonenumber_tx: phone number for sender. 4297 text: text string to verify. 4298 4299 Returns: 4300 Return True if 'text' equals to event['data']['Text'] 4301 and phone number match. 4302 """ 4303 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx) 4304 and event['data']['Text'].strip() == text) 4305 4306 4307def is_sms_partial_match(event, phonenumber_tx, text): 4308 """Return True if 'text' starts with event['data']['Text'] 4309 and phone number match. 4310 4311 Args: 4312 event: Event object to verify. 4313 phonenumber_tx: phone number for sender. 4314 text: text string to verify. 4315 4316 Returns: 4317 Return True if 'text' starts with event['data']['Text'] 4318 and phone number match. 4319 """ 4320 event_text = event['data']['Text'].strip() 4321 if event_text.startswith("("): 4322 event_text = event_text.split(")")[-1] 4323 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx) 4324 and text.startswith(event_text)) 4325 4326 4327def sms_send_receive_verify(log, 4328 ad_tx, 4329 ad_rx, 4330 array_message, 4331 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE, 4332 expected_result=True, 4333 slot_id_rx=None): 4334 """Send SMS, receive SMS, and verify content and sender's number. 4335 4336 Send (several) SMS from droid_tx to droid_rx. 4337 Verify SMS is sent, delivered and received. 4338 Verify received content and sender's number are correct. 4339 4340 Args: 4341 log: Log object. 4342 ad_tx: Sender's Android Device Object 4343 ad_rx: Receiver's Android Device Object 4344 array_message: the array of message to send/receive 4345 slot_id_rx: the slot on the Receiver's android device (0/1) 4346 """ 4347 subid_tx = get_outgoing_message_sub_id(ad_tx) 4348 if slot_id_rx is None: 4349 subid_rx = get_incoming_message_sub_id(ad_rx) 4350 else: 4351 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx) 4352 4353 result = sms_send_receive_verify_for_subscription( 4354 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time) 4355 if result != expected_result: 4356 log_messaging_screen_shot(ad_tx, test_name="sms_tx") 4357 log_messaging_screen_shot(ad_rx, test_name="sms_rx") 4358 return result == expected_result 4359 4360 4361def wait_for_matching_sms(log, 4362 ad_rx, 4363 phonenumber_tx, 4364 text, 4365 allow_multi_part_long_sms=True, 4366 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4367 """Wait for matching incoming SMS. 4368 4369 Args: 4370 log: Log object. 4371 ad_rx: Receiver's Android Device Object 4372 phonenumber_tx: Sender's phone number. 4373 text: SMS content string. 4374 allow_multi_part_long_sms: is long SMS allowed to be received as 4375 multiple short SMS. This is optional, default value is True. 4376 4377 Returns: 4378 True if matching incoming SMS is received. 4379 """ 4380 if not allow_multi_part_long_sms: 4381 try: 4382 ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match, 4383 max_wait_time, phonenumber_tx, 4384 text) 4385 ad_rx.log.info("Got event %s", EventSmsReceived) 4386 return True 4387 except Empty: 4388 ad_rx.log.error("No matched SMS received event.") 4389 return False 4390 else: 4391 try: 4392 received_sms = '' 4393 remaining_text = text 4394 while (remaining_text != ''): 4395 event = ad_rx.messaging_ed.wait_for_event( 4396 EventSmsReceived, is_sms_partial_match, max_wait_time, 4397 phonenumber_tx, remaining_text) 4398 event_text = event['data']['Text'].split(")")[-1].strip() 4399 event_text_length = len(event_text) 4400 ad_rx.log.info("Got event %s of text length %s from %s", 4401 EventSmsReceived, event_text_length, 4402 phonenumber_tx) 4403 remaining_text = remaining_text[event_text_length:] 4404 received_sms += event_text 4405 ad_rx.log.info("Received SMS of length %s", len(received_sms)) 4406 return True 4407 except Empty: 4408 ad_rx.log.error( 4409 "Missing SMS received event of text length %s from %s", 4410 len(remaining_text), phonenumber_tx) 4411 if received_sms != '': 4412 ad_rx.log.error( 4413 "Only received partial matched SMS of length %s", 4414 len(received_sms)) 4415 return False 4416 4417 4418def is_mms_match(event, phonenumber_tx, text): 4419 """Return True if 'text' equals to event['data']['Text'] 4420 and phone number match. 4421 4422 Args: 4423 event: Event object to verify. 4424 phonenumber_tx: phone number for sender. 4425 text: text string to verify. 4426 4427 Returns: 4428 Return True if 'text' equals to event['data']['Text'] 4429 and phone number match. 4430 """ 4431 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948 4432 return True 4433 4434 4435def wait_for_matching_mms(log, 4436 ad_rx, 4437 phonenumber_tx, 4438 text, 4439 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4440 """Wait for matching incoming SMS. 4441 4442 Args: 4443 log: Log object. 4444 ad_rx: Receiver's Android Device Object 4445 phonenumber_tx: Sender's phone number. 4446 text: SMS content string. 4447 allow_multi_part_long_sms: is long SMS allowed to be received as 4448 multiple short SMS. This is optional, default value is True. 4449 4450 Returns: 4451 True if matching incoming SMS is received. 4452 """ 4453 try: 4454 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948 4455 ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match, 4456 max_wait_time, phonenumber_tx, text) 4457 ad_rx.log.info("Got event %s", EventMmsDownloaded) 4458 return True 4459 except Empty: 4460 ad_rx.log.warning("No matched MMS downloaded event.") 4461 return False 4462 4463 4464def sms_send_receive_verify_for_subscription( 4465 log, 4466 ad_tx, 4467 ad_rx, 4468 subid_tx, 4469 subid_rx, 4470 array_message, 4471 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4472 """Send SMS, receive SMS, and verify content and sender's number. 4473 4474 Send (several) SMS from droid_tx to droid_rx. 4475 Verify SMS is sent, delivered and received. 4476 Verify received content and sender's number are correct. 4477 4478 Args: 4479 log: Log object. 4480 ad_tx: Sender's Android Device Object.. 4481 ad_rx: Receiver's Android Device Object. 4482 subid_tx: Sender's subsciption ID to be used for SMS 4483 subid_rx: Receiver's subsciption ID to be used for SMS 4484 array_message: the array of message to send/receive 4485 """ 4486 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num'] 4487 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num'] 4488 4489 for ad in (ad_tx, ad_rx): 4490 ad.send_keycode("BACK") 4491 if not getattr(ad, "messaging_droid", None): 4492 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4493 ad.messaging_ed.start() 4494 else: 4495 try: 4496 if not ad.messaging_droid.is_live: 4497 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4498 ad.messaging_ed.start() 4499 else: 4500 ad.messaging_ed.clear_all_events() 4501 ad.messaging_droid.logI( 4502 "Start sms_send_receive_verify_for_subscription test") 4503 except Exception: 4504 ad.log.info("Create new sl4a session for messaging") 4505 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4506 ad.messaging_ed.start() 4507 4508 for text in array_message: 4509 length = len(text) 4510 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.", 4511 phonenumber_tx, phonenumber_rx, length, text) 4512 try: 4513 ad_rx.messaging_ed.clear_events(EventSmsReceived) 4514 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess) 4515 ad_tx.messaging_ed.clear_events(EventSmsSentFailure) 4516 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage() 4517 time.sleep(1) #sleep 100ms after starting event tracking 4518 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length) 4519 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length) 4520 ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text, 4521 True) 4522 try: 4523 events = ad_tx.messaging_ed.pop_events( 4524 "(%s|%s|%s|%s)" % 4525 (EventSmsSentSuccess, EventSmsSentFailure, 4526 EventSmsDeliverSuccess, 4527 EventSmsDeliverFailure), max_wait_time) 4528 for event in events: 4529 ad_tx.log.info("Got event %s", event["name"]) 4530 if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure: 4531 if event.get("data") and event["data"].get("Reason"): 4532 ad_tx.log.error("%s with reason: %s", 4533 event["name"], 4534 event["data"]["Reason"]) 4535 return False 4536 elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess: 4537 break 4538 except Empty: 4539 ad_tx.log.error("No %s or %s event for SMS of length %s.", 4540 EventSmsSentSuccess, EventSmsSentFailure, 4541 length) 4542 return False 4543 4544 if not wait_for_matching_sms( 4545 log, 4546 ad_rx, 4547 phonenumber_tx, 4548 text, 4549 allow_multi_part_long_sms=True): 4550 ad_rx.log.error("No matching received SMS of length %s.", 4551 length) 4552 return False 4553 except Exception as e: 4554 log.error("Exception error %s", e) 4555 raise 4556 finally: 4557 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage() 4558 return True 4559 4560 4561def mms_send_receive_verify(log, 4562 ad_tx, 4563 ad_rx, 4564 array_message, 4565 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE, 4566 expected_result=True, 4567 slot_id_rx=None): 4568 """Send MMS, receive MMS, and verify content and sender's number. 4569 4570 Send (several) MMS from droid_tx to droid_rx. 4571 Verify MMS is sent, delivered and received. 4572 Verify received content and sender's number are correct. 4573 4574 Args: 4575 log: Log object. 4576 ad_tx: Sender's Android Device Object 4577 ad_rx: Receiver's Android Device Object 4578 array_message: the array of message to send/receive 4579 """ 4580 subid_tx = get_outgoing_message_sub_id(ad_tx) 4581 if slot_id_rx is None: 4582 subid_rx = get_incoming_message_sub_id(ad_rx) 4583 else: 4584 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx) 4585 4586 result = mms_send_receive_verify_for_subscription( 4587 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time) 4588 if result != expected_result: 4589 log_messaging_screen_shot(ad_tx, test_name="mms_tx") 4590 log_messaging_screen_shot(ad_rx, test_name="mms_rx") 4591 return result == expected_result 4592 4593 4594def sms_mms_send_logcat_check(ad, type, begin_time): 4595 type = type.upper() 4596 log_results = ad.search_logcat( 4597 "%s Message sent successfully" % type, begin_time=begin_time) 4598 if log_results: 4599 ad.log.info("Found %s sent successful log message: %s", type, 4600 log_results[-1]["log_message"]) 4601 return True 4602 else: 4603 log_results = ad.search_logcat( 4604 "ProcessSentMessageAction: Done sending %s message" % type, 4605 begin_time=begin_time) 4606 if log_results: 4607 for log_result in log_results: 4608 if "status is SUCCEEDED" in log_result["log_message"]: 4609 ad.log.info( 4610 "Found BugleDataModel %s send succeed log message: %s", 4611 type, log_result["log_message"]) 4612 return True 4613 return False 4614 4615 4616def sms_mms_receive_logcat_check(ad, type, begin_time): 4617 type = type.upper() 4618 smshandle_logs = ad.search_logcat( 4619 "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS", 4620 begin_time=begin_time) 4621 if smshandle_logs: 4622 ad.log.warning("Found %s", smshandle_logs[-1]["log_message"]) 4623 log_results = ad.search_logcat( 4624 "New %s Received" % type, begin_time=begin_time) or \ 4625 ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time) 4626 if log_results: 4627 ad.log.info("Found SL4A %s received log message: %s", type, 4628 log_results[-1]["log_message"]) 4629 return True 4630 else: 4631 log_results = ad.search_logcat( 4632 "Received %s message" % type, begin_time=begin_time) 4633 if log_results: 4634 ad.log.info("Found %s received log message: %s", type, 4635 log_results[-1]["log_message"]) 4636 log_results = ad.search_logcat( 4637 "ProcessDownloadedMmsAction", begin_time=begin_time) 4638 for log_result in log_results: 4639 ad.log.info("Found %s", log_result["log_message"]) 4640 if "status is SUCCEEDED" in log_result["log_message"]: 4641 ad.log.info("Download succeed with ProcessDownloadedMmsAction") 4642 return True 4643 return False 4644 4645 4646#TODO: add mms matching after mms message parser is added in sl4a. b/34276948 4647def mms_send_receive_verify_for_subscription( 4648 log, 4649 ad_tx, 4650 ad_rx, 4651 subid_tx, 4652 subid_rx, 4653 array_payload, 4654 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4655 """Send MMS, receive MMS, and verify content and sender's number. 4656 4657 Send (several) MMS from droid_tx to droid_rx. 4658 Verify MMS is sent, delivered and received. 4659 Verify received content and sender's number are correct. 4660 4661 Args: 4662 log: Log object. 4663 ad_tx: Sender's Android Device Object.. 4664 ad_rx: Receiver's Android Device Object. 4665 subid_tx: Sender's subsciption ID to be used for SMS 4666 subid_rx: Receiver's subsciption ID to be used for SMS 4667 array_message: the array of message to send/receive 4668 """ 4669 4670 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num'] 4671 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num'] 4672 4673 for ad in (ad_tx, ad_rx): 4674 ad.send_keycode("BACK") 4675 if "Permissive" not in ad.adb.shell("su root getenforce"): 4676 ad.adb.shell("su root setenforce 0") 4677 if not getattr(ad, "messaging_droid", None): 4678 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4679 ad.messaging_ed.start() 4680 else: 4681 try: 4682 if not ad.messaging_droid.is_live: 4683 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4684 ad.messaging_ed.start() 4685 else: 4686 ad.messaging_ed.clear_all_events() 4687 ad.messaging_droid.logI( 4688 "Start mms_send_receive_verify_for_subscription test") 4689 except Exception: 4690 ad.log.info("Create new sl4a session for messaging") 4691 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4692 ad.messaging_ed.start() 4693 4694 for subject, message, filename in array_payload: 4695 ad_tx.messaging_ed.clear_events(EventMmsSentSuccess) 4696 ad_tx.messaging_ed.clear_events(EventMmsSentFailure) 4697 ad_rx.messaging_ed.clear_events(EventMmsDownloaded) 4698 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage() 4699 ad_tx.log.info( 4700 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.", 4701 phonenumber_tx, phonenumber_rx, subject, message, filename) 4702 try: 4703 ad_tx.messaging_droid.smsSendMultimediaMessage( 4704 phonenumber_rx, subject, message, phonenumber_tx, filename) 4705 try: 4706 events = ad_tx.messaging_ed.pop_events( 4707 "(%s|%s)" % (EventMmsSentSuccess, 4708 EventMmsSentFailure), max_wait_time) 4709 for event in events: 4710 ad_tx.log.info("Got event %s", event["name"]) 4711 if event["name"] == EventMmsSentFailure: 4712 if event.get("data") and event["data"].get("Reason"): 4713 ad_tx.log.error("%s with reason: %s", 4714 event["name"], 4715 event["data"]["Reason"]) 4716 return False 4717 elif event["name"] == EventMmsSentSuccess: 4718 break 4719 except Empty: 4720 ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess, 4721 EventMmsSentFailure) 4722 4723 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, 4724 message, max_wait_time): 4725 return False 4726 except Exception as e: 4727 log.error("Exception error %s", e) 4728 raise 4729 finally: 4730 ad_rx.droid.smsStopTrackingIncomingMmsMessage() 4731 for ad in (ad_tx, ad_rx): 4732 ad.send_keycode("BACK") 4733 ad.adb.shell("su root setenforce 1") 4734 return True 4735 4736 4737def mms_receive_verify_after_call_hangup( 4738 log, ad_tx, ad_rx, array_message, 4739 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4740 """Verify the suspanded MMS during call will send out after call release. 4741 4742 Hangup call from droid_tx to droid_rx. 4743 Verify MMS is sent, delivered and received. 4744 Verify received content and sender's number are correct. 4745 4746 Args: 4747 log: Log object. 4748 ad_tx: Sender's Android Device Object 4749 ad_rx: Receiver's Android Device Object 4750 array_message: the array of message to send/receive 4751 """ 4752 return mms_receive_verify_after_call_hangup_for_subscription( 4753 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx), 4754 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time) 4755 4756 4757#TODO: add mms matching after mms message parser is added in sl4a. b/34276948 4758def mms_receive_verify_after_call_hangup_for_subscription( 4759 log, 4760 ad_tx, 4761 ad_rx, 4762 subid_tx, 4763 subid_rx, 4764 array_payload, 4765 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE): 4766 """Verify the suspanded MMS during call will send out after call release. 4767 4768 Hangup call from droid_tx to droid_rx. 4769 Verify MMS is sent, delivered and received. 4770 Verify received content and sender's number are correct. 4771 4772 Args: 4773 log: Log object. 4774 ad_tx: Sender's Android Device Object.. 4775 ad_rx: Receiver's Android Device Object. 4776 subid_tx: Sender's subsciption ID to be used for SMS 4777 subid_rx: Receiver's subsciption ID to be used for SMS 4778 array_message: the array of message to send/receive 4779 """ 4780 4781 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num'] 4782 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num'] 4783 for ad in (ad_tx, ad_rx): 4784 if not getattr(ad, "messaging_droid", None): 4785 ad.messaging_droid, ad.messaging_ed = ad.get_droid() 4786 ad.messaging_ed.start() 4787 for subject, message, filename in array_payload: 4788 ad_rx.log.info( 4789 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.", 4790 phonenumber_tx, phonenumber_rx, subject, message, filename) 4791 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage() 4792 time.sleep(5) 4793 try: 4794 hangup_call(log, ad_tx) 4795 hangup_call(log, ad_rx) 4796 try: 4797 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess, 4798 max_wait_time) 4799 ad_tx.log.info("Got event %s", EventMmsSentSuccess) 4800 except Empty: 4801 log.warning("No sent_success event.") 4802 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message): 4803 return False 4804 finally: 4805 ad_rx.droid.smsStopTrackingIncomingMmsMessage() 4806 return True 4807 4808 4809def ensure_preferred_network_type_for_subscription( 4810 ad, 4811 network_preference 4812 ): 4813 sub_id = ad.droid.subscriptionGetDefaultSubId() 4814 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4815 network_preference, sub_id): 4816 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.", 4817 sub_id, network_preference) 4818 return True 4819 4820 4821def ensure_network_rat(log, 4822 ad, 4823 network_preference, 4824 rat_family, 4825 voice_or_data=None, 4826 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4827 toggle_apm_after_setting=False): 4828 """Ensure ad's current network is in expected rat_family. 4829 """ 4830 return ensure_network_rat_for_subscription( 4831 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 4832 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting) 4833 4834 4835def ensure_network_rat_for_subscription( 4836 log, 4837 ad, 4838 sub_id, 4839 network_preference, 4840 rat_family, 4841 voice_or_data=None, 4842 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4843 toggle_apm_after_setting=False): 4844 """Ensure ad's current network is in expected rat_family. 4845 """ 4846 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4847 network_preference, sub_id): 4848 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.", 4849 sub_id, network_preference) 4850 return False 4851 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, 4852 voice_or_data): 4853 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family, 4854 voice_or_data) 4855 return True 4856 4857 if toggle_apm_after_setting: 4858 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 4859 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4860 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False) 4861 4862 result = wait_for_network_rat_for_subscription( 4863 log, ad, sub_id, rat_family, max_wait_time, voice_or_data) 4864 4865 log.info( 4866 "End of ensure_network_rat_for_subscription for %s. " 4867 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), " 4868 "data: %s(family: %s)", ad.serial, network_preference, rat_family, 4869 voice_or_data, 4870 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 4871 rat_family_from_rat( 4872 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 4873 sub_id)), 4874 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 4875 rat_family_from_rat( 4876 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 4877 sub_id))) 4878 return result 4879 4880 4881def ensure_network_preference(log, 4882 ad, 4883 network_preference, 4884 voice_or_data=None, 4885 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4886 toggle_apm_after_setting=False): 4887 """Ensure that current rat is within the device's preferred network rats. 4888 """ 4889 return ensure_network_preference_for_subscription( 4890 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 4891 voice_or_data, max_wait_time, toggle_apm_after_setting) 4892 4893 4894def ensure_network_preference_for_subscription( 4895 log, 4896 ad, 4897 sub_id, 4898 network_preference, 4899 voice_or_data=None, 4900 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4901 toggle_apm_after_setting=False): 4902 """Ensure ad's network preference is <network_preference> for sub_id. 4903 """ 4904 rat_family_list = rat_families_for_network_preference(network_preference) 4905 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription( 4906 network_preference, sub_id): 4907 log.error("Set Preferred Networks failed.") 4908 return False 4909 if is_droid_in_rat_family_list_for_subscription( 4910 log, ad, sub_id, rat_family_list, voice_or_data): 4911 return True 4912 4913 if toggle_apm_after_setting: 4914 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 4915 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 4916 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False) 4917 4918 result = wait_for_preferred_network_for_subscription( 4919 log, ad, sub_id, network_preference, max_wait_time, voice_or_data) 4920 4921 ad.log.info( 4922 "End of ensure_network_preference_for_subscription. " 4923 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), " 4924 "data: %s(family: %s)", network_preference, rat_family_list, 4925 voice_or_data, 4926 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 4927 rat_family_from_rat( 4928 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 4929 sub_id)), 4930 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 4931 rat_family_from_rat( 4932 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 4933 sub_id))) 4934 return result 4935 4936 4937def ensure_network_generation(log, 4938 ad, 4939 generation, 4940 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4941 voice_or_data=None, 4942 toggle_apm_after_setting=False): 4943 """Ensure ad's network is <network generation> for default subscription ID. 4944 4945 Set preferred network generation to <generation>. 4946 Toggle ON/OFF airplane mode if necessary. 4947 Wait for ad in expected network type. 4948 """ 4949 return ensure_network_generation_for_subscription( 4950 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 4951 max_wait_time, voice_or_data, toggle_apm_after_setting) 4952 4953 4954def ensure_network_generation_for_subscription( 4955 log, 4956 ad, 4957 sub_id, 4958 generation, 4959 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 4960 voice_or_data=None, 4961 toggle_apm_after_setting=False): 4962 """Ensure ad's network is <network generation> for specified subscription ID. 4963 4964 Set preferred network generation to <generation>. 4965 Toggle ON/OFF airplane mode if necessary. 4966 Wait for ad in expected network type. 4967 """ 4968 ad.log.info( 4969 "RAT network type voice: %s, data: %s", 4970 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 4971 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id)) 4972 4973 try: 4974 ad.log.info("Finding the network preference for generation %s for " 4975 "operator %s phone type %s", generation, 4976 ad.telephony["subscription"][sub_id]["operator"], 4977 ad.telephony["subscription"][sub_id]["phone_type"]) 4978 network_preference = network_preference_for_generation( 4979 generation, ad.telephony["subscription"][sub_id]["operator"], 4980 ad.telephony["subscription"][sub_id]["phone_type"]) 4981 if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \ 4982 and generation == GEN_4G: 4983 network_preference = NETWORK_MODE_LTE_ONLY 4984 ad.log.info("Network preference for %s is %s", generation, 4985 network_preference) 4986 rat_family = rat_family_for_generation( 4987 generation, ad.telephony["subscription"][sub_id]["operator"], 4988 ad.telephony["subscription"][sub_id]["phone_type"]) 4989 except KeyError as e: 4990 ad.log.error("Failed to find a rat_family entry for generation %s" 4991 " for subscriber id %s with error %s", generation, 4992 sub_id, e) 4993 return False 4994 4995 if not set_preferred_network_mode_pref(log, ad, sub_id, 4996 network_preference): 4997 return False 4998 4999 if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad): 5000 ad.log.info("MSIM - Non DDS, ignore data RAT") 5001 return True 5002 5003 if is_droid_in_network_generation_for_subscription( 5004 log, ad, sub_id, generation, voice_or_data): 5005 return True 5006 5007 if toggle_apm_after_setting: 5008 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False) 5009 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 5010 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False) 5011 5012 result = wait_for_network_generation_for_subscription( 5013 log, ad, sub_id, generation, max_wait_time, voice_or_data) 5014 5015 ad.log.info( 5016 "Ensure network %s %s %s. With network preference %s, " 5017 "current: voice: %s(family: %s), data: %s(family: %s)", generation, 5018 voice_or_data, result, network_preference, 5019 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id), 5020 rat_generation_from_rat( 5021 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 5022 sub_id)), 5023 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id), 5024 rat_generation_from_rat( 5025 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 5026 sub_id))) 5027 if not result: 5028 get_telephony_signal_strength(ad) 5029 return result 5030 5031 5032def wait_for_network_rat(log, 5033 ad, 5034 rat_family, 5035 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5036 voice_or_data=None): 5037 return wait_for_network_rat_for_subscription( 5038 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 5039 max_wait_time, voice_or_data) 5040 5041 5042def wait_for_network_rat_for_subscription( 5043 log, 5044 ad, 5045 sub_id, 5046 rat_family, 5047 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5048 voice_or_data=None): 5049 return _wait_for_droid_in_state_for_subscription( 5050 log, ad, sub_id, max_wait_time, 5051 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data) 5052 5053 5054def wait_for_not_network_rat(log, 5055 ad, 5056 rat_family, 5057 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5058 voice_or_data=None): 5059 return wait_for_not_network_rat_for_subscription( 5060 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 5061 max_wait_time, voice_or_data) 5062 5063 5064def wait_for_not_network_rat_for_subscription( 5065 log, 5066 ad, 5067 sub_id, 5068 rat_family, 5069 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5070 voice_or_data=None): 5071 return _wait_for_droid_in_state_for_subscription( 5072 log, ad, sub_id, max_wait_time, 5073 lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data) 5074 ) 5075 5076 5077def wait_for_preferred_network(log, 5078 ad, 5079 network_preference, 5080 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5081 voice_or_data=None): 5082 return wait_for_preferred_network_for_subscription( 5083 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference, 5084 max_wait_time, voice_or_data) 5085 5086 5087def wait_for_preferred_network_for_subscription( 5088 log, 5089 ad, 5090 sub_id, 5091 network_preference, 5092 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5093 voice_or_data=None): 5094 rat_family_list = rat_families_for_network_preference(network_preference) 5095 return _wait_for_droid_in_state_for_subscription( 5096 log, ad, sub_id, max_wait_time, 5097 is_droid_in_rat_family_list_for_subscription, rat_family_list, 5098 voice_or_data) 5099 5100 5101def wait_for_network_generation(log, 5102 ad, 5103 generation, 5104 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5105 voice_or_data=None): 5106 return wait_for_network_generation_for_subscription( 5107 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation, 5108 max_wait_time, voice_or_data) 5109 5110 5111def wait_for_network_generation_for_subscription( 5112 log, 5113 ad, 5114 sub_id, 5115 generation, 5116 max_wait_time=MAX_WAIT_TIME_NW_SELECTION, 5117 voice_or_data=None): 5118 return _wait_for_droid_in_state_for_subscription( 5119 log, ad, sub_id, max_wait_time, 5120 is_droid_in_network_generation_for_subscription, generation, 5121 voice_or_data) 5122 5123 5124def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None): 5125 return is_droid_in_rat_family_for_subscription( 5126 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family, 5127 voice_or_data) 5128 5129 5130def is_droid_in_rat_family_for_subscription(log, 5131 ad, 5132 sub_id, 5133 rat_family, 5134 voice_or_data=None): 5135 return is_droid_in_rat_family_list_for_subscription( 5136 log, ad, sub_id, [rat_family], voice_or_data) 5137 5138 5139def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None): 5140 return is_droid_in_rat_family_list_for_subscription( 5141 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list, 5142 voice_or_data) 5143 5144 5145def is_droid_in_rat_family_list_for_subscription(log, 5146 ad, 5147 sub_id, 5148 rat_family_list, 5149 voice_or_data=None): 5150 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 5151 if voice_or_data: 5152 service_list = [voice_or_data] 5153 5154 for service in service_list: 5155 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 5156 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 5157 continue 5158 if rat_family_from_rat(nw_rat) in rat_family_list: 5159 return True 5160 return False 5161 5162 5163def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data): 5164 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 5165 5166 Args: 5167 log: log object. 5168 ad: android device. 5169 nw_gen: expected generation "4g", "3g", "2g". 5170 voice_or_data: check voice network generation or data network generation 5171 This parameter is optional. If voice_or_data is None, then if 5172 either voice or data in expected generation, function will return True. 5173 5174 Returns: 5175 True if droid in expected network generation. Otherwise False. 5176 """ 5177 return is_droid_in_network_generation_for_subscription( 5178 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data) 5179 5180 5181def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen, 5182 voice_or_data): 5183 """Checks if a droid in expected network generation ("2g", "3g" or "4g"). 5184 5185 Args: 5186 log: log object. 5187 ad: android device. 5188 nw_gen: expected generation "4g", "3g", "2g". 5189 voice_or_data: check voice network generation or data network generation 5190 This parameter is optional. If voice_or_data is None, then if 5191 either voice or data in expected generation, function will return True. 5192 5193 Returns: 5194 True if droid in expected network generation. Otherwise False. 5195 """ 5196 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE] 5197 5198 if voice_or_data: 5199 service_list = [voice_or_data] 5200 5201 for service in service_list: 5202 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service) 5203 ad.log.info("%s network rat is %s", service, nw_rat) 5204 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat): 5205 continue 5206 5207 if rat_generation_from_rat(nw_rat) == nw_gen: 5208 ad.log.info("%s network rat %s is expected %s", service, nw_rat, 5209 nw_gen) 5210 return True 5211 else: 5212 ad.log.info("%s network rat %s is %s, does not meet expected %s", 5213 service, nw_rat, rat_generation_from_rat(nw_rat), 5214 nw_gen) 5215 return False 5216 5217 return False 5218 5219 5220def get_network_rat(log, ad, voice_or_data): 5221 """Get current network type (Voice network type, or data network type) 5222 for default subscription id 5223 5224 Args: 5225 ad: Android Device Object 5226 voice_or_data: Input parameter indicating to get voice network type or 5227 data network type. 5228 5229 Returns: 5230 Current voice/data network type. 5231 """ 5232 return get_network_rat_for_subscription( 5233 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 5234 5235 5236def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data): 5237 """Get current network type (Voice network type, or data network type) 5238 for specified subscription id 5239 5240 Args: 5241 ad: Android Device Object 5242 sub_id: subscription ID 5243 voice_or_data: Input parameter indicating to get voice network type or 5244 data network type. 5245 5246 Returns: 5247 Current voice/data network type. 5248 """ 5249 if voice_or_data == NETWORK_SERVICE_VOICE: 5250 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription( 5251 sub_id) 5252 elif voice_or_data == NETWORK_SERVICE_DATA: 5253 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription( 5254 sub_id) 5255 else: 5256 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id) 5257 5258 if ret_val is None: 5259 log.error("get_network_rat(): Unexpected null return value") 5260 return RAT_UNKNOWN 5261 else: 5262 return ret_val 5263 5264 5265def get_network_gen(log, ad, voice_or_data): 5266 """Get current network generation string (Voice network type, or data network type) 5267 5268 Args: 5269 ad: Android Device Object 5270 voice_or_data: Input parameter indicating to get voice network generation 5271 or data network generation. 5272 5273 Returns: 5274 Current voice/data network generation. 5275 """ 5276 return get_network_gen_for_subscription( 5277 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data) 5278 5279 5280def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data): 5281 """Get current network generation string (Voice network type, or data network type) 5282 5283 Args: 5284 ad: Android Device Object 5285 voice_or_data: Input parameter indicating to get voice network generation 5286 or data network generation. 5287 5288 Returns: 5289 Current voice/data network generation. 5290 """ 5291 try: 5292 return rat_generation_from_rat( 5293 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)) 5294 except KeyError as e: 5295 ad.log.error("KeyError %s", e) 5296 return GEN_UNKNOWN 5297 5298 5299def check_voice_mail_count(log, ad, voice_mail_count_before, 5300 voice_mail_count_after): 5301 """function to check if voice mail count is correct after leaving a new voice message. 5302 """ 5303 return get_voice_mail_count_check_function(get_operator_name(log, ad))( 5304 voice_mail_count_before, voice_mail_count_after) 5305 5306 5307def get_voice_mail_number(log, ad): 5308 """function to get the voice mail number 5309 """ 5310 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad)) 5311 if voice_mail_number is None: 5312 return get_phone_number(log, ad) 5313 return voice_mail_number 5314 5315 5316def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP): 5317 """Ensure ads idle (not in call). 5318 """ 5319 result = True 5320 for ad in ads: 5321 if not ensure_phone_idle(log, ad, max_time=max_time): 5322 result = False 5323 return result 5324 5325 5326def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP): 5327 """Ensure ad idle (not in call). 5328 """ 5329 if ad.droid.telecomIsInCall(): 5330 ad.droid.telecomEndCall() 5331 if not wait_for_droid_not_in_call(log, ad, max_time=max_time): 5332 ad.log.error("Failed to end call") 5333 return False 5334 return True 5335 5336 5337def ensure_phone_subscription(log, ad): 5338 """Ensure Phone Subscription. 5339 """ 5340 #check for sim and service 5341 duration = 0 5342 while duration < MAX_WAIT_TIME_NW_SELECTION: 5343 subInfo = ad.droid.subscriptionGetAllSubInfoList() 5344 if subInfo and len(subInfo) >= 1: 5345 ad.log.debug("Find valid subcription %s", subInfo) 5346 break 5347 else: 5348 ad.log.info("Did not find any subscription") 5349 time.sleep(5) 5350 duration += 5 5351 else: 5352 ad.log.error("Unable to find a valid subscription!") 5353 return False 5354 while duration < MAX_WAIT_TIME_NW_SELECTION: 5355 data_sub_id = ad.droid.subscriptionGetDefaultDataSubId() 5356 voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 5357 if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID: 5358 ad.log.debug("Find valid voice or data sub id") 5359 break 5360 else: 5361 ad.log.info("Did not find valid data or voice sub id") 5362 time.sleep(5) 5363 duration += 5 5364 else: 5365 ad.log.error("Unable to find valid data or voice sub id") 5366 return False 5367 while duration < MAX_WAIT_TIME_NW_SELECTION: 5368 data_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() 5369 if data_sub_id > INVALID_SUB_ID: 5370 data_rat = get_network_rat_for_subscription( 5371 log, ad, data_sub_id, NETWORK_SERVICE_DATA) 5372 else: 5373 data_rat = RAT_UNKNOWN 5374 if voice_sub_id > INVALID_SUB_ID: 5375 voice_rat = get_network_rat_for_subscription( 5376 log, ad, voice_sub_id, NETWORK_SERVICE_VOICE) 5377 else: 5378 voice_rat = RAT_UNKNOWN 5379 if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN: 5380 ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s", 5381 data_sub_id, data_rat, voice_sub_id, voice_rat) 5382 return True 5383 else: 5384 ad.log.info("Did not attach for data or voice service") 5385 time.sleep(5) 5386 duration += 5 5387 else: 5388 ad.log.error("Did not attach for voice or data service") 5389 return False 5390 5391 5392def ensure_phone_default_state(log, ad, check_subscription=True): 5393 """Ensure ad in default state. 5394 Phone not in call. 5395 Phone have no stored WiFi network and WiFi disconnected. 5396 Phone not in airplane mode. 5397 """ 5398 result = True 5399 if not toggle_airplane_mode(log, ad, False, False): 5400 ad.log.error("Fail to turn off airplane mode") 5401 result = False 5402 try: 5403 set_wifi_to_default(log, ad) 5404 if ad.droid.telecomIsInCall(): 5405 ad.droid.telecomEndCall() 5406 if not wait_for_droid_not_in_call(log, ad): 5407 ad.log.error("Failed to end call") 5408 ad.droid.telephonyFactoryReset() 5409 ad.droid.imsFactoryReset() 5410 data_roaming = getattr(ad, 'roaming', False) 5411 if get_cell_data_roaming_state_by_adb(ad) != data_roaming: 5412 set_cell_data_roaming_state_by_adb(ad, data_roaming) 5413 remove_mobile_data_usage_limit(ad) 5414 if not wait_for_not_network_rat( 5415 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA): 5416 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA, 5417 RAT_FAMILY_WLAN) 5418 result = False 5419 5420 if check_subscription and not ensure_phone_subscription(log, ad): 5421 ad.log.error("Unable to find a valid subscription!") 5422 result = False 5423 except Exception as e: 5424 ad.log.error("%s failure, toggle APM instead", e) 5425 toggle_airplane_mode_by_adb(log, ad, True) 5426 toggle_airplane_mode_by_adb(log, ad, False) 5427 ad.send_keycode("ENDCALL") 5428 ad.adb.shell("settings put global wfc_ims_enabled 0") 5429 ad.adb.shell("settings put global mobile_data 1") 5430 5431 return result 5432 5433 5434def ensure_phones_default_state(log, ads, check_subscription=True): 5435 """Ensure ads in default state. 5436 Phone not in call. 5437 Phone have no stored WiFi network and WiFi disconnected. 5438 Phone not in airplane mode. 5439 5440 Returns: 5441 True if all steps of restoring default state succeed. 5442 False if any of the steps to restore default state fails. 5443 """ 5444 tasks = [] 5445 for ad in ads: 5446 tasks.append((ensure_phone_default_state, (log, ad, 5447 check_subscription))) 5448 if not multithread_func(log, tasks): 5449 log.error("Ensure_phones_default_state Fail.") 5450 return False 5451 return True 5452 5453 5454def check_is_wifi_connected(log, ad, wifi_ssid): 5455 """Check if ad is connected to wifi wifi_ssid. 5456 5457 Args: 5458 log: Log object. 5459 ad: Android device object. 5460 wifi_ssid: WiFi network SSID. 5461 5462 Returns: 5463 True if wifi is connected to wifi_ssid 5464 False if wifi is not connected to wifi_ssid 5465 """ 5466 wifi_info = ad.droid.wifiGetConnectionInfo() 5467 if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid: 5468 ad.log.info("Wifi is connected to %s", wifi_ssid) 5469 ad.on_mobile_data = False 5470 return True 5471 else: 5472 ad.log.info("Wifi is not connected to %s", wifi_ssid) 5473 ad.log.debug("Wifi connection_info=%s", wifi_info) 5474 ad.on_mobile_data = True 5475 return False 5476 5477 5478def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3): 5479 """Ensure ad connected to wifi on network wifi_ssid. 5480 5481 Args: 5482 log: Log object. 5483 ad: Android device object. 5484 wifi_ssid: WiFi network SSID. 5485 wifi_pwd: optional secure network password. 5486 retries: the number of retries. 5487 5488 Returns: 5489 True if wifi is connected to wifi_ssid 5490 False if wifi is not connected to wifi_ssid 5491 """ 5492 network = {WIFI_SSID_KEY: wifi_ssid} 5493 if wifi_pwd: 5494 network[WIFI_PWD_KEY] = wifi_pwd 5495 for i in range(retries): 5496 if not ad.droid.wifiCheckState(): 5497 ad.log.info("Wifi state is down. Turn on Wifi") 5498 ad.droid.wifiToggleState(True) 5499 if check_is_wifi_connected(log, ad, wifi_ssid): 5500 ad.log.info("Wifi is connected to %s", wifi_ssid) 5501 return verify_internet_connection(log, ad, retries=3) 5502 else: 5503 ad.log.info("Connecting to wifi %s", wifi_ssid) 5504 try: 5505 ad.droid.wifiConnectByConfig(network) 5506 except Exception: 5507 ad.log.info("Connecting to wifi by wifiConnect instead") 5508 ad.droid.wifiConnect(network) 5509 time.sleep(20) 5510 if check_is_wifi_connected(log, ad, wifi_ssid): 5511 ad.log.info("Connected to Wifi %s", wifi_ssid) 5512 return verify_internet_connection(log, ad, retries=3) 5513 ad.log.info("Fail to connected to wifi %s", wifi_ssid) 5514 return False 5515 5516 5517def forget_all_wifi_networks(log, ad): 5518 """Forget all stored wifi network information 5519 5520 Args: 5521 log: log object 5522 ad: AndroidDevice object 5523 5524 Returns: 5525 boolean success (True) or failure (False) 5526 """ 5527 if not ad.droid.wifiGetConfiguredNetworks(): 5528 ad.on_mobile_data = True 5529 return True 5530 try: 5531 old_state = ad.droid.wifiCheckState() 5532 wifi_test_utils.reset_wifi(ad) 5533 wifi_toggle_state(log, ad, old_state) 5534 except Exception as e: 5535 log.error("forget_all_wifi_networks with exception: %s", e) 5536 return False 5537 ad.on_mobile_data = True 5538 return True 5539 5540 5541def wifi_reset(log, ad, disable_wifi=True): 5542 """Forget all stored wifi networks and (optionally) disable WiFi 5543 5544 Args: 5545 log: log object 5546 ad: AndroidDevice object 5547 disable_wifi: boolean to disable wifi, defaults to True 5548 Returns: 5549 boolean success (True) or failure (False) 5550 """ 5551 if not forget_all_wifi_networks(log, ad): 5552 ad.log.error("Unable to forget all networks") 5553 return False 5554 if not wifi_toggle_state(log, ad, not disable_wifi): 5555 ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi) 5556 return False 5557 return True 5558 5559 5560def set_wifi_to_default(log, ad): 5561 """Set wifi to default state (Wifi disabled and no configured network) 5562 5563 Args: 5564 log: log object 5565 ad: AndroidDevice object 5566 5567 Returns: 5568 boolean success (True) or failure (False) 5569 """ 5570 ad.droid.wifiFactoryReset() 5571 ad.droid.wifiToggleState(False) 5572 ad.on_mobile_data = True 5573 5574 5575def wifi_toggle_state(log, ad, state, retries=3): 5576 """Toggle the WiFi State 5577 5578 Args: 5579 log: log object 5580 ad: AndroidDevice object 5581 state: True, False, or None 5582 5583 Returns: 5584 boolean success (True) or failure (False) 5585 """ 5586 for i in range(retries): 5587 if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False): 5588 ad.on_mobile_data = not state 5589 return True 5590 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 5591 return False 5592 5593 5594def start_wifi_tethering(log, ad, ssid, password, ap_band=None): 5595 """Start a Tethering Session 5596 5597 Args: 5598 log: log object 5599 ad: AndroidDevice object 5600 ssid: the name of the WiFi network 5601 password: optional password, used for secure networks. 5602 ap_band=DEPRECATED specification of 2G or 5G tethering 5603 Returns: 5604 boolean success (True) or failure (False) 5605 """ 5606 return wifi_test_utils._assert_on_fail_handler( 5607 wifi_test_utils.start_wifi_tethering, 5608 False, 5609 ad, 5610 ssid, 5611 password, 5612 band=ap_band) 5613 5614 5615def stop_wifi_tethering(log, ad): 5616 """Stop a Tethering Session 5617 5618 Args: 5619 log: log object 5620 ad: AndroidDevice object 5621 Returns: 5622 boolean success (True) or failure (False) 5623 """ 5624 return wifi_test_utils._assert_on_fail_handler( 5625 wifi_test_utils.stop_wifi_tethering, False, ad) 5626 5627 5628def reset_preferred_network_type_to_allowable_range(log, ad): 5629 """If preferred network type is not in allowable range, reset to GEN_4G 5630 preferred network type. 5631 5632 Args: 5633 log: log object 5634 ad: android device object 5635 5636 Returns: 5637 None 5638 """ 5639 for sub_id, sub_info in ad.telephony["subscription"].items(): 5640 current_preference = \ 5641 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id) 5642 ad.log.debug("sub_id network preference is %s", current_preference) 5643 try: 5644 if current_preference not in get_allowable_network_preference( 5645 sub_info["operator"], sub_info["phone_type"]): 5646 network_preference = network_preference_for_generation( 5647 GEN_4G, sub_info["operator"], sub_info["phone_type"]) 5648 ad.droid.telephonySetPreferredNetworkTypesForSubscription( 5649 network_preference, sub_id) 5650 except KeyError: 5651 pass 5652 5653 5654def task_wrapper(task): 5655 """Task wrapper for multithread_func 5656 5657 Args: 5658 task[0]: function to be wrapped. 5659 task[1]: function args. 5660 5661 Returns: 5662 Return value of wrapped function call. 5663 """ 5664 func = task[0] 5665 params = task[1] 5666 return func(*params) 5667 5668 5669def run_multithread_func_async(log, task): 5670 """Starts a multi-threaded function asynchronously. 5671 5672 Args: 5673 log: log object. 5674 task: a task to be executed in parallel. 5675 5676 Returns: 5677 Future object representing the execution of the task. 5678 """ 5679 executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) 5680 try: 5681 future_object = executor.submit(task_wrapper, task) 5682 except Exception as e: 5683 log.error("Exception error %s", e) 5684 raise 5685 return future_object 5686 5687 5688def run_multithread_func(log, tasks): 5689 """Run multi-thread functions and return results. 5690 5691 Args: 5692 log: log object. 5693 tasks: a list of tasks to be executed in parallel. 5694 5695 Returns: 5696 results for tasks. 5697 """ 5698 MAX_NUMBER_OF_WORKERS = 10 5699 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks)) 5700 executor = concurrent.futures.ThreadPoolExecutor( 5701 max_workers=number_of_workers) 5702 if not log: log = logging 5703 try: 5704 results = list(executor.map(task_wrapper, tasks)) 5705 except Exception as e: 5706 log.error("Exception error %s", e) 5707 raise 5708 executor.shutdown() 5709 if log: 5710 log.info("multithread_func %s result: %s", 5711 [task[0].__name__ for task in tasks], results) 5712 return results 5713 5714 5715def multithread_func(log, tasks): 5716 """Multi-thread function wrapper. 5717 5718 Args: 5719 log: log object. 5720 tasks: tasks to be executed in parallel. 5721 5722 Returns: 5723 True if all tasks return True. 5724 False if any task return False. 5725 """ 5726 results = run_multithread_func(log, tasks) 5727 for r in results: 5728 if not r: 5729 return False 5730 return True 5731 5732 5733def multithread_func_and_check_results(log, tasks, expected_results): 5734 """Multi-thread function wrapper. 5735 5736 Args: 5737 log: log object. 5738 tasks: tasks to be executed in parallel. 5739 expected_results: check if the results from tasks match expected_results. 5740 5741 Returns: 5742 True if expected_results are met. 5743 False if expected_results are not met. 5744 """ 5745 return_value = True 5746 results = run_multithread_func(log, tasks) 5747 log.info("multithread_func result: %s, expecting %s", results, 5748 expected_results) 5749 for task, result, expected_result in zip(tasks, results, expected_results): 5750 if result != expected_result: 5751 logging.info("Result for task %s is %s, expecting %s", task[0], 5752 result, expected_result) 5753 return_value = False 5754 return return_value 5755 5756 5757def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME): 5758 """Set phone screen on time. 5759 5760 Args: 5761 log: Log object. 5762 ad: Android device object. 5763 screen_on_time: screen on time. 5764 This is optional, default value is MAX_SCREEN_ON_TIME. 5765 Returns: 5766 True if set successfully. 5767 """ 5768 ad.droid.setScreenTimeout(screen_on_time) 5769 return screen_on_time == ad.droid.getScreenTimeout() 5770 5771 5772def set_phone_silent_mode(log, ad, silent_mode=True): 5773 """Set phone silent mode. 5774 5775 Args: 5776 log: Log object. 5777 ad: Android device object. 5778 silent_mode: set phone silent or not. 5779 This is optional, default value is True (silent mode on). 5780 Returns: 5781 True if set successfully. 5782 """ 5783 ad.droid.toggleRingerSilentMode(silent_mode) 5784 ad.droid.setMediaVolume(0) 5785 ad.droid.setVoiceCallVolume(0) 5786 ad.droid.setAlarmVolume(0) 5787 ad.adb.ensure_root() 5788 ad.adb.shell("setprop ro.audio.silent 1", ignore_status=True) 5789 return silent_mode == ad.droid.checkRingerSilentMode() 5790 5791 5792def set_preferred_network_mode_pref(log, 5793 ad, 5794 sub_id, 5795 network_preference, 5796 timeout=WAIT_TIME_ANDROID_STATE_SETTLING): 5797 """Set Preferred Network Mode for Sub_id 5798 Args: 5799 log: Log object. 5800 ad: Android device object. 5801 sub_id: Subscription ID. 5802 network_preference: Network Mode Type 5803 """ 5804 begin_time = get_device_epoch_time(ad) 5805 if ad.droid.telephonyGetPreferredNetworkTypesForSubscription( 5806 sub_id) == network_preference: 5807 ad.log.info("Current ModePref for Sub %s is in %s", sub_id, 5808 network_preference) 5809 return True 5810 ad.log.info("Setting ModePref to %s for Sub %s", network_preference, 5811 sub_id) 5812 while timeout >= 0: 5813 if ad.droid.telephonySetPreferredNetworkTypesForSubscription( 5814 network_preference, sub_id): 5815 return True 5816 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 5817 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 5818 error_msg = "Failed to set sub_id %s PreferredNetworkType to %s" % ( 5819 sub_id, network_preference) 5820 search_results = ad.search_logcat( 5821 "REQUEST_SET_PREFERRED_NETWORK_TYPE error", begin_time=begin_time) 5822 if search_results: 5823 log_message = search_results[-1]["log_message"] 5824 if "DEVICE_IN_USE" in log_message: 5825 error_msg = "%s due to DEVICE_IN_USE" % error_msg 5826 else: 5827 error_msg = "%s due to %s" % (error_msg, log_message) 5828 ad.log.error(error_msg) 5829 return False 5830 5831 5832def set_preferred_subid_for_sms(log, ad, sub_id): 5833 """set subscription id for SMS 5834 5835 Args: 5836 log: Log object. 5837 ad: Android device object. 5838 sub_id :Subscription ID. 5839 5840 """ 5841 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id) 5842 ad.droid.subscriptionSetDefaultSmsSubId(sub_id) 5843 # Wait to make sure settings take effect 5844 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 5845 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId() 5846 5847 5848def set_preferred_subid_for_data(log, ad, sub_id): 5849 """set subscription id for data 5850 5851 Args: 5852 log: Log object. 5853 ad: Android device object. 5854 sub_id :Subscription ID. 5855 5856 """ 5857 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id) 5858 ad.droid.subscriptionSetDefaultDataSubId(sub_id) 5859 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 5860 # Wait to make sure settings take effect 5861 # Data SIM change takes around 1 min 5862 # Check whether data has changed to selected sim 5863 if not wait_for_data_connection(log, ad, True, 5864 MAX_WAIT_TIME_DATA_SUB_CHANGE): 5865 log.error("Data Connection failed - Not able to switch Data SIM") 5866 return False 5867 return True 5868 5869 5870def set_preferred_subid_for_voice(log, ad, sub_id): 5871 """set subscription id for voice 5872 5873 Args: 5874 log: Log object. 5875 ad: Android device object. 5876 sub_id :Subscription ID. 5877 5878 """ 5879 ad.log.info("Setting subscription %s as Voice SIM", sub_id) 5880 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id) 5881 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id) 5882 # Wait to make sure settings take effect 5883 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 5884 return True 5885 5886 5887def set_call_state_listen_level(log, ad, value, sub_id): 5888 """Set call state listen level for subscription id. 5889 5890 Args: 5891 log: Log object. 5892 ad: Android device object. 5893 value: True or False 5894 sub_id :Subscription ID. 5895 5896 Returns: 5897 True or False 5898 """ 5899 if sub_id == INVALID_SUB_ID: 5900 log.error("Invalid Subscription ID") 5901 return False 5902 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 5903 "Foreground", value, sub_id) 5904 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 5905 "Ringing", value, sub_id) 5906 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription( 5907 "Background", value, sub_id) 5908 return True 5909 5910 5911def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False): 5912 """set subscription id for voice, sms and data 5913 5914 Args: 5915 log: Log object. 5916 ad: Android device object. 5917 sub_id :Subscription ID. 5918 voice: True if to set subscription as default voice subscription 5919 sms: True if to set subscription as default sms subscription 5920 data: True if to set subscription as default data subscription 5921 5922 """ 5923 if sub_id == INVALID_SUB_ID: 5924 log.error("Invalid Subscription ID") 5925 return False 5926 else: 5927 if voice: 5928 if not set_preferred_subid_for_voice(log, ad, sub_id): 5929 return False 5930 if sms: 5931 if not set_preferred_subid_for_sms(log, ad, sub_id): 5932 return False 5933 if data: 5934 if not set_preferred_subid_for_data(log, ad, sub_id): 5935 return False 5936 return True 5937 5938 5939def is_event_match(event, field, value): 5940 """Return if <field> in "event" match <value> or not. 5941 5942 Args: 5943 event: event to test. This event need to have <field>. 5944 field: field to match. 5945 value: value to match. 5946 5947 Returns: 5948 True if <field> in "event" match <value>. 5949 False otherwise. 5950 """ 5951 return is_event_match_for_list(event, field, [value]) 5952 5953 5954def is_event_match_for_list(event, field, value_list): 5955 """Return if <field> in "event" match any one of the value 5956 in "value_list" or not. 5957 5958 Args: 5959 event: event to test. This event need to have <field>. 5960 field: field to match. 5961 value_list: a list of value to match. 5962 5963 Returns: 5964 True if <field> in "event" match one of the value in "value_list". 5965 False otherwise. 5966 """ 5967 try: 5968 value_in_event = event['data'][field] 5969 except KeyError: 5970 return False 5971 for value in value_list: 5972 if value_in_event == value: 5973 return True 5974 return False 5975 5976 5977def is_network_call_back_event_match(event, network_callback_id, 5978 network_callback_event): 5979 try: 5980 return ( 5981 (network_callback_id == event['data'][NetworkCallbackContainer.ID]) 5982 and (network_callback_event == event['data'] 5983 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT])) 5984 except KeyError: 5985 return False 5986 5987 5988def is_build_id(log, ad, build_id): 5989 """Return if ad's build id is the same as input parameter build_id. 5990 5991 Args: 5992 log: log object. 5993 ad: android device object. 5994 build_id: android build id. 5995 5996 Returns: 5997 True if ad's build id is the same as input parameter build_id. 5998 False otherwise. 5999 """ 6000 actual_bid = ad.droid.getBuildID() 6001 6002 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay()) 6003 #In case we want to log more stuff/more granularity... 6004 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID())) 6005 #log.info("{} BUILD FINGERPRINT: {} " 6006 # .format(ad.serial), ad.droid.getBuildFingerprint()) 6007 #log.info("{} BUILD TYPE: {} " 6008 # .format(ad.serial), ad.droid.getBuildType()) 6009 #log.info("{} BUILD NUMBER: {} " 6010 # .format(ad.serial), ad.droid.getBuildNumber()) 6011 if actual_bid.upper() != build_id.upper(): 6012 ad.log.error("%s: Incorrect Build ID", ad.model) 6013 return False 6014 return True 6015 6016 6017def is_uri_equivalent(uri1, uri2): 6018 """Check whether two input uris match or not. 6019 6020 Compare Uris. 6021 If Uris are tel URI, it will only take the digit part 6022 and compare as phone number. 6023 Else, it will just do string compare. 6024 6025 Args: 6026 uri1: 1st uri to be compared. 6027 uri2: 2nd uri to be compared. 6028 6029 Returns: 6030 True if two uris match. Otherwise False. 6031 """ 6032 6033 #If either is None/empty we return false 6034 if not uri1 or not uri2: 6035 return False 6036 6037 try: 6038 if uri1.startswith('tel:') and uri2.startswith('tel:'): 6039 uri1_number = get_number_from_tel_uri(uri1) 6040 uri2_number = get_number_from_tel_uri(uri2) 6041 return check_phone_number_match(uri1_number, uri2_number) 6042 else: 6043 return uri1 == uri2 6044 except AttributeError as e: 6045 return False 6046 6047 6048def get_call_uri(ad, call_id): 6049 """Get call's uri field. 6050 6051 Get Uri for call_id in ad. 6052 6053 Args: 6054 ad: android device object. 6055 call_id: the call id to get Uri from. 6056 6057 Returns: 6058 call's Uri if call is active and have uri field. None otherwise. 6059 """ 6060 try: 6061 call_detail = ad.droid.telecomCallGetDetails(call_id) 6062 return call_detail["Handle"]["Uri"] 6063 except: 6064 return None 6065 6066 6067def get_number_from_tel_uri(uri): 6068 """Get Uri number from tel uri 6069 6070 Args: 6071 uri: input uri 6072 6073 Returns: 6074 If input uri is tel uri, return the number part. 6075 else return None. 6076 """ 6077 if uri.startswith('tel:'): 6078 uri_number = ''.join( 6079 i for i in urllib.parse.unquote(uri) if i.isdigit()) 6080 return uri_number 6081 else: 6082 return None 6083 6084 6085def find_qxdm_log_mask(ad, mask="default.cfg"): 6086 """Find QXDM logger mask.""" 6087 if "/" not in mask: 6088 # Call nexuslogger to generate log mask 6089 start_nexuslogger(ad) 6090 # Find the log mask path 6091 for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs", 6092 "/vendor/etc/mdlog/"): 6093 out = ad.adb.shell( 6094 "find %s -type f -iname %s" % (path, mask), ignore_status=True) 6095 if out and "No such" not in out and "Permission denied" not in out: 6096 if path.startswith("/vendor/"): 6097 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH) 6098 else: 6099 setattr(ad, "qxdm_log_path", path) 6100 return out.split("\n")[0] 6101 if mask in ad.adb.shell("ls /vendor/etc/mdlog/"): 6102 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH) 6103 return "%s/%s" % ("/vendor/etc/mdlog/", mask) 6104 else: 6105 out = ad.adb.shell("ls %s" % mask, ignore_status=True) 6106 if out and "No such" not in out: 6107 qxdm_log_path, cfg_name = os.path.split(mask) 6108 setattr(ad, "qxdm_log_path", qxdm_log_path) 6109 return mask 6110 ad.log.warning("Could NOT find QXDM logger mask path for %s", mask) 6111 6112 6113def set_qxdm_logger_command(ad, mask=None): 6114 """Set QXDM logger always on. 6115 6116 Args: 6117 ad: android device object. 6118 6119 """ 6120 ## Neet to check if log mask will be generated without starting nexus logger 6121 masks = [] 6122 mask_path = None 6123 if mask: 6124 masks = [mask] 6125 masks.extend(["QC_Default.cfg", "default.cfg"]) 6126 for mask in masks: 6127 mask_path = find_qxdm_log_mask(ad, mask) 6128 if mask_path: break 6129 if not mask_path: 6130 ad.log.error("Cannot find QXDM mask %s", mask) 6131 ad.qxdm_logger_command = None 6132 return False 6133 else: 6134 ad.log.info("Use QXDM log mask %s", mask_path) 6135 ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path) 6136 output_path = os.path.join(ad.qxdm_log_path, "logs") 6137 ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 90 -c" % 6138 (mask_path, output_path)) 6139 for prop in ("persist.sys.modem.diag.mdlog", 6140 "persist.vendor.sys.modem.diag.mdlog"): 6141 if ad.adb.getprop(prop): 6142 # Enable qxdm always on if supported 6143 for conf_path in ("/data/vendor/radio/diag_logs", 6144 "/vendor/etc/mdlog"): 6145 if "diag.conf" in ad.adb.shell( 6146 "ls %s" % conf_path, ignore_status=True): 6147 conf_path = "%s/diag.conf" % conf_path 6148 ad.adb.shell('echo "%s" > %s' % 6149 (ad.qxdm_logger_command, conf_path)) 6150 break 6151 ad.adb.shell("setprop %s true" % prop, ignore_status=True) 6152 break 6153 return True 6154 6155 6156def stop_qxdm_logger(ad): 6157 """Stop QXDM logger.""" 6158 for cmd in ("diag_mdlog -k", "killall diag_mdlog"): 6159 output = ad.adb.shell("ps -ef | grep mdlog") or "" 6160 if "diag_mdlog" not in output: 6161 break 6162 ad.log.debug("Kill the existing qxdm process") 6163 ad.adb.shell(cmd, ignore_status=True) 6164 time.sleep(5) 6165 6166 6167def start_qxdm_logger(ad, begin_time=None): 6168 """Start QXDM logger.""" 6169 if not getattr(ad, "qxdm_log", True): return 6170 # Delete existing QXDM logs 5 minutes earlier than the begin_time 6171 current_time = get_current_epoch_time() 6172 if getattr(ad, "qxdm_log_path", None): 6173 seconds = None 6174 file_count = ad.adb.shell( 6175 "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path) 6176 if int(file_count) > 50: 6177 if begin_time: 6178 # if begin_time specified, delete old qxdm logs modified 6179 # 10 minutes before begin time 6180 seconds = int((current_time - begin_time) / 1000.0) + 10 * 60 6181 else: 6182 # if begin_time is not specified, delete old qxdm logs modified 6183 # 15 minutes before current time 6184 seconds = 15 * 60 6185 if seconds: 6186 # Remove qxdm logs modified more than specified seconds ago 6187 ad.adb.shell( 6188 "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" % 6189 (ad.qxdm_log_path, seconds)) 6190 ad.adb.shell( 6191 "find %s -type f -iname *.xml -not -mtime -%ss -delete" % 6192 (ad.qxdm_log_path, seconds)) 6193 if getattr(ad, "qxdm_logger_command", None): 6194 output = ad.adb.shell("ps -ef | grep mdlog") or "" 6195 if ad.qxdm_logger_command not in output: 6196 ad.log.debug("QXDM logging command %s is not running", 6197 ad.qxdm_logger_command) 6198 if "diag_mdlog" in output: 6199 # Kill the existing non-matching diag_mdlog process 6200 # Only one diag_mdlog process can be run 6201 stop_qxdm_logger(ad) 6202 ad.log.info("Start QXDM logger") 6203 ad.adb.shell_nb(ad.qxdm_logger_command) 6204 time.sleep(10) 6205 else: 6206 run_time = check_qxdm_logger_run_time(ad) 6207 if run_time < 600: 6208 # the last diag_mdlog started within 10 minutes ago 6209 # no need to restart 6210 return True 6211 if ad.search_logcat( 6212 "Diag_Lib: diag: In delete_log", 6213 begin_time=current_time - 6214 run_time) or not ad.get_file_names( 6215 ad.qxdm_log_path, 6216 begin_time=current_time - 600000, 6217 match_string="*.qmdl"): 6218 # diag_mdlog starts deleting files or no qmdl logs were 6219 # modified in the past 10 minutes 6220 ad.log.debug("Quit existing diag_mdlog and start a new one") 6221 stop_qxdm_logger(ad) 6222 ad.adb.shell_nb(ad.qxdm_logger_command) 6223 time.sleep(10) 6224 return True 6225 6226 6227def disable_qxdm_logger(ad): 6228 for prop in ("persist.sys.modem.diag.mdlog", 6229 "persist.vendor.sys.modem.diag.mdlog", 6230 "vendor.sys.modem.diag.mdlog_on"): 6231 if ad.adb.getprop(prop): 6232 ad.adb.shell("setprop %s false" % prop, ignore_status=True) 6233 for apk in ("com.android.nexuslogger", "com.android.pixellogger"): 6234 if ad.is_apk_installed(apk) and ad.is_apk_running(apk): 6235 ad.force_stop_apk(apk) 6236 stop_qxdm_logger(ad) 6237 return True 6238 6239 6240def check_qxdm_logger_run_time(ad): 6241 output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog") 6242 result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output) 6243 if result: 6244 return int(result.group(1)) * 60 * 60 + int( 6245 result.group(2)) * 60 + int(result.group(3)) 6246 else: 6247 result = re.search(r"(\d+):(\d+) diag_mdlog", output) 6248 if result: 6249 return int(result.group(1)) * 60 + int(result.group(2)) 6250 else: 6251 return 0 6252 6253 6254def start_qxdm_loggers(log, ads, begin_time=None): 6255 tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads 6256 if getattr(ad, "qxdm_log", True)] 6257 if tasks: run_multithread_func(log, tasks) 6258 6259 6260def stop_qxdm_loggers(log, ads): 6261 tasks = [(stop_qxdm_logger, [ad]) for ad in ads] 6262 run_multithread_func(log, tasks) 6263 6264 6265def start_nexuslogger(ad): 6266 """Start Nexus/Pixel Logger Apk.""" 6267 qxdm_logger_apk = None 6268 for apk, activity in (("com.android.nexuslogger", ".MainActivity"), 6269 ("com.android.pixellogger", 6270 ".ui.main.MainActivity")): 6271 if ad.is_apk_installed(apk): 6272 qxdm_logger_apk = apk 6273 break 6274 if not qxdm_logger_apk: return 6275 if ad.is_apk_running(qxdm_logger_apk): 6276 if "granted=true" in ad.adb.shell( 6277 "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk): 6278 return True 6279 else: 6280 ad.log.info("Kill %s" % qxdm_logger_apk) 6281 ad.force_stop_apk(qxdm_logger_apk) 6282 time.sleep(5) 6283 for perm in ("READ", "WRITE"): 6284 ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" % 6285 (qxdm_logger_apk, perm)) 6286 time.sleep(2) 6287 for i in range(3): 6288 ad.unlock_screen() 6289 ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1)) 6290 ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity)) 6291 time.sleep(5) 6292 if ad.is_apk_running(qxdm_logger_apk): 6293 ad.send_keycode("HOME") 6294 return True 6295 return False 6296 6297 6298def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"): 6299 """Check if QXDM logger always on is set. 6300 6301 Args: 6302 ad: android device object. 6303 6304 """ 6305 output = ad.adb.shell( 6306 "ls /data/vendor/radio/diag_logs/", ignore_status=True) 6307 if not output or "No such" in output: 6308 return True 6309 if mask_file not in ad.adb.shell( 6310 "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True): 6311 return False 6312 return True 6313 6314 6315def start_tcpdumps(ads, 6316 test_name="", 6317 begin_time=None, 6318 interface="any", 6319 mask="all"): 6320 for ad in ads: 6321 try: 6322 start_adb_tcpdump( 6323 ad, 6324 test_name=test_name, 6325 begin_time=begin_time, 6326 interface=interface, 6327 mask=mask) 6328 except Exception as e: 6329 ad.log.warning("Fail to start tcpdump due to %s", e) 6330 6331 6332def start_adb_tcpdump(ad, 6333 test_name="", 6334 begin_time=None, 6335 interface="any", 6336 mask="all"): 6337 """Start tcpdump on any iface 6338 6339 Args: 6340 ad: android device object. 6341 test_name: tcpdump file name will have this 6342 6343 """ 6344 out = ad.adb.shell("ls -l /data/local/tmp/tcpdump/") 6345 if "No such file" in out or not out: 6346 ad.adb.shell("mkdir /data/local/tmp/tcpdump") 6347 else: 6348 ad.adb.shell( 6349 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete") 6350 ad.adb.shell( 6351 "find /data/local/tmp/tcpdump -type f -size +5G -delete") 6352 6353 if not begin_time: 6354 begin_time = get_current_epoch_time() 6355 6356 out = ad.adb.shell( 6357 'ifconfig | grep -v -E "r_|-rmnet" | grep -E "lan|data"', 6358 ignore_status=True, 6359 timeout=180) 6360 intfs = re.findall(r"(\S+).*", out) 6361 if interface and interface not in ("any", "all"): 6362 if interface not in intfs: return 6363 intfs = [interface] 6364 6365 out = ad.adb.shell("ps -ef | grep tcpdump") 6366 cmds = [] 6367 for intf in intfs: 6368 if intf in out: 6369 ad.log.info("tcpdump on interface %s is already running", intf) 6370 continue 6371 else: 6372 log_file_name = "/data/local/tmp/tcpdump/tcpdump_%s_%s_%s_%s.pcap" \ 6373 % (ad.serial, intf, test_name, begin_time) 6374 if mask == "ims": 6375 cmds.append( 6376 "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or " 6377 "udp port 4500 -w %s" % (ad.serial, intf, log_file_name)) 6378 else: 6379 cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" % 6380 (ad.serial, intf, log_file_name)) 6381 for cmd in cmds: 6382 ad.log.info(cmd) 6383 try: 6384 start_standing_subprocess(cmd, 10) 6385 except Exception as e: 6386 ad.log.error(e) 6387 if cmds: 6388 time.sleep(5) 6389 6390 6391def stop_tcpdumps(ads): 6392 for ad in ads: 6393 stop_adb_tcpdump(ad) 6394 6395 6396def stop_adb_tcpdump(ad, interface="any"): 6397 """Stops tcpdump on any iface 6398 Pulls the tcpdump file in the tcpdump dir 6399 6400 Args: 6401 ad: android device object. 6402 6403 """ 6404 if interface == "any": 6405 try: 6406 ad.adb.shell("killall -9 tcpdump") 6407 except Exception as e: 6408 ad.log.error("Killing tcpdump with exception %s", e) 6409 else: 6410 out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface) 6411 if "tcpdump -i" in out: 6412 pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out) 6413 for pid in pids: 6414 ad.adb.shell("kill -9 %s" % pid) 6415 ad.adb.shell( 6416 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete") 6417 6418 6419def get_tcpdump_log(ad, test_name="", begin_time=None): 6420 """Stops tcpdump on any iface 6421 Pulls the tcpdump file in the tcpdump dir 6422 6423 Args: 6424 ad: android device object. 6425 test_name: test case name 6426 begin_time: test begin time 6427 """ 6428 logs = ad.get_file_names("/data/local/tmp/tcpdump", begin_time=begin_time) 6429 if logs: 6430 ad.log.info("Pulling tcpdumps %s", logs) 6431 log_path = os.path.join(ad.device_log_path, "TCPDUMP_%s" % ad.serial) 6432 utils.create_dir(log_path) 6433 ad.pull_files(logs, log_path) 6434 return True 6435 6436 6437def fastboot_wipe(ad, skip_setup_wizard=True): 6438 """Wipe the device in fastboot mode. 6439 6440 Pull sl4a apk from device. Terminate all sl4a sessions, 6441 Reboot the device to bootloader, wipe the device by fastboot. 6442 Reboot the device. wait for device to complete booting 6443 Re-intall and start an sl4a session. 6444 """ 6445 status = True 6446 # Pull sl4a apk from device 6447 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME) 6448 result = re.search(r"package:(.*)", out) 6449 if not result: 6450 ad.log.error("Couldn't find sl4a apk") 6451 else: 6452 sl4a_apk = result.group(1) 6453 ad.log.info("Get sl4a apk from %s", sl4a_apk) 6454 ad.pull_files([sl4a_apk], "/tmp/") 6455 ad.stop_services() 6456 attemps = 3 6457 for i in range(1, attemps + 1): 6458 try: 6459 if ad.serial in list_adb_devices(): 6460 ad.log.info("Reboot to bootloader") 6461 ad.adb.reboot("bootloader", ignore_status=True) 6462 time.sleep(10) 6463 if ad.serial in list_fastboot_devices(): 6464 ad.log.info("Wipe in fastboot") 6465 ad.fastboot._w(timeout=300, ignore_status=True) 6466 time.sleep(30) 6467 ad.log.info("Reboot in fastboot") 6468 ad.fastboot.reboot() 6469 ad.wait_for_boot_completion() 6470 ad.root_adb() 6471 if ad.skip_sl4a: 6472 break 6473 if ad.is_sl4a_installed(): 6474 break 6475 ad.log.info("Re-install sl4a") 6476 ad.adb.shell("settings put global package_verifier_enable 0") 6477 ad.adb.install("-r /tmp/base.apk") 6478 time.sleep(10) 6479 break 6480 except Exception as e: 6481 ad.log.warning(e) 6482 if i == attemps: 6483 abort_all_tests(log, str(e)) 6484 time.sleep(5) 6485 try: 6486 ad.start_adb_logcat() 6487 except: 6488 ad.log.error("Failed to start adb logcat!") 6489 if skip_setup_wizard: 6490 ad.exit_setup_wizard() 6491 if getattr(ad, "qxdm_log", True): 6492 set_qxdm_logger_command(ad, mask=getattr(ad, "qxdm_log_mask", None)) 6493 start_qxdm_logger(ad) 6494 if ad.skip_sl4a: return status 6495 bring_up_sl4a(ad) 6496 synchronize_device_time(ad) 6497 set_phone_silent_mode(ad.log, ad) 6498 # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 & 6499 # b/122327716 6500 activate_wfc_on_device(ad.log, ad) 6501 return status 6502 6503def install_carriersettings_apk(ad, carriersettingsapk, skip_setup_wizard=True): 6504 """ Carrier Setting Installation Steps 6505 6506 Pull sl4a apk from device. Terminate all sl4a sessions, 6507 Reboot the device to bootloader, wipe the device by fastboot. 6508 Reboot the device. wait for device to complete booting 6509 """ 6510 status = True 6511 if carriersettingsapk is None: 6512 ad.log.warning("CarrierSettingsApk is not provided, aborting") 6513 return False 6514 ad.log.info("Push carriersettings apk to the Android device.") 6515 android_apk_path = "/product/priv-app/CarrierSettings/CarrierSettings.apk" 6516 ad.adb.push("%s %s" % (carriersettingsapk, android_apk_path)) 6517 ad.stop_services() 6518 6519 attempts = 3 6520 for i in range(1, attempts + 1): 6521 try: 6522 if ad.serial in list_adb_devices(): 6523 ad.log.info("Reboot to bootloader") 6524 ad.adb.reboot("bootloader", ignore_status=True) 6525 time.sleep(30) 6526 if ad.serial in list_fastboot_devices(): 6527 ad.log.info("Reboot in fastboot") 6528 ad.fastboot.reboot() 6529 ad.wait_for_boot_completion() 6530 ad.root_adb() 6531 if ad.is_sl4a_installed(): 6532 break 6533 time.sleep(10) 6534 break 6535 except Exception as e: 6536 ad.log.warning(e) 6537 if i == attempts: 6538 abort_all_tests(log, str(e)) 6539 time.sleep(5) 6540 try: 6541 ad.start_adb_logcat() 6542 except: 6543 ad.log.error("Failed to start adb logcat!") 6544 if skip_setup_wizard: 6545 ad.exit_setup_wizard() 6546 return status 6547 6548 6549def bring_up_sl4a(ad, attemps=3): 6550 for i in range(attemps): 6551 try: 6552 droid, ed = ad.get_droid() 6553 ed.start() 6554 ad.log.info("Brought up new sl4a session") 6555 break 6556 except Exception as e: 6557 if i < attemps - 1: 6558 ad.log.info(e) 6559 time.sleep(10) 6560 else: 6561 ad.log.error(e) 6562 raise 6563 6564 6565def reboot_device(ad, recover_sim_state=True): 6566 sim_state = is_sim_ready(ad.log, ad) 6567 ad.reboot() 6568 if ad.qxdm_log: 6569 start_qxdm_logger(ad) 6570 ad.unlock_screen() 6571 if recover_sim_state: 6572 if not unlock_sim(ad): 6573 ad.log.error("Unable to unlock SIM") 6574 return False 6575 if sim_state and not _wait_for_droid_in_state( 6576 log, ad, MAX_WAIT_TIME_FOR_STATE_CHANGE, is_sim_ready): 6577 ad.log.error("Sim state didn't reach pre-reboot ready state") 6578 return False 6579 return True 6580 6581 6582def unlocking_device(ad, device_password=None): 6583 """First unlock device attempt, required after reboot""" 6584 ad.unlock_screen(device_password) 6585 time.sleep(2) 6586 ad.adb.wait_for_device(timeout=180) 6587 if not ad.is_waiting_for_unlock_pin(): 6588 return True 6589 else: 6590 ad.unlock_screen(device_password) 6591 time.sleep(2) 6592 ad.adb.wait_for_device(timeout=180) 6593 if ad.wait_for_window_ready(): 6594 return True 6595 ad.log.error("Unable to unlock to user window") 6596 return False 6597 6598 6599def refresh_sl4a_session(ad): 6600 try: 6601 ad.droid.logI("Checking SL4A connection") 6602 ad.log.debug("Existing sl4a session is active") 6603 return True 6604 except Exception as e: 6605 ad.log.warning("Existing sl4a session is NOT active: %s", e) 6606 try: 6607 ad.terminate_all_sessions() 6608 except Exception as e: 6609 ad.log.info("terminate_all_sessions with error %s", e) 6610 ad.ensure_screen_on() 6611 ad.log.info("Open new sl4a connection") 6612 bring_up_sl4a(ad) 6613 6614 6615def reset_device_password(ad, device_password=None): 6616 # Enable or Disable Device Password per test bed config 6617 unlock_sim(ad) 6618 screen_lock = ad.is_screen_lock_enabled() 6619 if device_password: 6620 try: 6621 refresh_sl4a_session(ad) 6622 ad.droid.setDevicePassword(device_password) 6623 except Exception as e: 6624 ad.log.warning("setDevicePassword failed with %s", e) 6625 try: 6626 ad.droid.setDevicePassword(device_password, "1111") 6627 except Exception as e: 6628 ad.log.warning( 6629 "setDevicePassword providing previous password error: %s", 6630 e) 6631 time.sleep(2) 6632 if screen_lock: 6633 # existing password changed 6634 return 6635 else: 6636 # enable device password and log in for the first time 6637 ad.log.info("Enable device password") 6638 ad.adb.wait_for_device(timeout=180) 6639 else: 6640 if not screen_lock: 6641 # no existing password, do not set password 6642 return 6643 else: 6644 # password is enabled on the device 6645 # need to disable the password and log in on the first time 6646 # with unlocking with a swipe 6647 ad.log.info("Disable device password") 6648 ad.unlock_screen(password="1111") 6649 refresh_sl4a_session(ad) 6650 ad.ensure_screen_on() 6651 try: 6652 ad.droid.disableDevicePassword() 6653 except Exception as e: 6654 ad.log.warning("disableDevicePassword failed with %s", e) 6655 fastboot_wipe(ad) 6656 time.sleep(2) 6657 ad.adb.wait_for_device(timeout=180) 6658 refresh_sl4a_session(ad) 6659 if not ad.is_adb_logcat_on: 6660 ad.start_adb_logcat() 6661 6662 6663def get_sim_state(ad): 6664 try: 6665 state = ad.droid.telephonyGetSimState() 6666 except Exception as e: 6667 ad.log.error(e) 6668 state = ad.adb.getprop("gsm.sim.state") 6669 return state 6670 6671 6672def is_sim_locked(ad): 6673 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED 6674 6675 6676def is_sim_lock_enabled(ad): 6677 # TODO: add sl4a fascade to check if sim is locked 6678 return getattr(ad, "is_sim_locked", False) 6679 6680 6681def unlock_sim(ad): 6682 #The puk and pin can be provided in testbed config file. 6683 #"AndroidDevice": [{"serial": "84B5T15A29018214", 6684 # "adb_logcat_param": "-b all", 6685 # "puk": "12345678", 6686 # "puk_pin": "1234"}] 6687 if not is_sim_locked(ad): 6688 return True 6689 else: 6690 ad.is_sim_locked = True 6691 puk_pin = getattr(ad, "puk_pin", "1111") 6692 try: 6693 if not hasattr(ad, 'puk'): 6694 ad.log.info("Enter SIM pin code") 6695 ad.droid.telephonySupplyPin(puk_pin) 6696 else: 6697 ad.log.info("Enter PUK code and pin") 6698 ad.droid.telephonySupplyPuk(ad.puk, puk_pin) 6699 except: 6700 # if sl4a is not available, use adb command 6701 ad.unlock_screen(puk_pin) 6702 if is_sim_locked(ad): 6703 ad.unlock_screen(puk_pin) 6704 time.sleep(30) 6705 return not is_sim_locked(ad) 6706 6707 6708def send_dialer_secret_code(ad, secret_code): 6709 """Send dialer secret code. 6710 6711 ad: android device controller 6712 secret_code: the secret code to be sent to dialer. the string between 6713 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#* 6714 """ 6715 action = 'android.provider.Telephony.SECRET_CODE' 6716 uri = 'android_secret_code://%s' % secret_code 6717 intent = ad.droid.makeIntent( 6718 action, 6719 uri, 6720 None, # type 6721 None, # extras 6722 None, # categories, 6723 None, # packagename, 6724 None, # classname, 6725 0x01000000) # flags 6726 ad.log.info('Issuing dialer secret dialer code: %s', secret_code) 6727 ad.droid.sendBroadcastIntent(intent) 6728 6729 6730def enable_radio_log_on(ad): 6731 if ad.adb.getprop("persist.vendor.radio.adb_log_on") != "1": 6732 ad.log.info("Enable radio adb_log_on and reboot") 6733 adb_disable_verity(ad) 6734 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1") 6735 reboot_device(ad) 6736 6737 6738def adb_disable_verity(ad): 6739 if ad.adb.getprop("ro.boot.veritymode") == "enforcing": 6740 ad.adb.disable_verity() 6741 reboot_device(ad) 6742 ad.adb.remount() 6743 6744 6745def recover_build_id(ad): 6746 build_fingerprint = ad.adb.getprop( 6747 "ro.build.fingerprint") or ad.adb.getprop( 6748 "ro.vendor.build.fingerprint") 6749 if not build_fingerprint: 6750 return 6751 build_id = build_fingerprint.split("/")[3] 6752 if ad.adb.getprop("ro.build.id") != build_id: 6753 build_id_override(ad, build_id) 6754 6755 6756def build_id_override(ad, new_build_id=None, postfix=None): 6757 build_fingerprint = ad.adb.getprop( 6758 "ro.build.fingerprint") or ad.adb.getprop( 6759 "ro.vendor.build.fingerprint") 6760 if build_fingerprint: 6761 build_id = build_fingerprint.split("/")[3] 6762 else: 6763 build_id = None 6764 existing_build_id = ad.adb.getprop("ro.build.id") 6765 if postfix in build_id: 6766 ad.log.info("Build id already contains %s", postfix) 6767 return 6768 if not new_build_id: 6769 if postfix and build_id: 6770 new_build_id = "%s.%s" % (build_id, postfix) 6771 if not new_build_id or existing_build_id == new_build_id: 6772 return 6773 ad.log.info("Override build id %s with %s", existing_build_id, 6774 new_build_id) 6775 adb_disable_verity(ad) 6776 ad.adb.remount() 6777 if "backup.prop" not in ad.adb.shell("ls /sdcard/"): 6778 ad.adb.shell("cp /default.prop /sdcard/backup.prop") 6779 ad.adb.shell("cat /default.prop | grep -v ro.build.id > /sdcard/test.prop") 6780 ad.adb.shell("echo ro.build.id=%s >> /sdcard/test.prop" % new_build_id) 6781 ad.adb.shell("cp /sdcard/test.prop /default.prop") 6782 reboot_device(ad) 6783 ad.log.info("ro.build.id = %s", ad.adb.getprop("ro.build.id")) 6784 6785 6786def enable_connectivity_metrics(ad): 6787 cmds = [ 6788 "pm enable com.android.connectivity.metrics", 6789 "am startservice -a com.google.android.gms.usagereporting.OPTIN_UR", 6790 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 6791 " -e usagestats:connectivity_metrics:enable_data_collection 1", 6792 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 6793 " -e usagestats:connectivity_metrics:telephony_snapshot_period_millis 180000" 6794 # By default it turn on all modules 6795 #"am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE" 6796 #" -e usagestats:connectivity_metrics:data_collection_bitmap 62" 6797 ] 6798 for cmd in cmds: 6799 ad.adb.shell(cmd, ignore_status=True) 6800 6801 6802def force_connectivity_metrics_upload(ad): 6803 cmd = "cmd jobscheduler run --force com.android.connectivity.metrics %s" 6804 for job_id in [2, 3, 5, 4, 1, 6]: 6805 ad.adb.shell(cmd % job_id, ignore_status=True) 6806 6807 6808def system_file_push(ad, src_file_path, dst_file_path): 6809 """Push system file on a device. 6810 6811 Push system file need to change some system setting and remount. 6812 """ 6813 cmd = "%s %s" % (src_file_path, dst_file_path) 6814 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 6815 skip_sl4a = True if "sl4a.apk" in src_file_path else False 6816 if "Read-only file system" in out: 6817 ad.log.info("Change read-only file system") 6818 adb_disable_verity(ad) 6819 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 6820 if "Read-only file system" in out: 6821 ad.reboot(skip_sl4a) 6822 out = ad.adb.push(cmd, timeout=300, ignore_status=True) 6823 if "error" in out: 6824 ad.log.error("%s failed with %s", cmd, out) 6825 return False 6826 else: 6827 ad.log.info("push %s succeed") 6828 if skip_sl4a: ad.reboot(skip_sl4a) 6829 return True 6830 else: 6831 return True 6832 elif "error" in out: 6833 return False 6834 else: 6835 return True 6836 6837 6838def flash_radio(ad, file_path, skip_setup_wizard=True): 6839 """Flash radio image.""" 6840 ad.stop_services() 6841 ad.log.info("Reboot to bootloader") 6842 ad.adb.reboot_bootloader(ignore_status=True) 6843 ad.log.info("Flash radio in fastboot") 6844 try: 6845 ad.fastboot.flash("radio %s" % file_path, timeout=300) 6846 except Exception as e: 6847 ad.log.error(e) 6848 ad.fastboot.reboot("bootloader") 6849 time.sleep(5) 6850 output = ad.fastboot.getvar("version-baseband") 6851 result = re.search(r"version-baseband: (\S+)", output) 6852 if not result: 6853 ad.log.error("fastboot getvar version-baseband output = %s", output) 6854 abort_all_tests(ad.log, "Radio version-baseband is not provided") 6855 fastboot_radio_version_output = result.group(1) 6856 for _ in range(2): 6857 try: 6858 ad.log.info("Reboot in fastboot") 6859 ad.fastboot.reboot() 6860 ad.wait_for_boot_completion() 6861 break 6862 except Exception as e: 6863 ad.log.error("Exception error %s", e) 6864 ad.root_adb() 6865 adb_radio_version_output = ad.adb.getprop("gsm.version.baseband") 6866 ad.log.info("adb getprop gsm.version.baseband = %s", 6867 adb_radio_version_output) 6868 if adb_radio_version_output != fastboot_radio_version_output: 6869 msg = ("fastboot radio version output %s does not match with adb" 6870 " radio version output %s" % (fastboot_radio_version_output, 6871 adb_radio_version_output)) 6872 abort_all_tests(ad.log, msg) 6873 if not ad.ensure_screen_on(): 6874 ad.log.error("User window cannot come up") 6875 ad.start_services(skip_setup_wizard=skip_setup_wizard) 6876 unlock_sim(ad) 6877 6878 6879def set_preferred_apn_by_adb(ad, pref_apn_name): 6880 """Select Pref APN 6881 Set Preferred APN on UI using content query/insert 6882 It needs apn name as arg, and it will match with plmn id 6883 """ 6884 try: 6885 plmn_id = get_plmn_by_adb(ad) 6886 out = ad.adb.shell("content query --uri content://telephony/carriers " 6887 "--where \"apn='%s' and numeric='%s'\"" % 6888 (pref_apn_name, plmn_id)) 6889 if "No result found" in out: 6890 ad.log.warning("Cannot find APN %s on device", pref_apn_name) 6891 return False 6892 else: 6893 apn_id = re.search(r'_id=(\d+)', out).group(1) 6894 ad.log.info("APN ID is %s", apn_id) 6895 ad.adb.shell("content insert --uri content:" 6896 "//telephony/carriers/preferapn --bind apn_id:i:%s" % 6897 (apn_id)) 6898 out = ad.adb.shell("content query --uri " 6899 "content://telephony/carriers/preferapn") 6900 if "No result found" in out: 6901 ad.log.error("Failed to set prefer APN %s", pref_apn_name) 6902 return False 6903 elif apn_id == re.search(r'_id=(\d+)', out).group(1): 6904 ad.log.info("Preferred APN set to %s", pref_apn_name) 6905 return True 6906 except Exception as e: 6907 ad.log.error("Exception while setting pref apn %s", e) 6908 return True 6909 6910 6911def check_apm_mode_on_by_serial(ad, serial_id): 6912 try: 6913 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id, 6914 "grep -i airplanemodeon", "cut -f2 -d ' '")) 6915 output = exe_cmd(apm_check_cmd) 6916 if output.decode("utf-8").split("\n")[0] == "true": 6917 return True 6918 else: 6919 return False 6920 except Exception as e: 6921 ad.log.warning("Exception during check apm mode on %s", e) 6922 return True 6923 6924 6925def set_apm_mode_on_by_serial(ad, serial_id): 6926 try: 6927 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id 6928 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id 6929 exe_cmd(cmd1) 6930 exe_cmd(cmd2) 6931 except Exception as e: 6932 ad.log.warning("Exception during set apm mode on %s", e) 6933 return True 6934 6935 6936def print_radio_info(ad, extra_msg=""): 6937 for prop in ("gsm.version.baseband", "persist.radio.ver_info", 6938 "persist.radio.cnv.ver_info"): 6939 output = ad.adb.getprop(prop) 6940 ad.log.info("%s%s = %s", extra_msg, prop, output) 6941 6942 6943def wait_for_state(state_check_func, 6944 state, 6945 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE, 6946 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK, 6947 *args, 6948 **kwargs): 6949 while max_wait_time >= 0: 6950 if state_check_func(*args, **kwargs) == state: 6951 return True 6952 time.sleep(checking_interval) 6953 max_wait_time -= checking_interval 6954 return False 6955 6956 6957def power_off_sim(ad, sim_slot_id=None, 6958 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE): 6959 try: 6960 if sim_slot_id is None: 6961 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN) 6962 verify_func = ad.droid.telephonyGetSimState 6963 verify_args = [] 6964 else: 6965 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, 6966 CARD_POWER_DOWN) 6967 verify_func = ad.droid.telephonyGetSimStateForSlotId 6968 verify_args = [sim_slot_id] 6969 except Exception as e: 6970 ad.log.error(e) 6971 return False 6972 while timeout > 0: 6973 sim_state = verify_func(*verify_args) 6974 if sim_state in (SIM_STATE_UNKNOWN, SIM_STATE_ABSENT): 6975 ad.log.info("SIM slot is powered off, SIM state is %s", sim_state) 6976 return True 6977 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK 6978 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK) 6979 ad.log.warning("Fail to power off SIM slot, sim_state=%s", 6980 verify_func(*verify_args)) 6981 return False 6982 6983 6984def power_on_sim(ad, sim_slot_id=None): 6985 try: 6986 if sim_slot_id is None: 6987 ad.droid.telephonySetSimPowerState(CARD_POWER_UP) 6988 verify_func = ad.droid.telephonyGetSimState 6989 verify_args = [] 6990 else: 6991 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP) 6992 verify_func = ad.droid.telephonyGetSimStateForSlotId 6993 verify_args = [sim_slot_id] 6994 except Exception as e: 6995 ad.log.error(e) 6996 return False 6997 if wait_for_state(verify_func, SIM_STATE_READY, 6998 MAX_WAIT_TIME_FOR_STATE_CHANGE, 6999 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args): 7000 ad.log.info("SIM slot is powered on, SIM state is READY") 7001 return True 7002 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED: 7003 ad.log.info("SIM is pin locked") 7004 return True 7005 else: 7006 ad.log.error("Fail to power on SIM slot") 7007 return False 7008 7009 7010def extract_test_log(log, src_file, dst_file, test_tag): 7011 cmd = "grep -n '%s' %s" % (test_tag, src_file) 7012 result = job.run(cmd, ignore_status=True) 7013 if not result.stdout or result.exit_status == 1: 7014 log.warning("Command %s returns %s", cmd, result) 7015 return 7016 line_nums = re.findall(r"(\d+).*", result.stdout) 7017 if line_nums: 7018 begin_line = int(line_nums[0]) 7019 end_line = int(line_nums[-1]) 7020 if end_line - begin_line <= 5: 7021 result = job.run("wc -l < %s" % src_file) 7022 if result.stdout: 7023 end_line = int(result.stdout) 7024 log.info("Extract %s from line %s to line %s to %s", src_file, 7025 begin_line, end_line, dst_file) 7026 job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line, 7027 src_file, dst_file)) 7028 7029 7030def get_device_epoch_time(ad): 7031 return int(1000 * float(ad.adb.shell("date +%s.%N"))) 7032 7033 7034def synchronize_device_time(ad): 7035 ad.adb.shell("put global auto_time 0", ignore_status=True) 7036 try: 7037 ad.adb.droid.setTime(get_current_epoch_time()) 7038 except Exception: 7039 try: 7040 ad.adb.shell("date `date +%m%d%H%M%G.%S`") 7041 except Exception: 7042 pass 7043 try: 7044 ad.adb.shell( 7045 "am broadcast -a android.intent.action.TIME_SET", 7046 ignore_status=True) 7047 except Exception: 7048 pass 7049 7050 7051def revert_default_telephony_setting(ad): 7052 toggle_airplane_mode_by_adb(ad.log, ad, True) 7053 default_data_roaming = int( 7054 ad.adb.getprop("ro.com.android.dataroaming") == 'true') 7055 default_network_preference = int( 7056 ad.adb.getprop("ro.telephony.default_network")) 7057 ad.log.info("Default data roaming %s, network preference %s", 7058 default_data_roaming, default_network_preference) 7059 new_data_roaming = abs(default_data_roaming - 1) 7060 new_network_preference = abs(default_network_preference - 1) 7061 ad.log.info( 7062 "Set data roaming = %s, mobile data = 0, network preference = %s", 7063 new_data_roaming, new_network_preference) 7064 ad.adb.shell("settings put global mobile_data 0") 7065 ad.adb.shell("settings put global data_roaming %s" % new_data_roaming) 7066 ad.adb.shell("settings put global preferred_network_mode %s" % 7067 new_network_preference) 7068 7069 7070def verify_default_telephony_setting(ad): 7071 ad.log.info("carrier_config: %s", dumpsys_carrier_config(ad)) 7072 default_data_roaming = int( 7073 ad.adb.getprop("ro.com.android.dataroaming") == 'true') 7074 default_network_preference = int( 7075 ad.adb.getprop("ro.telephony.default_network")) 7076 ad.log.info("Default data roaming %s, network preference %s", 7077 default_data_roaming, default_network_preference) 7078 data_roaming = int(ad.adb.shell("settings get global data_roaming")) 7079 mobile_data = int(ad.adb.shell("settings get global mobile_data")) 7080 network_preference = int( 7081 ad.adb.shell("settings get global preferred_network_mode")) 7082 airplane_mode = int(ad.adb.shell("settings get global airplane_mode_on")) 7083 result = True 7084 ad.log.info("data_roaming = %s, mobile_data = %s, " 7085 "network_perference = %s, airplane_mode = %s", data_roaming, 7086 mobile_data, network_preference, airplane_mode) 7087 if airplane_mode: 7088 ad.log.error("Airplane mode is on") 7089 result = False 7090 if data_roaming != default_data_roaming: 7091 ad.log.error("Data roaming is %s, expecting %s", data_roaming, 7092 default_data_roaming) 7093 result = False 7094 if not mobile_data: 7095 ad.log.error("Mobile data is off") 7096 result = False 7097 if network_preference != default_network_preference: 7098 ad.log.error("preferred_network_mode is %s, expecting %s", 7099 network_preference, default_network_preference) 7100 result = False 7101 return result 7102 7103 7104def log_messaging_screen_shot(ad, test_name=""): 7105 ad.ensure_screen_on() 7106 ad.send_keycode("HOME") 7107 ad.adb.shell("am start -n com.google.android.apps.messaging/.ui." 7108 "ConversationListActivity") 7109 log_screen_shot(ad, test_name) 7110 ad.adb.shell("am start -n com.google.android.apps.messaging/com.google." 7111 "android.apps.messaging.ui.conversation.ConversationActivity" 7112 " -e conversation_id 1") 7113 log_screen_shot(ad, test_name) 7114 ad.send_keycode("HOME") 7115 7116 7117def log_screen_shot(ad, test_name=""): 7118 file_name = "/sdcard/Pictures/screencap" 7119 if test_name: 7120 file_name = "%s_%s" % (file_name, test_name) 7121 file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time()) 7122 try: 7123 ad.adb.shell("screencap -p %s" % file_name) 7124 except: 7125 ad.log.error("Fail to log screen shot to %s", file_name) 7126 7127 7128def get_screen_shot_log(ad, test_name="", begin_time=None): 7129 logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time) 7130 if logs: 7131 ad.log.info("Pulling %s", logs) 7132 log_path = os.path.join(ad.device_log_path, "Screenshot_%s" % ad.serial) 7133 utils.create_dir(log_path) 7134 ad.pull_files(logs, log_path) 7135 ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True) 7136 7137 7138def get_screen_shot_logs(ads, test_name="", begin_time=None): 7139 for ad in ads: 7140 get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time) 7141 7142 7143def get_carrier_id_version(ad): 7144 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | " \ 7145 "grep -i carrier_list_version") 7146 if out and ":" in out: 7147 version = out.split(':')[1].lstrip() 7148 else: 7149 version = "0" 7150 ad.log.debug("Carrier Config Version is %s", version) 7151 return version 7152 7153 7154def get_carrier_config_version(ad): 7155 out = ad.adb.shell("dumpsys carrier_config | grep version_string") 7156 if out and "-" in out: 7157 version = out.split('-')[1] 7158 else: 7159 version = "0" 7160 ad.log.debug("Carrier Config Version is %s", version) 7161 return version 7162 7163 7164def install_googleaccountutil_apk(ad, account_util): 7165 ad.log.info("Install account_util %s", account_util) 7166 ad.ensure_screen_on() 7167 ad.adb.install("-r %s" % account_util, timeout=300, ignore_status=True) 7168 time.sleep(3) 7169 if not ad.is_apk_installed("com.google.android.tradefed.account"): 7170 ad.log.info("com.google.android.tradefed.account is not installed") 7171 return False 7172 return True 7173 7174 7175def install_googlefi_apk(ad, fi_util): 7176 ad.log.info("Install fi_util %s", fi_util) 7177 ad.ensure_screen_on() 7178 ad.adb.install("-r -g --user 0 %s" % fi_util, 7179 timeout=300, ignore_status=True) 7180 time.sleep(3) 7181 if not check_fi_apk_installed(ad): 7182 return False 7183 return True 7184 7185 7186def check_fi_apk_installed(ad): 7187 if not ad.is_apk_installed("com.google.android.apps.tycho"): 7188 ad.log.warning("com.google.android.apps.tycho is not installed") 7189 return False 7190 return True 7191 7192 7193def add_google_account(ad, retries=3): 7194 if not ad.is_apk_installed("com.google.android.tradefed.account"): 7195 ad.log.error("GoogleAccountUtil is not installed") 7196 return False 7197 for _ in range(retries): 7198 ad.ensure_screen_on() 7199 output = ad.adb.shell( 7200 'am instrument -w -e account "%s@gmail.com" -e password ' 7201 '"%s" -e sync true -e wait-for-checkin false ' 7202 'com.google.android.tradefed.account/.AddAccount' % 7203 (ad.user_account, ad.user_password)) 7204 if "result=SUCCESS" in output: 7205 ad.log.info("Google account is added successfully") 7206 return True 7207 ad.log.error("Failed to add google account - %s", output) 7208 return False 7209 7210 7211def remove_google_account(ad, retries=3): 7212 if not ad.is_apk_installed("com.google.android.tradefed.account"): 7213 ad.log.error("GoogleAccountUtil is not installed") 7214 return False 7215 for _ in range(retries): 7216 ad.ensure_screen_on() 7217 output = ad.adb.shell( 7218 'am instrument -w ' 7219 'com.google.android.tradefed.account/.RemoveAccounts') 7220 if "result=SUCCESS" in output: 7221 ad.log.info("google account is removed successfully") 7222 return True 7223 ad.log.error("Fail to remove google account due to %s", output) 7224 return False 7225 7226 7227def my_current_screen_content(ad, content): 7228 ad.adb.shell("uiautomator dump --window=WINDOW") 7229 out = ad.adb.shell("cat /sdcard/window_dump.xml | grep -E '%s'" % content) 7230 if not out: 7231 ad.log.warning("NOT FOUND - %s", content) 7232 return False 7233 return True 7234 7235 7236def activate_google_fi_account(ad, retries=3): 7237 _FI_APK = "com.google.android.apps.tycho" 7238 _FI_ACTIVATE_CMD = ('am start -c android.intent.category.DEFAULT -n ' 7239 'com.google.android.apps.tycho/.InitActivity --ez ' 7240 'in_setup_wizard false --ez force_show_account_chooser ' 7241 'false') 7242 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False) 7243 ad.adb.shell("settings put system screen_off_timeout 1800000") 7244 page_match_dict = { 7245 "Setup" : "Activate Google Fi to use your device for calls", 7246 "Switch" : "Switch to the Google Fi mobile network", 7247 "Connect" : "Connect to the Google Fi mobile network", 7248 "Move" : "Move number", 7249 "Activate" : "This takes a minute or two, sometimes longer", 7250 "Welcome" : "Welcome to Google Fi", 7251 "Account" : "Your current cycle ends in" 7252 } 7253 page_list = ["Account", "Setup", "Switch", "Connect", 7254 "Activate", "Move", "Welcome"] 7255 for _ in range(retries): 7256 ad.force_stop_apk(_FI_APK) 7257 ad.ensure_screen_on() 7258 ad.send_keycode("HOME") 7259 ad.adb.shell(_FI_ACTIVATE_CMD) 7260 time.sleep(15) 7261 for page in page_list: 7262 if my_current_screen_content(ad, page_match_dict[page]): 7263 ad.log.info("Ready for Step %s", page) 7264 log_screen_shot(ad, "fi_activation_step_%s" % page) 7265 if page in ("Setup", "Switch", "Connect"): 7266 ad.send_keycode("TAB") 7267 ad.send_keycode("TAB") 7268 ad.send_keycode("ENTER") 7269 time.sleep(30) 7270 elif page == "Move": 7271 ad.send_keycode("TAB") 7272 ad.send_keycode("ENTER") 7273 time.sleep(5) 7274 elif page == "Welcome": 7275 ad.send_keycode("TAB") 7276 ad.send_keycode("TAB") 7277 ad.send_keycode("TAB") 7278 ad.send_keycode("ENTER") 7279 ad.log.info("Activation SUCCESS using Fi App") 7280 time.sleep(5) 7281 ad.send_keycode("TAB") 7282 ad.send_keycode("TAB") 7283 ad.send_keycode("ENTER") 7284 return True 7285 elif page == "Activate": 7286 time.sleep(60) 7287 if my_current_screen_content(ad, page_match_dict[page]): 7288 time.sleep(60) 7289 elif page == "Account": 7290 return True 7291 else: 7292 ad.log.info("NOT FOUND - Page %s", page) 7293 log_screen_shot(ad, "fi_activation_step_%s_failure" % page) 7294 return False 7295 7296 7297def check_google_fi_activated(ad, retries=20): 7298 if check_fi_apk_installed(ad): 7299 _FI_APK = "com.google.android.apps.tycho" 7300 _FI_LAUNCH_CMD = ("am start -n %s/%s.AccountDetailsActivity" \ 7301 % (_FI_APK, _FI_APK)) 7302 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False) 7303 ad.adb.shell("settings put system screen_off_timeout 1800000") 7304 ad.force_stop_apk(_FI_APK) 7305 ad.ensure_screen_on() 7306 ad.send_keycode("HOME") 7307 ad.adb.shell(_FI_LAUNCH_CMD) 7308 time.sleep(10) 7309 if not my_current_screen_content(ad, "Your current cycle ends in"): 7310 ad.log.warning("Fi is not activated") 7311 return False 7312 ad.send_keycode("HOME") 7313 return True 7314 else: 7315 ad.log.info("Fi Apk is not yet installed") 7316 return False 7317 7318 7319def cleanup_configupdater(ad): 7320 cmds = ('rm -rf /data/data/com.google.android.configupdater/shared_prefs', 7321 'rm /data/misc/carrierid/carrier_list.pb', 7322 'setprop persist.telephony.test.carrierid.ota true', 7323 'rm /data/user_de/0/com.android.providers.telephony/shared_prefs' 7324 '/CarrierIdProvider.xml') 7325 for cmd in cmds: 7326 ad.log.info("Cleanup ConfigUpdater - %s", cmd) 7327 ad.adb.shell(cmd, ignore_status=True) 7328 7329 7330def pull_carrier_id_files(ad, carrier_id_path): 7331 utils.create_dir(carrier_id_path) 7332 ad.log.info("Pull CarrierId Files") 7333 cmds = ('/data/data/com.google.android.configupdater/shared_prefs/', 7334 '/data/misc/carrierid/', 7335 '/data/user_de/0/com.android.providers.telephony/shared_prefs/', 7336 '/data/data/com.android.providers.downloads/databases/downloads.db') 7337 for cmd in cmds: 7338 cmd = cmd + " %s" % carrier_id_path 7339 ad.adb.pull(cmd, timeout=30, ignore_status=True) 7340 7341 7342def bring_up_connectivity_monitor(ad): 7343 monitor_apk = None 7344 for apk in ("com.google.telephonymonitor", 7345 "com.google.android.connectivitymonitor"): 7346 if ad.is_apk_installed(apk): 7347 ad.log.info("apk %s is installed", apk) 7348 monitor_apk = apk 7349 break 7350 if not monitor_apk: 7351 ad.log.info("ConnectivityMonitor|TelephonyMonitor is not installed") 7352 return False 7353 toggle_connectivity_monitor_setting(ad, True) 7354 7355 if not ad.is_apk_running(monitor_apk): 7356 ad.log.info("%s is not running", monitor_apk) 7357 # Reboot 7358 ad.log.info("reboot to bring up %s", monitor_apk) 7359 reboot_device(ad) 7360 for i in range(30): 7361 if ad.is_apk_running(monitor_apk): 7362 ad.log.info("%s is running after reboot", monitor_apk) 7363 return True 7364 else: 7365 ad.log.info( 7366 "%s is not running after reboot. Wait and check again", 7367 monitor_apk) 7368 time.sleep(30) 7369 ad.log.error("%s is not running after reboot", monitor_apk) 7370 return False 7371 else: 7372 ad.log.info("%s is running", monitor_apk) 7373 return True 7374 7375 7376def toggle_connectivity_monitor_setting(ad, state=True): 7377 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon") 7378 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting) 7379 current_state = True if monitor_setting == "user_enabled" else False 7380 if current_state == state: 7381 return True 7382 elif state is None: 7383 state = not current_state 7384 expected_monitor_setting = "user_enabled" if state else "disabled" 7385 cmd = "setprop persist.radio.enable_tel_mon %s" % expected_monitor_setting 7386 ad.log.info("Toggle connectivity monitor by %s", cmd) 7387 ad.adb.shell( 7388 "am start -n com.android.settings/.DevelopmentSettings", 7389 ignore_status=True) 7390 ad.adb.shell(cmd) 7391 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon") 7392 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting) 7393 return monitor_setting == expected_monitor_setting 7394