1#!/usr/bin/env python3.4 2# 3# Copyright 2017 - 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""" 17 Test Script for Telephony Pre Check In Sanity 18""" 19 20import re 21import time 22from acts import signals 23from acts.test_decorators import test_tracker_info 24from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest 25from acts.test_utils.tel.tel_defines import CAPABILITY_WFC 26from acts.test_utils.tel.tel_defines import DEFAULT_DEVICE_PASSWORD 27from acts.test_utils.tel.tel_defines import PHONE_TYPE_CDMA 28from acts.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED 29from acts.test_utils.tel.tel_lookup_tables import operator_capabilities 30from acts.test_utils.tel.tel_test_utils import abort_all_tests 31from acts.test_utils.tel.tel_test_utils import call_setup_teardown 32from acts.test_utils.tel.tel_test_utils import dumpsys_last_call_info 33from acts.test_utils.tel.tel_test_utils import dumpsys_last_call_number 34from acts.test_utils.tel.tel_test_utils import dumpsys_new_call_info 35from acts.test_utils.tel.tel_test_utils import ensure_phone_default_state 36from acts.test_utils.tel.tel_test_utils import get_operator_name 37from acts.test_utils.tel.tel_test_utils import get_service_state_by_adb 38from acts.test_utils.tel.tel_test_utils import fastboot_wipe 39from acts.test_utils.tel.tel_test_utils import hangup_call_by_adb 40from acts.test_utils.tel.tel_test_utils import initiate_call 41from acts.test_utils.tel.tel_test_utils import is_sim_lock_enabled 42from acts.test_utils.tel.tel_test_utils import initiate_emergency_dialer_call_by_adb 43from acts.test_utils.tel.tel_test_utils import last_call_drop_reason 44from acts.test_utils.tel.tel_test_utils import reset_device_password 45from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb 46from acts.test_utils.tel.tel_test_utils import unlock_sim 47from acts.test_utils.tel.tel_test_utils import verify_internet_connection 48from acts.test_utils.tel.tel_test_utils import wait_for_cell_data_connection 49from acts.test_utils.tel.tel_test_utils import wait_for_sim_ready_by_adb 50from acts.test_utils.tel.tel_voice_utils import phone_setup_csfb 51from acts.test_utils.tel.tel_voice_utils import phone_setup_iwlan 52from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_3g 53from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_2g 54from acts.utils import get_current_epoch_time 55 56CARRIER_OVERRIDE_CMD = ( 57 "am broadcast -a com.google.android.carrier.action.LOCAL_OVERRIDE -n " 58 "com.google.android.carrier/.ConfigOverridingReceiver --ez") 59IMS_FIRST = "carrier_use_ims_first_for_emergency_bool" 60ALLOW_NON_EMERGENCY_CALL = "allow_non_emergency_calls_in_ecm_bool" 61BLOCK_DURATION_CMD = "duration_blocking_disabled_after_emergency_int" 62BLOCK_DURATION = 300 63 64 65class TelLiveEmergencyBase(TelephonyBaseTest): 66 def __init__(self, controllers): 67 TelephonyBaseTest.__init__(self, controllers) 68 self.number_of_devices = 1 69 fake_number = self.user_params.get("fake_emergency_number", "411") 70 self.fake_emergency_number = fake_number.strip("+").replace("-", "") 71 self.my_devices = self.android_devices[:] 72 73 def setup_class(self): 74 TelephonyBaseTest.setup_class(self) 75 for ad in self.android_devices: 76 if not is_sim_lock_enabled(ad): 77 self.setup_dut(ad) 78 return True 79 self.log.error("No device meets SIM READY or LOADED requirement") 80 raise signals.TestAbortClass("No device meets SIM requirement") 81 82 def setup_dut(self, ad): 83 self.dut = ad 84 output = self.dut.adb.shell("dumpsys carrier_config") 85 self.default_settings = {} 86 for setting in (IMS_FIRST, ALLOW_NON_EMERGENCY_CALL, 87 BLOCK_DURATION_CMD): 88 values = re.findall(r"%s = (\S+)" % setting, output) 89 if values: 90 self.default_settings[setting] = values[-1] 91 else: 92 self.default_settings[setting] = "" 93 self.dut.adb.shell(" ".join( 94 [CARRIER_OVERRIDE_CMD, BLOCK_DURATION_CMD, 95 "%s" % BLOCK_DURATION])) 96 self.dut_operator = get_operator_name(self.log, ad) 97 if self.dut_operator == "tmo": 98 self.fake_emergency_number = "611" 99 elif self.dut_operator == "vzw": 100 self.fake_emergency_number = "922" 101 elif self.dut_operator == "spt": 102 self.fake_emergency_number = "526" 103 if len(self.my_devices) > 1: 104 self.android_devices.remove(ad) 105 self.android_devices.insert(0, ad) 106 107 def teardown_class(self): 108 self.android_devices = self.my_devices 109 TelephonyBaseTest.teardown_class(self) 110 111 def setup_test(self): 112 if not unlock_sim(self.dut): 113 abort_all_tests(self.dut.log, "unable to unlock SIM") 114 self.expected_call_result = True 115 116 def teardown_test(self): 117 self.dut.ensure_screen_on() 118 self.dut.exit_setup_wizard() 119 reset_device_password(self.dut, None) 120 output = self.dut.adb.shell("dumpsys carrier_config") 121 for setting, state in self.default_settings.items(): 122 values = re.findall(r"%s = (\S+)" % setting, output) 123 if values and values[-1] != state: 124 self.dut.adb.shell(" ".join( 125 [CARRIER_OVERRIDE_CMD, setting, state])) 126 ensure_phone_default_state(self.log, self.dut) 127 128 def change_emergency_number_list(self): 129 test_number = "%s:%s" % (self.fake_emergency_number, 130 self.fake_emergency_number) 131 output = self.dut.adb.getprop("ril.test.emergencynumber") 132 if output != test_number: 133 cmd = "setprop ril.test.emergencynumber %s" % test_number 134 self.dut.log.info(cmd) 135 self.dut.adb.shell(cmd) 136 for _ in range(5): 137 existing = self.dut.adb.getprop("ril.ecclist") 138 self.dut.log.info("Existing ril.ecclist is: %s", existing) 139 if self.fake_emergency_number in existing: 140 return True 141 emergency_numbers = "%s,%s" % (existing, 142 self.fake_emergency_number) 143 cmd = "setprop ril.ecclist %s" % emergency_numbers 144 self.dut.log.info(cmd) 145 self.dut.adb.shell(cmd) 146 # After some system events, ril.ecclist might change 147 # wait sometime for it to settle 148 time.sleep(10) 149 if self.fake_emergency_number in existing: 150 return True 151 return False 152 153 def change_qcril_emergency_source_mcc_table(self): 154 # This will add the fake number into emergency number list for a mcc 155 # in qcril. Please note, the fake number will be send as an emergency 156 # number by modem and reach the real 911 by this 157 qcril_database_path = self.dut.adb.shell("find /data -iname qcril.db") 158 if not qcril_database_path: return 159 mcc = self.dut.droid.telephonyGetNetworkOperator() 160 mcc = mcc[:3] 161 self.dut.log.info("Add %s mcc %s in qcril_emergency_source_mcc_table") 162 self.dut.adb.shell( 163 "sqlite3 %s \"INSERT INTO qcril_emergency_source_mcc_table VALUES('%s','%s','','')\"" 164 % (qcril_database_path, mcc, self.fake_emergency_number)) 165 166 def fake_emergency_call_test(self, by_emergency_dialer=True, attemps=3): 167 self.dut.log.info("ServiceState is in %s", 168 get_service_state_by_adb(self.log, self.dut)) 169 if by_emergency_dialer: 170 dialing_func = initiate_emergency_dialer_call_by_adb 171 callee = self.fake_emergency_number 172 else: 173 dialing_func = initiate_call 174 # Initiate_call method has to have "+" in front 175 # otherwise the number will be in dialer without dial out 176 # with sl4a fascade. Need further investigation 177 callee = "+%s" % self.fake_emergency_number 178 for i in range(attemps): 179 begin_time = get_current_epoch_time() 180 result = True 181 if not self.change_emergency_number_list(): 182 self.dut.log.error("Unable to add number to ril.ecclist") 183 return False 184 time.sleep(1) 185 last_call_number = dumpsys_last_call_number(self.dut) 186 call_result = dialing_func(self.log, self.dut, callee) 187 time.sleep(3) 188 hangup_call_by_adb(self.dut) 189 if not call_result: 190 last_call_drop_reason(self.dut, begin_time) 191 self.dut.send_keycode("BACK") 192 self.dut.send_keycode("BACK") 193 if not dumpsys_new_call_info(self.dut, last_call_number): 194 result = False 195 if call_result == self.expected_call_result: 196 self.dut.log.info("Call to %s returns %s as expected", callee, 197 self.expected_call_result) 198 else: 199 self.dut.log.info("Call to %s returns %s", callee, 200 not self.expected_call_result) 201 result = False 202 if result: 203 return True 204 ecclist = self.dut.adb.getprop("ril.ecclist") 205 self.dut.log.info("ril.ecclist = %s", ecclist) 206 if self.fake_emergency_number in ecclist: 207 if i == attemps - 1: 208 self.dut.log.error("%s is in ril-ecclist, but call failed", 209 self.fake_emergency_number) 210 else: 211 self.dut.log.warning( 212 "%s is in ril-ecclist, but call failed, try again", 213 self.fake_emergency_number) 214 else: 215 if i == attemps - 1: 216 self.dut.log.error("Fail to write %s to ril-ecclist", 217 self.fake_emergency_number) 218 else: 219 self.dut.log.info("%s is not in ril-ecclist", 220 self.fake_emergency_number) 221 self.dut.log.info("fake_emergency_call_test result is %s", result) 222 return result 223 224 def set_ims_first(self, state): 225 output = self.dut.adb.shell( 226 "dumpsys carrier_config | grep %s | tail -1" % IMS_FIRST) 227 self.dut.log.info(output) 228 if state in output: return 229 cmd = " ".join([CARRIER_OVERRIDE_CMD, IMS_FIRST, state]) 230 self.dut.log.info(cmd) 231 self.dut.adb.shell(cmd) 232 self.dut.log.info( 233 self.dut.adb.shell( 234 "dumpsys carrier_config | grep %s | tail -1" % IMS_FIRST)) 235 236 def set_allow_non_emergency_call(self, state): 237 output = self.dut.adb.shell( 238 "dumpsys carrier_config | grep %s | tail -1" % 239 ALLOW_NON_EMERGENCY_CALL) 240 self.dut.log.info(output) 241 if state in output: return 242 cmd = " ".join([CARRIER_OVERRIDE_CMD, ALLOW_NON_EMERGENCY_CALL, state]) 243 self.dut.log.info(cmd) 244 self.dut.adb.shell(cmd) 245 self.dut.log.info( 246 self.dut.adb.shell("dumpsys carrier_config | grep %s | tail -1" % 247 ALLOW_NON_EMERGENCY_CALL)) 248 249 def check_emergency_call_back_mode(self, 250 by_emergency_dialer=True, 251 non_emergency_call_allowed=True, 252 attemps=3): 253 state = "true" if non_emergency_call_allowed else "false" 254 self.set_allow_non_emergency_call(state) 255 result = True 256 for _ in range(attemps): 257 if not self.change_emergency_number_list(): 258 self.dut.log.error("Unable to add number to ril.ecclist") 259 return False 260 last_call_number = dumpsys_last_call_number(self.dut) 261 self.dut.log.info("Hung up fake emergency call in ringing") 262 if by_emergency_dialer: 263 initiate_emergency_dialer_call_by_adb( 264 self.log, self.dut, self.fake_emergency_number, timeout=0) 265 else: 266 callee = "+%s" % self.fake_emergency_number 267 self.dut.droid.telecomCallNumber(callee) 268 time.sleep(3) 269 hangup_call_by_adb(self.dut) 270 ecclist = self.dut.adb.getprop("ril.ecclist") 271 self.dut.log.info("ril.ecclist = %s", ecclist) 272 if self.fake_emergency_number in ecclist: 273 break 274 call_info = dumpsys_new_call_info(self.dut, last_call_number) 275 if not call_info: 276 return False 277 call_tech = call_info.get("callTechnologies", "") 278 if "CDMA" in call_tech: 279 expected_ecbm = True 280 expected_data = False 281 expected_call = non_emergency_call_allowed 282 elif "GSM" in call_tech: 283 expected_ecbm = True 284 expected_data = True 285 expected_call = True 286 else: 287 expected_ecbm = False 288 expected_data = True 289 expected_call = True 290 last_call_number = dumpsys_last_call_number(self.dut) 291 begin_time = get_current_epoch_time() 292 self.dut.ensure_screen_on() 293 self.dut.exit_setup_wizard() 294 reset_device_password(self.dut, None) 295 call_check = call_setup_teardown( 296 self.log, self.dut, self.android_devices[1], ad_hangup=self.dut) 297 if call_check != expected_call: 298 self.dut.log.error("Regular phone call is %s, expecting %s", 299 call_check, expected_call) 300 result = False 301 call_info = dumpsys_new_call_info(self.dut, last_call_number) 302 if not call_info: 303 self.dut.log.error("New call is not in dumpsys telecom") 304 return False 305 if expected_ecbm: 306 if "ecbm" in call_info["callProperties"]: 307 self.dut.log.info("New call is in ecbm.") 308 else: 309 self.dut.log.error( 310 "New call is not in emergency call back mode.") 311 result = False 312 else: 313 if "ecbm" in call_info["callProperties"]: 314 self.dut.log.error("New call is in emergency call back mode") 315 result = False 316 if not expected_data: 317 if self.dut.droid.telephonyGetDataConnectionState(): 318 self.dut.log.info( 319 "Data connection is off as expected in ECB mode") 320 self.dut.log.info("Wait for getting out of ecbm") 321 if not wait_for_cell_data_connection(self.log, self.dut, True, 322 400): 323 self.dut.log.error( 324 "Data connection didn't come back after 5 minutes") 325 result = False 326 #if not self.dut.droid.telephonyGetDataConnectionState(): 327 # self.dut.log.error( 328 # "Data connection is not coming back") 329 # result = False 330 elif not verify_internet_connection(self.log, self.dut): 331 self.dut.log.error( 332 "Internet connection check failed after getting out of ECB" 333 ) 334 result = False 335 336 else: 337 self.dut.log.error("Data connection is not off in ECB mode") 338 if not verify_internet_connection(self.log, self.dut, False): 339 self.dut.log.error("Internet connection is not off") 340 result = False 341 else: 342 if self.dut.droid.telephonyGetDataConnectionState(): 343 self.dut.log.info("Data connection is on as expected") 344 if not verify_internet_connection(self.log, self.dut): 345 self.dut.log.error("Internet connection check failed") 346 result = False 347 else: 348 self.dut.log.error("Data connection is off, expecting on") 349 result = False 350 if expected_call: 351 return result 352 elapsed_time = (get_current_epoch_time() - begin_time) / 1000 353 if elapsed_time < BLOCK_DURATION: 354 time.sleep(BLOCK_DURATION - elapsed_time + 10) 355 if not call_setup_teardown( 356 self.log, self.dut, self.android_devices[1], 357 ad_hangup=self.dut): 358 self.dut.log.error("Regular phone call failed after out of ecbm") 359 result = False 360 return result 361 362 def check_normal_call(self): 363 result = True 364 if "wfc" not in self.test_name: 365 toggle_airplane_mode_by_adb(self.log, self.dut, False) 366 self.dut.ensure_screen_on() 367 self.dut.exit_setup_wizard() 368 reset_device_password(self.dut, None) 369 begin_time = get_current_epoch_time() 370 if not call_setup_teardown( 371 self.log, 372 self.android_devices[1], 373 self.dut, 374 ad_hangup=self.android_devices[1]): 375 self.dut.log.error("Regular MT phone call fails") 376 self.dut.log.info("call_info = %s", dumpsys_last_call_info( 377 self.dut)) 378 result = False 379 if not call_setup_teardown( 380 self.log, self.dut, self.android_devices[1], 381 ad_hangup=self.dut): 382 self.dut.log.error("Regular MO phone call fails") 383 self.dut.log.info("call_info = %s", dumpsys_last_call_info( 384 self.dut)) 385 result = False 386 return result 387