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