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