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