blob: 7581ef45e820da454f47d238dac555451c0ba103 [file] [log] [blame]
Alexander Dorokhine7abf60e2016-02-10 10:56:09 -08001#!/usr/bin/env python3.4
Ang Li73697b32015-12-03 00:41:53 +00002#
Alexander Dorokhine7abf60e2016-02-10 10:56:09 -08003# Copyright 2016 - Google
Ang Li73697b32015-12-03 00:41:53 +00004#
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
Alexander Dorokhine642e63f2016-02-11 13:32:37 -080017from future import standard_library
18standard_library.install_aliases()
19
Ang Li73697b32015-12-03 00:41:53 +000020import concurrent.futures
Ang Li5bd83f32016-05-23 14:39:38 -070021import logging
Betty Zhouccd171d2017-02-13 15:11:33 -080022import os
Ang Li73697b32015-12-03 00:41:53 +000023import urllib.parse
24import time
Ang Li73697b32015-12-03 00:41:53 +000025
26from queue import Empty
Betty Zhou5534e672017-03-07 13:47:10 -080027from acts.asserts import abort_all
Ang Li73697b32015-12-03 00:41:53 +000028from acts.controllers.android_device import AndroidDevice
Yang Liu46ed7222015-12-28 14:08:52 -080029from acts.controllers.event_dispatcher import EventDispatcher
Yang Liu9a9a4f72016-02-19 10:45:04 -080030from acts.test_utils.tel.tel_defines import AOSP_PREFIX
Yang Liu46ed7222015-12-28 14:08:52 -080031from acts.test_utils.tel.tel_defines import CARRIER_UNKNOWN
Betty Zhou9e54fc22017-01-19 12:15:53 -080032from acts.test_utils.tel.tel_defines import COUNTRY_CODE_LIST
Yang Liu46ed7222015-12-28 14:08:52 -080033from acts.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
34from acts.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
Betty Zhou9e2bf402017-02-01 19:04:09 -080035from acts.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE
36from acts.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE
Yang Liu98fd9d72016-03-04 12:14:49 -080037from acts.test_utils.tel.tel_defines import GEN_4G
Yang Liu46ed7222015-12-28 14:08:52 -080038from acts.test_utils.tel.tel_defines import GEN_UNKNOWN
39from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
40from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
41from acts.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
42from acts.test_utils.tel.tel_defines import INVALID_SUB_ID
43from acts.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
44from acts.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME
Yang Liudf164e32016-01-07 16:49:32 -080045from acts.test_utils.tel.tel_defines import \
46 MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
47from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Nathan Haroldeb60b192016-08-24 14:41:55 -070048from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
Yang Liudf164e32016-01-07 16:49:32 -080049from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
50from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
51from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
52from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
Yang Liu598b93d2016-03-22 17:07:59 -070053from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
Yang Liudf164e32016-01-07 16:49:32 -080054from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
55from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
56from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS
Yang Liu855d5f82016-01-27 15:35:48 -080057from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
Yang Liudf164e32016-01-07 16:49:32 -080058from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
Yang Liudfc37b62016-01-20 18:08:47 -080059from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
60from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
Yang Liue51e93d2015-12-30 10:45:42 -080061from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
Yang Liu46ed7222015-12-28 14:08:52 -080062from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
63from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
64from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
65from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
66from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT
67from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT
68from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT
69from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT
70from acts.test_utils.tel.tel_defines import RAT_FAMILY_GSM
71from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE
72from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
Yang Liucde45aa2016-02-22 13:46:41 -080073from acts.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
Yang Liu46ed7222015-12-28 14:08:52 -080074from acts.test_utils.tel.tel_defines import RAT_1XRTT
75from acts.test_utils.tel.tel_defines import RAT_UNKNOWN
76from acts.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
77from acts.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
78from acts.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
79from acts.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
80from acts.test_utils.tel.tel_defines import SIM_STATE_READY
Betty Zhou9e54fc22017-01-19 12:15:53 -080081from acts.test_utils.tel.tel_defines import WAIT_TIME_SUPPLY_PUK_CODE
Yang Liu46ed7222015-12-28 14:08:52 -080082from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
83from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
84from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
85from acts.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT
Yang Liudf164e32016-01-07 16:49:32 -080086from acts.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
Yang Liu46ed7222015-12-28 14:08:52 -080087from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
Betty Zhouf25ce442017-03-03 14:28:36 -080088from acts.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
tturney0eddcae2016-03-30 19:59:14 -070089from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
Yang Liu46ed7222015-12-28 14:08:52 -080090from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
Yang Liudf164e32016-01-07 16:49:32 -080091from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
Yang Liu46ed7222015-12-28 14:08:52 -080092from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
Yang Liudf164e32016-01-07 16:49:32 -080093from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
Yang Liu46ed7222015-12-28 14:08:52 -080094from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED
95from acts.test_utils.tel.tel_defines import EventCallStateChanged
96from acts.test_utils.tel.tel_defines import EventConnectivityChanged
97from acts.test_utils.tel.tel_defines import EventDataConnectionStateChanged
98from acts.test_utils.tel.tel_defines import EventDataSmsReceived
99from acts.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
100from acts.test_utils.tel.tel_defines import EventServiceStateChanged
101from acts.test_utils.tel.tel_defines import EventMmsSentSuccess
Betty Zhoua27e5d42017-01-17 11:33:04 -0800102from acts.test_utils.tel.tel_defines import EventMmsDownloaded
Yang Liu46ed7222015-12-28 14:08:52 -0800103from acts.test_utils.tel.tel_defines import EventSmsReceived
104from acts.test_utils.tel.tel_defines import EventSmsSentSuccess
Yang Liudc8564b2016-01-27 14:15:37 -0800105from acts.test_utils.tel.tel_defines import CallStateContainer
Yang Liu8e6adff2016-02-05 10:24:04 -0800106from acts.test_utils.tel.tel_defines import DataConnectionStateContainer
Yang Liudc8564b2016-01-27 14:15:37 -0800107from acts.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
Yang Liu8e6adff2016-02-05 10:24:04 -0800108from acts.test_utils.tel.tel_defines import NetworkCallbackContainer
109from acts.test_utils.tel.tel_defines import ServiceStateContainer
Yang Liu46ed7222015-12-28 14:08:52 -0800110from acts.test_utils.tel.tel_lookup_tables import \
111 connection_type_from_type_string
112from acts.test_utils.tel.tel_lookup_tables import is_valid_rat
Yang Liu98fd9d72016-03-04 12:14:49 -0800113from acts.test_utils.tel.tel_lookup_tables import get_allowable_network_preference
Yang Liu46ed7222015-12-28 14:08:52 -0800114from acts.test_utils.tel.tel_lookup_tables import \
115 get_voice_mail_count_check_function
116from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_number_function
117from acts.test_utils.tel.tel_lookup_tables import \
118 network_preference_for_generaton
119from acts.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
120from acts.test_utils.tel.tel_lookup_tables import \
121 rat_families_for_network_preference
122from acts.test_utils.tel.tel_lookup_tables import rat_family_for_generation
Yang Liu7a2e7ee2015-12-28 15:32:44 -0800123from acts.test_utils.tel.tel_lookup_tables import rat_family_from_rat
124from acts.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
Yang Liucc1c6502016-04-19 10:50:06 -0700125from acts.test_utils.tel.tel_subscription_utils import \
126 get_default_data_sub_id
127from acts.test_utils.tel.tel_subscription_utils import \
128 get_outgoing_message_sub_id
129from acts.test_utils.tel.tel_subscription_utils import \
130 get_outgoing_voice_sub_id
131from acts.test_utils.tel.tel_subscription_utils import \
132 get_incoming_voice_sub_id
133from acts.test_utils.tel.tel_subscription_utils import \
134 get_incoming_message_sub_id
Betty Zhoua37acd32017-02-23 20:04:24 -0800135from acts.test_utils.wifi.wifi_test_utils import WifiEnums
136from acts.test_utils.wifi.wifi_test_utils import wifi_connect
137from acts.test_utils.wifi.wifi_test_utils import wifi_toggle_state
138from acts.test_utils.wifi.wifi_test_utils import reset_wifi
139from acts.test_utils.wifi.wifi_test_utils import toggle_wifi_and_wait_for_reconnection
140from acts.test_utils.wifi import wifi_constants
Yang Liu46ed7222015-12-28 14:08:52 -0800141from acts.utils import load_config
Ang Li5bd83f32016-05-23 14:39:38 -0700142
143log = logging
Ang Li73697b32015-12-03 00:41:53 +0000144
Nathan Harold123c9da2015-12-30 16:33:25 -0800145
Ang Li73697b32015-12-03 00:41:53 +0000146class TelTestUtilsError(Exception):
147 pass
148
Nathan Harold123c9da2015-12-30 16:33:25 -0800149
Betty Zhou5534e672017-03-07 13:47:10 -0800150def abort_all_tests(log, msg):
151 log.error("Aborting all ongoing tests due to: %s.", msg)
152 abort_all(msg)
153
154
Betty Zhou5b069a02016-12-06 19:23:44 -0800155def get_phone_number_by_adb(ad):
156 return ad.adb.shell("service call iphonesubinfo 13")
157
158
159def get_iccid_by_adb(ad):
160 return ad.adb.shell("service call iphonesubinfo 11")
161
162
163def get_operator_by_adb(ad):
164 return ad.adb.getprop("gsm.sim.operator.alpha")
165
166
167def get_sub_id_by_adb(ad):
168 return ad.adb.shell("service call iphonesubinfo 5")
169
170
171def setup_droid_properties_by_adb(log, ad, sim_filename=None):
Ang Li73697b32015-12-03 00:41:53 +0000172
173 # Check to see if droid already has this property
174 if hasattr(ad, 'cfg'):
175 return
176
Betty Zhou5b069a02016-12-06 19:23:44 -0800177 sim_data = None
178 if sim_filename:
179 try:
180 sim_data = load_config(sim_filename)
181 except Exception:
Betty Zhouccd171d2017-02-13 15:11:33 -0800182 log.warning("Failed to load %s!", sim_filename)
Betty Zhou5b069a02016-12-06 19:23:44 -0800183
Betty Zhou76a83f72016-12-20 14:21:11 -0800184 sub_id = get_sub_id_by_adb(ad)
Betty Zhou5b069a02016-12-06 19:23:44 -0800185 phone_number = get_phone_number_by_adb(ad) or sim_data[iccid]["phone_num"]
186 if not phone_number:
Betty Zhou5534e672017-03-07 13:47:10 -0800187 abort_all_tests(ad.log, "Failed to find valid phone number")
Betty Zhou5b069a02016-12-06 19:23:44 -0800188 sim_record = {
Betty Zhoua27e5d42017-01-17 11:33:04 -0800189 'phone_num': phone_number_formatter(phone_number),
190 'iccid': get_iccid_by_adb(ad),
191 'operator': get_operator_by_adb(ad)
192 }
Betty Zhou5b069a02016-12-06 19:23:44 -0800193 device_props = {'subscription': {sub_id: sim_record}}
Betty Zhouccd171d2017-02-13 15:11:33 -0800194 ad.log.info("subId %s SIM record: %s", sub_id, sim_record)
Betty Zhou5b069a02016-12-06 19:23:44 -0800195 setattr(ad, 'cfg', device_props)
196
197
198def setup_droid_properties(log, ad, sim_filename=None):
199
200 # Check to see if droid already has this property
201 if hasattr(ad, 'cfg'):
202 return
203
Betty Zhou9e54fc22017-01-19 12:15:53 -0800204 #The puk and pin should be provided in testbed config file in the format of
205 #"AndroidDevice": [{"serial": "84B5T15A29018214",
206 # "adb_logcat_param": "-b all",
207 # "puk": "12345678",
208 # "puk_pin": "1234"}]
209 if hasattr(ad, 'puk'):
210 if not hasattr(ad, 'puk_pin'):
Betty Zhou5534e672017-03-07 13:47:10 -0800211 abort_all_tests(ad.log, "puk_pin is not provided")
Betty Zhouccd171d2017-02-13 15:11:33 -0800212 ad.log.info("Enter PUK code and pin")
Betty Zhou9e54fc22017-01-19 12:15:53 -0800213 if not ad.droid.telephonySupplyPuk(ad.puk, ad.puk_pin):
Betty Zhou5534e672017-03-07 13:47:10 -0800214 abort_all_tests(
215 ad.log,
216 "Puk and puk_pin provided in testbed config do NOT work")
Betty Zhou9e54fc22017-01-19 12:15:53 -0800217 time.sleep(WAIT_TIME_SUPPLY_PUK_CODE)
218
Betty Zhou9e2bf402017-02-01 19:04:09 -0800219 if getattr(ad, 'data_roaming', False):
220 ad.log.info("Enable cell data roaming")
221 toggle_cell_data_roaming(ad, True)
222
Betty Zhou5b069a02016-12-06 19:23:44 -0800223 if ad.skip_sl4a:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800224 return setup_droid_properties_by_adb(
225 log, ad, sim_filename=sim_filename)
Betty Zhouccd171d2017-02-13 15:11:33 -0800226
Ang Li73697b32015-12-03 00:41:53 +0000227 device_props = {}
228 device_props['subscription'] = {}
229
230 try:
231 sim_data = load_config(sim_filename)
232 except Exception:
Betty Zhouccd171d2017-02-13 15:11:33 -0800233 log.warning("Failed to load %s!", sim_filename)
234 sim_data = {}
Ang Li73697b32015-12-03 00:41:53 +0000235 sub_info_list = ad.droid.subscriptionGetAllSubInfoList()
236 found_sims = 0
237 for sub_info in sub_info_list:
238 sub_id = sub_info['subscriptionId']
239 if sub_info['simSlotIndex'] is not INVALID_SIM_SLOT_INDEX:
240 found_sims += 1
241 sim_record = {}
Betty Zhouccd171d2017-02-13 15:11:33 -0800242 sim_serial = ad.droid.telephonyGetSimSerialNumberForSubscription(
243 sub_id)
244 if not sim_serial:
245 ad.log.error("Unable to find ICC-ID for SIM")
246 number = ad.droid.telephonyGetLine1NumberForSubscription(sub_id)
247 if not number:
248 ad.log.warn("Unable to retrieve phone number from device")
249 if sim_serial not in sim_data:
250 ad.log.error("ICCID %s is not provided in sim file %s",
251 sim_serial, sim_filename)
Betty Zhou5534e672017-03-07 13:47:10 -0800252 abort_all_tests(
253 ad.log,
254 "Failed to find valid phone number for ICCID %s" %
255 sim_serial)
Betty Zhouccd171d2017-02-13 15:11:33 -0800256 number = sim_data[sim_serial]["phone_num"]
Ang Li73697b32015-12-03 00:41:53 +0000257 sim_record['phone_num'] = number
Betty Zhouccd171d2017-02-13 15:11:33 -0800258 sim_record['iccid'] = sim_serial
Ang Li73697b32015-12-03 00:41:53 +0000259 sim_record['operator'] = get_operator_name(log, ad, sub_id)
260 device_props['subscription'][sub_id] = sim_record
Betty Zhoua37acd32017-02-23 20:04:24 -0800261 ad.log.info("SubId %s SIM record: %s", sub_id, sim_record)
Ang Li73697b32015-12-03 00:41:53 +0000262
263 if found_sims == 0:
Betty Zhouccd171d2017-02-13 15:11:33 -0800264 ad.log.warning("No Valid SIMs found in device")
Ang Li73697b32015-12-03 00:41:53 +0000265 setattr(ad, 'cfg', device_props)
266
Nathan Harold7642fc92016-05-02 18:29:11 -0700267
Yang Liu6c70e022016-03-07 16:19:42 -0800268def refresh_droid_config(log, ad):
269 """ Update Android Device cfg records for each sub_id.
270 1. Update Phone Number using Line1Number (if Line1Number is valid).
271 2. Update Operator name.
Yang Liuad9c63d2016-02-25 13:59:23 -0800272
273 Args:
274 log: log object
275 ad: android device object
Yang Liuad9c63d2016-02-25 13:59:23 -0800276
277 Returns:
Yang Liu6c70e022016-03-07 16:19:42 -0800278 None
Yang Liuad9c63d2016-02-25 13:59:23 -0800279 """
Betty Zhoua37acd32017-02-23 20:04:24 -0800280 if not hasattr(ad, 'cfg'):
281 return
Yang Liu6c70e022016-03-07 16:19:42 -0800282 for sub_id in ad.cfg['subscription']:
283 # Update Phone number
284 number = ad.droid.telephonyGetLine1NumberForSubscription(sub_id)
285 if number:
286 number = phone_number_formatter(number)
287 ad.cfg['subscription'][sub_id]['phone_num'] = number
288 # Update Operator Name
Nathan Harold7642fc92016-05-02 18:29:11 -0700289 ad.cfg['subscription'][sub_id]['operator'] = get_operator_name(log, ad,
290 sub_id)
291
Nathan Harold123c9da2015-12-30 16:33:25 -0800292
Yang Liu7ce19982016-03-09 12:20:41 -0800293def get_slot_index_from_subid(log, ad, sub_id):
294 try:
295 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
296 return info['simSlotIndex']
tturney10eda2e2016-03-30 19:55:57 -0700297 except KeyError:
Yang Liu7ce19982016-03-09 12:20:41 -0800298 return INVALID_SIM_SLOT_INDEX
299
Nathan Harold123c9da2015-12-30 16:33:25 -0800300
Ang Li73697b32015-12-03 00:41:53 +0000301def get_num_active_sims(log, ad):
302 """ Get the number of active SIM cards by counting slots
303
304 Args:
305 ad: android_device object.
306
307 Returns:
308 result: The number of loaded (physical) SIM cards
309 """
310 # using a dictionary as a cheap way to prevent double counting
311 # in the situation where multiple subscriptions are on the same SIM.
312 # yes, this is a corner corner case.
313 valid_sims = {}
314 subInfo = ad.droid.subscriptionGetAllSubInfoList()
315 for info in subInfo:
316 ssidx = info['simSlotIndex']
317 if ssidx == INVALID_SIM_SLOT_INDEX:
318 continue
319 valid_sims[ssidx] = True
320 return len(valid_sims.keys())
321
Nathan Harold123c9da2015-12-30 16:33:25 -0800322
Betty Zhoua37acd32017-02-23 20:04:24 -0800323def toggle_airplane_mode_by_adb(log, ad, new_state=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800324 """ Toggle the state of airplane mode.
325
326 Args:
327 log: log handler.
328 ad: android_device object.
329 new_state: Airplane mode state to set to.
330 If None, opposite of the current state.
331 strict_checking: Whether to turn on strict checking that checks all features.
332
333 Returns:
334 result: True if operation succeed. False if error happens.
335 """
336 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
337 if new_state == cur_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800338 ad.log.info("Airplane mode already in %s", new_state)
Betty Zhou5b069a02016-12-06 19:23:44 -0800339 return True
340 elif new_state is None:
341 new_state = not cur_state
342
343 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state))
344 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE")
345 return True
346
347
Betty Zhou28732962016-11-28 15:00:58 -0800348def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000349 """ Toggle the state of airplane mode.
350
351 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800352 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000353 ad: android_device object.
354 new_state: Airplane mode state to set to.
355 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800356 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000357
358 Returns:
359 result: True if operation succeed. False if error happens.
360 """
Betty Zhou5b069a02016-12-06 19:23:44 -0800361 if ad.skip_sl4a:
362 return toggle_airplane_mode_by_adb(log, ad, new_state)
363 else:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800364 return toggle_airplane_mode_msim(
365 log, ad, new_state, strict_checking=strict_checking)
Ang Li73697b32015-12-03 00:41:53 +0000366
Nathan Harold123c9da2015-12-30 16:33:25 -0800367
Ang Li73697b32015-12-03 00:41:53 +0000368def is_expected_event(event_to_check, events_list):
369 """ check whether event is present in the event list
370
371 Args:
372 event_to_check: event to be checked.
373 events_list: list of events
374 Returns:
375 result: True if event present in the list. False if not.
376 """
377 for event in events_list:
378 if event in event_to_check['name']:
379 return True
380 return False
381
Nathan Harold123c9da2015-12-30 16:33:25 -0800382
Ang Li73697b32015-12-03 00:41:53 +0000383def is_sim_ready(log, ad, sim_slot_id=None):
384 """ check whether SIM is ready.
385
386 Args:
387 ad: android_device object.
388 sim_slot_id: check the SIM status for sim_slot_id
389 This is optional. If this is None, check default SIM.
390
391 Returns:
392 result: True if all SIMs are ready. False if not.
393 """
394 if sim_slot_id is None:
Yang Liuaed3eef2015-12-15 18:40:25 -0800395 status = ad.droid.telephonyGetSimState()
Ang Li73697b32015-12-03 00:41:53 +0000396 else:
Yang Liuaed3eef2015-12-15 18:40:25 -0800397 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id)
Ang Li73697b32015-12-03 00:41:53 +0000398 if status != SIM_STATE_READY:
Nathan Harold123c9da2015-12-30 16:33:25 -0800399 log.info("Sim not ready")
400 return False
Ang Li73697b32015-12-03 00:41:53 +0000401 return True
402
Nathan Harold123c9da2015-12-30 16:33:25 -0800403
Ang Li73697b32015-12-03 00:41:53 +0000404def _is_expecting_event(event_recv_list):
405 """ check for more event is expected in event list
406
407 Args:
408 event_recv_list: list of events
409 Returns:
410 result: True if more events are expected. False if not.
411 """
412 for state in event_recv_list:
413 if state is False:
Nathan Harold123c9da2015-12-30 16:33:25 -0800414 return True
Ang Li73697b32015-12-03 00:41:53 +0000415 return False
416
Nathan Harold123c9da2015-12-30 16:33:25 -0800417
418def _set_event_list(event_recv_list, sub_id_list, sub_id, value):
Ang Li73697b32015-12-03 00:41:53 +0000419 """ set received event in expected event list
420
421 Args:
422 event_recv_list: list of received events
423 sub_id_list: subscription ID list
424 sub_id: subscription id of current event
425 value: True or False
426 Returns:
427 None.
428 """
429 for i in range(len(sub_id_list)):
430 if sub_id_list[i] == sub_id:
431 event_recv_list[i] = value
432
Nathan Harold123c9da2015-12-30 16:33:25 -0800433
Nathan Harold54129bb2016-09-29 19:40:52 -0700434def _wait_for_bluetooth_in_state(log, ad, state, max_wait):
435 # FIXME: These event names should be defined in a common location
436 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn'
437 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff'
Nathan Harold9b1b2f12016-10-14 12:42:57 -0700438 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT)
439 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT)
440
Nathan Harold54129bb2016-09-29 19:40:52 -0700441 ad.droid.bluetoothStartListeningForAdapterStateChange()
442 try:
443 bt_state = ad.droid.bluetoothCheckState()
444 if bt_state == state:
445 return True
446 if max_wait <= 0:
Betty Zhoua37acd32017-02-23 20:04:24 -0800447 ad.log.error("Time out: bluetooth state still %s, expecting %s",
448 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700449 return False
450
Betty Zhoua27e5d42017-01-17 11:33:04 -0800451 event = {
452 False: _BLUETOOTH_STATE_OFF_EVENT,
453 True: _BLUETOOTH_STATE_ON_EVENT
454 }[state]
Nathan Harold54129bb2016-09-29 19:40:52 -0700455 ad.ed.pop_event(event, max_wait)
456 return True
457 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800458 ad.log.error("Time out: bluetooth state still in %s, expecting %s",
459 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700460 return False
461 finally:
462 ad.droid.bluetoothStopListeningForAdapterStateChange()
463
464
465# TODO: replace this with an event-based function
466def _wait_for_wifi_in_state(log, ad, state, max_wait):
467 return _wait_for_droid_in_state(log, ad, max_wait,
468 lambda log, ad, state: \
469 (True if ad.droid.wifiCheckState() == state else False),
470 state)
471
472
Betty Zhou28732962016-11-28 15:00:58 -0800473def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000474 """ Toggle the state of airplane mode.
475
476 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800477 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000478 ad: android_device object.
479 new_state: Airplane mode state to set to.
480 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800481 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000482
483 Returns:
484 result: True if operation succeed. False if error happens.
485 """
Ang Li73697b32015-12-03 00:41:53 +0000486
487 ad.ed.clear_all_events()
488 sub_id_list = []
489
490 active_sub_info = ad.droid.subscriptionGetAllSubInfoList()
Nathan Harold123c9da2015-12-30 16:33:25 -0800491 for info in active_sub_info:
Ang Li73697b32015-12-03 00:41:53 +0000492 sub_id_list.append(info['subscriptionId'])
493
494 cur_state = ad.droid.connectivityCheckAirplaneMode()
495 if cur_state == new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800496 ad.log.info("Airplane mode already in %s", new_state)
Ang Li73697b32015-12-03 00:41:53 +0000497 return True
498 elif new_state is None:
Betty Zhoua37acd32017-02-23 20:04:24 -0800499 ad.log.info("APM Current State %s New state %s", cur_state, new_state)
Ang Li73697b32015-12-03 00:41:53 +0000500
501 if new_state is None:
502 new_state = not cur_state
503
Yang Liu8e6adff2016-02-05 10:24:04 -0800504 service_state_list = []
Ang Li73697b32015-12-03 00:41:53 +0000505 if new_state:
Yang Liu8e6adff2016-02-05 10:24:04 -0800506 service_state_list.append(SERVICE_STATE_POWER_OFF)
Betty Zhoua37acd32017-02-23 20:04:24 -0800507 ad.log.info("Turn on airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000508
509 else:
510 # If either one of these 3 events show up, it should be OK.
511 # Normal SIM, phone in service
Yang Liu8e6adff2016-02-05 10:24:04 -0800512 service_state_list.append(SERVICE_STATE_IN_SERVICE)
Ang Li73697b32015-12-03 00:41:53 +0000513 # NO SIM, or Dead SIM, or no Roaming coverage.
Yang Liu8e6adff2016-02-05 10:24:04 -0800514 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE)
515 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY)
Betty Zhoua37acd32017-02-23 20:04:24 -0800516 ad.log.info("Turn off airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000517
518 for sub_id in sub_id_list:
Nathan Harold123c9da2015-12-30 16:33:25 -0800519 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription(
520 sub_id)
Nathan Harold54129bb2016-09-29 19:40:52 -0700521
522 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Ang Li73697b32015-12-03 00:41:53 +0000523 ad.droid.connectivityToggleAirplaneMode(new_state)
524
525 event = None
526
527 try:
528 try:
Nathan Harold7642fc92016-05-02 18:29:11 -0700529 event = ad.ed.wait_for_event(
530 EventServiceStateChanged,
531 is_event_match_for_list,
532 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT,
533 field=ServiceStateContainer.SERVICE_STATE,
534 value_list=service_state_list)
Ang Li73697b32015-12-03 00:41:53 +0000535 except Empty:
536 pass
537 if event is None:
Betty Zhoua37acd32017-02-23 20:04:24 -0800538 ad.log.error("Did not get expected service state %s",
539 service_state_list)
Nathan Harold9b1b2f12016-10-14 12:42:57 -0700540 return False
541 else:
Betty Zhoua37acd32017-02-23 20:04:24 -0800542 ad.log.info("Received event: %s", event)
Ang Li73697b32015-12-03 00:41:53 +0000543 finally:
544 for sub_id in sub_id_list:
Nathan Harold123c9da2015-12-30 16:33:25 -0800545 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
546 sub_id)
Ang Li73697b32015-12-03 00:41:53 +0000547
Nathan Harold54129bb2016-09-29 19:40:52 -0700548 # APM on (new_state=True) will turn off bluetooth but may not turn it on
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800549 try:
550 if new_state and not _wait_for_bluetooth_in_state(
Betty Zhoua27e5d42017-01-17 11:33:04 -0800551 log, ad, False, timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800552 ad.log.error(
553 "Failed waiting for bluetooth during airplane mode toggle")
Betty Zhou28732962016-11-28 15:00:58 -0800554 if strict_checking: return False
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800555 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -0800556 ad.log.error("Failed to check bluetooth state due to %s", e)
Betty Zhou28732962016-11-28 15:00:58 -0800557 if strict_checking:
558 raise
Nathan Harold54129bb2016-09-29 19:40:52 -0700559
560 # APM on (new_state=True) will turn off wifi but may not turn it on
Nathan Harold450a7682016-10-12 12:57:17 -0700561 if new_state and not _wait_for_wifi_in_state(log, ad, False,
562 timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800563 ad.log.error("Failed waiting for wifi during airplane mode toggle on")
564 if strict_checking: return False
Nathan Harold54129bb2016-09-29 19:40:52 -0700565
566 if ad.droid.connectivityCheckAirplaneMode() != new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800567 ad.log.error("Set airplane mode to %s failed", new_state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700568 return False
Ang Li73697b32015-12-03 00:41:53 +0000569 return True
570
Nathan Harold123c9da2015-12-30 16:33:25 -0800571
572def wait_and_answer_call(log,
573 ad,
574 incoming_number=None,
Ang Li73697b32015-12-03 00:41:53 +0000575 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
576 """Wait for an incoming call on default voice subscription and
577 accepts the call.
578
579 Args:
580 ad: android device object.
581 incoming_number: Expected incoming number.
582 Optional. Default is None
Ang Li73697b32015-12-03 00:41:53 +0000583 incall_ui_display: after answer the call, bring in-call UI to foreground or
584 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
585 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
586 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
587 else, do nothing.
588
589 Returns:
590 True: if incoming call is received and answered successfully.
591 False: for errors
592 """
593 return wait_and_answer_call_for_subscription(
Yang Liu963c93c2016-04-05 10:52:00 -0700594 log, ad, get_incoming_voice_sub_id(ad), incoming_number,
Yang Liu855d5f82016-01-27 15:35:48 -0800595 incall_ui_display)
Nathan Harold123c9da2015-12-30 16:33:25 -0800596
Ang Li73697b32015-12-03 00:41:53 +0000597
598def wait_for_ringing_event(log, ad, wait_time):
Nathan Harold54c7c742016-08-04 19:40:44 -0700599 log.warning("***DEPRECATED*** wait_for_ringing_event()")
600 return _wait_for_ringing_event(log, ad, wait_time)
601
602
603def _wait_for_ringing_event(log, ad, wait_time):
Ang Li73697b32015-12-03 00:41:53 +0000604 """Wait for ringing event.
605
606 Args:
607 log: log object.
608 ad: android device object.
609 wait_time: max time to wait for ringing event.
610
611 Returns:
612 event_ringing if received ringing event.
613 otherwise return None.
614 """
Ang Li73697b32015-12-03 00:41:53 +0000615 event_ringing = None
616
Nathan Harold0111e202016-09-27 17:03:00 -0700617 try:
618 event_ringing = ad.ed.wait_for_event(
619 EventCallStateChanged,
620 is_event_match,
621 timeout=wait_time,
622 field=CallStateContainer.CALL_STATE,
623 value=TELEPHONY_STATE_RINGING)
Betty Zhoua37acd32017-02-23 20:04:24 -0800624 ad.log.info("Receive ringing event")
Nathan Harold0111e202016-09-27 17:03:00 -0700625 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800626 ad.log.info("No Ringing Event")
Nathan Harold0111e202016-09-27 17:03:00 -0700627 finally:
628 return event_ringing
Ang Li73697b32015-12-03 00:41:53 +0000629
Nathan Harold123c9da2015-12-30 16:33:25 -0800630
Nathan Harold54c7c742016-08-04 19:40:44 -0700631def wait_for_ringing_call(log, ad, incoming_number=None):
632 """Wait for an incoming call on default voice subscription and
Ang Li73697b32015-12-03 00:41:53 +0000633 accepts the call.
634
635 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -0700636 log: log object.
637 ad: android device object.
638 incoming_number: Expected incoming number.
639 Optional. Default is None
640
641 Returns:
642 True: if incoming call is received and answered successfully.
643 False: for errors
644 """
645 return wait_for_ringing_call_for_subscription(
646 log, ad, get_incoming_voice_sub_id(ad), incoming_number)
647
648
Betty Zhoua37acd32017-02-23 20:04:24 -0800649def wait_for_ringing_call_for_subscription(
650 log,
651 ad,
652 sub_id,
653 incoming_number=None,
654 event_tracking_started=False,
655 timeout=MAX_WAIT_TIME_CALLEE_RINGING):
Nathan Harold54c7c742016-08-04 19:40:44 -0700656 """Wait for an incoming call on specified subscription.
657
658 Args:
659 log: log object.
Ang Li73697b32015-12-03 00:41:53 +0000660 ad: android device object.
661 sub_id: subscription ID
Betty Zhoua37acd32017-02-23 20:04:24 -0800662 incoming_number: Expected incoming number. Default is None
663 event_tracking_started: True if event tracking already state outside
664 timeout: time to wait for ring
Ang Li73697b32015-12-03 00:41:53 +0000665
666 Returns:
667 True: if incoming call is received and answered successfully.
668 False: for errors
669 """
Betty Zhoua37acd32017-02-23 20:04:24 -0800670 if not event_tracking_started:
Nathan Harold54c7c742016-08-04 19:40:44 -0700671 ad.ed.clear_all_events()
672 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -0800673 event_ringing = _wait_for_ringing_event(log, ad, timeout)
674 if not event_tracking_started:
Nathan Harold54c7c742016-08-04 19:40:44 -0700675 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhoubb192482017-03-01 14:38:56 -0800676 if not event_ringing and not (
677 ad.droid.telephonyGetCallStateForSubscription(sub_id) ==
678 TELEPHONY_STATE_RINGING or ad.droid.telecomIsRinging()):
679 ad.log.info("Not in call ringing state")
680 return False
Betty Zhoua37acd32017-02-23 20:04:24 -0800681 if not incoming_number:
682 return True
683
684 result = check_phone_number_match(
685 event_ringing['data'][CallStateContainer.INCOMING_NUMBER],
686 incoming_number)
687 if not result:
688 ad.log.error(
689 "Incoming Number not match. Expected number:%s, actual number:%s",
690 incoming_number,
691 event_ringing['data'][CallStateContainer.INCOMING_NUMBER])
692 return False
693 return True
694
695
696def wait_for_call_offhook_event(
697 log,
698 ad,
Betty Zhoubb192482017-03-01 14:38:56 -0800699 sub_id,
Betty Zhoua37acd32017-02-23 20:04:24 -0800700 event_tracking_started=False,
701 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
702 """Wait for an incoming call on specified subscription.
703
704 Args:
705 log: log object.
706 ad: android device object.
707 event_tracking_started: True if event tracking already state outside
708 timeout: time to wait for event
709
710 Returns:
711 True: if call offhook event is received.
712 False: if call offhook event is not received.
713 """
714 if not event_tracking_started:
715 ad.ed.clear_all_events()
716 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
717 try:
718 ad.ed.wait_for_event(
719 EventCallStateChanged,
720 is_event_match,
721 timeout=timeout,
722 field=CallStateContainer.CALL_STATE,
723 value=TELEPHONY_STATE_OFFHOOK)
724 except Empty:
Betty Zhoubb192482017-03-01 14:38:56 -0800725 ad.log.info("No event for call state change to OFFHOOK")
Betty Zhoua37acd32017-02-23 20:04:24 -0800726 return False
727 finally:
728 if not event_tracking_started:
729 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
730 sub_id)
Nathan Harold54c7c742016-08-04 19:40:44 -0700731 return True
732
733
734def wait_and_answer_call_for_subscription(
735 log,
736 ad,
737 sub_id,
738 incoming_number=None,
Betty Zhoua37acd32017-02-23 20:04:24 -0800739 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhoua37acd32017-02-23 20:04:24 -0800740 timeout=MAX_WAIT_TIME_CALLEE_RINGING):
Nathan Harold54c7c742016-08-04 19:40:44 -0700741 """Wait for an incoming call on specified subscription and
742 accepts the call.
743
744 Args:
745 log: log object.
746 ad: android device object.
747 sub_id: subscription ID
748 incoming_number: Expected incoming number.
749 Optional. Default is None
750 incall_ui_display: after answer the call, bring in-call UI to foreground or
751 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
752 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
753 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
754 else, do nothing.
755
756 Returns:
757 True: if incoming call is received and answered successfully.
758 False: for errors
759 """
Ang Li73697b32015-12-03 00:41:53 +0000760 ad.ed.clear_all_events()
Yang Liuaed3eef2015-12-15 18:40:25 -0800761 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -0800762 result = False
Ang Li73697b32015-12-03 00:41:53 +0000763 try:
Betty Zhouf25ce442017-03-03 14:28:36 -0800764 if not _wait_for_droid_in_state(
765 log,
766 ad,
767 timeout,
768 wait_for_ringing_call_for_subscription,
769 sub_id,
770 incoming_number=None,
771 event_tracking_started=True):
Betty Zhoua37acd32017-02-23 20:04:24 -0800772 ad.log.info("Could not answer a call: phone never rang.")
773 return False
Betty Zhouf25ce442017-03-03 14:28:36 -0800774 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
Betty Zhoubb192482017-03-01 14:38:56 -0800775 ad.log.info("Accept the ring call")
Betty Zhouf25ce442017-03-03 14:28:36 -0800776 ad.droid.telecomAcceptRingingCall()
777
Betty Zhoua37acd32017-02-23 20:04:24 -0800778 if wait_for_call_offhook_event(
Betty Zhoubb192482017-03-01 14:38:56 -0800779 log, ad, sub_id, event_tracking_started=True,
780 timeout=timeout) or ad.droid.telecomIsInCall():
Betty Zhoua37acd32017-02-23 20:04:24 -0800781 ad.log.info("Call answered successfully.")
782 return True
783 else:
784 ad.log.error("Could not answer the call.")
Ang Li73697b32015-12-03 00:41:53 +0000785 return False
786 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -0800787 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -0800788 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
789 ad.droid.telecomShowInCallScreen()
790 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
791 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +0000792
Nathan Harold123c9da2015-12-30 16:33:25 -0800793
794def wait_and_reject_call(log,
795 ad,
796 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -0700797 delay_reject=WAIT_TIME_REJECT_CALL,
798 reject=True):
Ang Li73697b32015-12-03 00:41:53 +0000799 """Wait for an incoming call on default voice subscription and
800 reject the call.
801
802 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -0700803 log: log object.
Ang Li73697b32015-12-03 00:41:53 +0000804 ad: android device object.
805 incoming_number: Expected incoming number.
806 Optional. Default is None
807 delay_reject: time to wait before rejecting the call
808 Optional. Default is WAIT_TIME_REJECT_CALL
809
810 Returns:
811 True: if incoming call is received and reject successfully.
812 False: for errors
813 """
814 return wait_and_reject_call_for_subscription(
Yang Liu598b93d2016-03-22 17:07:59 -0700815 log, ad, get_incoming_voice_sub_id(ad), incoming_number, delay_reject,
816 reject)
Ang Li73697b32015-12-03 00:41:53 +0000817
Nathan Harold123c9da2015-12-30 16:33:25 -0800818
819def wait_and_reject_call_for_subscription(log,
820 ad,
821 sub_id,
822 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -0700823 delay_reject=WAIT_TIME_REJECT_CALL,
824 reject=True):
Ang Li73697b32015-12-03 00:41:53 +0000825 """Wait for an incoming call on specific subscription and
826 reject the call.
827
828 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -0700829 log: log object.
Ang Li73697b32015-12-03 00:41:53 +0000830 ad: android device object.
831 sub_id: subscription ID
832 incoming_number: Expected incoming number.
833 Optional. Default is None
834 delay_reject: time to wait before rejecting the call
835 Optional. Default is WAIT_TIME_REJECT_CALL
836
837 Returns:
838 True: if incoming call is received and reject successfully.
839 False: for errors
840 """
Ang Li73697b32015-12-03 00:41:53 +0000841
Nathan Harold54c7c742016-08-04 19:40:44 -0700842 if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
843 incoming_number):
844 log.error("Could not reject a call: phone never rang.")
845 return False
Ang Li73697b32015-12-03 00:41:53 +0000846
847 ad.ed.clear_all_events()
Yang Liuaed3eef2015-12-15 18:40:25 -0800848 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Yang Liu598b93d2016-03-22 17:07:59 -0700849 if reject is True:
850 # Delay between ringing and reject.
851 time.sleep(delay_reject)
852 log.info("Reject on callee.")
853 is_find = False
854 # Loop the call list and find the matched one to disconnect.
855 for call in ad.droid.telecomCallGetCallIds():
856 if check_phone_number_match(
857 get_number_from_tel_uri(get_call_uri(ad, call)),
858 incoming_number):
859 ad.droid.telecomCallDisconnect(call)
860 is_find = True
861 if is_find is False:
862 log.error("Did not find matching call to reject.")
863 return False
864 else:
865 # don't reject on callee. Just ignore the incoming call.
866 log.info("Received incoming call. Ignore it.")
Ang Li73697b32015-12-03 00:41:53 +0000867 try:
Yang Liu598b93d2016-03-22 17:07:59 -0700868 ad.ed.wait_for_event(
869 EventCallStateChanged,
870 is_event_match_for_list,
871 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
872 field=CallStateContainer.CALL_STATE,
873 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
Ang Li73697b32015-12-03 00:41:53 +0000874 except Empty:
875 log.error("No onCallStateChangedIdle event received.")
876 return False
877 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -0800878 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +0000879 return True
880
Nathan Harold123c9da2015-12-30 16:33:25 -0800881
Ang Li73697b32015-12-03 00:41:53 +0000882def hangup_call(log, ad):
883 """Hang up ongoing active call.
Nathan Harold54c7c742016-08-04 19:40:44 -0700884
885 Args:
886 log: log object.
887 ad: android device object.
888
889 Returns:
Nathan Haroldd2d30092016-10-12 12:45:55 -0700890 True: if all calls are cleared
Nathan Harold54c7c742016-08-04 19:40:44 -0700891 False: for errors
Ang Li73697b32015-12-03 00:41:53 +0000892 """
Nathan Haroldd2d30092016-10-12 12:45:55 -0700893 # short circuit in case no calls are active
894 if not ad.droid.telecomIsInCall():
895 return True
Ang Li73697b32015-12-03 00:41:53 +0000896 ad.ed.clear_all_events()
Yang Liuaed3eef2015-12-15 18:40:25 -0800897 ad.droid.telephonyStartTrackingCallState()
Ang Li73697b32015-12-03 00:41:53 +0000898 log.info("Hangup call.")
899 ad.droid.telecomEndCall()
900
901 try:
Nathan Harold4a144a42016-09-19 14:16:24 -0700902 ad.ed.wait_for_event(
903 EventCallStateChanged,
904 is_event_match,
905 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
906 field=CallStateContainer.CALL_STATE,
907 value=TELEPHONY_STATE_IDLE)
Ang Li73697b32015-12-03 00:41:53 +0000908 except Empty:
909 if ad.droid.telecomIsInCall():
910 log.error("Hangup call failed.")
911 return False
912 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -0800913 ad.droid.telephonyStopTrackingCallStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000914 return True
915
Nathan Harold123c9da2015-12-30 16:33:25 -0800916
Ang Li73697b32015-12-03 00:41:53 +0000917def disconnect_call_by_id(log, ad, call_id):
918 """Disconnect call by call id.
919 """
920 ad.droid.telecomCallDisconnect(call_id)
921 return True
922
Nathan Harold54c7c742016-08-04 19:40:44 -0700923
Yang Liu3197de22016-04-11 13:59:41 -0700924def _phone_number_remove_prefix(number):
925 """Remove the country code and other prefix from the input phone number.
926 Currently only handle phone number with the following formats:
927 (US phone number format)
928 +1abcxxxyyyy
929 1abcxxxyyyy
930 abcxxxyyyy
931 abc xxx yyyy
932 abc.xxx.yyyy
933 abc-xxx-yyyy
934 (EEUK phone number format)
935 +44abcxxxyyyy
936 0abcxxxyyyy
937
938 Args:
939 number: input phone number
940
941 Returns:
942 Phone number without country code or prefix
943 """
Yang Liu8fcffd52016-05-31 18:38:35 -0700944 if number is None:
945 return None, None
Betty Zhou9e54fc22017-01-19 12:15:53 -0800946 for country_code in COUNTRY_CODE_LIST:
Yang Liu3197de22016-04-11 13:59:41 -0700947 if number.startswith(country_code):
948 return number[len(country_code):], country_code
949 if number[0] == "1" or number[0] == "0":
950 return number[1:], None
Yang Liu8fcffd52016-05-31 18:38:35 -0700951 return number, None
Yang Liu3197de22016-04-11 13:59:41 -0700952
Nathan Harold123c9da2015-12-30 16:33:25 -0800953
Ang Li73697b32015-12-03 00:41:53 +0000954def check_phone_number_match(number1, number2):
955 """Check whether two input phone numbers match or not.
956
957 Compare the two input phone numbers.
958 If they match, return True; otherwise, return False.
959 Currently only handle phone number with the following formats:
960 (US phone number format)
961 +1abcxxxyyyy
962 1abcxxxyyyy
963 abcxxxyyyy
964 abc xxx yyyy
965 abc.xxx.yyyy
966 abc-xxx-yyyy
Yang Liu3197de22016-04-11 13:59:41 -0700967 (EEUK phone number format)
968 +44abcxxxyyyy
969 0abcxxxyyyy
970
971 There are some scenarios we can not verify, one example is:
972 number1 = +15555555555, number2 = 5555555555
973 (number2 have no country code)
Ang Li73697b32015-12-03 00:41:53 +0000974
975 Args:
976 number1: 1st phone number to be compared.
977 number2: 2nd phone number to be compared.
978
979 Returns:
980 True if two phone numbers match. Otherwise False.
981 """
Betty Zhou9e54fc22017-01-19 12:15:53 -0800982 # Handle extra country code attachment when matching phone number
983 if number1 in number2 or number2 in number1:
984 return True
Yang Liu3197de22016-04-11 13:59:41 -0700985 # Remove country code and prefix
986 number1, country_code1 = _phone_number_remove_prefix(number1)
987 number2, country_code2 = _phone_number_remove_prefix(number2)
Nathan Harold54c7c742016-08-04 19:40:44 -0700988 if ((country_code1 is not None) and (country_code2 is not None) and
Yang Liu3197de22016-04-11 13:59:41 -0700989 (country_code1 != country_code2)):
Betty Zhou9e54fc22017-01-19 12:15:53 -0800990 logging.info("country_code1 %s and country_code2 %s does not match" %
991 (country_code1, country_code2))
Yang Liu3197de22016-04-11 13:59:41 -0700992 return False
Ang Li73697b32015-12-03 00:41:53 +0000993 # Remove white spaces, dashes, dots
Yang Liu3197de22016-04-11 13:59:41 -0700994 number1 = phone_number_formatter(number1)
995 number2 = phone_number_formatter(number2)
Betty Zhou9e54fc22017-01-19 12:15:53 -0800996 if number1 != number2:
997 logging.info("phone number1 %s and number2 %s does not match" %
998 (number1, number2))
999 return False
1000 return True
Ang Li73697b32015-12-03 00:41:53 +00001001
1002
Betty Zhoubb192482017-03-01 14:38:56 -08001003def initiate_call(log,
1004 ad,
1005 callee_number,
1006 emergency=False,
1007 timeout=MAX_WAIT_TIME_CALL_INITIATION,
1008 checking_interval=5):
Ang Li73697b32015-12-03 00:41:53 +00001009 """Make phone call from caller to callee.
1010
1011 Args:
1012 ad_caller: Caller android device object.
1013 callee_number: Callee phone number.
1014 emergency : specify the call is emergency.
1015 Optional. Default value is False.
1016
1017 Returns:
1018 result: if phone call is placed successfully.
1019 """
Betty Zhoubb192482017-03-01 14:38:56 -08001020 ad.ed.clear_all_events()
1021 sub_id = get_outgoing_voice_sub_id(ad)
1022 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001023
1024 try:
1025 # Make a Call
Betty Zhoubb192482017-03-01 14:38:56 -08001026 ad.log.info("Make a phone call to %s", callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001027 if emergency:
Betty Zhoubb192482017-03-01 14:38:56 -08001028 ad.droid.telecomCallEmergencyNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001029 else:
Betty Zhoubb192482017-03-01 14:38:56 -08001030 ad.droid.telecomCallNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001031
1032 # Verify OFFHOOK event
Betty Zhoubb192482017-03-01 14:38:56 -08001033 checking_retries = int(timeout / checking_interval)
1034 for i in range(checking_retries):
1035 if (ad.droid.telecomIsInCall() and
1036 ad.droid.telephonyGetCallState() == TELEPHONY_STATE_OFFHOOK
1037 and ad.droid.telecomGetCallState() ==
1038 TELEPHONY_STATE_OFFHOOK) or wait_for_call_offhook_event(
1039 log, ad, sub_id, True, checking_interval):
1040 return True
1041 ad.log.error(
1042 "Make call to %s fail. telecomIsInCall:%s, Telecom State:%s,"
1043 " Telephony State:%s", callee_number, ad.droid.telecomIsInCall(),
1044 ad.droid.telephonyGetCallState(), ad.droid.telecomGetCallState())
Ang Li73697b32015-12-03 00:41:53 +00001045 return False
1046 finally:
Betty Zhoubb192482017-03-01 14:38:56 -08001047 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001048
Nathan Harold123c9da2015-12-30 16:33:25 -08001049
Yang Liu598b93d2016-03-22 17:07:59 -07001050def call_reject(log, ad_caller, ad_callee, reject=True):
1051 """Caller call Callee, then reject on callee.
1052
1053
1054 """
1055 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
1056 subid_callee = ad_callee.incoming_voice_sub_id
Betty Zhoua37acd32017-02-23 20:04:24 -08001057 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
1058 subid_callee)
Yang Liu598b93d2016-03-22 17:07:59 -07001059 return call_reject_for_subscription(log, ad_caller, ad_callee,
1060 subid_caller, subid_callee, reject)
1061
1062
1063def call_reject_for_subscription(log,
1064 ad_caller,
1065 ad_callee,
1066 subid_caller,
1067 subid_callee,
1068 reject=True):
1069 """
1070 """
1071
1072 class _CallSequenceException(Exception):
1073 pass
1074
1075 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num']
1076 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num']
1077
Betty Zhoua37acd32017-02-23 20:04:24 -08001078 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Yang Liu598b93d2016-03-22 17:07:59 -07001079 try:
1080 if not initiate_call(log, ad_caller, callee_number):
1081 raise _CallSequenceException("Initiate call failed.")
1082
1083 if not wait_and_reject_call_for_subscription(
1084 log, ad_callee, subid_callee, caller_number,
1085 WAIT_TIME_REJECT_CALL, reject):
1086 raise _CallSequenceException("Reject call fail.")
1087 # Check if incoming call is cleared on callee or not.
1088 if ad_callee.droid.telephonyGetCallStateForSubscription(
1089 subid_callee) == TELEPHONY_STATE_RINGING:
1090 raise _CallSequenceException("Incoming call is not cleared.")
1091 # Hangup on caller
1092 hangup_call(log, ad_caller)
1093 except _CallSequenceException as e:
1094 log.error(e)
1095 return False
1096 return True
1097
1098
Nathan Harold123c9da2015-12-30 16:33:25 -08001099def call_reject_leave_message(log,
1100 ad_caller,
1101 ad_callee,
1102 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08001103 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00001104 """On default voice subscription, Call from caller to callee,
1105 reject on callee, caller leave a voice mail.
1106
1107 1. Caller call Callee.
1108 2. Callee reject incoming call.
1109 3. Caller leave a voice mail.
1110 4. Verify callee received the voice mail notification.
1111
1112 Args:
1113 ad_caller: caller android device object.
1114 ad_callee: callee android device object.
1115 verify_caller_func: function to verify caller is in correct state while in-call.
1116 This is optional, default is None.
1117 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08001118 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00001119
1120 Returns:
1121 True: if voice message is received on callee successfully.
1122 False: for errors
1123 """
Yang Liu963c93c2016-04-05 10:52:00 -07001124 subid_caller = get_outgoing_voice_sub_id(ad_caller)
1125 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08001126 return call_reject_leave_message_for_subscription(
1127 log, ad_caller, ad_callee, subid_caller, subid_callee,
1128 verify_caller_func, wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00001129
Nathan Harold123c9da2015-12-30 16:33:25 -08001130
1131def call_reject_leave_message_for_subscription(
1132 log,
1133 ad_caller,
1134 ad_callee,
1135 subid_caller,
1136 subid_callee,
1137 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08001138 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00001139 """On specific voice subscription, Call from caller to callee,
1140 reject on callee, caller leave a voice mail.
1141
1142 1. Caller call Callee.
1143 2. Callee reject incoming call.
1144 3. Caller leave a voice mail.
1145 4. Verify callee received the voice mail notification.
1146
1147 Args:
1148 ad_caller: caller android device object.
1149 ad_callee: callee android device object.
1150 subid_caller: caller's subscription id.
1151 subid_callee: callee's subscription id.
1152 verify_caller_func: function to verify caller is in correct state while in-call.
1153 This is optional, default is None.
1154 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08001155 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00001156
1157 Returns:
1158 True: if voice message is received on callee successfully.
1159 False: for errors
1160 """
Nathan Harold123c9da2015-12-30 16:33:25 -08001161
Ang Li73697b32015-12-03 00:41:53 +00001162 class _CallSequenceException(Exception):
1163 pass
1164 # Currently this test utility only works for TMO and ATT and SPT.
1165 # It does not work for VZW (see b/21559800)
1166 # "with VVM TelephonyManager APIs won't work for vm"
1167
1168 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num']
1169 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num']
1170
Betty Zhoua37acd32017-02-23 20:04:24 -08001171 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001172
1173 try:
1174
1175 if not initiate_call(log, ad_caller, callee_number):
1176 raise _CallSequenceException("Initiate call failed.")
1177
1178 if not wait_and_reject_call_for_subscription(
Nathan Harold4a144a42016-09-19 14:16:24 -07001179 log, ad_callee, subid_callee, incoming_number=caller_number):
Ang Li73697b32015-12-03 00:41:53 +00001180 raise _CallSequenceException("Reject call fail.")
1181
Yang Liuaed3eef2015-12-15 18:40:25 -08001182 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001183 subid_callee)
Yang Liuaed3eef2015-12-15 18:40:25 -08001184 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001185 subid_callee)
1186
1187 # -1 means there are unread voice mail, but the count is unknown
1188 # 0 means either this API not working (VZW) or no unread voice mail.
1189 if voice_mail_count_before != 0:
1190 log.warning("--Pending new Voice Mail, please clear on phone.--")
1191
1192 # ensure that all internal states are updated in telecom
1193 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
1194 ad_callee.ed.clear_all_events()
1195
1196 if verify_caller_func and not verify_caller_func(log, ad_caller):
Nathan Harold123c9da2015-12-30 16:33:25 -08001197 raise _CallSequenceException("Caller not in correct state!")
Ang Li73697b32015-12-03 00:41:53 +00001198
Yang Liu7a2e7ee2015-12-28 15:32:44 -08001199 # TODO: b/26293512 Need to play some sound to leave message.
1200 # Otherwise carrier voice mail server may drop this voice mail.
Ang Li73697b32015-12-03 00:41:53 +00001201
1202 time.sleep(wait_time_in_call)
1203
1204 if not verify_caller_func:
1205 caller_state_result = ad_caller.droid.telecomIsInCall()
1206 else:
1207 caller_state_result = verify_caller_func(log, ad_caller)
1208 if not caller_state_result:
1209 raise _CallSequenceException(
Nathan Harold123c9da2015-12-30 16:33:25 -08001210 "Caller not in correct state after {} seconds".format(
1211 wait_time_in_call))
Ang Li73697b32015-12-03 00:41:53 +00001212
1213 if not hangup_call(log, ad_caller):
Nathan Harold123c9da2015-12-30 16:33:25 -08001214 raise _CallSequenceException("Error in Hanging-Up Call")
Ang Li73697b32015-12-03 00:41:53 +00001215
1216 log.info("Wait for voice mail indicator on callee.")
1217 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08001218 event = ad_callee.ed.wait_for_event(
1219 EventMessageWaitingIndicatorChanged,
1220 _is_on_message_waiting_event_true)
Ang Li73697b32015-12-03 00:41:53 +00001221 log.info(event)
1222 except Empty:
Nathan Harold123c9da2015-12-30 16:33:25 -08001223 raise _CallSequenceException("No expected event {}.".format(
1224 EventMessageWaitingIndicatorChanged))
Yang Liuaed3eef2015-12-15 18:40:25 -08001225 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001226 subid_callee)
Betty Zhoua37acd32017-02-23 20:04:24 -08001227 ad_callee.log.info(
1228 "telephonyGetVoiceMailCount output - before: %s, after: %s",
1229 voice_mail_count_before, voice_mail_count_after)
Ang Li73697b32015-12-03 00:41:53 +00001230
1231 # voice_mail_count_after should:
1232 # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
1233 # or equals to -1 [For TMO]
1234 # -1 means there are unread voice mail, but the count is unknown
Nathan Harold123c9da2015-12-30 16:33:25 -08001235 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
Ang Li73697b32015-12-03 00:41:53 +00001236 voice_mail_count_after):
Yang Liuaed3eef2015-12-15 18:40:25 -08001237 log.error("telephonyGetVoiceMailCount output is incorrect.")
Ang Li73697b32015-12-03 00:41:53 +00001238 return False
1239
1240 except _CallSequenceException as e:
1241 log.error(e)
1242 return False
1243 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001244 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001245 subid_callee)
1246 return True
1247
Nathan Harold123c9da2015-12-30 16:33:25 -08001248
Ang Li73697b32015-12-03 00:41:53 +00001249def call_voicemail_erase_all_pending_voicemail(log, ad):
1250 """Script for phone to erase all pending voice mail.
1251 This script only works for TMO and ATT and SPT currently.
1252 This script only works if phone have already set up voice mail options,
1253 and phone should disable password protection for voice mail.
1254
1255 1. If phone don't have pending voice message, return True.
1256 2. Dial voice mail number.
1257 For TMO, the number is '123'
1258 For ATT, the number is phone's number
1259 For SPT, the number is phone's number
1260 3. Wait for voice mail connection setup.
1261 4. Wait for voice mail play pending voice message.
1262 5. Send DTMF to delete one message.
1263 The digit is '7'.
1264 6. Repeat steps 4 and 5 until voice mail server drop this call.
1265 (No pending message)
Yang Liuaed3eef2015-12-15 18:40:25 -08001266 6. Check telephonyGetVoiceMailCount result. it should be 0.
Ang Li73697b32015-12-03 00:41:53 +00001267
1268 Args:
1269 log: log object
1270 ad: android device object
1271 Returns:
1272 False if error happens. True is succeed.
1273 """
1274 log.info("Erase all pending voice mail.")
Yang Liuaed3eef2015-12-15 18:40:25 -08001275 if ad.droid.telephonyGetVoiceMailCount() == 0:
Ang Li73697b32015-12-03 00:41:53 +00001276 log.info("No Pending voice mail.")
1277 return True
1278
1279 voice_mail_number = get_voice_mail_number(log, ad)
1280
1281 if not initiate_call(log, ad, voice_mail_number):
1282 log.error("Initiate call failed.")
1283 return False
Yang Liudf164e32016-01-07 16:49:32 -08001284 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00001285 callId = ad.droid.telecomCallGetCallIds()[0]
Yang Liudf164e32016-01-07 16:49:32 -08001286 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00001287 count = MAX_SAVED_VOICE_MAIL
Nathan Harold123c9da2015-12-30 16:33:25 -08001288 while (is_phone_in_call(log, ad) and (count > 0)):
Ang Li73697b32015-12-03 00:41:53 +00001289 log.info("Press 7 to delete voice mail.")
1290 ad.droid.telecomCallPlayDtmfTone(callId, VOICEMAIL_DELETE_DIGIT)
1291 ad.droid.telecomCallStopDtmfTone(callId)
Yang Liudf164e32016-01-07 16:49:32 -08001292 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00001293 count -= 1
1294 log.info("Voice mail server dropped this call.")
Yang Liuaed3eef2015-12-15 18:40:25 -08001295 # wait for telephonyGetVoiceMailCount to update correct result
Yang Liudf164e32016-01-07 16:49:32 -08001296 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
Nathan Harold123c9da2015-12-30 16:33:25 -08001297 while ((remaining_time > 0) and
1298 (ad.droid.telephonyGetVoiceMailCount() != 0)):
Ang Li73697b32015-12-03 00:41:53 +00001299 time.sleep(1)
1300 remaining_time -= 1
Yang Liuaed3eef2015-12-15 18:40:25 -08001301 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
Betty Zhoua37acd32017-02-23 20:04:24 -08001302 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
Ang Li73697b32015-12-03 00:41:53 +00001303 return (current_voice_mail_count == 0)
1304
Nathan Harold123c9da2015-12-30 16:33:25 -08001305
Ang Li73697b32015-12-03 00:41:53 +00001306def _is_on_message_waiting_event_true(event):
1307 """Private function to return if the received EventMessageWaitingIndicatorChanged
Yang Liudc8564b2016-01-27 14:15:37 -08001308 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
Ang Li73697b32015-12-03 00:41:53 +00001309 """
Yang Liudc8564b2016-01-27 14:15:37 -08001310 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
Ang Li73697b32015-12-03 00:41:53 +00001311
Nathan Harold123c9da2015-12-30 16:33:25 -08001312
1313def call_setup_teardown(log,
1314 ad_caller,
1315 ad_callee,
1316 ad_hangup=None,
1317 verify_caller_func=None,
1318 verify_callee_func=None,
1319 wait_time_in_call=WAIT_TIME_IN_CALL,
1320 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
Ang Li73697b32015-12-03 00:41:53 +00001321 """ Call process, including make a phone call from caller,
1322 accept from callee, and hang up. The call is on default voice subscription
1323
1324 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08001325 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00001326
1327 Args:
1328 ad_caller: Caller Android Device Object.
1329 ad_callee: Callee Android Device Object.
1330 ad_hangup: Android Device Object end the phone call.
1331 Optional. Default value is None, and phone call will continue.
1332 verify_call_mode_caller: func_ptr to verify caller in correct mode
1333 Optional. Default is None
1334 verify_call_mode_caller: func_ptr to verify caller in correct mode
1335 Optional. Default is None
1336 incall_ui_display: after answer the call, bring in-call UI to foreground or
1337 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1338 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1339 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1340 else, do nothing.
1341
1342 Returns:
1343 True if call process without any error.
1344 False if error happened.
1345
1346 """
Yang Liu963c93c2016-04-05 10:52:00 -07001347 subid_caller = get_outgoing_voice_sub_id(ad_caller)
1348 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08001349 return call_setup_teardown_for_subscription(
1350 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
1351 verify_caller_func, verify_callee_func, wait_time_in_call,
1352 incall_ui_display)
Ang Li73697b32015-12-03 00:41:53 +00001353
1354
Nathan Harold123c9da2015-12-30 16:33:25 -08001355def call_setup_teardown_for_subscription(
1356 log,
1357 ad_caller,
1358 ad_callee,
1359 subid_caller,
1360 subid_callee,
1361 ad_hangup=None,
1362 verify_caller_func=None,
1363 verify_callee_func=None,
1364 wait_time_in_call=WAIT_TIME_IN_CALL,
1365 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
Ang Li73697b32015-12-03 00:41:53 +00001366 """ Call process, including make a phone call from caller,
1367 accept from callee, and hang up. The call is on specified subscription
1368
1369 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08001370 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00001371
1372 Args:
1373 ad_caller: Caller Android Device Object.
1374 ad_callee: Callee Android Device Object.
1375 subid_caller: Caller subscription ID
1376 subid_callee: Callee subscription ID
1377 ad_hangup: Android Device Object end the phone call.
1378 Optional. Default value is None, and phone call will continue.
1379 verify_call_mode_caller: func_ptr to verify caller in correct mode
1380 Optional. Default is None
1381 verify_call_mode_caller: func_ptr to verify caller in correct mode
1382 Optional. Default is None
1383 incall_ui_display: after answer the call, bring in-call UI to foreground or
1384 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1385 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1386 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1387 else, do nothing.
1388
1389 Returns:
1390 True if call process without any error.
1391 False if error happened.
1392
1393 """
Yang Liu13406292016-02-23 14:58:25 -08001394 CHECK_INTERVAL = 3
Betty Zhoubb192482017-03-01 14:38:56 -08001395 result = True
Nathan Harold123c9da2015-12-30 16:33:25 -08001396
Ang Li73697b32015-12-03 00:41:53 +00001397 class _CallSequenceException(Exception):
1398 pass
1399
1400 caller_number = ad_caller.cfg['subscription'][subid_caller]['phone_num']
1401 callee_number = ad_callee.cfg['subscription'][subid_callee]['phone_num']
1402
Betty Zhoua37acd32017-02-23 20:04:24 -08001403 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001404
1405 try:
1406 if not initiate_call(log, ad_caller, callee_number):
1407 raise _CallSequenceException("Initiate call failed.")
1408
1409 if not wait_and_answer_call_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08001410 log,
1411 ad_callee,
1412 subid_callee,
1413 incoming_number=caller_number,
Ang Li73697b32015-12-03 00:41:53 +00001414 incall_ui_display=incall_ui_display):
1415 raise _CallSequenceException("Answer call fail.")
1416
1417 # ensure that all internal states are updated in telecom
1418 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
1419
1420 if verify_caller_func and not verify_caller_func(log, ad_caller):
Nathan Harold123c9da2015-12-30 16:33:25 -08001421 raise _CallSequenceException("Caller not in correct state!")
Ang Li73697b32015-12-03 00:41:53 +00001422 if verify_callee_func and not verify_callee_func(log, ad_callee):
Nathan Harold123c9da2015-12-30 16:33:25 -08001423 raise _CallSequenceException("Callee not in correct state!")
Ang Li73697b32015-12-03 00:41:53 +00001424
Yang Liu13406292016-02-23 14:58:25 -08001425 elapsed_time = 0
Nathan Harold7642fc92016-05-02 18:29:11 -07001426 while (elapsed_time < wait_time_in_call):
1427 CHECK_INTERVAL = min(CHECK_INTERVAL,
1428 wait_time_in_call - elapsed_time)
Yang Liu13406292016-02-23 14:58:25 -08001429 time.sleep(CHECK_INTERVAL)
1430 elapsed_time += CHECK_INTERVAL
1431 if not verify_caller_func:
1432 caller_state_result = ad_caller.droid.telecomIsInCall()
1433 else:
1434 caller_state_result = verify_caller_func(log, ad_caller)
1435 if not caller_state_result:
1436 raise _CallSequenceException(
1437 "Caller not in correct state at <{}>/<{}> second.".format(
1438 elapsed_time, wait_time_in_call))
1439 if not verify_callee_func:
1440 callee_state_result = ad_callee.droid.telecomIsInCall()
1441 else:
1442 callee_state_result = verify_callee_func(log, ad_callee)
1443 if not callee_state_result:
1444 raise _CallSequenceException(
1445 "Callee not in correct state at <{}>/<{}> second.".format(
1446 elapsed_time, wait_time_in_call))
Ang Li73697b32015-12-03 00:41:53 +00001447
1448 if not ad_hangup:
1449 return True
1450
1451 if not hangup_call(log, ad_hangup):
Nathan Harold123c9da2015-12-30 16:33:25 -08001452 raise _CallSequenceException("Error in Hanging-Up Call")
Ang Li73697b32015-12-03 00:41:53 +00001453
1454 return True
1455
1456 except _CallSequenceException as e:
1457 log.error(e)
Betty Zhoubb192482017-03-01 14:38:56 -08001458 result = False
Ang Li73697b32015-12-03 00:41:53 +00001459 return False
1460 finally:
Betty Zhoubb192482017-03-01 14:38:56 -08001461 if ad_hangup or not result:
Ang Li73697b32015-12-03 00:41:53 +00001462 for ad in [ad_caller, ad_callee]:
1463 try:
1464 if ad.droid.telecomIsInCall():
1465 ad.droid.telecomEndCall()
1466 except Exception as e:
1467 log.error(str(e))
1468
Nathan Harold123c9da2015-12-30 16:33:25 -08001469
Betty Zhoua37acd32017-02-23 20:04:24 -08001470def phone_number_formatter(input_string, formatter=None):
Ang Li73697b32015-12-03 00:41:53 +00001471 """Get expected format of input phone number string.
1472
1473 Args:
1474 input_string: (string) input phone number.
1475 The input could be 10/11/12 digital, with or without " "/"-"/"."
Betty Zhoua37acd32017-02-23 20:04:24 -08001476 formatter: (int) expected format, this could be 7/10/11/12
1477 if formatter is 7: output string would be 7 digital number.
1478 if formatter is 10: output string would be 10 digital (standard) number.
1479 if formatter is 11: output string would be "1" + 10 digital number.
1480 if formatter is 12: output string would be "+1" + 10 digital number.
Ang Li73697b32015-12-03 00:41:53 +00001481
1482 Returns:
1483 If no error happen, return phone number in expected format.
1484 Else, return None.
1485 """
1486 # make sure input_string is 10 digital
1487 # Remove white spaces, dashes, dots
Nathan Harold123c9da2015-12-30 16:33:25 -08001488 input_string = input_string.replace(" ", "").replace("-", "").replace(".",
1489 "")
Betty Zhoua37acd32017-02-23 20:04:24 -08001490 if not formatter:
Nathan Haroldae6a0da2016-03-16 20:56:47 +00001491 return input_string
Ang Li73697b32015-12-03 00:41:53 +00001492 # Remove "1" or "+1"from front
1493 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT and
Nathan Harold123c9da2015-12-30 16:33:25 -08001494 input_string[0] == "1"):
Ang Li73697b32015-12-03 00:41:53 +00001495 input_string = input_string[1:]
1496 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT and
1497 input_string[0:2] == "+1"):
1498 input_string = input_string[2:]
1499 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT and
Betty Zhoua37acd32017-02-23 20:04:24 -08001500 formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT):
Ang Li73697b32015-12-03 00:41:53 +00001501 return input_string
1502 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
1503 return None
1504 # change input_string according to format
Betty Zhoua37acd32017-02-23 20:04:24 -08001505 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08001506 input_string = "+1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001507 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08001508 input_string = "1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001509 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00001510 input_string = input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001511 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00001512 input_string = input_string[3:]
1513 else:
1514 return None
1515 return input_string
1516
Nathan Harold123c9da2015-12-30 16:33:25 -08001517
Ang Li73697b32015-12-03 00:41:53 +00001518def get_internet_connection_type(log, ad):
1519 """Get current active connection type name.
1520
1521 Args:
1522 log: Log object.
1523 ad: Android Device Object.
1524 Returns:
1525 current active connection type name.
1526 """
1527 if not ad.droid.connectivityNetworkIsConnected():
1528 return 'none'
1529 return connection_type_from_type_string(
1530 ad.droid.connectivityNetworkGetActiveConnectionTypeName())
1531
Nathan Harold123c9da2015-12-30 16:33:25 -08001532
1533def verify_http_connection(log,
1534 ad,
1535 url="http://www.google.com/",
1536 retry=3,
1537 retry_interval=5):
Ang Li73697b32015-12-03 00:41:53 +00001538 """Make ping request and return status.
1539
1540 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001541 log: log object
Ang Li73697b32015-12-03 00:41:53 +00001542 ad: Android Device Object.
1543 url: Optional. The ping request will be made to this URL.
1544 Default Value is "http://www.google.com/".
1545
1546 """
Nathan Harold123c9da2015-12-30 16:33:25 -08001547 for i in range(0, retry + 1):
Ang Li73697b32015-12-03 00:41:53 +00001548
1549 try:
1550 http_response = ad.droid.httpPing(url)
1551 except:
1552 http_response = None
1553
1554 # If httpPing failed, it may return {} (if phone just turn off APM) or
1555 # None (regular fail)
1556 # So here use "if http_response" to see if it pass or fail
Nathan Harold123c9da2015-12-30 16:33:25 -08001557 if http_response:
Betty Zhoua37acd32017-02-23 20:04:24 -08001558 ad.log.info("Verify Internet succeeded")
Ang Li73697b32015-12-03 00:41:53 +00001559 return True
1560 else:
1561 if i < retry:
1562 time.sleep(retry_interval)
Betty Zhoua37acd32017-02-23 20:04:24 -08001563 ad.log.info("Verify Internet retry failed after %s second",
1564 i * retry_interval)
Ang Li73697b32015-12-03 00:41:53 +00001565 return False
1566
1567
Betty Zhouccd171d2017-02-13 15:11:33 -08001568def _generate_file_name_and_out_path(url, out_path):
1569 file_name = url.split("/")[-1]
1570 if not out_path:
1571 out_path = "/sdcard/Download/%s" % file_name
1572 elif out_path.endswith("/"):
1573 out_path = os.path.join(out_path, file_name)
1574 else:
1575 file_name = out_path.split("/")[-1]
1576 return file_name, out_path
1577
1578
1579def _check_file_existance(ad, file_name, out_path, expected_file_size=None):
1580 """Check file existance by file_name and out_path. If expected_file_size
1581 is provided, then also check if the file meet the file size requirement.
1582 """
1583 if out_path.endswith("/"):
1584 out_path = os.path.join(out_path, file_name)
1585 out = ad.adb.shell("ls -l %s" % out_path, ignore_status=True)
1586 # Handle some old version adb returns error message "No such" into std_out
1587 if "No such" not in out and file_name in out:
1588 if expected_file_size:
1589 file_size = int(out.split(" ")[4])
1590 if file_size >= expected_file_size:
1591 ad.log.info("File %s of size %s is in %s", file_name,
1592 file_size, out_path)
1593 return True
1594 else:
1595 ad.log.error(
1596 "File size for %s in %s is %s does not meet expected %s",
1597 file_name, out_path, file_size, expected_file_size)
1598 return False
1599 else:
1600 ad.log.info("File %s is in %s", file_name, out_path)
1601 return True
1602 else:
1603 ad.log.error("File %s does not exist in %s.", file_name, out_path)
1604 return False
1605
1606
1607def http_file_download_by_adb(log,
1608 ad,
1609 url,
1610 out_path=None,
1611 expected_file_size=None,
1612 remove_file_after_check=True,
1613 timeout=300,
1614 limit_rate=100000,
1615 retry=3):
1616 """Download http file by adb curl.
1617
1618 Args:
1619 log: log object
1620 ad: Android Device Object.
1621 url: The url that file to be downloaded from".
1622 out_path: Optional. Where to download file to.
1623 out_path is /sdcard/Download/ by default.
1624 expected_file_size: Optional. Provided if checking the download file meet
1625 expected file size in unit of byte.
1626 remove_file_after_check: Whether to remove the downloaded file after
1627 check.
1628 timeout: timeout for file download to complete.
1629 limit_rate: download rate in bps. None, if do not apply rate limit.
1630 retry: the retry request times provided in curl command.
1631 """
1632 file_name, out_path = _generate_file_name_and_out_path(url, out_path)
1633 curl_cmd = "curl"
1634 if limit_rate:
1635 curl_cmd += " --limit-rate %s" % limit_rate
1636 if retry:
1637 curl_cmd += " --retry %s" % retry
1638 curl_cmd += " --url %s > %s" % (url, out_path)
1639 try:
1640 ad.log.info("Download file from %s to %s by adb shell command %s", url,
1641 out_path, curl_cmd)
1642 ad.adb.shell(curl_cmd, timeout=timeout)
1643 if _check_file_existance(ad, file_name, out_path, expected_file_size):
1644 ad.log.info("File %s is downloaded from %s successfully",
1645 file_name, url)
1646 return True
1647 else:
1648 ad.log.warn("Fail to download file from %s", url)
1649 return False
1650 except Exception as e:
1651 ad.log.warn("Download file from %s failed with exception %s", url, e)
1652 return False
1653 finally:
1654 if remove_file_after_check:
1655 ad.log.info("Remove the downloaded file %s", out_path)
1656 ad.adb.shell("rm %s" % out_path, ignore_status=True)
1657
1658
1659def http_file_download_by_sl4a(log,
1660 ad,
1661 url,
1662 out_path=None,
1663 expected_file_size=None,
1664 remove_file_after_check=True,
1665 timeout=300):
1666 """Download http file by sl4a RPC call.
1667
1668 Args:
1669 log: log object
1670 ad: Android Device Object.
1671 url: The url that file to be downloaded from".
1672 out_path: Optional. Where to download file to.
1673 out_path is /sdcard/Download/ by default.
1674 expected_file_size: Optional. Provided if checking the download file meet
1675 expected file size in unit of byte.
1676 remove_file_after_check: Whether to remove the downloaded file after
1677 check.
1678 timeout: timeout for file download to complete.
1679 """
1680 file_name, out_path = _generate_file_name_and_out_path(url, out_path)
1681 try:
1682 ad.log.info("Download file from %s to %s by sl4a RPC call", url,
1683 out_path)
1684 ad.droid.httpDownloadFile(url, out_path, timeout=timeout)
1685 if _check_file_existance(ad, file_name, out_path, expected_file_size):
1686 ad.log.info("File %s is downloaded from %s successfully",
1687 file_name, url)
1688 return True
1689 else:
1690 ad.log.warn("Fail to download file from %s", url)
1691 return False
1692 except Exception as e:
1693 ad.log.error("Download file from %s failed with exception %s", url, e)
1694 raise
1695 finally:
1696 if remove_file_after_check:
1697 ad.log.info("Remove the downloaded file %s", out_path)
1698 ad.adb.shell("rm %s" % out_path, ignore_status=True)
1699
1700
Ang Li73697b32015-12-03 00:41:53 +00001701def _connection_state_change(_event, target_state, connection_type):
1702 if connection_type:
1703 if 'TypeName' not in _event['data']:
1704 return False
1705 connection_type_string_in_event = _event['data']['TypeName']
Nathan Harold123c9da2015-12-30 16:33:25 -08001706 cur_type = connection_type_from_type_string(
1707 connection_type_string_in_event)
Ang Li73697b32015-12-03 00:41:53 +00001708 if cur_type != connection_type:
1709 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08001710 "_connection_state_change expect: %s, received: %s <type %s>",
1711 connection_type, connection_type_string_in_event, cur_type)
Ang Li73697b32015-12-03 00:41:53 +00001712 return False
1713
Nathan Harold123c9da2015-12-30 16:33:25 -08001714 if 'isConnected' in _event['data'] and _event['data'][
1715 'isConnected'] == target_state:
Ang Li73697b32015-12-03 00:41:53 +00001716 return True
1717 return False
1718
1719
Nathan Harold123c9da2015-12-30 16:33:25 -08001720def wait_for_cell_data_connection(
Nathan Harold4a144a42016-09-19 14:16:24 -07001721 log, ad, state, timeout_value=EventDispatcher.DEFAULT_TIMEOUT):
Ang Li73697b32015-12-03 00:41:53 +00001722 """Wait for data connection status to be expected value for default
1723 data subscription.
1724
1725 Wait for the data connection status to be DATA_STATE_CONNECTED
1726 or DATA_STATE_DISCONNECTED.
1727
1728 Args:
1729 log: Log object.
1730 ad: Android Device Object.
1731 state: Expected status: True or False.
1732 If True, it will wait for status to be DATA_STATE_CONNECTED.
1733 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
1734 timeout_value: wait for cell data timeout value.
1735 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT
1736
1737 Returns:
1738 True if success.
1739 False if failed.
1740 """
Yang Liu963c93c2016-04-05 10:52:00 -07001741 sub_id = get_default_data_sub_id(ad)
Nathan Harold123c9da2015-12-30 16:33:25 -08001742 return wait_for_cell_data_connection_for_subscription(log, ad, sub_id,
1743 state, timeout_value)
1744
Ang Li73697b32015-12-03 00:41:53 +00001745
1746def _is_data_connection_state_match(log, ad, expected_data_connection_state):
Nathan Harold123c9da2015-12-30 16:33:25 -08001747 return (expected_data_connection_state ==
1748 ad.droid.telephonyGetDataConnectionState())
Ang Li73697b32015-12-03 00:41:53 +00001749
Ang Li73697b32015-12-03 00:41:53 +00001750
Nathan Harold123c9da2015-12-30 16:33:25 -08001751def _is_network_connected_state_match(log, ad,
1752 expected_network_connected_state):
1753 return (expected_network_connected_state ==
1754 ad.droid.connectivityNetworkIsConnected())
1755
1756
1757def wait_for_cell_data_connection_for_subscription(
Nathan Harold4a144a42016-09-19 14:16:24 -07001758 log, ad, sub_id, state, timeout_value=EventDispatcher.DEFAULT_TIMEOUT):
Ang Li73697b32015-12-03 00:41:53 +00001759 """Wait for data connection status to be expected value for specified
1760 subscrption id.
1761
1762 Wait for the data connection status to be DATA_STATE_CONNECTED
1763 or DATA_STATE_DISCONNECTED.
1764
1765 Args:
1766 log: Log object.
1767 ad: Android Device Object.
1768 sub_id: subscription Id
1769 state: Expected status: True or False.
1770 If True, it will wait for status to be DATA_STATE_CONNECTED.
1771 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
1772 timeout_value: wait for cell data timeout value.
1773 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT
1774
1775 Returns:
1776 True if success.
1777 False if failed.
1778 """
Yang Liu8e6adff2016-02-05 10:24:04 -08001779 state_str = {
1780 True: DATA_STATE_CONNECTED,
1781 False: DATA_STATE_DISCONNECTED
Ang Li73697b32015-12-03 00:41:53 +00001782 }[state]
1783
1784 ad.ed.clear_all_events()
Nathan Harold123c9da2015-12-30 16:33:25 -08001785 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
1786 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001787 ad.droid.connectivityStartTrackingConnectivityStateChange()
1788 try:
Yang Liu7a2e7ee2015-12-28 15:32:44 -08001789 # TODO: b/26293147 There is no framework API to get data connection
1790 # state by sub id
Yang Liuaed3eef2015-12-15 18:40:25 -08001791 data_state = ad.droid.telephonyGetDataConnectionState()
Ang Li73697b32015-12-03 00:41:53 +00001792 if data_state == state_str:
Nathan Harold123c9da2015-12-30 16:33:25 -08001793 return _wait_for_nw_data_connection(
1794 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00001795
1796 try:
Nathan Harold7642fc92016-05-02 18:29:11 -07001797 event = ad.ed.wait_for_event(
1798 EventDataConnectionStateChanged,
1799 is_event_match,
1800 timeout=timeout_value,
Yang Liu8e6adff2016-02-05 10:24:04 -08001801 field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
1802 value=state_str)
Ang Li73697b32015-12-03 00:41:53 +00001803 except Empty:
Betty Zhouf25ce442017-03-03 14:28:36 -08001804 ad.log.info("No expected event EventDataConnectionStateChanged %s",
1805 state_str)
Ang Li73697b32015-12-03 00:41:53 +00001806
Yang Liudf164e32016-01-07 16:49:32 -08001807 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00001808 # data connection state.
1809 # Otherwise, the network state will not be correct.
1810 # The bug is tracked here: b/20921915
Ang Li73697b32015-12-03 00:41:53 +00001811
Yang Liu7a2e7ee2015-12-28 15:32:44 -08001812 # Previously we use _is_data_connection_state_match,
1813 # but telephonyGetDataConnectionState sometimes return wrong value.
1814 # The bug is tracked here: b/22612607
1815 # So we use _is_network_connected_state_match.
Ang Li73697b32015-12-03 00:41:53 +00001816
Nathan Harold7642fc92016-05-02 18:29:11 -07001817 if _wait_for_droid_in_state(log, ad,
1818 MAX_WAIT_TIME_CONNECTION_STATE_UPDATE,
Nathan Harold123c9da2015-12-30 16:33:25 -08001819 _is_network_connected_state_match, state):
1820 return _wait_for_nw_data_connection(
1821 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00001822 else:
1823 return False
1824
1825 finally:
Nathan Harold123c9da2015-12-30 16:33:25 -08001826 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
1827 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001828
Nathan Harold123c9da2015-12-30 16:33:25 -08001829
1830def wait_for_wifi_data_connection(
Nathan Harold4a144a42016-09-19 14:16:24 -07001831 log, ad, state, timeout_value=EventDispatcher.DEFAULT_TIMEOUT):
Ang Li73697b32015-12-03 00:41:53 +00001832 """Wait for data connection status to be expected value and connection is by WiFi.
1833
1834 Args:
1835 log: Log object.
1836 ad: Android Device Object.
1837 state: Expected status: True or False.
1838 If True, it will wait for status to be DATA_STATE_CONNECTED.
1839 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
1840 timeout_value: wait for network data timeout value.
1841 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT
1842
1843 Returns:
1844 True if success.
1845 False if failed.
1846 """
Betty Zhoua37acd32017-02-23 20:04:24 -08001847 ad.log.info("wait_for_wifi_data_connection")
Nathan Harold123c9da2015-12-30 16:33:25 -08001848 return _wait_for_nw_data_connection(
1849 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00001850
1851
Nathan Harold123c9da2015-12-30 16:33:25 -08001852def wait_for_data_connection(log,
1853 ad,
1854 state,
Ang Li73697b32015-12-03 00:41:53 +00001855 timeout_value=EventDispatcher.DEFAULT_TIMEOUT):
1856 """Wait for data connection status to be expected value.
1857
1858 Wait for the data connection status to be DATA_STATE_CONNECTED
1859 or DATA_STATE_DISCONNECTED.
1860
1861 Args:
1862 log: Log object.
1863 ad: Android Device Object.
1864 state: Expected status: True or False.
1865 If True, it will wait for status to be DATA_STATE_CONNECTED.
1866 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
1867 timeout_value: wait for network data timeout value.
1868 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT
1869
1870 Returns:
1871 True if success.
1872 False if failed.
1873 """
1874 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
1875
1876
Nathan Harold123c9da2015-12-30 16:33:25 -08001877def _wait_for_nw_data_connection(
1878 log,
1879 ad,
1880 is_connected,
1881 connection_type=None,
1882 timeout_value=EventDispatcher.DEFAULT_TIMEOUT):
Ang Li73697b32015-12-03 00:41:53 +00001883 """Wait for data connection status to be expected value.
1884
1885 Wait for the data connection status to be DATA_STATE_CONNECTED
1886 or DATA_STATE_DISCONNECTED.
1887
1888 Args:
1889 log: Log object.
1890 ad: Android Device Object.
1891 is_connected: Expected connection status: True or False.
1892 If True, it will wait for status to be DATA_STATE_CONNECTED.
1893 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
1894 connection_type: expected connection type.
1895 This is optional, if it is None, then any connection type will return True.
1896 timeout_value: wait for network data timeout value.
1897 This is optional, default value is EventDispatcher.DEFAULT_TIMEOUT
1898
1899 Returns:
1900 True if success.
1901 False if failed.
1902 """
1903 ad.ed.clear_all_events()
1904 ad.droid.connectivityStartTrackingConnectivityStateChange()
1905 try:
1906 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
1907 if is_connected == cur_data_connection_state:
1908 current_type = get_internet_connection_type(log, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08001909 ad.log.info("current datat connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00001910 if not connection_type:
1911 return True
1912 else:
1913 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08001914 ad.log.info("data connection not on %s!", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00001915 return True
1916 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08001917 ad.log.info("data connection on %s as expected",
1918 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00001919 return True
1920 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08001921 ad.log.info("current data connection state: %s target: %s",
1922 cur_data_connection_state, is_connected)
Ang Li73697b32015-12-03 00:41:53 +00001923
1924 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08001925 event = ad.ed.wait_for_event(
1926 EventConnectivityChanged, _connection_state_change,
1927 timeout_value, is_connected, connection_type)
Betty Zhoua37acd32017-02-23 20:04:24 -08001928 ad.log.info("received event: %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001929 except Empty:
1930 pass
1931
Nathan Harold123c9da2015-12-30 16:33:25 -08001932 log.info(
1933 "_wait_for_nw_data_connection: check connection after wait event.")
Yang Liudf164e32016-01-07 16:49:32 -08001934 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00001935 # data connection state.
1936 # Otherwise, the network state will not be correct.
1937 # The bug is tracked here: b/20921915
Nathan Harold7642fc92016-05-02 18:29:11 -07001938 if _wait_for_droid_in_state(
1939 log, ad, MAX_WAIT_TIME_CONNECTION_STATE_UPDATE,
1940 _is_network_connected_state_match, is_connected):
Ang Li73697b32015-12-03 00:41:53 +00001941 current_type = get_internet_connection_type(log, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08001942 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00001943 if not connection_type:
1944 return True
1945 else:
1946 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08001947 ad.log.info("data connection not on %s", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00001948 return True
1949 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08001950 ad.log.info("after event wait, data connection on %s",
1951 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00001952 return True
1953 else:
1954 return False
1955 else:
1956 return False
1957 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -08001958 ad.log.error("Exception error %s", str(e))
Ang Li73697b32015-12-03 00:41:53 +00001959 return False
1960 finally:
1961 ad.droid.connectivityStopTrackingConnectivityStateChange()
1962
Nathan Harold123c9da2015-12-30 16:33:25 -08001963
Betty Zhou9e2bf402017-02-01 19:04:09 -08001964def toggle_cell_data_roaming(ad, state):
1965 """Enable cell data roaming for default data subscription.
1966
1967 Wait for the data roaming status to be DATA_STATE_CONNECTED
1968 or DATA_STATE_DISCONNECTED.
1969
1970 Args:
1971 log: Log object.
1972 ad: Android Device Object.
1973 state: True or False for enable or disable cell data roaming.
1974
1975 Returns:
1976 True if success.
1977 False if failed.
1978 """
1979 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state]
1980 action_str = {True: "Enable", False: "Disable"}[state]
1981 if ad.droid.connectivityCheckDataRoamingMode() == state:
1982 ad.log.info("Data roaming is already in state %s", state)
1983 return True
1984 if not ad.droid.connectivitySetDataRoaming(state_int):
1985 ad.error.info("Fail to config data roaming into state %s", state)
1986 return False
1987 if ad.droid.connectivityCheckDataRoamingMode() == state:
1988 ad.log.info("Data roaming is configured into state %s", state)
1989 return True
1990 else:
1991 ad.log.error("Data roaming is not configured into state %s", state)
1992 return False
1993
1994
Ang Li73697b32015-12-03 00:41:53 +00001995def verify_incall_state(log, ads, expected_status):
1996 """Verify phones in incall state or not.
1997
1998 Verify if all phones in the array <ads> are in <expected_status>.
1999
2000 Args:
2001 log: Log object.
2002 ads: Array of Android Device Object. All droid in this array will be tested.
2003 expected_status: If True, verify all Phones in incall state.
2004 If False, verify all Phones not in incall state.
2005
2006 """
2007 result = True
2008 for ad in ads:
2009 if ad.droid.telecomIsInCall() is not expected_status:
Betty Zhoua37acd32017-02-23 20:04:24 -08002010 ad.log.error("InCall status:%s, expected:%s",
2011 ad.droid.telecomIsInCall(), expected_status)
Ang Li73697b32015-12-03 00:41:53 +00002012 result = False
2013 return result
2014
Nathan Harold123c9da2015-12-30 16:33:25 -08002015
Ang Li73697b32015-12-03 00:41:53 +00002016def verify_active_call_number(log, ad, expected_number):
2017 """Verify the number of current active call.
2018
2019 Verify if the number of current active call in <ad> is
2020 equal to <expected_number>.
2021
2022 Args:
2023 ad: Android Device Object.
2024 expected_number: Expected active call number.
2025 """
2026 calls = ad.droid.telecomCallGetCallIds()
2027 if calls is None:
2028 actual_number = 0
2029 else:
2030 actual_number = len(calls)
2031 if actual_number != expected_number:
Betty Zhoua37acd32017-02-23 20:04:24 -08002032 ad.log.error("Active Call number is %s, expecting", actual_number,
2033 expected_number)
Ang Li73697b32015-12-03 00:41:53 +00002034 return False
2035 return True
2036
Nathan Harold123c9da2015-12-30 16:33:25 -08002037
Ang Li73697b32015-12-03 00:41:53 +00002038def num_active_calls(log, ad):
2039 """Get the count of current active calls.
2040
2041 Args:
2042 log: Log object.
2043 ad: Android Device Object.
2044
2045 Returns:
2046 Count of current active calls.
2047 """
2048 calls = ad.droid.telecomCallGetCallIds()
2049 return len(calls) if calls else 0
2050
Nathan Harold123c9da2015-12-30 16:33:25 -08002051
Ang Li73697b32015-12-03 00:41:53 +00002052def toggle_volte(log, ad, new_state=None):
2053 """Toggle enable/disable VoLTE for default voice subscription.
2054
2055 Args:
2056 ad: Android device object.
2057 new_state: VoLTE mode state to set to.
2058 True for enable, False for disable.
2059 If None, opposite of the current state.
2060
2061 Raises:
2062 TelTestUtilsError if platform does not support VoLTE.
2063 """
2064 return toggle_volte_for_subscription(
Yang Liu963c93c2016-04-05 10:52:00 -07002065 log, ad, get_outgoing_voice_sub_id(ad), new_state)
Ang Li73697b32015-12-03 00:41:53 +00002066
2067
2068def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
2069 """Toggle enable/disable VoLTE for specified voice subscription.
2070
2071 Args:
2072 ad: Android device object.
2073 sub_id: subscription ID
2074 new_state: VoLTE mode state to set to.
2075 True for enable, False for disable.
2076 If None, opposite of the current state.
2077
2078 Raises:
2079 TelTestUtilsError if platform does not support VoLTE.
2080 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002081 # TODO: b/26293960 No framework API available to set IMS by SubId.
Ang Li73697b32015-12-03 00:41:53 +00002082 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
2083 raise TelTestUtilsError("VoLTE not supported by platform.")
2084 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
2085 if new_state is None:
2086 new_state = not current_state
2087 if new_state != current_state:
2088 ad.droid.imsSetEnhanced4gMode(new_state)
2089 return True
2090
Nathan Harold123c9da2015-12-30 16:33:25 -08002091
Ang Li73697b32015-12-03 00:41:53 +00002092def set_wfc_mode(log, ad, wfc_mode):
2093 """Set WFC enable/disable and mode.
2094
2095 Args:
2096 log: Log object
2097 ad: Android device object.
2098 wfc_mode: WFC mode to set to.
2099 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
2100 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
2101
2102 Returns:
2103 True if success. False if ad does not support WFC or error happened.
2104 """
2105 try:
Betty Zhoua37acd32017-02-23 20:04:24 -08002106 ad.log.info("Set wfc mode to %s", wfc_mode)
Ang Li73697b32015-12-03 00:41:53 +00002107 if not ad.droid.imsIsWfcEnabledByPlatform():
2108 if wfc_mode == WFC_MODE_DISABLED:
2109 return True
2110 else:
2111 log.error("WFC not supported by platform.")
2112 return False
2113
2114 ad.droid.imsSetWfcMode(wfc_mode)
2115
2116 except Exception as e:
2117 log.error(e)
2118 return False
2119
2120 return True
2121
Nathan Harold123c9da2015-12-30 16:33:25 -08002122
Nathan Harold0a011532016-08-24 19:17:44 -07002123def toggle_video_calling(log, ad, new_state=None):
2124 """Toggle enable/disable Video calling for default voice subscription.
2125
2126 Args:
2127 ad: Android device object.
2128 new_state: Video mode state to set to.
2129 True for enable, False for disable.
2130 If None, opposite of the current state.
2131
2132 Raises:
2133 TelTestUtilsError if platform does not support Video calling.
2134 """
2135 if not ad.droid.imsIsVtEnabledByPlatform():
2136 if new_state is not False:
2137 raise TelTestUtilsError("VT not supported by platform.")
2138 # if the user sets VT false and it's unavailable we just let it go
2139 return False
2140
2141 current_state = ad.droid.imsIsVtEnabledByUser()
2142 if new_state is None:
2143 new_state = not current_state
2144 if new_state != current_state:
2145 ad.droid.imsSetVtSetting(new_state)
2146 return True
Nathan Harold123c9da2015-12-30 16:33:25 -08002147
Nathan Harold72f9bff2016-09-19 14:16:24 -07002148
Nathan Harold123c9da2015-12-30 16:33:25 -08002149def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args,
2150 **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07002151 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00002152 if state_check_func(log, ad, *args, **kwargs):
2153 return True
2154
Betty Zhouf25ce442017-03-03 14:28:36 -08002155 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
2156 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00002157
2158 return False
2159
2160
Nathan Harold123c9da2015-12-30 16:33:25 -08002161def _wait_for_droid_in_state_for_subscription(
2162 log, ad, sub_id, max_time, state_check_func, *args, **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07002163 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00002164 if state_check_func(log, ad, sub_id, *args, **kwargs):
2165 return True
2166
Betty Zhouf25ce442017-03-03 14:28:36 -08002167 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
2168 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00002169
2170 return False
2171
2172
Nathan Harold123c9da2015-12-30 16:33:25 -08002173def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args,
2174 **kwargs):
Ang Li73697b32015-12-03 00:41:53 +00002175 while max_time > 0:
2176 success = True
2177 for ad in ads:
2178 if not state_check_func(log, ad, *args, **kwargs):
2179 success = False
2180 break
2181 if success:
2182 return True
2183
Betty Zhouf25ce442017-03-03 14:28:36 -08002184 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
2185 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00002186
2187 return False
2188
Nathan Harold123c9da2015-12-30 16:33:25 -08002189
Ang Li73697b32015-12-03 00:41:53 +00002190def is_phone_in_call(log, ad):
2191 """Return True if phone in call.
2192
2193 Args:
2194 log: log object.
2195 ad: android device.
2196 """
2197 return ad.droid.telecomIsInCall()
2198
Nathan Harold123c9da2015-12-30 16:33:25 -08002199
Ang Li73697b32015-12-03 00:41:53 +00002200def is_phone_not_in_call(log, ad):
2201 """Return True if phone not in call.
2202
2203 Args:
2204 log: log object.
2205 ad: android device.
2206 """
Nathan Haroldeb60b192016-08-24 14:41:55 -07002207 return ((not ad.droid.telecomIsInCall()) and
2208 (ad.droid.telephonyGetCallState() == TELEPHONY_STATE_IDLE))
Ang Li73697b32015-12-03 00:41:53 +00002209
Nathan Harold123c9da2015-12-30 16:33:25 -08002210
Ang Li73697b32015-12-03 00:41:53 +00002211def wait_for_droid_in_call(log, ad, max_time):
2212 """Wait for android to be in call state.
2213
2214 Args:
2215 log: log object.
2216 ad: android device.
2217 max_time: maximal wait time.
2218
2219 Returns:
2220 If phone become in call state within max_time, return True.
2221 Return False if timeout.
2222 """
2223 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
2224
Nathan Harold7642fc92016-05-02 18:29:11 -07002225
Yang Liu855d5f82016-01-27 15:35:48 -08002226def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
2227 """Wait for android to be in telecom ringing state.
2228
2229 Args:
2230 log: log object.
2231 ad: android device.
2232 max_time: maximal wait time. This is optional.
2233 Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
2234
2235 Returns:
2236 If phone become in telecom ringing state within max_time, return True.
2237 Return False if timeout.
2238 """
Nathan Harold7642fc92016-05-02 18:29:11 -07002239 return _wait_for_droid_in_state(
2240 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
Yang Liu855d5f82016-01-27 15:35:48 -08002241
Nathan Harold123c9da2015-12-30 16:33:25 -08002242
Nathan Haroldeb60b192016-08-24 14:41:55 -07002243def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00002244 """Wait for android to be not in call state.
2245
2246 Args:
2247 log: log object.
2248 ad: android device.
2249 max_time: maximal wait time.
2250
2251 Returns:
2252 If phone become not in call state within max_time, return True.
2253 Return False if timeout.
2254 """
2255 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
2256
Nathan Harold123c9da2015-12-30 16:33:25 -08002257
Ang Li73697b32015-12-03 00:41:53 +00002258def _is_attached(log, ad, voice_or_data):
2259 return _is_attached_for_subscription(
2260 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
2261
Nathan Harold123c9da2015-12-30 16:33:25 -08002262
Ang Li73697b32015-12-03 00:41:53 +00002263def _is_attached_for_subscription(log, ad, sub_id, voice_or_data):
Betty Zhouf25ce442017-03-03 14:28:36 -08002264 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)
2265 ad.log.info("Sub_id %s network rate is %s for %s", sub_id, rat,
2266 voice_or_data)
2267 return rat != RAT_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00002268
Nathan Harold123c9da2015-12-30 16:33:25 -08002269
Ang Li73697b32015-12-03 00:41:53 +00002270def wait_for_voice_attach(log, ad, max_time):
2271 """Wait for android device to attach on voice.
2272
2273 Args:
2274 log: log object.
2275 ad: android device.
2276 max_time: maximal wait time.
2277
2278 Returns:
2279 Return True if device attach voice within max_time.
2280 Return False if timeout.
2281 """
2282 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
2283 NETWORK_SERVICE_VOICE)
2284
Nathan Harold123c9da2015-12-30 16:33:25 -08002285
Ang Li73697b32015-12-03 00:41:53 +00002286def wait_for_voice_attach_for_subscription(log, ad, sub_id, max_time):
2287 """Wait for android device to attach on voice in subscription id.
2288
2289 Args:
2290 log: log object.
2291 ad: android device.
2292 sub_id: subscription id.
2293 max_time: maximal wait time.
2294
2295 Returns:
2296 Return True if device attach voice within max_time.
2297 Return False if timeout.
2298 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002299 if not _wait_for_droid_in_state_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08002300 log, ad, sub_id, max_time, _is_attached_for_subscription,
2301 NETWORK_SERVICE_VOICE):
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002302 return False
2303
2304 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
2305 # receive incoming call immediately.
2306 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
Yang Liudf164e32016-01-07 16:49:32 -08002307 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002308 return True
Ang Li73697b32015-12-03 00:41:53 +00002309
Nathan Harold123c9da2015-12-30 16:33:25 -08002310
Ang Li73697b32015-12-03 00:41:53 +00002311def wait_for_data_attach(log, ad, max_time):
2312 """Wait for android device to attach on data.
2313
2314 Args:
2315 log: log object.
2316 ad: android device.
2317 max_time: maximal wait time.
2318
2319 Returns:
2320 Return True if device attach data within max_time.
2321 Return False if timeout.
2322 """
2323 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
2324 NETWORK_SERVICE_DATA)
2325
Nathan Harold123c9da2015-12-30 16:33:25 -08002326
Ang Li73697b32015-12-03 00:41:53 +00002327def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time):
2328 """Wait for android device to attach on data in subscription id.
2329
2330 Args:
2331 log: log object.
2332 ad: android device.
2333 sub_id: subscription id.
2334 max_time: maximal wait time.
2335
2336 Returns:
2337 Return True if device attach data within max_time.
2338 Return False if timeout.
2339 """
2340 return _wait_for_droid_in_state_for_subscription(
2341 log, ad, sub_id, max_time, _is_attached_for_subscription,
2342 NETWORK_SERVICE_DATA)
2343
Nathan Harold123c9da2015-12-30 16:33:25 -08002344
Yang Liu9b85ce52016-02-16 12:25:11 -08002345def is_ims_registered(log, ad):
2346 """Return True if IMS registered.
2347
2348 Args:
2349 log: log object.
2350 ad: android device.
2351
2352 Returns:
2353 Return True if IMS registered.
2354 Return False if IMS not registered.
2355 """
Yang Liuaed3eef2015-12-15 18:40:25 -08002356 return ad.droid.telephonyIsImsRegistered()
Ang Li73697b32015-12-03 00:41:53 +00002357
Nathan Harold123c9da2015-12-30 16:33:25 -08002358
Ang Li73697b32015-12-03 00:41:53 +00002359def wait_for_ims_registered(log, ad, max_time):
2360 """Wait for android device to register on ims.
2361
2362 Args:
2363 log: log object.
2364 ad: android device.
2365 max_time: maximal wait time.
2366
2367 Returns:
2368 Return True if device register ims successfully within max_time.
2369 Return False if timeout.
2370 """
Yang Liu9b85ce52016-02-16 12:25:11 -08002371 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered)
Ang Li73697b32015-12-03 00:41:53 +00002372
Nathan Harold123c9da2015-12-30 16:33:25 -08002373
Yang Liu9b85ce52016-02-16 12:25:11 -08002374def is_volte_enabled(log, ad):
2375 """Return True if VoLTE feature bit is True.
2376
2377 Args:
2378 log: log object.
2379 ad: android device.
2380
2381 Returns:
2382 Return True if VoLTE feature bit is True and IMS registered.
2383 Return False if VoLTE feature bit is False or IMS not registered.
2384 """
Yang Liub93d7292016-02-19 10:41:40 -08002385 volte_status = ad.droid.telephonyIsVolteAvailable()
2386 if volte_status is True and is_ims_registered(log, ad) is False:
Betty Zhoua37acd32017-02-23 20:04:24 -08002387 ad.log.error("Error! VoLTE is Available, but IMS is not registered.")
Yang Liu9b85ce52016-02-16 12:25:11 -08002388 return False
Yang Liub93d7292016-02-19 10:41:40 -08002389 return volte_status
Ang Li73697b32015-12-03 00:41:53 +00002390
Nathan Harold123c9da2015-12-30 16:33:25 -08002391
Yang Liu9b85ce52016-02-16 12:25:11 -08002392def is_video_enabled(log, ad):
2393 """Return True if Video Calling feature bit is True.
2394
2395 Args:
2396 log: log object.
2397 ad: android device.
2398
2399 Returns:
2400 Return True if Video Calling feature bit is True and IMS registered.
2401 Return False if Video Calling feature bit is False or IMS not registered.
2402 """
Yang Liub93d7292016-02-19 10:41:40 -08002403 video_status = ad.droid.telephonyIsVideoCallingAvailable()
2404 if video_status is True and is_ims_registered(log, ad) is False:
Yang Liu9b85ce52016-02-16 12:25:11 -08002405 log.error("Error! Video Call is Available, but IMS is not registered.")
2406 return False
Yang Liub93d7292016-02-19 10:41:40 -08002407 return video_status
Ang Li73697b32015-12-03 00:41:53 +00002408
Nathan Harold123c9da2015-12-30 16:33:25 -08002409
Ang Li73697b32015-12-03 00:41:53 +00002410def wait_for_volte_enabled(log, ad, max_time):
2411 """Wait for android device to report VoLTE enabled bit true.
2412
2413 Args:
2414 log: log object.
2415 ad: android device.
2416 max_time: maximal wait time.
2417
2418 Returns:
2419 Return True if device report VoLTE enabled bit true within max_time.
2420 Return False if timeout.
2421 """
Yang Liu9b85ce52016-02-16 12:25:11 -08002422 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled)
Ang Li73697b32015-12-03 00:41:53 +00002423
Nathan Harold123c9da2015-12-30 16:33:25 -08002424
Ang Li73697b32015-12-03 00:41:53 +00002425def wait_for_video_enabled(log, ad, max_time):
2426 """Wait for android device to report Video Telephony enabled bit true.
2427
2428 Args:
2429 log: log object.
2430 ad: android device.
2431 max_time: maximal wait time.
2432
2433 Returns:
2434 Return True if device report Video Telephony enabled bit true within max_time.
2435 Return False if timeout.
2436 """
Yang Liu9b85ce52016-02-16 12:25:11 -08002437 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
Ang Li73697b32015-12-03 00:41:53 +00002438
Nathan Harold123c9da2015-12-30 16:33:25 -08002439
Ang Li73697b32015-12-03 00:41:53 +00002440def is_wfc_enabled(log, ad):
2441 """Return True if WiFi Calling feature bit is True.
2442
2443 Args:
2444 log: log object.
2445 ad: android device.
2446
2447 Returns:
Yang Liu9b85ce52016-02-16 12:25:11 -08002448 Return True if WiFi Calling feature bit is True and IMS registered.
2449 Return False if WiFi Calling feature bit is False or IMS not registered.
Ang Li73697b32015-12-03 00:41:53 +00002450 """
Yang Liub93d7292016-02-19 10:41:40 -08002451 wfc_status = ad.droid.telephonyIsWifiCallingAvailable()
2452 if wfc_status is True and is_ims_registered(log, ad) is False:
Betty Zhoua27e5d42017-01-17 11:33:04 -08002453 log.error(
2454 "Error! WiFi Calling is Available, but IMS is not registered.")
Yang Liu9b85ce52016-02-16 12:25:11 -08002455 return False
Yang Liub93d7292016-02-19 10:41:40 -08002456 return wfc_status
Ang Li73697b32015-12-03 00:41:53 +00002457
Nathan Harold123c9da2015-12-30 16:33:25 -08002458
Yang Liudfc37b62016-01-20 18:08:47 -08002459def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00002460 """Wait for android device to report WiFi Calling enabled bit true.
2461
2462 Args:
2463 log: log object.
2464 ad: android device.
2465 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08002466 Default value is MAX_WAIT_TIME_WFC_ENABLED.
Ang Li73697b32015-12-03 00:41:53 +00002467
2468 Returns:
2469 Return True if device report WiFi Calling enabled bit true within max_time.
2470 Return False if timeout.
2471 """
2472 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
2473
Nathan Harold123c9da2015-12-30 16:33:25 -08002474
Yang Liudfc37b62016-01-20 18:08:47 -08002475def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
Ang Li73697b32015-12-03 00:41:53 +00002476 """Wait for android device to report WiFi Calling enabled bit false.
2477
2478 Args:
2479 log: log object.
2480 ad: android device.
2481 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08002482 Default value is MAX_WAIT_TIME_WFC_DISABLED.
Ang Li73697b32015-12-03 00:41:53 +00002483
2484 Returns:
2485 Return True if device report WiFi Calling enabled bit false within max_time.
2486 Return False if timeout.
2487 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002488 return _wait_for_droid_in_state(
2489 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
2490
Ang Li73697b32015-12-03 00:41:53 +00002491
2492def get_phone_number(log, ad):
2493 """Get phone number for default subscription
2494
2495 Args:
2496 log: log object.
2497 ad: Android device object.
2498
2499 Returns:
2500 Phone number.
2501 """
Nathan Harold7642fc92016-05-02 18:29:11 -07002502 return get_phone_number_for_subscription(log, ad,
2503 get_outgoing_voice_sub_id(ad))
Nathan Harold123c9da2015-12-30 16:33:25 -08002504
Ang Li73697b32015-12-03 00:41:53 +00002505
2506def get_phone_number_for_subscription(log, ad, subid):
2507 """Get phone number for subscription
2508
2509 Args:
2510 log: log object.
2511 ad: Android device object.
2512 subid: subscription id.
2513
2514 Returns:
2515 Phone number.
2516 """
2517 number = None
2518 try:
2519 number = ad.cfg['subscription'][subid]['phone_num']
2520 except KeyError:
Yang Liuaed3eef2015-12-15 18:40:25 -08002521 number = ad.droid.telephonyGetLine1NumberForSubscription(subid)
Ang Li73697b32015-12-03 00:41:53 +00002522 return number
2523
Nathan Harold123c9da2015-12-30 16:33:25 -08002524
Ang Li73697b32015-12-03 00:41:53 +00002525def set_phone_number(log, ad, phone_num):
2526 """Set phone number for default subscription
2527
2528 Args:
2529 log: log object.
2530 ad: Android device object.
2531 phone_num: phone number string.
2532
2533 Returns:
2534 True if success.
2535 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002536 return set_phone_number_for_subscription(
Yang Liu963c93c2016-04-05 10:52:00 -07002537 log, ad, get_outgoing_voice_sub_id(ad), phone_num)
Nathan Harold123c9da2015-12-30 16:33:25 -08002538
Ang Li73697b32015-12-03 00:41:53 +00002539
2540def set_phone_number_for_subscription(log, ad, subid, phone_num):
2541 """Set phone number for subscription
2542
2543 Args:
2544 log: log object.
2545 ad: Android device object.
2546 subid: subscription id.
2547 phone_num: phone number string.
2548
2549 Returns:
2550 True if success.
2551 """
2552 try:
2553 ad.cfg['subscription'][subid]['phone_num'] = phone_num
2554 except Exception:
2555 return False
2556 return True
2557
Nathan Harold123c9da2015-12-30 16:33:25 -08002558
Ang Li73697b32015-12-03 00:41:53 +00002559def get_operator_name(log, ad, subId=None):
2560 """Get operator name (e.g. vzw, tmo) of droid.
2561
2562 Args:
2563 ad: Android device object.
2564 sub_id: subscription ID
2565 Optional, default is None
2566
2567 Returns:
2568 Operator name.
2569 """
2570 try:
2571 if subId is not None:
2572 result = operator_name_from_plmn_id(
Yang Liuaed3eef2015-12-15 18:40:25 -08002573 ad.droid.telephonyGetSimOperatorForSubscription(subId))
Ang Li73697b32015-12-03 00:41:53 +00002574 else:
2575 result = operator_name_from_plmn_id(
Yang Liuaed3eef2015-12-15 18:40:25 -08002576 ad.droid.telephonyGetSimOperator())
Ang Li73697b32015-12-03 00:41:53 +00002577 except KeyError:
2578 result = CARRIER_UNKNOWN
2579 return result
2580
Nathan Harold123c9da2015-12-30 16:33:25 -08002581
Yang Liu9a9a4f72016-02-19 10:45:04 -08002582def get_model_name(ad):
2583 """Get android device model name
2584
2585 Args:
2586 ad: Android device object
2587
2588 Returns:
2589 model name string
2590 """
2591 # TODO: Create translate table.
2592 model = ad.model
Nathan Harold7642fc92016-05-02 18:29:11 -07002593 if (model.startswith(AOSP_PREFIX)):
Yang Liu9a9a4f72016-02-19 10:45:04 -08002594 model = model[len(AOSP_PREFIX):]
2595 return model
2596
2597
Ang Li73697b32015-12-03 00:41:53 +00002598def is_sms_match(event, phonenumber_tx, text):
2599 """Return True if 'text' equals to event['data']['Text']
2600 and phone number match.
2601
2602 Args:
2603 event: Event object to verify.
2604 phonenumber_tx: phone number for sender.
2605 text: text string to verify.
2606
2607 Returns:
2608 Return True if 'text' equals to event['data']['Text']
2609 and phone number match.
2610 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002611 return (
2612 check_phone_number_match(event['data']['Sender'], phonenumber_tx) and
2613 event['data']['Text'] == text)
2614
Ang Li73697b32015-12-03 00:41:53 +00002615
2616def is_sms_partial_match(event, phonenumber_tx, text):
2617 """Return True if 'text' starts with event['data']['Text']
2618 and phone number match.
2619
2620 Args:
2621 event: Event object to verify.
2622 phonenumber_tx: phone number for sender.
2623 text: text string to verify.
2624
2625 Returns:
2626 Return True if 'text' starts with event['data']['Text']
2627 and phone number match.
2628 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002629 return (
2630 check_phone_number_match(event['data']['Sender'], phonenumber_tx) and
2631 text.startswith(event['data']['Text']))
2632
Ang Li73697b32015-12-03 00:41:53 +00002633
2634def sms_send_receive_verify(log, ad_tx, ad_rx, array_message):
2635 """Send SMS, receive SMS, and verify content and sender's number.
2636
2637 Send (several) SMS from droid_tx to droid_rx.
2638 Verify SMS is sent, delivered and received.
2639 Verify received content and sender's number are correct.
2640
2641 Args:
2642 log: Log object.
2643 ad_tx: Sender's Android Device Object
2644 ad_rx: Receiver's Android Device Object
2645 array_message: the array of message to send/receive
2646 """
Yang Liu963c93c2016-04-05 10:52:00 -07002647 subid_tx = get_outgoing_message_sub_id(ad_tx)
2648 subid_rx = get_incoming_message_sub_id(ad_rx)
Nathan Harold123c9da2015-12-30 16:33:25 -08002649 return sms_send_receive_verify_for_subscription(
tturney0eddcae2016-03-30 19:59:14 -07002650 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message)
Ang Li73697b32015-12-03 00:41:53 +00002651
Nathan Harold123c9da2015-12-30 16:33:25 -08002652
2653def wait_for_matching_sms(log,
2654 ad_rx,
2655 phonenumber_tx,
2656 text,
2657 allow_multi_part_long_sms=True):
Ang Li73697b32015-12-03 00:41:53 +00002658 """Wait for matching incoming SMS.
2659
2660 Args:
2661 log: Log object.
2662 ad_rx: Receiver's Android Device Object
2663 phonenumber_tx: Sender's phone number.
2664 text: SMS content string.
2665 allow_multi_part_long_sms: is long SMS allowed to be received as
2666 multiple short SMS. This is optional, default value is True.
2667
2668 Returns:
2669 True if matching incoming SMS is received.
2670 """
2671 if not allow_multi_part_long_sms:
2672 try:
2673 ad_rx.ed.wait_for_event(EventSmsReceived, is_sms_match,
Yang Liudf164e32016-01-07 16:49:32 -08002674 MAX_WAIT_TIME_SMS_RECEIVE, phonenumber_tx,
Nathan Harold123c9da2015-12-30 16:33:25 -08002675 text)
Ang Li73697b32015-12-03 00:41:53 +00002676 return True
2677 except Empty:
2678 log.error("No matched SMS received event.")
2679 return False
2680 else:
2681 try:
2682 received_sms = ''
Nathan Harold123c9da2015-12-30 16:33:25 -08002683 while (text != ''):
2684 event = ad_rx.ed.wait_for_event(
2685 EventSmsReceived, is_sms_partial_match,
Yang Liudf164e32016-01-07 16:49:32 -08002686 MAX_WAIT_TIME_SMS_RECEIVE, phonenumber_tx, text)
Ang Li73697b32015-12-03 00:41:53 +00002687 text = text[len(event['data']['Text']):]
2688 received_sms += event['data']['Text']
2689 return True
2690 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -08002691 ad_rx.log.error("No matched SMS received event.")
Ang Li73697b32015-12-03 00:41:53 +00002692 if received_sms != '':
Betty Zhoua37acd32017-02-23 20:04:24 -08002693 ad_rx.log.error("Only received partial matched SMS: %s",
2694 received_sms)
Ang Li73697b32015-12-03 00:41:53 +00002695 return False
2696
Nathan Harold123c9da2015-12-30 16:33:25 -08002697
Betty Zhoua27e5d42017-01-17 11:33:04 -08002698def is_mms_match(event, phonenumber_tx, text):
2699 """Return True if 'text' equals to event['data']['Text']
2700 and phone number match.
2701
2702 Args:
2703 event: Event object to verify.
2704 phonenumber_tx: phone number for sender.
2705 text: text string to verify.
2706
2707 Returns:
2708 Return True if 'text' equals to event['data']['Text']
2709 and phone number match.
2710 """
2711 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
2712 return True
2713
2714
2715def wait_for_matching_mms(log, ad_rx, phonenumber_tx, text):
2716 """Wait for matching incoming SMS.
2717
2718 Args:
2719 log: Log object.
2720 ad_rx: Receiver's Android Device Object
2721 phonenumber_tx: Sender's phone number.
2722 text: SMS content string.
2723 allow_multi_part_long_sms: is long SMS allowed to be received as
2724 multiple short SMS. This is optional, default value is True.
2725
2726 Returns:
2727 True if matching incoming SMS is received.
2728 """
2729 try:
2730 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
2731 ad_rx.ed.wait_for_event(EventMmsDownloaded, is_mms_match,
2732 MAX_WAIT_TIME_SMS_RECEIVE, phonenumber_tx,
2733 text)
2734 return True
2735 except Empty:
Betty Zhou2e08ac32017-01-27 14:21:29 -08002736 log.warn("No matched MMS downloaded event.")
Betty Zhoua27e5d42017-01-17 11:33:04 -08002737 return False
2738
2739
Ang Li73697b32015-12-03 00:41:53 +00002740def sms_send_receive_verify_for_subscription(log, ad_tx, ad_rx, subid_tx,
Nathan Harold123c9da2015-12-30 16:33:25 -08002741 subid_rx, array_message):
Ang Li73697b32015-12-03 00:41:53 +00002742 """Send SMS, receive SMS, and verify content and sender's number.
2743
2744 Send (several) SMS from droid_tx to droid_rx.
2745 Verify SMS is sent, delivered and received.
2746 Verify received content and sender's number are correct.
2747
2748 Args:
2749 log: Log object.
2750 ad_tx: Sender's Android Device Object..
2751 ad_rx: Receiver's Android Device Object.
2752 subid_tx: Sender's subsciption ID to be used for SMS
2753 subid_rx: Receiver's subsciption ID to be used for SMS
2754 array_message: the array of message to send/receive
2755 """
2756
2757 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num']
2758 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num']
2759 for text in array_message:
Betty Zhoua37acd32017-02-23 20:04:24 -08002760 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
2761 phonenumber_tx, phonenumber_rx, len(text), text)
Ang Li73697b32015-12-03 00:41:53 +00002762 result = False
2763 ad_rx.ed.clear_all_events()
2764 ad_rx.droid.smsStartTrackingIncomingSmsMessage()
2765 try:
2766 ad_tx.droid.smsSendTextMessage(phonenumber_rx, text, True)
2767
2768 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08002769 ad_tx.ed.pop_event(EventSmsSentSuccess,
Yang Liudf164e32016-01-07 16:49:32 -08002770 MAX_WAIT_TIME_SMS_SENT_SUCCESS)
Ang Li73697b32015-12-03 00:41:53 +00002771 except Empty:
2772 log.error("No sent_success event.")
2773 return False
2774
Nathan Harold4a144a42016-09-19 14:16:24 -07002775 if not wait_for_matching_sms(
2776 log,
2777 ad_rx,
2778 phonenumber_tx,
2779 text,
2780 allow_multi_part_long_sms=True):
Ang Li73697b32015-12-03 00:41:53 +00002781 return False
2782 finally:
2783 ad_rx.droid.smsStopTrackingIncomingSmsMessage()
2784 return True
2785
Nathan Harold123c9da2015-12-30 16:33:25 -08002786
Ang Li73697b32015-12-03 00:41:53 +00002787def mms_send_receive_verify(log, ad_tx, ad_rx, array_message):
Betty Zhou2e08ac32017-01-27 14:21:29 -08002788 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00002789
Betty Zhou2e08ac32017-01-27 14:21:29 -08002790 Send (several) MMS from droid_tx to droid_rx.
2791 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00002792 Verify received content and sender's number are correct.
2793
2794 Args:
2795 log: Log object.
2796 ad_tx: Sender's Android Device Object
2797 ad_rx: Receiver's Android Device Object
2798 array_message: the array of message to send/receive
2799 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002800 return mms_send_receive_verify_for_subscription(
Yang Liu963c93c2016-04-05 10:52:00 -07002801 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
2802 get_incoming_message_sub_id(ad_rx), array_message)
Nathan Harold123c9da2015-12-30 16:33:25 -08002803
Ang Li73697b32015-12-03 00:41:53 +00002804
Betty Zhoua27e5d42017-01-17 11:33:04 -08002805#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Ang Li73697b32015-12-03 00:41:53 +00002806def mms_send_receive_verify_for_subscription(log, ad_tx, ad_rx, subid_tx,
Nathan Harold123c9da2015-12-30 16:33:25 -08002807 subid_rx, array_payload):
Betty Zhou2e08ac32017-01-27 14:21:29 -08002808 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00002809
Betty Zhou2e08ac32017-01-27 14:21:29 -08002810 Send (several) MMS from droid_tx to droid_rx.
2811 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00002812 Verify received content and sender's number are correct.
2813
2814 Args:
2815 log: Log object.
2816 ad_tx: Sender's Android Device Object..
2817 ad_rx: Receiver's Android Device Object.
2818 subid_tx: Sender's subsciption ID to be used for SMS
2819 subid_rx: Receiver's subsciption ID to be used for SMS
2820 array_message: the array of message to send/receive
2821 """
2822
Ang Li73697b32015-12-03 00:41:53 +00002823 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num']
2824 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num']
2825 for subject, message, filename in array_payload:
Betty Zhoua37acd32017-02-23 20:04:24 -08002826 ad_tx.log.info(
2827 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
2828 phonenumber_tx, phonenumber_rx, subject, message, filename)
Ang Li73697b32015-12-03 00:41:53 +00002829 result = False
2830 ad_rx.ed.clear_all_events()
2831 ad_rx.droid.smsStartTrackingIncomingMmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00002832 try:
2833 ad_tx.droid.smsSendMultimediaMessage(
Nathan Harold123c9da2015-12-30 16:33:25 -08002834 phonenumber_rx, subject, message, phonenumber_tx, filename)
Betty Zhoua27e5d42017-01-17 11:33:04 -08002835 try:
2836 ad_tx.ed.pop_event(EventMmsSentSuccess,
2837 MAX_WAIT_TIME_SMS_SENT_SUCCESS)
2838 except Empty:
Betty Zhoubb192482017-03-01 14:38:56 -08002839 ad_tx.log.warn("No sent_success event.")
Betty Zhou2e08ac32017-01-27 14:21:29 -08002840 return False
2841
2842 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
2843 return False
2844 finally:
2845 ad_rx.droid.smsStopTrackingIncomingMmsMessage()
2846 return True
2847
2848
2849def mms_receive_verify_after_call_hangup(log, ad_tx, ad_rx, array_message):
2850 """Verify the suspanded MMS during call will send out after call release.
2851
2852 Hangup call from droid_tx to droid_rx.
2853 Verify MMS is sent, delivered and received.
2854 Verify received content and sender's number are correct.
2855
2856 Args:
2857 log: Log object.
2858 ad_tx: Sender's Android Device Object
2859 ad_rx: Receiver's Android Device Object
2860 array_message: the array of message to send/receive
2861 """
2862 return mms_receive_verify_after_call_hangup_for_subscription(
2863 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
2864 get_incoming_message_sub_id(ad_rx), array_message)
2865
2866
2867#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
2868def mms_receive_verify_after_call_hangup_for_subscription(
2869 log, ad_tx, ad_rx, subid_tx, subid_rx, array_payload):
2870 """Verify the suspanded MMS during call will send out after call release.
2871
2872 Hangup call from droid_tx to droid_rx.
2873 Verify MMS is sent, delivered and received.
2874 Verify received content and sender's number are correct.
2875
2876 Args:
2877 log: Log object.
2878 ad_tx: Sender's Android Device Object..
2879 ad_rx: Receiver's Android Device Object.
2880 subid_tx: Sender's subsciption ID to be used for SMS
2881 subid_rx: Receiver's subsciption ID to be used for SMS
2882 array_message: the array of message to send/receive
2883 """
2884
2885 phonenumber_tx = ad_tx.cfg['subscription'][subid_tx]['phone_num']
2886 phonenumber_rx = ad_rx.cfg['subscription'][subid_rx]['phone_num']
2887 for subject, message, filename in array_payload:
Betty Zhoua37acd32017-02-23 20:04:24 -08002888 ad_rx.log.info(
2889 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
2890 phonenumber_tx, phonenumber_rx, subject, message, filename)
Betty Zhou2e08ac32017-01-27 14:21:29 -08002891 result = False
2892 ad_rx.ed.clear_all_events()
2893 ad_rx.droid.smsStartTrackingIncomingMmsMessage()
2894 time.sleep(5)
2895 try:
2896 hangup_call(log, ad_tx)
2897 hangup_call(log, ad_rx)
2898 try:
2899 ad_tx.ed.pop_event(EventMmsSentSuccess,
2900 MAX_WAIT_TIME_SMS_SENT_SUCCESS)
2901 except Empty:
2902 log.warn("No sent_success event.")
Betty Zhoua27e5d42017-01-17 11:33:04 -08002903 return False
Ang Li73697b32015-12-03 00:41:53 +00002904
Betty Zhoua27e5d42017-01-17 11:33:04 -08002905 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
Ang Li73697b32015-12-03 00:41:53 +00002906 return False
2907 finally:
Ang Li73697b32015-12-03 00:41:53 +00002908 ad_rx.droid.smsStopTrackingIncomingMmsMessage()
2909 return True
2910
Nathan Harold123c9da2015-12-30 16:33:25 -08002911
2912def ensure_network_rat(log,
2913 ad,
2914 network_preference,
2915 rat_family,
2916 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08002917 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08002918 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08002919 """Ensure ad's current network is in expected rat_family.
2920 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002921 return ensure_network_rat_for_subscription(
2922 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08002923 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
Ang Li73697b32015-12-03 00:41:53 +00002924
Nathan Harold123c9da2015-12-30 16:33:25 -08002925
Nathan Harold7642fc92016-05-02 18:29:11 -07002926def ensure_network_rat_for_subscription(
2927 log,
2928 ad,
2929 sub_id,
2930 network_preference,
2931 rat_family,
2932 voice_or_data=None,
2933 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
2934 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08002935 """Ensure ad's current network is in expected rat_family.
2936 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002937 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
2938 network_preference, sub_id):
Betty Zhoua37acd32017-02-23 20:04:24 -08002939 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
2940 sub_id, network_preference)
Yang Liue23e5b12015-12-07 17:17:27 -08002941 return False
2942 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
Nathan Harold123c9da2015-12-30 16:33:25 -08002943 voice_or_data):
Betty Zhoua37acd32017-02-23 20:04:24 -08002944 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
2945 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08002946 return True
2947
2948 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08002949 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08002950 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08002951 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08002952
2953 result = wait_for_network_rat_for_subscription(
2954 log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
2955
Nathan Harold123c9da2015-12-30 16:33:25 -08002956 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08002957 "End of ensure_network_rat_for_subscription for %s. "
2958 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
2959 "data: %s(family: %s)", ad.serial, network_preference, rat_family,
2960 voice_or_data,
2961 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
2962 rat_family_from_rat(
2963 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
2964 sub_id)),
2965 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
2966 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08002967 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08002968 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08002969 return result
2970
Nathan Harold123c9da2015-12-30 16:33:25 -08002971
2972def ensure_network_preference(log,
2973 ad,
2974 network_preference,
2975 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08002976 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08002977 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08002978 """Ensure that current rat is within the device's preferred network rats.
2979 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002980 return ensure_network_preference_for_subscription(
2981 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08002982 voice_or_data, max_wait_time, toggle_apm_after_setting)
2983
Nathan Harold123c9da2015-12-30 16:33:25 -08002984
2985def ensure_network_preference_for_subscription(
2986 log,
2987 ad,
2988 sub_id,
2989 network_preference,
2990 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08002991 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08002992 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08002993 """Ensure ad's network preference is <network_preference> for sub_id.
2994 """
2995 rat_family_list = rat_families_for_network_preference(network_preference)
Nathan Harold123c9da2015-12-30 16:33:25 -08002996 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
2997 network_preference, sub_id):
Yang Liue23e5b12015-12-07 17:17:27 -08002998 log.error("Set Preferred Networks failed.")
2999 return False
Nathan Harold123c9da2015-12-30 16:33:25 -08003000 if is_droid_in_rat_family_list_for_subscription(
3001 log, ad, sub_id, rat_family_list, voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08003002 return True
3003
3004 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08003005 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08003006 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08003007 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08003008
3009 result = wait_for_preferred_network_for_subscription(
3010 log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
3011
Betty Zhoua37acd32017-02-23 20:04:24 -08003012 ad.log.info(
3013 "End of ensure_network_preference_for_subscription. "
3014 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
3015 "data: %s(family: %s)", network_preference, rat_family_list,
3016 voice_or_data,
3017 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
3018 rat_family_from_rat(
3019 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
3020 sub_id)),
3021 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
3022 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08003023 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08003024 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08003025 return result
3026
Nathan Harold123c9da2015-12-30 16:33:25 -08003027
3028def ensure_network_generation(log,
3029 ad,
3030 generation,
Yang Liudf164e32016-01-07 16:49:32 -08003031 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003032 voice_or_data=None,
3033 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08003034 """Ensure ad's network is <network generation> for default subscription ID.
3035
3036 Set preferred network generation to <generation>.
3037 Toggle ON/OFF airplane mode if necessary.
3038 Wait for ad in expected network type.
3039 """
3040 return ensure_network_generation_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08003041 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
3042 max_wait_time, voice_or_data, toggle_apm_after_setting)
Yang Liue23e5b12015-12-07 17:17:27 -08003043
Nathan Harold123c9da2015-12-30 16:33:25 -08003044
3045def ensure_network_generation_for_subscription(
3046 log,
3047 ad,
3048 sub_id,
3049 generation,
Yang Liudf164e32016-01-07 16:49:32 -08003050 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003051 voice_or_data=None,
3052 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08003053 """Ensure ad's network is <network generation> for specified subscription ID.
3054
3055 Set preferred network generation to <generation>.
3056 Toggle ON/OFF airplane mode if necessary.
3057 Wait for ad in expected network type.
3058 """
Betty Zhoua37acd32017-02-23 20:04:24 -08003059 ad.log.info(
3060 "RAT network type voice: %s, data: %s",
3061 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
3062 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
3063 if is_droid_in_network_generation_for_subscription(
3064 log, ad, sub_id, generation, voice_or_data):
3065 return True
3066
3067 # Update the setting if necessary
Yang Liue23e5b12015-12-07 17:17:27 -08003068 operator = get_operator_name(log, ad, sub_id)
3069 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08003070 network_preference = network_preference_for_generaton(generation,
3071 operator)
Yang Liue23e5b12015-12-07 17:17:27 -08003072 rat_family = rat_family_for_generation(generation, operator)
3073 except KeyError:
Betty Zhoua37acd32017-02-23 20:04:24 -08003074 ad.log.error("Failed to find a rat_family entry for "
3075 "PLMN: %s, operator:%s, generation: %s",
3076 ad.droid.telephonyGetSimOperatorForSubscription(sub_id),
3077 operator, generation)
Yang Liue23e5b12015-12-07 17:17:27 -08003078 return False
3079
Nathan Harold4a144a42016-09-19 14:16:24 -07003080 current_network_preference = \
3081 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(
3082 sub_id)
3083
Nathan Harold4a144a42016-09-19 14:16:24 -07003084 if (current_network_preference is not network_preference and
3085 not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
3086 network_preference, sub_id)):
Betty Zhoua37acd32017-02-23 20:04:24 -08003087 ad.log.error(
3088 "Network preference is %s. Set Preferred Networks to %s failed.",
3089 current_network_preference, network_preference)
Yang Liue23e5b12015-12-07 17:17:27 -08003090 return False
3091
Nathan Harold4a144a42016-09-19 14:16:24 -07003092 if is_droid_in_network_generation_for_subscription(
3093 log, ad, sub_id, generation, voice_or_data):
3094 return True
3095
Yang Liue23e5b12015-12-07 17:17:27 -08003096 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08003097 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08003098 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08003099 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08003100
3101 result = wait_for_network_generation_for_subscription(
3102 log, ad, sub_id, generation, max_wait_time, voice_or_data)
3103
Betty Zhoua37acd32017-02-23 20:04:24 -08003104 ad.log.info(
3105 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
3106 "data: %s(family: %s)", network_preference, generation, voice_or_data,
3107 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
3108 rat_generation_from_rat(
3109 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
3110 sub_id)),
3111 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
3112 rat_generation_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08003113 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08003114 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08003115
3116 return result
3117
Yang Liue23e5b12015-12-07 17:17:27 -08003118
Nathan Harold123c9da2015-12-30 16:33:25 -08003119def wait_for_network_rat(log,
3120 ad,
3121 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08003122 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003123 voice_or_data=None):
3124 return wait_for_network_rat_for_subscription(
3125 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
3126 max_wait_time, voice_or_data)
3127
3128
Nathan Harold7642fc92016-05-02 18:29:11 -07003129def wait_for_network_rat_for_subscription(
3130 log,
3131 ad,
3132 sub_id,
3133 rat_family,
3134 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
3135 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08003136 return _wait_for_droid_in_state_for_subscription(
3137 log, ad, sub_id, max_wait_time,
3138 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
3139
Yang Liue23e5b12015-12-07 17:17:27 -08003140
Nathan Harold123c9da2015-12-30 16:33:25 -08003141def wait_for_not_network_rat(log,
3142 ad,
3143 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08003144 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003145 voice_or_data=None):
3146 return wait_for_not_network_rat_for_subscription(
3147 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
3148 max_wait_time, voice_or_data)
3149
3150
3151def wait_for_not_network_rat_for_subscription(
3152 log,
3153 ad,
3154 sub_id,
3155 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08003156 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003157 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08003158 return _wait_for_droid_in_state_for_subscription(
3159 log, ad, sub_id, max_wait_time,
Betty Zhoua27e5d42017-01-17 11:33:04 -08003160 lambda log, ad, sub_id, * args, ** kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)
3161 )
Yang Liue23e5b12015-12-07 17:17:27 -08003162
Nathan Harold123c9da2015-12-30 16:33:25 -08003163
3164def wait_for_preferred_network(log,
3165 ad,
3166 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08003167 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003168 voice_or_data=None):
3169 return wait_for_preferred_network_for_subscription(
3170 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08003171 max_wait_time, voice_or_data)
3172
Nathan Harold123c9da2015-12-30 16:33:25 -08003173
3174def wait_for_preferred_network_for_subscription(
3175 log,
3176 ad,
3177 sub_id,
3178 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08003179 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003180 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08003181 rat_family_list = rat_families_for_network_preference(network_preference)
3182 return _wait_for_droid_in_state_for_subscription(
3183 log, ad, sub_id, max_wait_time,
3184 is_droid_in_rat_family_list_for_subscription, rat_family_list,
3185 voice_or_data)
3186
Nathan Harold123c9da2015-12-30 16:33:25 -08003187
3188def wait_for_network_generation(log,
3189 ad,
3190 generation,
Yang Liudf164e32016-01-07 16:49:32 -08003191 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003192 voice_or_data=None):
3193 return wait_for_network_generation_for_subscription(
3194 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
3195 max_wait_time, voice_or_data)
3196
3197
3198def wait_for_network_generation_for_subscription(
3199 log,
3200 ad,
3201 sub_id,
3202 generation,
Yang Liudf164e32016-01-07 16:49:32 -08003203 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08003204 voice_or_data=None):
3205 return _wait_for_droid_in_state_for_subscription(
3206 log, ad, sub_id, max_wait_time,
3207 is_droid_in_network_generation_for_subscription, generation,
Yang Liue23e5b12015-12-07 17:17:27 -08003208 voice_or_data)
3209
Yang Liue23e5b12015-12-07 17:17:27 -08003210
3211def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None):
Nathan Harold123c9da2015-12-30 16:33:25 -08003212 return is_droid_in_rat_family_for_subscription(
3213 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
3214 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08003215
Yang Liue23e5b12015-12-07 17:17:27 -08003216
Nathan Harold123c9da2015-12-30 16:33:25 -08003217def is_droid_in_rat_family_for_subscription(log,
3218 ad,
3219 sub_id,
3220 rat_family,
3221 voice_or_data=None):
3222 return is_droid_in_rat_family_list_for_subscription(
3223 log, ad, sub_id, [rat_family], voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08003224
Nathan Harold123c9da2015-12-30 16:33:25 -08003225
3226def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None):
3227 return is_droid_in_rat_family_list_for_subscription(
3228 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list,
3229 voice_or_data)
3230
3231
3232def is_droid_in_rat_family_list_for_subscription(log,
3233 ad,
3234 sub_id,
3235 rat_family_list,
3236 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08003237 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
3238 if voice_or_data:
3239 service_list = [voice_or_data]
3240
3241 for service in service_list:
3242 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
3243 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
3244 continue
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003245 if rat_family_from_rat(nw_rat) in rat_family_list:
Yang Liue23e5b12015-12-07 17:17:27 -08003246 return True
3247 return False
3248
Nathan Harold123c9da2015-12-30 16:33:25 -08003249
Yang Liue23e5b12015-12-07 17:17:27 -08003250def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data):
3251 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00003252
3253 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08003254 log: log object.
3255 ad: android device.
3256 nw_gen: expected generation "4g", "3g", "2g".
3257 voice_or_data: check voice network generation or data network generation
3258 This parameter is optional. If voice_or_data is None, then if
3259 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00003260
3261 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08003262 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00003263 """
Yang Liue23e5b12015-12-07 17:17:27 -08003264 return is_droid_in_network_generation_for_subscription(
3265 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data)
Ang Li73697b32015-12-03 00:41:53 +00003266
Nathan Harold123c9da2015-12-30 16:33:25 -08003267
3268def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen,
3269 voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08003270 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00003271
3272 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08003273 log: log object.
3274 ad: android device.
3275 nw_gen: expected generation "4g", "3g", "2g".
3276 voice_or_data: check voice network generation or data network generation
3277 This parameter is optional. If voice_or_data is None, then if
3278 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00003279
3280 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08003281 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00003282 """
Yang Liue23e5b12015-12-07 17:17:27 -08003283 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
Ang Li73697b32015-12-03 00:41:53 +00003284
Yang Liue23e5b12015-12-07 17:17:27 -08003285 if voice_or_data:
3286 service_list = [voice_or_data]
Ang Li73697b32015-12-03 00:41:53 +00003287
Yang Liue23e5b12015-12-07 17:17:27 -08003288 for service in service_list:
3289 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
Ang Li73697b32015-12-03 00:41:53 +00003290
Yang Liue23e5b12015-12-07 17:17:27 -08003291 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
3292 continue
3293
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003294 if rat_generation_from_rat(nw_rat) == nw_gen:
Yang Liue23e5b12015-12-07 17:17:27 -08003295 return True
3296 else:
3297 return False
3298
3299 return False
Ang Li73697b32015-12-03 00:41:53 +00003300
Nathan Harold123c9da2015-12-30 16:33:25 -08003301
Ang Li73697b32015-12-03 00:41:53 +00003302def get_network_rat(log, ad, voice_or_data):
3303 """Get current network type (Voice network type, or data network type)
3304 for default subscription id
3305
3306 Args:
3307 ad: Android Device Object
3308 voice_or_data: Input parameter indicating to get voice network type or
3309 data network type.
3310
3311 Returns:
3312 Current voice/data network type.
3313 """
3314 return get_network_rat_for_subscription(
3315 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
3316
Nathan Harold123c9da2015-12-30 16:33:25 -08003317
Ang Li73697b32015-12-03 00:41:53 +00003318def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data):
3319 """Get current network type (Voice network type, or data network type)
3320 for specified subscription id
3321
3322 Args:
3323 ad: Android Device Object
3324 sub_id: subscription ID
3325 voice_or_data: Input parameter indicating to get voice network type or
3326 data network type.
3327
3328 Returns:
3329 Current voice/data network type.
3330 """
3331 if voice_or_data == NETWORK_SERVICE_VOICE:
Nathan Harold123c9da2015-12-30 16:33:25 -08003332 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
3333 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003334 elif voice_or_data == NETWORK_SERVICE_DATA:
Nathan Harold123c9da2015-12-30 16:33:25 -08003335 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
3336 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003337 else:
Yang Liuaed3eef2015-12-15 18:40:25 -08003338 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003339
3340 if ret_val is None:
3341 log.error("get_network_rat(): Unexpected null return value")
3342 return RAT_UNKNOWN
3343 else:
3344 return ret_val
3345
Nathan Harold123c9da2015-12-30 16:33:25 -08003346
Ang Li73697b32015-12-03 00:41:53 +00003347def get_network_gen(log, ad, voice_or_data):
3348 """Get current network generation string (Voice network type, or data network type)
3349
3350 Args:
3351 ad: Android Device Object
3352 voice_or_data: Input parameter indicating to get voice network generation
3353 or data network generation.
3354
3355 Returns:
3356 Current voice/data network generation.
3357 """
3358 return get_network_gen_for_subscription(
3359 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
3360
Nathan Harold123c9da2015-12-30 16:33:25 -08003361
Ang Li73697b32015-12-03 00:41:53 +00003362def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data):
3363 """Get current network generation string (Voice network type, or data network type)
3364
3365 Args:
3366 ad: Android Device Object
3367 voice_or_data: Input parameter indicating to get voice network generation
3368 or data network generation.
3369
3370 Returns:
3371 Current voice/data network generation.
3372 """
3373 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07003374 return rat_generation_from_rat(
3375 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data))
Betty Zhoua37acd32017-02-23 20:04:24 -08003376 except KeyError as e:
3377 ad.log.error("KeyError %s", e)
Yang Liue23e5b12015-12-07 17:17:27 -08003378 return GEN_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00003379
Nathan Harold123c9da2015-12-30 16:33:25 -08003380
3381def check_voice_mail_count(log, ad, voice_mail_count_before,
3382 voice_mail_count_after):
Ang Li73697b32015-12-03 00:41:53 +00003383 """function to check if voice mail count is correct after leaving a new voice message.
3384 """
3385 return get_voice_mail_count_check_function(get_operator_name(log, ad))(
3386 voice_mail_count_before, voice_mail_count_after)
3387
Nathan Harold123c9da2015-12-30 16:33:25 -08003388
Ang Li73697b32015-12-03 00:41:53 +00003389def get_voice_mail_number(log, ad):
3390 """function to get the voice mail number
3391 """
Nathan Harold4a144a42016-09-19 14:16:24 -07003392 voice_mail_number = get_voice_mail_number_function(
3393 get_operator_name(log, ad))()
Ang Li73697b32015-12-03 00:41:53 +00003394 if voice_mail_number is None:
3395 return get_phone_number(log, ad)
3396 return voice_mail_number
3397
Nathan Harold123c9da2015-12-30 16:33:25 -08003398
3399def ensure_phones_idle(log,
3400 ads,
Ang Li73697b32015-12-03 00:41:53 +00003401 settling_time=WAIT_TIME_ANDROID_STATE_SETTLING):
3402 """Ensure ads idle (not in call).
3403 """
3404 for ad in ads:
3405 if ad.droid.telecomIsInCall():
3406 ad.droid.telecomEndCall()
3407 # Leave the delay time to make sure droid can recover to idle from ongoing call.
3408 time.sleep(settling_time)
3409 return True
3410
Nathan Harold123c9da2015-12-30 16:33:25 -08003411
3412def ensure_phone_idle(log, ad, settling_time=WAIT_TIME_ANDROID_STATE_SETTLING):
Ang Li73697b32015-12-03 00:41:53 +00003413 """Ensure ad idle (not in call).
3414 """
3415 return ensure_phones_idle(log, [ad], settling_time)
3416
Nathan Harold123c9da2015-12-30 16:33:25 -08003417
Ang Li73697b32015-12-03 00:41:53 +00003418def ensure_phone_default_state(log, ad):
3419 """Ensure ad in default state.
3420 Phone not in call.
3421 Phone have no stored WiFi network and WiFi disconnected.
3422 Phone not in airplane mode.
3423 """
3424 result = True
Nathan Haroldeb60b192016-08-24 14:41:55 -07003425
Betty Zhouf25ce442017-03-03 14:28:36 -08003426 try:
3427 ad.droid.telephonyFactoryReset()
3428 if ad.droid.telecomIsInCall():
3429 ad.droid.telecomEndCall()
3430 if not wait_for_droid_not_in_call(log, ad):
3431 ad.log.error("Failed to end call on %s")
3432 except Exception as e:
3433 ad.log.error("Failure %s, toggle APM instead", e)
3434 toggle_airplane_mode(log, ad, True, False)
3435 ad.droid.telephonyToggleDataConnection(True)
Nathan Haroldeb60b192016-08-24 14:41:55 -07003436
Betty Zhouf25ce442017-03-03 14:28:36 -08003437 if not toggle_airplane_mode(log, ad, False, False):
3438 ad.log.error("Fail to turn off airplane mode")
3439 result = False
Ang Li73697b32015-12-03 00:41:53 +00003440 set_wfc_mode(log, ad, WFC_MODE_DISABLED)
Nathan Harold0a011532016-08-24 19:17:44 -07003441 toggle_video_calling(log, ad, False)
Betty Zhouf25ce442017-03-03 14:28:36 -08003442 set_wifi_to_default(log, ad)
Betty Zhouccd171d2017-02-13 15:11:33 -08003443
Nathan Harold72f9bff2016-09-19 14:16:24 -07003444 if not wait_for_not_network_rat(
3445 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
Betty Zhoua37acd32017-02-23 20:04:24 -08003446 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA, RAT_FAMILY_WLAN)
Ang Li73697b32015-12-03 00:41:53 +00003447 result = False
Nathan Haroldeb60b192016-08-24 14:41:55 -07003448
Ang Li73697b32015-12-03 00:41:53 +00003449 # Leave the delay time to make sure droid can recover to idle from ongoing call.
3450 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
3451 return result
3452
Nathan Harold123c9da2015-12-30 16:33:25 -08003453
Ang Li73697b32015-12-03 00:41:53 +00003454def ensure_phones_default_state(log, ads):
3455 """Ensure ads in default state.
3456 Phone not in call.
3457 Phone have no stored WiFi network and WiFi disconnected.
3458 Phone not in airplane mode.
Nathan Haroldeb60b192016-08-24 14:41:55 -07003459
3460 Returns:
3461 True if all steps of restoring default state succeed.
3462 False if any of the steps to restore default state fails.
Ang Li73697b32015-12-03 00:41:53 +00003463 """
3464 tasks = []
3465 for ad in ads:
3466 tasks.append((ensure_phone_default_state, (log, ad)))
3467 if not multithread_func(log, tasks):
3468 log.error("Ensure_phones_default_state Fail.")
3469 return False
3470 return True
3471
Nathan Harold123c9da2015-12-30 16:33:25 -08003472
Betty Zhoua37acd32017-02-23 20:04:24 -08003473def check_is_wifi_connected(log, ad, wifi_ssid):
3474 """Check if ad is connected to wifi wifi_ssid.
Ang Li73697b32015-12-03 00:41:53 +00003475
3476 Args:
3477 log: Log object.
3478 ad: Android device object.
3479 wifi_ssid: WiFi network SSID.
Ang Li73697b32015-12-03 00:41:53 +00003480
Betty Zhoua37acd32017-02-23 20:04:24 -08003481 Returns:
3482 True if wifi is connected to wifi_ssid
3483 False if wifi is not connected to wifi_ssid
Ang Li73697b32015-12-03 00:41:53 +00003484 """
Betty Zhoua37acd32017-02-23 20:04:24 -08003485 wifi_info = ad.droid.wifiGetConnectionInfo()
3486 if wifi_info["supplicant_state"] == "completed" and wifi_info[
3487 "SSID"] == wifi_ssid:
3488 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhouccd171d2017-02-13 15:11:33 -08003489 return True
Betty Zhoua37acd32017-02-23 20:04:24 -08003490 else:
3491 ad.log.info("Wifi is not connected to %s", wifi_ssid)
3492 ad.log.debug("Wifi connection_info=%s", wifi_info)
3493 return False
3494
3495
3496def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3):
3497 """Ensure ad connected to wifi on network wifi_ssid.
3498
3499 Args:
3500 log: Log object.
3501 ad: Android device object.
3502 wifi_ssid: WiFi network SSID.
3503 wifi_pwd: optional secure network password.
3504 retries: the number of retries.
3505
3506 Returns:
3507 True if wifi is connected to wifi_ssid
3508 False if wifi is not connected to wifi_ssid
3509 """
Betty Zhouf25ce442017-03-03 14:28:36 -08003510 network = {WifiEnums.SSID_KEY: wifi_ssid}
3511 if wifi_pwd:
3512 network[WifiEnums.PWD_KEY] = wifi_pwd
3513 for i in range(retries):
3514 if not ad.droid.wifiCheckState():
3515 ad.log.info("Wifi state is down. Turn on Wifi")
3516 ad.droid.wifiToggleState(True)
3517 if check_is_wifi_connected(log, ad, wifi_ssid):
3518 ad.log.info("Wifi is connected to %s", wifi_ssid)
3519 return True
3520 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08003521 ad.log.info("Connecting to wifi %s", wifi_ssid)
Betty Zhoubb192482017-03-01 14:38:56 -08003522 if ad.build_info["build_id"].startswith("O"):
3523 ad.droid.wifiConnectByConfig(network)
3524 else:
3525 ad.droid.wifiConnect(network)
Betty Zhoua37acd32017-02-23 20:04:24 -08003526 time.sleep(20)
3527 if check_is_wifi_connected(log, ad, wifi_ssid):
3528 return True
3529 ad.log.info("Fail to connected to wifi %s", wifi_ssid)
Ang Li73697b32015-12-03 00:41:53 +00003530 return False
3531
Nathan Harold123c9da2015-12-30 16:33:25 -08003532
Betty Zhoua37acd32017-02-23 20:04:24 -08003533def forget_all_wifi_networks(log, ad):
3534 """Forget all stored wifi network information
3535
3536 Args:
3537 log: log object
3538 ad: AndroidDevice object
3539
3540 Returns:
3541 boolean success (True) or failure (False)
3542 """
3543 if not ad.droid.wifiGetConfiguredNetworks():
3544 return True
3545 try:
3546 old_state = ad.droid.wifiCheckState()
3547 reset_wifi(ad)
3548 wifi_toggle_state(ad, new_state=old_state)
3549 except Exception as e:
3550 log.error("forget_all_wifi_networks with exception: %s", e)
3551 return False
3552 return True
3553
3554
3555def set_wifi_to_default(log, ad):
3556 """Set wifi to default state (Wifi disabled and no configured network)
3557
3558 Args:
3559 log: log object
3560 ad: AndroidDevice object
3561
3562 Returns:
3563 boolean success (True) or failure (False)
3564 """
Betty Zhouf25ce442017-03-03 14:28:36 -08003565 ad.droid.wifiFactoryReset()
Betty Zhoua37acd32017-02-23 20:04:24 -08003566 ad.droid.wifiToggleState(False)
3567 #try to use wifi_test_utils after bug fix
3568 #if not wifi_toggle_state(ad, new_state=False, assert_on_fail=False):
3569 # ad.log.error("Fail to turn off WIFI")
3570 # return False
3571
3572
Yang Liu98fd9d72016-03-04 12:14:49 -08003573def reset_preferred_network_type_to_allowable_range(log, ad):
3574 """If preferred network type is not in allowable range, reset to GEN_4G
3575 preferred network type.
3576
3577 Args:
3578 log: log object
3579 ad: android device object
3580
3581 Returns:
3582 None
3583 """
3584 sub_info_list = ad.droid.subscriptionGetAllSubInfoList()
3585 for sub_info in sub_info_list:
3586 sub_id = sub_info['subscriptionId']
3587 operator = get_operator_name(log, ad, sub_id)
3588 current_preference = \
3589 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id)
Betty Zhoubb192482017-03-01 14:38:56 -08003590 ad.log.debug("sub_id network preference is %s", current_preference)
Yang Liu4072cfa2016-04-06 11:25:07 -07003591 try:
Nathan Harold7642fc92016-05-02 18:29:11 -07003592 if current_preference not in get_allowable_network_preference(
3593 operator):
3594 network_preference = network_preference_for_generaton(GEN_4G,
3595 operator)
Yang Liu4072cfa2016-04-06 11:25:07 -07003596 ad.droid.telephonySetPreferredNetworkTypesForSubscription(
3597 network_preference, sub_id)
3598 except KeyError:
3599 pass
Yang Liu98fd9d72016-03-04 12:14:49 -08003600
Nathan Harold7642fc92016-05-02 18:29:11 -07003601
Ang Li73697b32015-12-03 00:41:53 +00003602def task_wrapper(task):
3603 """Task wrapper for multithread_func
3604
3605 Args:
3606 task[0]: function to be wrapped.
3607 task[1]: function args.
3608
3609 Returns:
3610 Return value of wrapped function call.
3611 """
3612 func = task[0]
3613 params = task[1]
3614 return func(*params)
3615
Nathan Harold123c9da2015-12-30 16:33:25 -08003616
Betty Zhouccd171d2017-02-13 15:11:33 -08003617def run_multithread_func(log, tasks):
3618 """Run multi-thread functions and return results.
3619
3620 Args:
3621 log: log object.
3622 tasks: a list of tasks to be executed in parallel.
3623
3624 Returns:
3625 results for tasks.
3626 """
3627 MAX_NUMBER_OF_WORKERS = 4
3628 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
3629 executor = concurrent.futures.ThreadPoolExecutor(
3630 max_workers=number_of_workers)
3631 results = list(executor.map(task_wrapper, tasks))
3632 executor.shutdown()
Betty Zhoua37acd32017-02-23 20:04:24 -08003633 log.info("multithread_func %s result: %s",
3634 [task[0].__name__ for task in tasks], results)
Betty Zhouccd171d2017-02-13 15:11:33 -08003635 return results
3636
3637
Ang Li73697b32015-12-03 00:41:53 +00003638def multithread_func(log, tasks):
3639 """Multi-thread function wrapper.
3640
3641 Args:
3642 log: log object.
3643 tasks: tasks to be executed in parallel.
3644
3645 Returns:
3646 True if all tasks return True.
3647 False if any task return False.
3648 """
Betty Zhouccd171d2017-02-13 15:11:33 -08003649 results = run_multithread_func(log, tasks)
Ang Li73697b32015-12-03 00:41:53 +00003650 for r in results:
3651 if not r:
3652 return False
3653 return True
3654
Nathan Harold123c9da2015-12-30 16:33:25 -08003655
Betty Zhouccd171d2017-02-13 15:11:33 -08003656def multithread_func_and_check_results(log, tasks, expected_results):
3657 """Multi-thread function wrapper.
3658
3659 Args:
3660 log: log object.
3661 tasks: tasks to be executed in parallel.
3662 expected_results: check if the results from tasks match expected_results.
3663
3664 Returns:
3665 True if expected_results are met.
3666 False if expected_results are not met.
3667 """
3668 return_value = True
3669 results = run_multithread_func(log, tasks)
3670 log.info("multithread_func result: %s, expecting %s", results,
3671 expected_results)
3672 for task, result, expected_result in zip(tasks, results, expected_results):
3673 if result != expected_result:
3674 logging.info("Result for task %s is %s, expecting %s", task[0],
3675 result, expected_result)
3676 return_value = False
3677 return return_value
3678
3679
Ang Li73697b32015-12-03 00:41:53 +00003680def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME):
3681 """Set phone screen on time.
3682
3683 Args:
3684 log: Log object.
3685 ad: Android device object.
3686 screen_on_time: screen on time.
3687 This is optional, default value is MAX_SCREEN_ON_TIME.
3688 Returns:
3689 True if set successfully.
3690 """
3691 ad.droid.setScreenTimeout(screen_on_time)
3692 return screen_on_time == ad.droid.getScreenTimeout()
3693
Nathan Harold123c9da2015-12-30 16:33:25 -08003694
Ang Li73697b32015-12-03 00:41:53 +00003695def set_phone_silent_mode(log, ad, silent_mode=True):
3696 """Set phone silent mode.
3697
3698 Args:
3699 log: Log object.
3700 ad: Android device object.
3701 silent_mode: set phone silent or not.
3702 This is optional, default value is True (silent mode on).
3703 Returns:
3704 True if set successfully.
3705 """
3706 ad.droid.toggleRingerSilentMode(silent_mode)
Betty Zhoua37acd32017-02-23 20:04:24 -08003707 ad.droid.setMediaVolume(0)
3708 ad.droid.setVoiceCallVolume(0)
3709 ad.droid.setAlarmVolume(0)
3710
Ang Li73697b32015-12-03 00:41:53 +00003711 return silent_mode == ad.droid.checkRingerSilentMode()
3712
Nathan Harold123c9da2015-12-30 16:33:25 -08003713
Ang Li73697b32015-12-03 00:41:53 +00003714def set_preferred_subid_for_sms(log, ad, sub_id):
3715 """set subscription id for SMS
3716
3717 Args:
3718 log: Log object.
3719 ad: Android device object.
3720 sub_id :Subscription ID.
3721
3722 """
Betty Zhoua37acd32017-02-23 20:04:24 -08003723 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003724 ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
3725 # Wait to make sure settings take effect
3726 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
3727 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId()
3728
Nathan Harold123c9da2015-12-30 16:33:25 -08003729
Ang Li73697b32015-12-03 00:41:53 +00003730def set_preferred_subid_for_data(log, ad, sub_id):
3731 """set subscription id for data
3732
3733 Args:
3734 log: Log object.
3735 ad: Android device object.
3736 sub_id :Subscription ID.
3737
3738 """
Betty Zhoua37acd32017-02-23 20:04:24 -08003739 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003740 ad.droid.subscriptionSetDefaultDataSubId(sub_id)
3741 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
3742 # Wait to make sure settings take effect
3743 # Data SIM change takes around 1 min
3744 # Check whether data has changed to selected sim
Nathan Harold7642fc92016-05-02 18:29:11 -07003745 if not wait_for_data_connection(log, ad, True,
3746 MAX_WAIT_TIME_DATA_SUB_CHANGE):
Ang Li73697b32015-12-03 00:41:53 +00003747 log.error("Data Connection failed - Not able to switch Data SIM")
3748 return False
3749 return True
3750
Nathan Harold123c9da2015-12-30 16:33:25 -08003751
Ang Li73697b32015-12-03 00:41:53 +00003752def set_preferred_subid_for_voice(log, ad, sub_id):
3753 """set subscription id for voice
3754
3755 Args:
3756 log: Log object.
3757 ad: Android device object.
3758 sub_id :Subscription ID.
3759
3760 """
Betty Zhoua37acd32017-02-23 20:04:24 -08003761 ad.log.info("Setting subscription %s as Voice SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003762 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
3763 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
3764 # Wait to make sure settings take effect
3765 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
3766 return True
3767
Nathan Harold123c9da2015-12-30 16:33:25 -08003768
Ang Li73697b32015-12-03 00:41:53 +00003769def set_call_state_listen_level(log, ad, value, sub_id):
3770 """Set call state listen level for subscription id.
3771
3772 Args:
3773 log: Log object.
3774 ad: Android device object.
3775 value: True or False
3776 sub_id :Subscription ID.
3777
3778 Returns:
3779 True or False
3780 """
3781 if sub_id == INVALID_SUB_ID:
3782 log.error("Invalid Subscription ID")
3783 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08003784 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08003785 "Foreground", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08003786 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08003787 "Ringing", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08003788 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08003789 "Background", value, sub_id)
Ang Li73697b32015-12-03 00:41:53 +00003790 return True
3791
Nathan Harold123c9da2015-12-30 16:33:25 -08003792
Ang Li73697b32015-12-03 00:41:53 +00003793def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False):
3794 """set subscription id for voice, sms and data
3795
3796 Args:
3797 log: Log object.
3798 ad: Android device object.
3799 sub_id :Subscription ID.
3800 voice: True if to set subscription as default voice subscription
3801 sms: True if to set subscription as default sms subscription
3802 data: True if to set subscription as default data subscription
3803
3804 """
3805 if sub_id == INVALID_SUB_ID:
3806 log.error("Invalid Subscription ID")
3807 return False
3808 else:
3809 if voice:
3810 if not set_preferred_subid_for_voice(log, ad, sub_id):
3811 return False
3812 if sms:
3813 if not set_preferred_subid_for_sms(log, ad, sub_id):
3814 return False
3815 if data:
Nathan Harold123c9da2015-12-30 16:33:25 -08003816 if not set_preferred_subid_for_data(log, ad, sub_id):
Ang Li73697b32015-12-03 00:41:53 +00003817 return False
3818 return True
3819
Nathan Harold7642fc92016-05-02 18:29:11 -07003820
Yang Liu8e6adff2016-02-05 10:24:04 -08003821def is_event_match(event, field, value):
3822 """Return if <field> in "event" match <value> or not.
Ang Li73697b32015-12-03 00:41:53 +00003823
3824 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08003825 event: event to test. This event need to have <field>.
3826 field: field to match.
3827 value: value to match.
Ang Li73697b32015-12-03 00:41:53 +00003828
3829 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08003830 True if <field> in "event" match <value>.
Ang Li73697b32015-12-03 00:41:53 +00003831 False otherwise.
3832 """
Yang Liu8e6adff2016-02-05 10:24:04 -08003833 return is_event_match_for_list(event, field, [value])
Ang Li73697b32015-12-03 00:41:53 +00003834
Nathan Harold123c9da2015-12-30 16:33:25 -08003835
Yang Liu8e6adff2016-02-05 10:24:04 -08003836def is_event_match_for_list(event, field, value_list):
3837 """Return if <field> in "event" match any one of the value
3838 in "value_list" or not.
Ang Li73697b32015-12-03 00:41:53 +00003839
3840 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08003841 event: event to test. This event need to have <field>.
3842 field: field to match.
3843 value_list: a list of value to match.
Ang Li73697b32015-12-03 00:41:53 +00003844
3845 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08003846 True if <field> in "event" match one of the value in "value_list".
Ang Li73697b32015-12-03 00:41:53 +00003847 False otherwise.
3848 """
3849 try:
Yang Liu8e6adff2016-02-05 10:24:04 -08003850 value_in_event = event['data'][field]
Ang Li73697b32015-12-03 00:41:53 +00003851 except KeyError:
3852 return False
Yang Liu8e6adff2016-02-05 10:24:04 -08003853 for value in value_list:
3854 if value_in_event == value:
Ang Li73697b32015-12-03 00:41:53 +00003855 return True
3856 return False
3857
Nathan Harold123c9da2015-12-30 16:33:25 -08003858
Yang Liu8e6adff2016-02-05 10:24:04 -08003859def is_network_call_back_event_match(event, network_callback_id,
3860 network_callback_event):
Ang Li73697b32015-12-03 00:41:53 +00003861 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07003862 return (
3863 (network_callback_id == event['data'][NetworkCallbackContainer.ID])
3864 and
3865 (network_callback_event ==
3866 event['data'][NetworkCallbackContainer.NETWORK_CALLBACK_EVENT]))
Ang Li73697b32015-12-03 00:41:53 +00003867 except KeyError:
3868 return False
3869
Nathan Harold123c9da2015-12-30 16:33:25 -08003870
Ang Li73697b32015-12-03 00:41:53 +00003871def is_build_id(log, ad, build_id):
3872 """Return if ad's build id is the same as input parameter build_id.
3873
3874 Args:
3875 log: log object.
3876 ad: android device object.
3877 build_id: android build id.
3878
3879 Returns:
3880 True if ad's build id is the same as input parameter build_id.
3881 False otherwise.
3882 """
3883 actual_bid = ad.droid.getBuildID()
3884
Betty Zhoua37acd32017-02-23 20:04:24 -08003885 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay())
Ang Li73697b32015-12-03 00:41:53 +00003886 #In case we want to log more stuff/more granularity...
3887 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID()))
3888 #log.info("{} BUILD FINGERPRINT: {} "
3889 # .format(ad.serial), ad.droid.getBuildFingerprint())
3890 #log.info("{} BUILD TYPE: {} "
3891 # .format(ad.serial), ad.droid.getBuildType())
3892 #log.info("{} BUILD NUMBER: {} "
3893 # .format(ad.serial), ad.droid.getBuildNumber())
3894 if actual_bid.upper() != build_id.upper():
Betty Zhoua37acd32017-02-23 20:04:24 -08003895 ad.log.error("%s: Incorrect Build ID", ad.model)
Ang Li73697b32015-12-03 00:41:53 +00003896 return False
3897 return True
3898
Nathan Harold123c9da2015-12-30 16:33:25 -08003899
Ang Li73697b32015-12-03 00:41:53 +00003900def is_uri_equivalent(uri1, uri2):
3901 """Check whether two input uris match or not.
3902
3903 Compare Uris.
3904 If Uris are tel URI, it will only take the digit part
3905 and compare as phone number.
3906 Else, it will just do string compare.
3907
3908 Args:
3909 uri1: 1st uri to be compared.
3910 uri2: 2nd uri to be compared.
3911
3912 Returns:
3913 True if two uris match. Otherwise False.
3914 """
Nathan Harold23683d22015-12-14 16:19:08 -08003915
3916 #If either is None/empty we return false
3917 if not uri1 or not uri2:
3918 return False
3919
3920 try:
3921 if uri1.startswith('tel:') and uri2.startswith('tel:'):
Yang Liu598b93d2016-03-22 17:07:59 -07003922 uri1_number = get_number_from_tel_uri(uri1)
3923 uri2_number = get_number_from_tel_uri(uri2)
Nathan Harold23683d22015-12-14 16:19:08 -08003924 return check_phone_number_match(uri1_number, uri2_number)
3925 else:
3926 return uri1 == uri2
3927 except AttributeError as e:
3928 return False
Ang Li73697b32015-12-03 00:41:53 +00003929
Nathan Harold123c9da2015-12-30 16:33:25 -08003930
Ang Li73697b32015-12-03 00:41:53 +00003931def get_call_uri(ad, call_id):
3932 """Get call's uri field.
3933
3934 Get Uri for call_id in ad.
3935
3936 Args:
3937 ad: android device object.
3938 call_id: the call id to get Uri from.
3939
3940 Returns:
3941 call's Uri if call is active and have uri field. None otherwise.
3942 """
3943 try:
3944 call_detail = ad.droid.telecomCallGetDetails(call_id)
3945 return call_detail["Handle"]["Uri"]
3946 except:
3947 return None
3948
Nathan Harold7642fc92016-05-02 18:29:11 -07003949
Yang Liu598b93d2016-03-22 17:07:59 -07003950def get_number_from_tel_uri(uri):
3951 """Get Uri number from tel uri
3952
3953 Args:
3954 uri: input uri
3955
3956 Returns:
3957 If input uri is tel uri, return the number part.
3958 else return None.
3959 """
3960 if uri.startswith('tel:'):
Nathan Harold4a144a42016-09-19 14:16:24 -07003961 uri_number = ''.join(
3962 i for i in urllib.parse.unquote(uri) if i.isdigit())
Yang Liu598b93d2016-03-22 17:07:59 -07003963 return uri_number
3964 else:
3965 return None
3966
3967
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003968# TODO: b/26294018 Remove wrapper class once wifi_utils methods updated
Ang Li73697b32015-12-03 00:41:53 +00003969class WifiUtils():
3970
tturneyf640a712015-12-30 15:18:15 -08003971 from acts.test_utils.wifi.wifi_test_utils \
3972 import reset_wifi as _reset_wifi
3973 from acts.test_utils.wifi.wifi_test_utils \
Ang Li73697b32015-12-03 00:41:53 +00003974 import wifi_connect as _wifi_connect
tturneyf640a712015-12-30 15:18:15 -08003975 from acts.test_utils.wifi.wifi_test_utils \
Ang Li73697b32015-12-03 00:41:53 +00003976 import wifi_toggle_state as _wifi_toggle_state
tturneyf640a712015-12-30 15:18:15 -08003977 from acts.test_utils.wifi.wifi_test_utils \
Ang Li73697b32015-12-03 00:41:53 +00003978 import start_wifi_tethering as _start_wifi_tethering
tturneyf640a712015-12-30 15:18:15 -08003979 from acts.test_utils.wifi.wifi_test_utils \
Ang Li73697b32015-12-03 00:41:53 +00003980 import stop_wifi_tethering as _stop_wifi_tethering
tturneyf640a712015-12-30 15:18:15 -08003981 from acts.test_utils.wifi.wifi_test_utils \
Ang Li73697b32015-12-03 00:41:53 +00003982 import WifiEnums as _WifiEnums
Rebecca Silberstein06e86502016-11-22 22:03:54 -08003983 from acts.test_utils.wifi import wifi_constants
Ang Li73697b32015-12-03 00:41:53 +00003984
3985 WIFI_CONFIG_APBAND_2G = _WifiEnums.WIFI_CONFIG_APBAND_2G
3986 WIFI_CONFIG_APBAND_5G = _WifiEnums.WIFI_CONFIG_APBAND_5G
3987 SSID_KEY = _WifiEnums.SSID_KEY
Yang Liu2bf30892015-12-17 09:53:45 -08003988 PWD_KEY = _WifiEnums.PWD_KEY
Ang Li73697b32015-12-03 00:41:53 +00003989
3990 @staticmethod
3991 def wifi_toggle_state(log, ad, state):
Nathan Harold1451fbc2016-06-27 10:01:18 -07003992 """Toggle the WiFi State
3993
3994 Args:
3995 log: log object
3996 ad: AndroidDevice object
3997 state: True, False, or None
3998
3999 Returns:
4000 boolean success (True) or failure (False)
4001 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004002 return WifiUtils._wifi_toggle_state(ad, state, assert_on_fail=False)
Ang Li73697b32015-12-03 00:41:53 +00004003
4004 @staticmethod
Nathan Harold1451fbc2016-06-27 10:01:18 -07004005 def forget_all_networks(log, ad):
4006 """Forget all stored wifi network information
4007
4008 Args:
4009 log: log object
4010 ad: AndroidDevice object
4011
4012 Returns:
4013 boolean success (True) or failure (False)
4014 """
Betty Zhouccd171d2017-02-13 15:11:33 -08004015 if not ad.droid.wifiGetConfiguredNetworks():
4016 return True
Betty Zhou13bd05e2017-02-10 20:48:14 -08004017 try:
4018 old_state = ad.droid.wifiCheckState()
4019 WifiUtils._reset_wifi(ad)
4020 ad.droid.wifiToggleState(old_state)
4021 except Exception as e:
4022 log.error("WifiUtils.forget_all_networks exception: %s", e)
Ang Li73697b32015-12-03 00:41:53 +00004023 return False
Ang Li73697b32015-12-03 00:41:53 +00004024 return True
4025
4026 @staticmethod
Nathan Harold1451fbc2016-06-27 10:01:18 -07004027 def wifi_reset(log, ad, disable_wifi=True):
4028 """Forget all stored wifi networks and (optionally) disable WiFi
4029
4030 Args:
4031 log: log object
4032 ad: AndroidDevice object
4033 disable_wifi: boolean to disable wifi, defaults to True
4034 Returns:
4035 boolean success (True) or failure (False)
4036 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004037 if not WifiUtils.forget_all_networks(log, ad):
4038 ad.log.error("Unable to forget all networks")
Betty Zhou13bd05e2017-02-10 20:48:14 -08004039 return False
Betty Zhoua37acd32017-02-23 20:04:24 -08004040 if not WifiUtils.wifi_toggle_state(log, ad, not disable_wifi):
4041 ad.log.error("Failed to toggle WiFi state to %s!",
4042 not disable_wifi)
4043 return False
Betty Zhou13bd05e2017-02-10 20:48:14 -08004044 return True
Nathan Harold1451fbc2016-06-27 10:01:18 -07004045
4046 @staticmethod
Ang Li73697b32015-12-03 00:41:53 +00004047 def wifi_connect(log, ad, ssid, password=None):
Nathan Harold1451fbc2016-06-27 10:01:18 -07004048 """Connect to a WiFi network with a provided SSID and Password
4049
4050 Args:
4051 log: log object
4052 ad: AndroidDevice object
4053 ssid: the name of the WiFi network
4054 password: optional password, used for secure networks.
4055 Returns:
4056 boolean success (True) or failure (False)
4057 """
Betty Zhou13bd05e2017-02-10 20:48:14 -08004058 network = {WifiUtils.SSID_KEY: ssid}
4059 if password:
4060 network[WifiUtils.PWD_KEY] = password
Betty Zhoua37acd32017-02-23 20:04:24 -08004061 return WifiUtils._wifi_connect(ad, network, assert_on_fail=False)
Ang Li73697b32015-12-03 00:41:53 +00004062
4063 @staticmethod
4064 def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
Nathan Harold1451fbc2016-06-27 10:01:18 -07004065 """Start a Tethering Session
4066
4067 Args:
4068 log: log object
4069 ad: AndroidDevice object
4070 ssid: the name of the WiFi network
4071 password: optional password, used for secure networks.
4072 ap_band=DEPRECATED specification of 2G or 5G tethering
4073 Returns:
4074 boolean success (True) or failure (False)
4075 """
Ang Li73697b32015-12-03 00:41:53 +00004076 try:
Betty Zhouaab8cec2016-11-15 14:41:44 -08004077 WifiUtils._start_wifi_tethering(ad, ssid, password, ap_band)
Ang Li73697b32015-12-03 00:41:53 +00004078 except Exception as e:
Betty Zhou13bd05e2017-02-10 20:48:14 -08004079 log.error("WifiUtils.start_wifi_tethering exception: %s", e)
Ang Li73697b32015-12-03 00:41:53 +00004080 return False
Betty Zhouaab8cec2016-11-15 14:41:44 -08004081 return True
Ang Li73697b32015-12-03 00:41:53 +00004082
4083 @staticmethod
4084 def stop_wifi_tethering(log, ad):
Nathan Harold1451fbc2016-06-27 10:01:18 -07004085 """Stop a Tethering Session
4086
4087 Args:
4088 log: log object
4089 ad: AndroidDevice object
4090 Returns:
4091 boolean success (True) or failure (False)
4092 """
Ang Li73697b32015-12-03 00:41:53 +00004093 try:
4094 WifiUtils._stop_wifi_tethering(ad)
4095 return True
4096 except Exception as e:
Betty Zhou13bd05e2017-02-10 20:48:14 -08004097 log.error("WifiUtils.stop_wifi_tethering exception: %s", e)
Ang Li73697b32015-12-03 00:41:53 +00004098 return False