blob: 268e18d04cd25ce38970055a47a20b26d0e2597a [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
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
Betty Zhou2e01bc82017-03-17 10:55:57 -070021import json
Ang Li5bd83f32016-05-23 14:39:38 -070022import logging
Betty Zhou17dcabb2017-05-25 19:14:58 -070023import re
Betty Zhouccd171d2017-02-13 15:11:33 -080024import os
Ang Li73697b32015-12-03 00:41:53 +000025import urllib.parse
26import time
Ang Li73697b32015-12-03 00:41:53 +000027
Betty Zhou3b2de072018-03-15 16:46:26 -070028from acts import signals
Betty Zhoue62b1f12018-01-24 17:05:20 -080029from acts import utils
Ang Li73697b32015-12-03 00:41:53 +000030from queue import Empty
Betty Zhou5534e672017-03-07 13:47:10 -080031from acts.asserts import abort_all
Betty Zhou2e01bc82017-03-17 10:55:57 -070032from acts.controllers.adb import AdbError
Betty Zhou9a96fc32018-02-01 16:44:05 -080033from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
Betty Zhou92437702018-02-07 19:49:07 -080034from acts.controllers.android_device import SL4A_APK_NAME
Betty Zhou3db27a32018-04-23 14:31:25 -070035from acts.libs.proc import job
Yang Liu9a9a4f72016-02-19 10:45:04 -080036from acts.test_utils.tel.tel_defines import AOSP_PREFIX
Betty Zhoud49a0ce2018-01-19 17:49:53 -080037from acts.test_utils.tel.tel_defines import CARD_POWER_DOWN
38from acts.test_utils.tel.tel_defines import CARD_POWER_UP
Yang Liu46ed7222015-12-28 14:08:52 -080039from acts.test_utils.tel.tel_defines import CARRIER_UNKNOWN
Betty Zhou9e54fc22017-01-19 12:15:53 -080040from acts.test_utils.tel.tel_defines import COUNTRY_CODE_LIST
Yang Liu46ed7222015-12-28 14:08:52 -080041from acts.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
42from acts.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
Betty Zhou9e2bf402017-02-01 19:04:09 -080043from acts.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE
44from acts.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE
Yang Liu98fd9d72016-03-04 12:14:49 -080045from acts.test_utils.tel.tel_defines import GEN_4G
Yang Liu46ed7222015-12-28 14:08:52 -080046from acts.test_utils.tel.tel_defines import GEN_UNKNOWN
47from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
48from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
49from acts.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
50from acts.test_utils.tel.tel_defines import INVALID_SUB_ID
51from acts.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
52from acts.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME
Yang Liudf164e32016-01-07 16:49:32 -080053from acts.test_utils.tel.tel_defines import \
54 MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
55from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Nathan Haroldeb60b192016-08-24 14:41:55 -070056from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
Yang Liudf164e32016-01-07 16:49:32 -080057from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
58from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
59from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
60from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
Yang Liu598b93d2016-03-22 17:07:59 -070061from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
Yang Liudf164e32016-01-07 16:49:32 -080062from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
63from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
64from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS
Yang Liu855d5f82016-01-27 15:35:48 -080065from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
Yang Liudf164e32016-01-07 16:49:32 -080066from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
Yang Liudfc37b62016-01-20 18:08:47 -080067from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
68from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
Yang Liue51e93d2015-12-30 10:45:42 -080069from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
Yang Liu46ed7222015-12-28 14:08:52 -080070from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
71from acts.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
72from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
73from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
74from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT
75from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT
76from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT
77from acts.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT
78from acts.test_utils.tel.tel_defines import RAT_FAMILY_GSM
79from acts.test_utils.tel.tel_defines import RAT_FAMILY_LTE
80from acts.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
Yang Liucde45aa2016-02-22 13:46:41 -080081from acts.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
Yang Liu46ed7222015-12-28 14:08:52 -080082from acts.test_utils.tel.tel_defines import RAT_1XRTT
83from acts.test_utils.tel.tel_defines import RAT_UNKNOWN
84from acts.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
85from acts.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
Betty Zhou688c1032017-11-20 20:08:04 -080086from acts.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING
Yang Liu46ed7222015-12-28 14:08:52 -080087from acts.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
88from acts.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
Betty Zhou6dd0ac62018-04-27 18:59:12 -070089from acts.test_utils.tel.tel_defines import SIM_STATE_ABSENT
Betty Zhoue66efb42018-01-31 19:45:56 -080090from acts.test_utils.tel.tel_defines import SIM_STATE_LOADED
91from acts.test_utils.tel.tel_defines import SIM_STATE_NOT_READY
Betty Zhou59ccab62017-08-17 18:17:29 -070092from acts.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
Yang Liu46ed7222015-12-28 14:08:52 -080093from acts.test_utils.tel.tel_defines import SIM_STATE_READY
Betty Zhoud49a0ce2018-01-19 17:49:53 -080094from acts.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
Yang Liu46ed7222015-12-28 14:08:52 -080095from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
96from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
97from acts.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
98from acts.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT
Yang Liudf164e32016-01-07 16:49:32 -080099from acts.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
Yang Liu46ed7222015-12-28 14:08:52 -0800100from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
Betty Zhouf25ce442017-03-03 14:28:36 -0800101from acts.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
Betty Zhouddc76402018-01-23 16:29:25 -0800102from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
tturney0eddcae2016-03-30 19:59:14 -0700103from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
Yang Liu46ed7222015-12-28 14:08:52 -0800104from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
Yang Liudf164e32016-01-07 16:49:32 -0800105from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
Yang Liu46ed7222015-12-28 14:08:52 -0800106from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
Yang Liudf164e32016-01-07 16:49:32 -0800107from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
Yang Liu46ed7222015-12-28 14:08:52 -0800108from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED
Jaineel760329b2018-01-16 13:55:24 -0800109from acts.test_utils.tel.tel_defines import TYPE_MOBILE
110from acts.test_utils.tel.tel_defines import TYPE_WIFI
Yang Liu46ed7222015-12-28 14:08:52 -0800111from acts.test_utils.tel.tel_defines import EventCallStateChanged
112from acts.test_utils.tel.tel_defines import EventConnectivityChanged
113from acts.test_utils.tel.tel_defines import EventDataConnectionStateChanged
114from acts.test_utils.tel.tel_defines import EventDataSmsReceived
115from acts.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
116from acts.test_utils.tel.tel_defines import EventServiceStateChanged
Betty Zhou4411c202018-03-29 18:27:25 -0700117from acts.test_utils.tel.tel_defines import EventMmsSentFailure
Yang Liu46ed7222015-12-28 14:08:52 -0800118from acts.test_utils.tel.tel_defines import EventMmsSentSuccess
Betty Zhoua27e5d42017-01-17 11:33:04 -0800119from acts.test_utils.tel.tel_defines import EventMmsDownloaded
Yang Liu46ed7222015-12-28 14:08:52 -0800120from acts.test_utils.tel.tel_defines import EventSmsReceived
Betty Zhouc9f723b2018-04-10 18:08:21 -0700121from acts.test_utils.tel.tel_defines import EventSmsDeliverFailure
122from acts.test_utils.tel.tel_defines import EventSmsDeliverSuccess
Betty Zhou4411c202018-03-29 18:27:25 -0700123from acts.test_utils.tel.tel_defines import EventSmsSentFailure
Yang Liu46ed7222015-12-28 14:08:52 -0800124from acts.test_utils.tel.tel_defines import EventSmsSentSuccess
Yang Liudc8564b2016-01-27 14:15:37 -0800125from acts.test_utils.tel.tel_defines import CallStateContainer
Yang Liu8e6adff2016-02-05 10:24:04 -0800126from acts.test_utils.tel.tel_defines import DataConnectionStateContainer
Yang Liudc8564b2016-01-27 14:15:37 -0800127from acts.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
Yang Liu8e6adff2016-02-05 10:24:04 -0800128from acts.test_utils.tel.tel_defines import NetworkCallbackContainer
129from acts.test_utils.tel.tel_defines import ServiceStateContainer
Yang Liu46ed7222015-12-28 14:08:52 -0800130from acts.test_utils.tel.tel_lookup_tables import \
131 connection_type_from_type_string
132from acts.test_utils.tel.tel_lookup_tables import is_valid_rat
Yang Liu98fd9d72016-03-04 12:14:49 -0800133from acts.test_utils.tel.tel_lookup_tables import get_allowable_network_preference
Yang Liu46ed7222015-12-28 14:08:52 -0800134from acts.test_utils.tel.tel_lookup_tables import \
135 get_voice_mail_count_check_function
Betty Zhou94023182017-06-07 18:02:14 -0700136from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number
Betty Zhoua6c82eb2017-04-13 18:09:03 -0700137from acts.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit
Yang Liu46ed7222015-12-28 14:08:52 -0800138from acts.test_utils.tel.tel_lookup_tables import \
Jaineelc52d6852017-10-27 15:03:54 -0700139 network_preference_for_generation
Betty Zhoub14c1012018-04-20 11:27:00 -0700140from acts.test_utils.tel.tel_lookup_tables import \
141 operator_name_from_network_name
Yang Liu46ed7222015-12-28 14:08:52 -0800142from acts.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
143from acts.test_utils.tel.tel_lookup_tables import \
144 rat_families_for_network_preference
145from acts.test_utils.tel.tel_lookup_tables import rat_family_for_generation
Yang Liu7a2e7ee2015-12-28 15:32:44 -0800146from acts.test_utils.tel.tel_lookup_tables import rat_family_from_rat
147from acts.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
Yang Liucc1c6502016-04-19 10:50:06 -0700148from acts.test_utils.tel.tel_subscription_utils import \
149 get_default_data_sub_id
150from acts.test_utils.tel.tel_subscription_utils import \
151 get_outgoing_message_sub_id
152from acts.test_utils.tel.tel_subscription_utils import \
153 get_outgoing_voice_sub_id
154from acts.test_utils.tel.tel_subscription_utils import \
155 get_incoming_voice_sub_id
156from acts.test_utils.tel.tel_subscription_utils import \
157 get_incoming_message_sub_id
Betty Zhouf987b8f2017-03-09 16:34:00 -0800158from acts.test_utils.wifi import wifi_test_utils
Betty Zhoua37acd32017-02-23 20:04:24 -0800159from acts.test_utils.wifi import wifi_constants
Betty Zhou8e11e442017-03-30 20:00:34 -0700160from acts.utils import adb_shell_ping
Yang Liu46ed7222015-12-28 14:08:52 -0800161from acts.utils import load_config
Jaineel55ae6f92017-06-29 17:44:19 -0700162from acts.utils import create_dir
163from acts.utils import start_standing_subprocess
164from acts.utils import stop_standing_subprocess
Jaineelc9e7bfa2017-08-07 14:11:30 -0700165from acts.logger import epoch_to_log_line_timestamp
166from acts.logger import normalize_log_line_timestamp
167from acts.utils import get_current_epoch_time
Jaineel5576d432017-10-19 15:36:42 -0700168from acts.utils import exe_cmd
Ang Li5bd83f32016-05-23 14:39:38 -0700169
Betty Zhouf987b8f2017-03-09 16:34:00 -0800170WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY
171WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY
172WIFI_CONFIG_APBAND_2G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_2G
173WIFI_CONFIG_APBAND_5G = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_5G
Ang Li5bd83f32016-05-23 14:39:38 -0700174log = logging
Betty Zhoudd781f82017-08-08 14:46:23 -0700175STORY_LINE = "+19523521350"
Ang Li73697b32015-12-03 00:41:53 +0000176
Nathan Harold123c9da2015-12-30 16:33:25 -0800177
Betty Zhou7f45f552017-03-15 19:12:52 -0700178class _CallSequenceException(Exception):
179 pass
180
181
Ang Li73697b32015-12-03 00:41:53 +0000182class TelTestUtilsError(Exception):
183 pass
184
Nathan Harold123c9da2015-12-30 16:33:25 -0800185
Betty Zhou5534e672017-03-07 13:47:10 -0800186def abort_all_tests(log, msg):
187 log.error("Aborting all ongoing tests due to: %s.", msg)
188 abort_all(msg)
189
190
Betty Zhou5b069a02016-12-06 19:23:44 -0800191def get_phone_number_by_adb(ad):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700192 return phone_number_formatter(
193 ad.adb.shell("service call iphonesubinfo 13"))
Betty Zhou5b069a02016-12-06 19:23:44 -0800194
195
196def get_iccid_by_adb(ad):
197 return ad.adb.shell("service call iphonesubinfo 11")
198
199
200def get_operator_by_adb(ad):
201 return ad.adb.getprop("gsm.sim.operator.alpha")
202
203
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700204def get_plmn_by_adb(ad):
205 return ad.adb.getprop("gsm.sim.operator.numeric")
206
207
Betty Zhou5b069a02016-12-06 19:23:44 -0800208def get_sub_id_by_adb(ad):
209 return ad.adb.shell("service call iphonesubinfo 5")
210
211
212def setup_droid_properties_by_adb(log, ad, sim_filename=None):
Ang Li73697b32015-12-03 00:41:53 +0000213
Betty Zhou5b069a02016-12-06 19:23:44 -0800214 sim_data = None
215 if sim_filename:
216 try:
217 sim_data = load_config(sim_filename)
218 except Exception:
Betty Zhouccd171d2017-02-13 15:11:33 -0800219 log.warning("Failed to load %s!", sim_filename)
Betty Zhou5b069a02016-12-06 19:23:44 -0800220
Betty Zhou76a83f72016-12-20 14:21:11 -0800221 sub_id = get_sub_id_by_adb(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700222 iccid = get_iccid_by_adb(ad)
223 ad.log.info("iccid = %s", iccid)
224 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700225 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"])
226 else:
227 phone_number = get_phone_number_by_adb(ad)
Betty Zhouddb361d2017-09-07 17:07:20 -0700228 if not phone_number and hasattr(ad, phone_number):
229 phone_number = ad.phone_number
Betty Zhou5b069a02016-12-06 19:23:44 -0800230 if not phone_number:
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700231 ad.log.error("Failed to find valid phone number for %s", iccid)
Betty Zhoud4b75c52018-04-03 15:20:00 -0700232 abort_all_tests(ad.log, "Failed to find valid phone number for %s")
Betty Zhou3b2de072018-03-15 16:46:26 -0700233 sub_record = {
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700234 'phone_num': phone_number,
Betty Zhoua27e5d42017-01-17 11:33:04 -0800235 'iccid': get_iccid_by_adb(ad),
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700236 'sim_operator_name': get_operator_by_adb(ad),
237 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad))
Betty Zhoua27e5d42017-01-17 11:33:04 -0800238 }
Betty Zhou3b2de072018-03-15 16:46:26 -0700239 device_props = {'subscription': {sub_id: sub_record}}
240 ad.log.info("subId %s SIM record: %s", sub_id, sub_record)
241 setattr(ad, 'telephony', device_props)
Betty Zhou5b069a02016-12-06 19:23:44 -0800242
243
244def setup_droid_properties(log, ad, sim_filename=None):
245
Betty Zhou5b069a02016-12-06 19:23:44 -0800246 if ad.skip_sl4a:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800247 return setup_droid_properties_by_adb(
248 log, ad, sim_filename=sim_filename)
Betty Zhouccd171d2017-02-13 15:11:33 -0800249
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700250 refresh_droid_config(log, ad)
Ang Li73697b32015-12-03 00:41:53 +0000251 device_props = {}
252 device_props['subscription'] = {}
253
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700254 sim_data = {}
255 if sim_filename:
256 try:
257 sim_data = load_config(sim_filename)
258 except Exception:
259 log.warning("Failed to load %s!", sim_filename)
Betty Zhou3b2de072018-03-15 16:46:26 -0700260 if not ad.telephony["subscription"]:
Betty Zhou28e07e12018-04-11 12:12:11 -0700261 abort_all_tests(ad.log, "No valid subscription")
Betty Zhoude88d172017-10-27 18:20:29 -0700262 result = True
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800263 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhou3b2de072018-03-15 16:46:26 -0700264 for sub_id, sub_info in ad.telephony["subscription"].items():
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700265 sub_info["operator"] = get_operator_name(log, ad, sub_id)
266 iccid = sub_info["iccid"]
267 if not iccid:
Betty Zhou3b2de072018-03-15 16:46:26 -0700268 ad.log.warning("Unable to find ICC-ID for subscriber %s", sub_id)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700269 continue
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800270 if sub_info.get("phone_num"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700271 if iccid in sim_data and sim_data[iccid].get("phone_num"):
272 if not check_phone_number_match(sim_data[iccid]["phone_num"],
273 sub_info["phone_num"]):
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800274 ad.log.warning(
275 "phone_num %s in sim card data file for iccid %s"
Betty Zhou3b2de072018-03-15 16:46:26 -0700276 " do not match phone_num %s from subscription",
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800277 sim_data[iccid]["phone_num"], iccid,
278 sub_info["phone_num"])
Betty Zhou3b2de072018-03-15 16:46:26 -0700279 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
280 else:
281 if iccid in sim_data and sim_data[iccid].get("phone_num"):
282 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
283 elif sub_id == active_sub_id:
284 phone_number = get_phone_number_by_secret_code(
285 ad, sub_info["sim_operator_name"])
286 if phone_number:
287 sub_info["phone_num"] = phone_number
288 elif getattr(ad, "phone_num", None):
289 sub_info["phone_num"] = ad.phone_number
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800290 if (not sub_info.get("phone_num")) and sub_id == active_sub_id:
291 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info)
292 ad.log.error(
293 "Unable to retrieve phone number for sub %s with iccid"
294 " %s from device or testbed config or sim card file %s",
295 sub_id, iccid, sim_filename)
296 result = False
Betty Zhouee311052017-12-19 13:09:56 -0800297 if not hasattr(
298 ad, 'roaming'
Betty Zhou3b2de072018-03-15 16:46:26 -0700299 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and sub_info["sim_operator_name"].strip(
300 ) not in sub_info["network_operator_name"].strip():
Betty Zhou2cf788e2017-06-27 17:25:53 -0700301 ad.log.info("roaming is not enabled, enable it")
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700302 setattr(ad, 'roaming', True)
Betty Zhou70cc4332017-09-20 15:06:13 -0700303 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items()))
Betty Zhou2cf788e2017-06-27 17:25:53 -0700304 data_roaming = getattr(ad, 'roaming', False)
305 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
306 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Betty Zhou739d6b72018-04-18 10:38:53 -0700307 # Setup VoWiFi MDN for Verizon. b/33187374
Betty Zhouddb361d2017-09-07 17:07:20 -0700308 if not result:
309 abort_all_tests(ad.log, "Failed to find valid phone number")
Ang Li73697b32015-12-03 00:41:53 +0000310
Betty Zhou3b2de072018-03-15 16:46:26 -0700311 ad.log.debug("telephony = %s", ad.telephony)
Ang Li73697b32015-12-03 00:41:53 +0000312
Nathan Harold7642fc92016-05-02 18:29:11 -0700313
Yang Liu6c70e022016-03-07 16:19:42 -0800314def refresh_droid_config(log, ad):
Betty Zhou3b2de072018-03-15 16:46:26 -0700315 """ Update Android Device telephony records for each sub_id.
Yang Liuad9c63d2016-02-25 13:59:23 -0800316
317 Args:
318 log: log object
319 ad: android device object
Yang Liuad9c63d2016-02-25 13:59:23 -0800320
321 Returns:
Yang Liu6c70e022016-03-07 16:19:42 -0800322 None
Yang Liuad9c63d2016-02-25 13:59:23 -0800323 """
Betty Zhou3b2de072018-03-15 16:46:26 -0700324 if not getattr(ad, 'telephony', {}):
325 setattr(ad, 'telephony', {"subscription": {}})
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700326 droid = ad.droid
327 sub_info_list = droid.subscriptionGetAllSubInfoList()
Betty Zhou3b2de072018-03-15 16:46:26 -0700328 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700329 for sub_info in sub_info_list:
330 sub_id = sub_info["subscriptionId"]
331 sim_slot = sub_info["simSlotIndex"]
332 if sim_slot != INVALID_SIM_SLOT_INDEX:
Betty Zhou3b2de072018-03-15 16:46:26 -0700333 if sub_id not in ad.telephony["subscription"]:
334 ad.telephony["subscription"][sub_id] = {}
335 sub_record = ad.telephony["subscription"][sub_id]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800336 if sub_info.get("iccId"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700337 sub_record["iccid"] = sub_info["iccId"]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800338 else:
Betty Zhou3b2de072018-03-15 16:46:26 -0700339 sub_record[
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800340 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription(
341 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700342 sub_record["sim_slot"] = sim_slot
343 if sub_info.get("mcc"):
344 sub_record["mcc"] = sub_info["mcc"]
345 if sub_info.get("mnc"):
346 sub_record["mnc"] = sub_info["mnc"]
347 if sub_info.get("displayName"):
348 sub_record["display_name"] = sub_info["displayName"]
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700349 try:
Betty Zhou3b2de072018-03-15 16:46:26 -0700350 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700351 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription(
352 sub_id)
353 except:
Betty Zhou3b2de072018-03-15 16:46:26 -0700354 if not sub_record.get("phone_type"):
355 sub_record["phone_type"] = droid.telephonyGetPhoneType()
356 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700357 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription(
358 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700359 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700360 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription(
361 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700362 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700363 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription(
364 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700365 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700366 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription(
367 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700368 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700369 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription(
370 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700371 if active_sub_id == sub_id:
372 try:
373 sub_record[
374 "carrier_id"] = ad.droid.telephonyGetSimCarrierId()
375 sub_record[
376 "carrier_id_name"] = ad.droid.telephonyGetSimCarrierIdName(
377 )
378 except:
379 ad.log.info("Carrier ID is not supported")
380 if not sub_info.get("number"):
381 sub_info[
382 "number"] = droid.telephonyGetLine1NumberForSubscription(
383 sub_id)
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800384 if sub_info.get("number"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700385 if sub_record.get("phone_num"):
386 # Use the phone number provided in sim info file by default
387 # as the sub_info["number"] may not be formatted in a
388 # dialable number
389 if not check_phone_number_match(sub_info["number"],
390 sub_record["phone_num"]):
391 ad.log.info(
392 "Subscriber phone number changed from %s to %s",
393 sub_record["phone_num"], sub_info["number"])
394 sub_record["phone_num"] = sub_info["number"]
395 else:
396 sub_record["phone_num"] = phone_number_formatter(
397 sub_info["number"])
398 #ad.telephony['subscription'][sub_id] = sub_record
399 ad.log.info("SubId %s info: %s", sub_id, sorted(
400 sub_record.items()))
Nathan Harold7642fc92016-05-02 18:29:11 -0700401
Nathan Harold123c9da2015-12-30 16:33:25 -0800402
Betty Zhouddb361d2017-09-07 17:07:20 -0700403def get_phone_number_by_secret_code(ad, operator):
404 if "T-Mobile" in operator:
405 ad.droid.telecomDialNumber("#686#")
406 ad.send_keycode("ENTER")
Betty Zhoub4062372017-09-08 11:29:38 -0700407 for _ in range(12):
408 output = ad.search_logcat("mobile number")
409 if output:
410 result = re.findall(r"mobile number is (\S+)",
411 output[-1]["log_message"])
Betty Zhou70cc4332017-09-20 15:06:13 -0700412 ad.send_keycode("BACK")
Betty Zhoub4062372017-09-08 11:29:38 -0700413 return result[0]
414 else:
415 time.sleep(5)
416 return ""
Betty Zhouddb361d2017-09-07 17:07:20 -0700417
418
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700419def get_user_config_profile(ad):
420 return {
421 "WFC Mode":
422 ad.droid.imsGetWfcMode(),
423 "WFC Enabled":
424 is_wfc_enabled(ad.log, ad),
425 "Airplane Mode":
426 ad.droid.connectivityCheckAirplaneMode(),
427 "Platform Enhanced 4G LTE Mode":
428 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(),
429 "User Enhanced 4G LTE Mode":
430 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser(),
431 "VoLTE Enabled":
432 ad.droid.telephonyIsVolteAvailable()
433 }
434
435
Yang Liu7ce19982016-03-09 12:20:41 -0800436def get_slot_index_from_subid(log, ad, sub_id):
437 try:
438 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
439 return info['simSlotIndex']
tturney10eda2e2016-03-30 19:55:57 -0700440 except KeyError:
Yang Liu7ce19982016-03-09 12:20:41 -0800441 return INVALID_SIM_SLOT_INDEX
442
Nathan Harold123c9da2015-12-30 16:33:25 -0800443
Ang Li73697b32015-12-03 00:41:53 +0000444def get_num_active_sims(log, ad):
445 """ Get the number of active SIM cards by counting slots
446
447 Args:
448 ad: android_device object.
449
450 Returns:
451 result: The number of loaded (physical) SIM cards
452 """
453 # using a dictionary as a cheap way to prevent double counting
454 # in the situation where multiple subscriptions are on the same SIM.
455 # yes, this is a corner corner case.
456 valid_sims = {}
457 subInfo = ad.droid.subscriptionGetAllSubInfoList()
458 for info in subInfo:
459 ssidx = info['simSlotIndex']
460 if ssidx == INVALID_SIM_SLOT_INDEX:
461 continue
462 valid_sims[ssidx] = True
463 return len(valid_sims.keys())
464
Nathan Harold123c9da2015-12-30 16:33:25 -0800465
Betty Zhoua37acd32017-02-23 20:04:24 -0800466def toggle_airplane_mode_by_adb(log, ad, new_state=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800467 """ Toggle the state of airplane mode.
468
469 Args:
470 log: log handler.
471 ad: android_device object.
472 new_state: Airplane mode state to set to.
473 If None, opposite of the current state.
474 strict_checking: Whether to turn on strict checking that checks all features.
475
476 Returns:
477 result: True if operation succeed. False if error happens.
478 """
479 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
480 if new_state == cur_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800481 ad.log.info("Airplane mode already in %s", new_state)
Betty Zhou5b069a02016-12-06 19:23:44 -0800482 return True
483 elif new_state is None:
484 new_state = not cur_state
485
486 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state))
487 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE")
488 return True
489
490
Betty Zhou28732962016-11-28 15:00:58 -0800491def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000492 """ Toggle the state of airplane mode.
493
494 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800495 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000496 ad: android_device object.
497 new_state: Airplane mode state to set to.
498 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800499 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000500
501 Returns:
502 result: True if operation succeed. False if error happens.
503 """
Betty Zhou5b069a02016-12-06 19:23:44 -0800504 if ad.skip_sl4a:
505 return toggle_airplane_mode_by_adb(log, ad, new_state)
506 else:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800507 return toggle_airplane_mode_msim(
508 log, ad, new_state, strict_checking=strict_checking)
Ang Li73697b32015-12-03 00:41:53 +0000509
Nathan Harold123c9da2015-12-30 16:33:25 -0800510
Betty Zhou17dcabb2017-05-25 19:14:58 -0700511def get_telephony_signal_strength(ad):
Betty Zhou17dcabb2017-05-25 19:14:58 -0700512 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0,
513 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160,
514 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0,
515 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0,
516 # 'lteDbm': -112, 'gsmSignalStrength': 99}
Betty Zhouf7da39e2018-04-16 16:28:58 -0700517 try:
518 signal_strength = ad.droid.telephonyGetSignalStrength()
519 if not signal_strength:
520 signal_strength = {}
521 except Exception as e:
522 ad.log.error(e)
523 signal_strength = {}
Betty Zhou17dcabb2017-05-25 19:14:58 -0700524 out = ad.adb.shell("dumpsys telephony.registry | grep -i signalstrength")
525 signals = re.findall(r"(-*\d+)", out)
526 for i, val in enumerate(
527 ("gsmSignalStrength", "gsmBitErrorRate", "cdmaDbm", "cdmaEcio",
528 "evdoDbm", "evdoEcio", "evdoSnr", "lteSignalStrength", "lteRsrp",
529 "lteRsrq", "lteRssnr", "lteCqi", "lteRsrpBoost")):
530 signal_strength[val] = signal_strength.get(val, int(signals[i]))
531 ad.log.info("Telephony Signal strength = %s", signal_strength)
532 return signal_strength
533
534
Jaineele64be822017-11-30 16:36:36 -0800535def get_wifi_signal_strength(ad):
536 signal_strength = ad.droid.wifiGetConnectionInfo()['rssi']
537 ad.log.info("WiFi Signal Strength is %s" % signal_strength)
538 return signal_strength
539
540
Ang Li73697b32015-12-03 00:41:53 +0000541def is_expected_event(event_to_check, events_list):
542 """ check whether event is present in the event list
543
544 Args:
545 event_to_check: event to be checked.
546 events_list: list of events
547 Returns:
548 result: True if event present in the list. False if not.
549 """
550 for event in events_list:
551 if event in event_to_check['name']:
552 return True
553 return False
554
Nathan Harold123c9da2015-12-30 16:33:25 -0800555
Ang Li73697b32015-12-03 00:41:53 +0000556def is_sim_ready(log, ad, sim_slot_id=None):
557 """ check whether SIM is ready.
558
559 Args:
560 ad: android_device object.
561 sim_slot_id: check the SIM status for sim_slot_id
562 This is optional. If this is None, check default SIM.
563
564 Returns:
565 result: True if all SIMs are ready. False if not.
566 """
567 if sim_slot_id is None:
Yang Liuaed3eef2015-12-15 18:40:25 -0800568 status = ad.droid.telephonyGetSimState()
Ang Li73697b32015-12-03 00:41:53 +0000569 else:
Yang Liuaed3eef2015-12-15 18:40:25 -0800570 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id)
Ang Li73697b32015-12-03 00:41:53 +0000571 if status != SIM_STATE_READY:
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700572 ad.log.info("Sim state is %s, not ready", status)
Nathan Harold123c9da2015-12-30 16:33:25 -0800573 return False
Ang Li73697b32015-12-03 00:41:53 +0000574 return True
575
Nathan Harold123c9da2015-12-30 16:33:25 -0800576
Betty Zhou688c1032017-11-20 20:08:04 -0800577def is_sim_ready_by_adb(log, ad):
Betty Zhoue66efb42018-01-31 19:45:56 -0800578 state = ad.adb.getprop("gsm.sim.state")
Betty Zhou28e07e12018-04-11 12:12:11 -0700579 ad.log.info("gsm.sim.state = %s", state)
Betty Zhoue66efb42018-01-31 19:45:56 -0800580 return state == SIM_STATE_READY or state == SIM_STATE_LOADED
Betty Zhou688c1032017-11-20 20:08:04 -0800581
582
583def wait_for_sim_ready_by_adb(log, ad, wait_time=90):
584 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb)
585
586
587def get_service_state_by_adb(log, ad):
588 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState")
589 if "mVoiceRegState" in output:
590 result = re.search(r"mVoiceRegState=(\S+)\((\S+)\)", output)
591 if result:
Betty Zhouee311052017-12-19 13:09:56 -0800592 ad.log.info("mVoiceRegState is %s %s", result.group(1),
593 result.group(2))
Betty Zhou688c1032017-11-20 20:08:04 -0800594 return result.group(2)
595 else:
596 result = re.search(r"mServiceState=(\S+)", output)
597 if result:
Betty Zhouee311052017-12-19 13:09:56 -0800598 ad.log.info("mServiceState=%s %s", result.group(1),
Betty Zhou688c1032017-11-20 20:08:04 -0800599 SERVICE_STATE_MAPPING[result.group(1)])
600 return SERVICE_STATE_MAPPING[result.group(1)]
601
602
Ang Li73697b32015-12-03 00:41:53 +0000603def _is_expecting_event(event_recv_list):
604 """ check for more event is expected in event list
605
606 Args:
607 event_recv_list: list of events
608 Returns:
609 result: True if more events are expected. False if not.
610 """
611 for state in event_recv_list:
612 if state is False:
Nathan Harold123c9da2015-12-30 16:33:25 -0800613 return True
Ang Li73697b32015-12-03 00:41:53 +0000614 return False
615
Nathan Harold123c9da2015-12-30 16:33:25 -0800616
617def _set_event_list(event_recv_list, sub_id_list, sub_id, value):
Ang Li73697b32015-12-03 00:41:53 +0000618 """ set received event in expected event list
619
620 Args:
621 event_recv_list: list of received events
622 sub_id_list: subscription ID list
623 sub_id: subscription id of current event
624 value: True or False
625 Returns:
626 None.
627 """
628 for i in range(len(sub_id_list)):
629 if sub_id_list[i] == sub_id:
630 event_recv_list[i] = value
631
Nathan Harold123c9da2015-12-30 16:33:25 -0800632
Nathan Harold54129bb2016-09-29 19:40:52 -0700633def _wait_for_bluetooth_in_state(log, ad, state, max_wait):
634 # FIXME: These event names should be defined in a common location
635 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn'
636 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff'
Nathan Harold9b1b2f12016-10-14 12:42:57 -0700637 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT)
638 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT)
639
Nathan Harold54129bb2016-09-29 19:40:52 -0700640 ad.droid.bluetoothStartListeningForAdapterStateChange()
641 try:
642 bt_state = ad.droid.bluetoothCheckState()
643 if bt_state == state:
644 return True
645 if max_wait <= 0:
Betty Zhoua37acd32017-02-23 20:04:24 -0800646 ad.log.error("Time out: bluetooth state still %s, expecting %s",
647 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700648 return False
649
Betty Zhoua27e5d42017-01-17 11:33:04 -0800650 event = {
651 False: _BLUETOOTH_STATE_OFF_EVENT,
652 True: _BLUETOOTH_STATE_ON_EVENT
653 }[state]
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700654 event = ad.ed.pop_event(event, max_wait)
655 ad.log.info("Got event %s", event['name'])
Nathan Harold54129bb2016-09-29 19:40:52 -0700656 return True
657 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800658 ad.log.error("Time out: bluetooth state still in %s, expecting %s",
659 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700660 return False
661 finally:
662 ad.droid.bluetoothStopListeningForAdapterStateChange()
663
664
665# TODO: replace this with an event-based function
666def _wait_for_wifi_in_state(log, ad, state, max_wait):
667 return _wait_for_droid_in_state(log, ad, max_wait,
668 lambda log, ad, state: \
669 (True if ad.droid.wifiCheckState() == state else False),
670 state)
671
672
Betty Zhou28732962016-11-28 15:00:58 -0800673def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000674 """ Toggle the state of airplane mode.
675
676 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800677 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000678 ad: android_device object.
679 new_state: Airplane mode state to set to.
680 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800681 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000682
683 Returns:
684 result: True if operation succeed. False if error happens.
685 """
Ang Li73697b32015-12-03 00:41:53 +0000686
Ang Li73697b32015-12-03 00:41:53 +0000687 cur_state = ad.droid.connectivityCheckAirplaneMode()
688 if cur_state == new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800689 ad.log.info("Airplane mode already in %s", new_state)
Ang Li73697b32015-12-03 00:41:53 +0000690 return True
691 elif new_state is None:
Ang Li73697b32015-12-03 00:41:53 +0000692 new_state = not cur_state
Betty Zhoub66d48f2018-04-09 12:00:53 -0700693 ad.log.info("Toggle APM mode, from current tate %s to %s", cur_state,
694 new_state)
Ang Li73697b32015-12-03 00:41:53 +0000695
Betty Zhoue123c672018-03-21 19:57:11 -0700696 sub_id_list = []
697 active_sub_info = ad.droid.subscriptionGetAllSubInfoList()
698 for info in active_sub_info:
699 sub_id_list.append(info['subscriptionId'])
700
701 ad.ed.clear_all_events()
702 time.sleep(0.1)
Yang Liu8e6adff2016-02-05 10:24:04 -0800703 service_state_list = []
Ang Li73697b32015-12-03 00:41:53 +0000704 if new_state:
Yang Liu8e6adff2016-02-05 10:24:04 -0800705 service_state_list.append(SERVICE_STATE_POWER_OFF)
Betty Zhoua37acd32017-02-23 20:04:24 -0800706 ad.log.info("Turn on airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000707
708 else:
709 # If either one of these 3 events show up, it should be OK.
710 # Normal SIM, phone in service
Yang Liu8e6adff2016-02-05 10:24:04 -0800711 service_state_list.append(SERVICE_STATE_IN_SERVICE)
Ang Li73697b32015-12-03 00:41:53 +0000712 # NO SIM, or Dead SIM, or no Roaming coverage.
Yang Liu8e6adff2016-02-05 10:24:04 -0800713 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE)
714 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY)
Betty Zhoua37acd32017-02-23 20:04:24 -0800715 ad.log.info("Turn off airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000716
717 for sub_id in sub_id_list:
Nathan Harold123c9da2015-12-30 16:33:25 -0800718 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription(
719 sub_id)
Nathan Harold54129bb2016-09-29 19:40:52 -0700720
721 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Ang Li73697b32015-12-03 00:41:53 +0000722 ad.droid.connectivityToggleAirplaneMode(new_state)
723
Ang Li73697b32015-12-03 00:41:53 +0000724 try:
725 try:
Nathan Harold7642fc92016-05-02 18:29:11 -0700726 event = ad.ed.wait_for_event(
727 EventServiceStateChanged,
728 is_event_match_for_list,
729 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT,
730 field=ServiceStateContainer.SERVICE_STATE,
731 value_list=service_state_list)
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700732 ad.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +0000733 except Empty:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700734 ad.log.warning("Did not get expected service state change to %s",
735 service_state_list)
Betty Zhoua36c4352018-04-05 18:49:32 -0700736 finally:
737 for sub_id in sub_id_list:
738 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
739 sub_id)
740 except Exception as e:
741 ad.log.error(e)
Ang Li73697b32015-12-03 00:41:53 +0000742
Nathan Harold54129bb2016-09-29 19:40:52 -0700743 # APM on (new_state=True) will turn off bluetooth but may not turn it on
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800744 try:
745 if new_state and not _wait_for_bluetooth_in_state(
Betty Zhoua27e5d42017-01-17 11:33:04 -0800746 log, ad, False, timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800747 ad.log.error(
748 "Failed waiting for bluetooth during airplane mode toggle")
Betty Zhou28732962016-11-28 15:00:58 -0800749 if strict_checking: return False
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800750 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -0800751 ad.log.error("Failed to check bluetooth state due to %s", e)
Betty Zhou28732962016-11-28 15:00:58 -0800752 if strict_checking:
753 raise
Nathan Harold54129bb2016-09-29 19:40:52 -0700754
755 # APM on (new_state=True) will turn off wifi but may not turn it on
Nathan Harold450a7682016-10-12 12:57:17 -0700756 if new_state and not _wait_for_wifi_in_state(log, ad, False,
757 timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800758 ad.log.error("Failed waiting for wifi during airplane mode toggle on")
759 if strict_checking: return False
Nathan Harold54129bb2016-09-29 19:40:52 -0700760
761 if ad.droid.connectivityCheckAirplaneMode() != new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800762 ad.log.error("Set airplane mode to %s failed", new_state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700763 return False
Ang Li73697b32015-12-03 00:41:53 +0000764 return True
765
Nathan Harold123c9da2015-12-30 16:33:25 -0800766
767def wait_and_answer_call(log,
768 ad,
769 incoming_number=None,
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700770 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
771 caller=None):
Ang Li73697b32015-12-03 00:41:53 +0000772 """Wait for an incoming call on default voice subscription and
773 accepts the call.
774
775 Args:
776 ad: android device object.
777 incoming_number: Expected incoming number.
778 Optional. Default is None
Ang Li73697b32015-12-03 00:41:53 +0000779 incall_ui_display: after answer the call, bring in-call UI to foreground or
780 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
781 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
782 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
783 else, do nothing.
784
785 Returns:
786 True: if incoming call is received and answered successfully.
787 False: for errors
788 """
789 return wait_and_answer_call_for_subscription(
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700790 log,
791 ad,
792 get_incoming_voice_sub_id(ad),
793 incoming_number,
794 incall_ui_display=incall_ui_display,
795 caller=caller)
Nathan Harold123c9da2015-12-30 16:33:25 -0800796
Ang Li73697b32015-12-03 00:41:53 +0000797
798def wait_for_ringing_event(log, ad, wait_time):
Nathan Harold54c7c742016-08-04 19:40:44 -0700799 log.warning("***DEPRECATED*** wait_for_ringing_event()")
800 return _wait_for_ringing_event(log, ad, wait_time)
801
802
803def _wait_for_ringing_event(log, ad, wait_time):
Ang Li73697b32015-12-03 00:41:53 +0000804 """Wait for ringing event.
805
806 Args:
807 log: log object.
808 ad: android device object.
809 wait_time: max time to wait for ringing event.
810
811 Returns:
812 event_ringing if received ringing event.
813 otherwise return None.
814 """
Ang Li73697b32015-12-03 00:41:53 +0000815 event_ringing = None
816
Nathan Harold0111e202016-09-27 17:03:00 -0700817 try:
818 event_ringing = ad.ed.wait_for_event(
819 EventCallStateChanged,
820 is_event_match,
821 timeout=wait_time,
822 field=CallStateContainer.CALL_STATE,
823 value=TELEPHONY_STATE_RINGING)
Betty Zhoua37acd32017-02-23 20:04:24 -0800824 ad.log.info("Receive ringing event")
Nathan Harold0111e202016-09-27 17:03:00 -0700825 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800826 ad.log.info("No Ringing Event")
Nathan Harold0111e202016-09-27 17:03:00 -0700827 finally:
828 return event_ringing
Ang Li73697b32015-12-03 00:41:53 +0000829
Nathan Harold123c9da2015-12-30 16:33:25 -0800830
Nathan Harold54c7c742016-08-04 19:40:44 -0700831def wait_for_ringing_call(log, ad, incoming_number=None):
832 """Wait for an incoming call on default voice subscription and
Ang Li73697b32015-12-03 00:41:53 +0000833 accepts the call.
834
835 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -0700836 log: log object.
837 ad: android device object.
838 incoming_number: Expected incoming number.
839 Optional. Default is None
840
841 Returns:
842 True: if incoming call is received and answered successfully.
843 False: for errors
844 """
845 return wait_for_ringing_call_for_subscription(
846 log, ad, get_incoming_voice_sub_id(ad), incoming_number)
847
848
Betty Zhoua37acd32017-02-23 20:04:24 -0800849def wait_for_ringing_call_for_subscription(
850 log,
851 ad,
852 sub_id,
853 incoming_number=None,
Betty Zhou7f45f552017-03-15 19:12:52 -0700854 caller=None,
Betty Zhoua37acd32017-02-23 20:04:24 -0800855 event_tracking_started=False,
Betty Zhoubcffe442017-07-05 17:27:55 -0700856 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
857 retries=1):
Nathan Harold54c7c742016-08-04 19:40:44 -0700858 """Wait for an incoming call on specified subscription.
859
860 Args:
861 log: log object.
Ang Li73697b32015-12-03 00:41:53 +0000862 ad: android device object.
863 sub_id: subscription ID
Betty Zhoua37acd32017-02-23 20:04:24 -0800864 incoming_number: Expected incoming number. Default is None
865 event_tracking_started: True if event tracking already state outside
866 timeout: time to wait for ring
Ang Li73697b32015-12-03 00:41:53 +0000867
868 Returns:
869 True: if incoming call is received and answered successfully.
870 False: for errors
871 """
Betty Zhoua37acd32017-02-23 20:04:24 -0800872 if not event_tracking_started:
Betty Zhou287f9df2018-01-23 10:57:55 -0800873 ad.ed.clear_events(EventCallStateChanged)
Nathan Harold54c7c742016-08-04 19:40:44 -0700874 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Betty Zhoubcffe442017-07-05 17:27:55 -0700875 event_ringing = None
876 for i in range(retries):
877 event_ringing = _wait_for_ringing_event(log, ad, timeout)
878 if event_ringing:
879 ad.log.info("callee received ring event")
880 break
881 if ad.droid.telephonyGetCallStateForSubscription(
882 sub_id
883 ) == TELEPHONY_STATE_RINGING or ad.droid.telecomIsRinging():
884 ad.log.info("callee in ringing state")
885 break
886 if i == retries - 1:
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800887 ad.log.info(
Betty Zhoubcffe442017-07-05 17:27:55 -0700888 "callee didn't receive ring event or got into ringing state")
889 return False
Betty Zhoua37acd32017-02-23 20:04:24 -0800890 if not event_tracking_started:
Nathan Harold54c7c742016-08-04 19:40:44 -0700891 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhou7f45f552017-03-15 19:12:52 -0700892 if caller and not caller.droid.telecomIsInCall():
893 caller.log.error("Caller not in call state")
894 raise _CallSequenceException("Caller not in call state")
Betty Zhoua37acd32017-02-23 20:04:24 -0800895 if not incoming_number:
896 return True
897
Betty Zhoubcffe442017-07-05 17:27:55 -0700898 if event_ringing and not check_phone_number_match(
899 event_ringing['data'][CallStateContainer.INCOMING_NUMBER],
900 incoming_number):
Betty Zhoua37acd32017-02-23 20:04:24 -0800901 ad.log.error(
902 "Incoming Number not match. Expected number:%s, actual number:%s",
903 incoming_number,
904 event_ringing['data'][CallStateContainer.INCOMING_NUMBER])
905 return False
906 return True
907
908
909def wait_for_call_offhook_event(
910 log,
911 ad,
Betty Zhoubb192482017-03-01 14:38:56 -0800912 sub_id,
Betty Zhoua37acd32017-02-23 20:04:24 -0800913 event_tracking_started=False,
914 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
915 """Wait for an incoming call on specified subscription.
916
917 Args:
918 log: log object.
919 ad: android device object.
920 event_tracking_started: True if event tracking already state outside
921 timeout: time to wait for event
922
923 Returns:
924 True: if call offhook event is received.
925 False: if call offhook event is not received.
926 """
927 if not event_tracking_started:
Betty Zhou287f9df2018-01-23 10:57:55 -0800928 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoua37acd32017-02-23 20:04:24 -0800929 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
930 try:
931 ad.ed.wait_for_event(
932 EventCallStateChanged,
933 is_event_match,
934 timeout=timeout,
935 field=CallStateContainer.CALL_STATE,
936 value=TELEPHONY_STATE_OFFHOOK)
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700937 ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK)
Betty Zhoua37acd32017-02-23 20:04:24 -0800938 except Empty:
Betty Zhoubb192482017-03-01 14:38:56 -0800939 ad.log.info("No event for call state change to OFFHOOK")
Betty Zhoua37acd32017-02-23 20:04:24 -0800940 return False
941 finally:
942 if not event_tracking_started:
943 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
944 sub_id)
Nathan Harold54c7c742016-08-04 19:40:44 -0700945 return True
946
947
948def wait_and_answer_call_for_subscription(
949 log,
950 ad,
951 sub_id,
952 incoming_number=None,
Betty Zhoua37acd32017-02-23 20:04:24 -0800953 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700954 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
955 caller=None):
Nathan Harold54c7c742016-08-04 19:40:44 -0700956 """Wait for an incoming call on specified subscription and
957 accepts the call.
958
959 Args:
960 log: log object.
961 ad: android device object.
962 sub_id: subscription ID
963 incoming_number: Expected incoming number.
964 Optional. Default is None
965 incall_ui_display: after answer the call, bring in-call UI to foreground or
966 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
967 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
968 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
969 else, do nothing.
970
971 Returns:
972 True: if incoming call is received and answered successfully.
973 False: for errors
974 """
Betty Zhou287f9df2018-01-23 10:57:55 -0800975 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -0800976 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +0000977 try:
Betty Zhouf25ce442017-03-03 14:28:36 -0800978 if not _wait_for_droid_in_state(
979 log,
980 ad,
981 timeout,
982 wait_for_ringing_call_for_subscription,
983 sub_id,
984 incoming_number=None,
Betty Zhou7f45f552017-03-15 19:12:52 -0700985 caller=caller,
Betty Zhoue5c0b232017-03-14 18:55:40 -0700986 event_tracking_started=True,
987 timeout=WAIT_TIME_BETWEEN_STATE_CHECK):
Betty Zhoua37acd32017-02-23 20:04:24 -0800988 ad.log.info("Could not answer a call: phone never rang.")
989 return False
Betty Zhouf25ce442017-03-03 14:28:36 -0800990 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
Betty Zhoubb192482017-03-01 14:38:56 -0800991 ad.log.info("Accept the ring call")
Betty Zhouf25ce442017-03-03 14:28:36 -0800992 ad.droid.telecomAcceptRingingCall()
993
Betty Zhou68fc0d02017-04-26 13:42:54 -0700994 if ad.droid.telecomIsInCall() or wait_for_call_offhook_event(
Betty Zhoubb192482017-03-01 14:38:56 -0800995 log, ad, sub_id, event_tracking_started=True,
996 timeout=timeout) or ad.droid.telecomIsInCall():
Betty Zhoua37acd32017-02-23 20:04:24 -0800997 ad.log.info("Call answered successfully.")
998 return True
999 else:
1000 ad.log.error("Could not answer the call.")
Ang Li73697b32015-12-03 00:41:53 +00001001 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07001002 except Exception as e:
1003 log.error(e)
1004 return False
Ang Li73697b32015-12-03 00:41:53 +00001005 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001006 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -08001007 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
1008 ad.droid.telecomShowInCallScreen()
1009 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
1010 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +00001011
Nathan Harold123c9da2015-12-30 16:33:25 -08001012
1013def wait_and_reject_call(log,
1014 ad,
1015 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001016 delay_reject=WAIT_TIME_REJECT_CALL,
1017 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001018 """Wait for an incoming call on default voice subscription and
1019 reject the call.
1020
1021 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001022 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001023 ad: android device object.
1024 incoming_number: Expected incoming number.
1025 Optional. Default is None
1026 delay_reject: time to wait before rejecting the call
1027 Optional. Default is WAIT_TIME_REJECT_CALL
1028
1029 Returns:
1030 True: if incoming call is received and reject successfully.
1031 False: for errors
1032 """
Betty Zhouee311052017-12-19 13:09:56 -08001033 return wait_and_reject_call_for_subscription(log, ad,
1034 get_incoming_voice_sub_id(ad),
1035 incoming_number, delay_reject,
1036 reject)
Ang Li73697b32015-12-03 00:41:53 +00001037
Nathan Harold123c9da2015-12-30 16:33:25 -08001038
1039def wait_and_reject_call_for_subscription(log,
1040 ad,
1041 sub_id,
1042 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001043 delay_reject=WAIT_TIME_REJECT_CALL,
1044 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001045 """Wait for an incoming call on specific subscription and
1046 reject the call.
1047
1048 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001049 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001050 ad: android device object.
1051 sub_id: subscription ID
1052 incoming_number: Expected incoming number.
1053 Optional. Default is None
1054 delay_reject: time to wait before rejecting the call
1055 Optional. Default is WAIT_TIME_REJECT_CALL
1056
1057 Returns:
1058 True: if incoming call is received and reject successfully.
1059 False: for errors
1060 """
Ang Li73697b32015-12-03 00:41:53 +00001061
Nathan Harold54c7c742016-08-04 19:40:44 -07001062 if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
1063 incoming_number):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001064 ad.log.error("Could not reject a call: phone never rang.")
Nathan Harold54c7c742016-08-04 19:40:44 -07001065 return False
Ang Li73697b32015-12-03 00:41:53 +00001066
Betty Zhou287f9df2018-01-23 10:57:55 -08001067 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001068 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Yang Liu598b93d2016-03-22 17:07:59 -07001069 if reject is True:
1070 # Delay between ringing and reject.
1071 time.sleep(delay_reject)
Yang Liu598b93d2016-03-22 17:07:59 -07001072 is_find = False
1073 # Loop the call list and find the matched one to disconnect.
1074 for call in ad.droid.telecomCallGetCallIds():
1075 if check_phone_number_match(
1076 get_number_from_tel_uri(get_call_uri(ad, call)),
1077 incoming_number):
1078 ad.droid.telecomCallDisconnect(call)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001079 ad.log.info("Callee reject the call")
Yang Liu598b93d2016-03-22 17:07:59 -07001080 is_find = True
1081 if is_find is False:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001082 ad.log.error("Callee did not find matching call to reject.")
Yang Liu598b93d2016-03-22 17:07:59 -07001083 return False
1084 else:
1085 # don't reject on callee. Just ignore the incoming call.
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001086 ad.log.info("Callee received incoming call. Ignore it.")
Ang Li73697b32015-12-03 00:41:53 +00001087 try:
Yang Liu598b93d2016-03-22 17:07:59 -07001088 ad.ed.wait_for_event(
1089 EventCallStateChanged,
1090 is_event_match_for_list,
1091 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1092 field=CallStateContainer.CALL_STATE,
1093 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
Ang Li73697b32015-12-03 00:41:53 +00001094 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001095 ad.log.error("No onCallStateChangedIdle event received.")
Ang Li73697b32015-12-03 00:41:53 +00001096 return False
1097 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001098 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001099 return True
1100
Nathan Harold123c9da2015-12-30 16:33:25 -08001101
Ang Li73697b32015-12-03 00:41:53 +00001102def hangup_call(log, ad):
1103 """Hang up ongoing active call.
Nathan Harold54c7c742016-08-04 19:40:44 -07001104
1105 Args:
1106 log: log object.
1107 ad: android device object.
1108
1109 Returns:
Nathan Haroldd2d30092016-10-12 12:45:55 -07001110 True: if all calls are cleared
Nathan Harold54c7c742016-08-04 19:40:44 -07001111 False: for errors
Ang Li73697b32015-12-03 00:41:53 +00001112 """
Nathan Haroldd2d30092016-10-12 12:45:55 -07001113 # short circuit in case no calls are active
1114 if not ad.droid.telecomIsInCall():
1115 return True
Betty Zhou287f9df2018-01-23 10:57:55 -08001116 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001117 ad.droid.telephonyStartTrackingCallState()
Betty Zhouf27f5482017-07-24 18:56:17 -07001118 ad.log.info("Hangup call.")
Ang Li73697b32015-12-03 00:41:53 +00001119 ad.droid.telecomEndCall()
1120
1121 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07001122 ad.ed.wait_for_event(
1123 EventCallStateChanged,
1124 is_event_match,
1125 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1126 field=CallStateContainer.CALL_STATE,
1127 value=TELEPHONY_STATE_IDLE)
Ang Li73697b32015-12-03 00:41:53 +00001128 except Empty:
1129 if ad.droid.telecomIsInCall():
Betty Zhoufe726dc2018-04-25 19:31:33 -07001130 ad.log.error("Telecom is in call, hangup call failed.")
Ang Li73697b32015-12-03 00:41:53 +00001131 return False
1132 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001133 ad.droid.telephonyStopTrackingCallStateChange()
Betty Zhoufe726dc2018-04-25 19:31:33 -07001134 if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1):
1135 ad.log.error("Telecom is in call, hangup call failed.")
1136 return False
1137 return True
Ang Li73697b32015-12-03 00:41:53 +00001138
Nathan Harold123c9da2015-12-30 16:33:25 -08001139
Ang Li73697b32015-12-03 00:41:53 +00001140def disconnect_call_by_id(log, ad, call_id):
1141 """Disconnect call by call id.
1142 """
1143 ad.droid.telecomCallDisconnect(call_id)
1144 return True
1145
Nathan Harold54c7c742016-08-04 19:40:44 -07001146
Yang Liu3197de22016-04-11 13:59:41 -07001147def _phone_number_remove_prefix(number):
1148 """Remove the country code and other prefix from the input phone number.
1149 Currently only handle phone number with the following formats:
1150 (US phone number format)
1151 +1abcxxxyyyy
1152 1abcxxxyyyy
1153 abcxxxyyyy
1154 abc xxx yyyy
1155 abc.xxx.yyyy
1156 abc-xxx-yyyy
1157 (EEUK phone number format)
1158 +44abcxxxyyyy
1159 0abcxxxyyyy
1160
1161 Args:
1162 number: input phone number
1163
1164 Returns:
1165 Phone number without country code or prefix
1166 """
Yang Liu8fcffd52016-05-31 18:38:35 -07001167 if number is None:
1168 return None, None
Betty Zhou9e54fc22017-01-19 12:15:53 -08001169 for country_code in COUNTRY_CODE_LIST:
Yang Liu3197de22016-04-11 13:59:41 -07001170 if number.startswith(country_code):
1171 return number[len(country_code):], country_code
1172 if number[0] == "1" or number[0] == "0":
1173 return number[1:], None
Yang Liu8fcffd52016-05-31 18:38:35 -07001174 return number, None
Yang Liu3197de22016-04-11 13:59:41 -07001175
Nathan Harold123c9da2015-12-30 16:33:25 -08001176
Ang Li73697b32015-12-03 00:41:53 +00001177def check_phone_number_match(number1, number2):
1178 """Check whether two input phone numbers match or not.
1179
1180 Compare the two input phone numbers.
1181 If they match, return True; otherwise, return False.
1182 Currently only handle phone number with the following formats:
1183 (US phone number format)
1184 +1abcxxxyyyy
1185 1abcxxxyyyy
1186 abcxxxyyyy
1187 abc xxx yyyy
1188 abc.xxx.yyyy
1189 abc-xxx-yyyy
Yang Liu3197de22016-04-11 13:59:41 -07001190 (EEUK phone number format)
1191 +44abcxxxyyyy
1192 0abcxxxyyyy
1193
1194 There are some scenarios we can not verify, one example is:
1195 number1 = +15555555555, number2 = 5555555555
1196 (number2 have no country code)
Ang Li73697b32015-12-03 00:41:53 +00001197
1198 Args:
1199 number1: 1st phone number to be compared.
1200 number2: 2nd phone number to be compared.
1201
1202 Returns:
1203 True if two phone numbers match. Otherwise False.
1204 """
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001205 number1 = phone_number_formatter(number1)
1206 number2 = phone_number_formatter(number2)
Betty Zhou9e54fc22017-01-19 12:15:53 -08001207 # Handle extra country code attachment when matching phone number
Betty Zhoue32dd3b2017-11-28 19:05:55 -08001208 if number1[-7:] in number2 or number2[-7:] in number1:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001209 return True
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001210 else:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001211 logging.info("phone number1 %s and number2 %s does not match" %
1212 (number1, number2))
1213 return False
Ang Li73697b32015-12-03 00:41:53 +00001214
1215
Betty Zhoubb192482017-03-01 14:38:56 -08001216def initiate_call(log,
1217 ad,
1218 callee_number,
1219 emergency=False,
1220 timeout=MAX_WAIT_TIME_CALL_INITIATION,
Betty Zhouf7da39e2018-04-16 16:28:58 -07001221 checking_interval=5):
Ang Li73697b32015-12-03 00:41:53 +00001222 """Make phone call from caller to callee.
1223
1224 Args:
1225 ad_caller: Caller android device object.
1226 callee_number: Callee phone number.
1227 emergency : specify the call is emergency.
1228 Optional. Default value is False.
1229
1230 Returns:
1231 result: if phone call is placed successfully.
1232 """
Betty Zhou287f9df2018-01-23 10:57:55 -08001233 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoubb192482017-03-01 14:38:56 -08001234 sub_id = get_outgoing_voice_sub_id(ad)
1235 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001236
1237 try:
1238 # Make a Call
Betty Zhoubb192482017-03-01 14:38:56 -08001239 ad.log.info("Make a phone call to %s", callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001240 if emergency:
Betty Zhoubb192482017-03-01 14:38:56 -08001241 ad.droid.telecomCallEmergencyNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001242 else:
Betty Zhoubb192482017-03-01 14:38:56 -08001243 ad.droid.telecomCallNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001244
1245 # Verify OFFHOOK event
Betty Zhoubb192482017-03-01 14:38:56 -08001246 checking_retries = int(timeout / checking_interval)
1247 for i in range(checking_retries):
1248 if (ad.droid.telecomIsInCall() and
1249 ad.droid.telephonyGetCallState() == TELEPHONY_STATE_OFFHOOK
Betty Zhouee311052017-12-19 13:09:56 -08001250 and ad.droid.telecomGetCallState() ==
1251 TELEPHONY_STATE_OFFHOOK) or wait_for_call_offhook_event(
1252 log, ad, sub_id, True, checking_interval):
Betty Zhoubb192482017-03-01 14:38:56 -08001253 return True
Betty Zhou8da03782017-07-28 18:02:24 -07001254 ad.log.info(
Betty Zhoubb192482017-03-01 14:38:56 -08001255 "Make call to %s fail. telecomIsInCall:%s, Telecom State:%s,"
Betty Zhouee311052017-12-19 13:09:56 -08001256 " Telephony State:%s", callee_number, ad.droid.telecomIsInCall(),
Betty Zhoubb192482017-03-01 14:38:56 -08001257 ad.droid.telephonyGetCallState(), ad.droid.telecomGetCallState())
Betty Zhoua301c202018-02-13 15:11:47 -08001258 reasons = ad.search_logcat(
1259 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause")
1260 if reasons:
1261 ad.log.info(reasons[-1]["log_message"])
Ang Li73697b32015-12-03 00:41:53 +00001262 return False
1263 finally:
Betty Zhoubb192482017-03-01 14:38:56 -08001264 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001265
Nathan Harold123c9da2015-12-30 16:33:25 -08001266
Betty Zhou8da03782017-07-28 18:02:24 -07001267def dial_phone_number(ad, callee_number):
1268 for number in str(callee_number):
1269 if number == "#":
1270 ad.send_keycode("POUND")
1271 elif number == "*":
1272 ad.send_keycode("STAR")
1273 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]:
1274 ad.send_keycode("%s" % number)
1275
1276
1277def get_call_state_by_adb(ad):
1278 return ad.adb.shell("dumpsys telephony.registry | grep mCallState")
1279
1280
1281def check_call_state_connected_by_adb(ad):
1282 return "2" in get_call_state_by_adb(ad)
1283
1284
1285def check_call_state_idle_by_adb(ad):
1286 return "0" in get_call_state_by_adb(ad)
1287
1288
1289def check_call_state_ring_by_adb(ad):
1290 return "1" in get_call_state_by_adb(ad)
1291
1292
1293def get_incoming_call_number_by_adb(ad):
1294 output = ad.adb.shell(
1295 "dumpsys telephony.registry | grep mCallIncomingNumber")
1296 return re.search(r"mCallIncomingNumber=(.*)", output).group(1)
1297
1298
1299def emergency_dialer_call_by_keyevent(ad, callee_number):
1300 for i in range(3):
1301 if "EmergencyDialer" in ad.get_my_current_focus_window():
1302 ad.log.info("EmergencyDialer is the current focus window")
1303 break
1304 elif i <= 2:
1305 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
1306 time.sleep(1)
1307 else:
1308 ad.log.error("Unable to bring up EmergencyDialer")
1309 return False
1310 ad.log.info("Make a phone call to %s", callee_number)
1311 dial_phone_number(ad, callee_number)
1312 ad.send_keycode("CALL")
1313
1314
1315def initiate_emergency_dialer_call_by_adb(
1316 log,
1317 ad,
1318 callee_number,
1319 timeout=MAX_WAIT_TIME_CALL_INITIATION,
1320 checking_interval=5):
1321 """Make emergency call by EmergencyDialer.
1322
1323 Args:
1324 ad: Caller android device object.
1325 callee_number: Callee phone number.
1326 emergency : specify the call is emergency.
1327 Optional. Default value is False.
1328
1329 Returns:
1330 result: if phone call is placed successfully.
1331 """
1332 try:
1333 # Make a Call
1334 ad.wakeup_screen()
Betty Zhou3c2e2542018-02-21 12:23:04 -08001335 ad.send_keycode("MENU")
Betty Zhou8da03782017-07-28 18:02:24 -07001336 ad.log.info("Call %s", callee_number)
Betty Zhou4617cba2017-08-10 11:58:39 -07001337 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
Betty Zhou8da03782017-07-28 18:02:24 -07001338 ad.adb.shell(
1339 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" %
1340 callee_number)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001341 if not timeout: return True
Betty Zhou8da03782017-07-28 18:02:24 -07001342 ad.log.info("Check call state")
1343 # Verify Call State
1344 elapsed_time = 0
1345 while elapsed_time < timeout:
1346 time.sleep(checking_interval)
1347 elapsed_time += checking_interval
1348 if check_call_state_connected_by_adb(ad):
1349 ad.log.info("Call to %s is connected", callee_number)
1350 return True
Betty Zhou13e7adf2017-09-06 14:01:10 -07001351 if check_call_state_idle_by_adb(ad):
1352 ad.log.info("Call to %s failed", callee_number)
1353 return False
Betty Zhou8da03782017-07-28 18:02:24 -07001354 ad.log.info("Make call to %s failed", callee_number)
1355 return False
1356 except Exception as e:
1357 ad.log.error("initiate emergency call failed with error %s", e)
1358
1359
Betty Zhoucbda4122018-01-16 19:15:42 -08001360def hangup_call_by_adb(ad):
Betty Zhou8da03782017-07-28 18:02:24 -07001361 """Make emergency call by EmergencyDialer.
1362
1363 Args:
1364 ad: Caller android device object.
1365 callee_number: Callee phone number.
1366 """
1367 ad.log.info("End call by adb")
1368 ad.send_keycode("ENDCALL")
1369
1370
Betty Zhouf7da39e2018-04-16 16:28:58 -07001371def dumpsys_all_call_info(ad):
Betty Zhoudd781f82017-08-08 14:46:23 -07001372 """ Get call information by dumpsys telecom. """
Betty Zhou8da03782017-07-28 18:02:24 -07001373 output = ad.adb.shell("dumpsys telecom")
1374 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL)
1375 calls_info = []
1376 for call in calls:
1377 call_info = {}
Betty Zhoudd781f82017-08-08 14:46:23 -07001378 for attr in ("startTime", "endTime", "direction", "isInterrupted",
Betty Zhou8da03782017-07-28 18:02:24 -07001379 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001380 "connectionService", "isVideoCall", "callProperties"):
Betty Zhou8da03782017-07-28 18:02:24 -07001381 match = re.search(r"%s: (.*)" % attr, call)
1382 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001383 if attr in ("startTime", "endTime"):
1384 call_info[attr] = epoch_to_log_line_timestamp(
1385 int(match.group(1)))
1386 else:
1387 call_info[attr] = match.group(1)
Betty Zhou8da03782017-07-28 18:02:24 -07001388 call_info["inCallServices"] = re.findall(r"name: (.*)", call)
1389 calls_info.append(call_info)
1390 ad.log.debug("calls_info = %s", calls_info)
1391 return calls_info
1392
1393
Betty Zhouf7da39e2018-04-16 16:28:58 -07001394def dumpsys_last_call_info(ad):
1395 """ Get call information by dumpsys telecom. """
1396 num = dumpsys_last_call_number(ad)
1397 output = ad.adb.shell("dumpsys telecom")
1398 result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL)
Betty Zhou739d6b72018-04-18 10:38:53 -07001399 call_info = {"TC": num}
Betty Zhouf7da39e2018-04-16 16:28:58 -07001400 if result:
1401 result = result.group(1)
1402 for attr in ("startTime", "endTime", "direction", "isInterrupted",
1403 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001404 "isVideoCall", "callProperties"):
Betty Zhouf7da39e2018-04-16 16:28:58 -07001405 match = re.search(r"%s: (.*)" % attr, result)
1406 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001407 if attr in ("startTime", "endTime"):
1408 call_info[attr] = epoch_to_log_line_timestamp(
1409 int(match.group(1)))
1410 else:
1411 call_info[attr] = match.group(1)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001412 ad.log.debug("call_info = %s", call_info)
1413 return call_info
1414
1415
1416def dumpsys_last_call_number(ad):
1417 output = ad.adb.shell("dumpsys telecom")
1418 call_nums = re.findall("Call TC@(\d+):", output)
1419 if not call_nums:
1420 return 0
1421 else:
1422 return int(call_nums[-1])
1423
1424
Betty Zhoufe726dc2018-04-25 19:31:33 -07001425def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5):
1426 for i in range(retries):
1427 if dumpsys_last_call_number(ad) > last_tc_number:
1428 call_info = dumpsys_last_call_info(ad)
1429 ad.log.info("New call info = %s", sorted(call_info.items()))
1430 return call_info
1431 else:
1432 time.sleep(interval)
1433 ad.log.error("New call is not in sysdump telecom")
1434 return {}
1435
1436
Yang Liu598b93d2016-03-22 17:07:59 -07001437def call_reject(log, ad_caller, ad_callee, reject=True):
1438 """Caller call Callee, then reject on callee.
1439
1440
1441 """
1442 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
1443 subid_callee = ad_callee.incoming_voice_sub_id
Betty Zhoua37acd32017-02-23 20:04:24 -08001444 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
1445 subid_callee)
Yang Liu598b93d2016-03-22 17:07:59 -07001446 return call_reject_for_subscription(log, ad_caller, ad_callee,
1447 subid_caller, subid_callee, reject)
1448
1449
1450def call_reject_for_subscription(log,
1451 ad_caller,
1452 ad_callee,
1453 subid_caller,
1454 subid_callee,
1455 reject=True):
1456 """
1457 """
1458
Betty Zhou3b2de072018-03-15 16:46:26 -07001459 caller_number = ad_caller.telephony['subscription'][subid_caller][
1460 'phone_num']
1461 callee_number = ad_callee.telephony['subscription'][subid_callee][
1462 'phone_num']
Yang Liu598b93d2016-03-22 17:07:59 -07001463
Betty Zhoua37acd32017-02-23 20:04:24 -08001464 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Yang Liu598b93d2016-03-22 17:07:59 -07001465 try:
1466 if not initiate_call(log, ad_caller, callee_number):
1467 raise _CallSequenceException("Initiate call failed.")
1468
1469 if not wait_and_reject_call_for_subscription(
1470 log, ad_callee, subid_callee, caller_number,
1471 WAIT_TIME_REJECT_CALL, reject):
1472 raise _CallSequenceException("Reject call fail.")
1473 # Check if incoming call is cleared on callee or not.
1474 if ad_callee.droid.telephonyGetCallStateForSubscription(
1475 subid_callee) == TELEPHONY_STATE_RINGING:
1476 raise _CallSequenceException("Incoming call is not cleared.")
1477 # Hangup on caller
1478 hangup_call(log, ad_caller)
1479 except _CallSequenceException as e:
1480 log.error(e)
1481 return False
1482 return True
1483
1484
Nathan Harold123c9da2015-12-30 16:33:25 -08001485def call_reject_leave_message(log,
1486 ad_caller,
1487 ad_callee,
1488 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08001489 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00001490 """On default voice subscription, Call from caller to callee,
1491 reject on callee, caller leave a voice mail.
1492
1493 1. Caller call Callee.
1494 2. Callee reject incoming call.
1495 3. Caller leave a voice mail.
1496 4. Verify callee received the voice mail notification.
1497
1498 Args:
1499 ad_caller: caller android device object.
1500 ad_callee: callee android device object.
1501 verify_caller_func: function to verify caller is in correct state while in-call.
1502 This is optional, default is None.
1503 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08001504 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00001505
1506 Returns:
1507 True: if voice message is received on callee successfully.
1508 False: for errors
1509 """
Yang Liu963c93c2016-04-05 10:52:00 -07001510 subid_caller = get_outgoing_voice_sub_id(ad_caller)
1511 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08001512 return call_reject_leave_message_for_subscription(
1513 log, ad_caller, ad_callee, subid_caller, subid_callee,
1514 verify_caller_func, wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00001515
Nathan Harold123c9da2015-12-30 16:33:25 -08001516
1517def call_reject_leave_message_for_subscription(
1518 log,
1519 ad_caller,
1520 ad_callee,
1521 subid_caller,
1522 subid_callee,
1523 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08001524 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00001525 """On specific voice subscription, Call from caller to callee,
1526 reject on callee, caller leave a voice mail.
1527
1528 1. Caller call Callee.
1529 2. Callee reject incoming call.
1530 3. Caller leave a voice mail.
1531 4. Verify callee received the voice mail notification.
1532
1533 Args:
1534 ad_caller: caller android device object.
1535 ad_callee: callee android device object.
1536 subid_caller: caller's subscription id.
1537 subid_callee: callee's subscription id.
1538 verify_caller_func: function to verify caller is in correct state while in-call.
1539 This is optional, default is None.
1540 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08001541 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00001542
1543 Returns:
1544 True: if voice message is received on callee successfully.
1545 False: for errors
1546 """
Nathan Harold123c9da2015-12-30 16:33:25 -08001547
Ang Li73697b32015-12-03 00:41:53 +00001548 # Currently this test utility only works for TMO and ATT and SPT.
1549 # It does not work for VZW (see b/21559800)
1550 # "with VVM TelephonyManager APIs won't work for vm"
1551
Betty Zhou3b2de072018-03-15 16:46:26 -07001552 caller_number = ad_caller.telephony['subscription'][subid_caller][
1553 'phone_num']
1554 callee_number = ad_callee.telephony['subscription'][subid_callee][
1555 'phone_num']
Ang Li73697b32015-12-03 00:41:53 +00001556
Betty Zhoua37acd32017-02-23 20:04:24 -08001557 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001558
1559 try:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001560 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
1561 subid_callee)
1562 ad_callee.log.info("voice mail count is %s", voice_mail_count_before)
1563 # -1 means there are unread voice mail, but the count is unknown
1564 # 0 means either this API not working (VZW) or no unread voice mail.
1565 if voice_mail_count_before != 0:
1566 log.warning("--Pending new Voice Mail, please clear on phone.--")
Ang Li73697b32015-12-03 00:41:53 +00001567
1568 if not initiate_call(log, ad_caller, callee_number):
1569 raise _CallSequenceException("Initiate call failed.")
1570
1571 if not wait_and_reject_call_for_subscription(
Nathan Harold4a144a42016-09-19 14:16:24 -07001572 log, ad_callee, subid_callee, incoming_number=caller_number):
Ang Li73697b32015-12-03 00:41:53 +00001573 raise _CallSequenceException("Reject call fail.")
1574
Yang Liuaed3eef2015-12-15 18:40:25 -08001575 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001576 subid_callee)
Ang Li73697b32015-12-03 00:41:53 +00001577
1578 # ensure that all internal states are updated in telecom
1579 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhou287f9df2018-01-23 10:57:55 -08001580 ad_callee.ed.ad.ed.clear_events(EventCallStateChanged)
Ang Li73697b32015-12-03 00:41:53 +00001581
1582 if verify_caller_func and not verify_caller_func(log, ad_caller):
Nathan Harold123c9da2015-12-30 16:33:25 -08001583 raise _CallSequenceException("Caller not in correct state!")
Ang Li73697b32015-12-03 00:41:53 +00001584
Yang Liu7a2e7ee2015-12-28 15:32:44 -08001585 # TODO: b/26293512 Need to play some sound to leave message.
1586 # Otherwise carrier voice mail server may drop this voice mail.
Ang Li73697b32015-12-03 00:41:53 +00001587 time.sleep(wait_time_in_call)
1588
1589 if not verify_caller_func:
1590 caller_state_result = ad_caller.droid.telecomIsInCall()
1591 else:
1592 caller_state_result = verify_caller_func(log, ad_caller)
1593 if not caller_state_result:
1594 raise _CallSequenceException(
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001595 "Caller %s not in correct state after %s seconds" %
1596 (ad_caller.serial, wait_time_in_call))
Ang Li73697b32015-12-03 00:41:53 +00001597
1598 if not hangup_call(log, ad_caller):
Nathan Harold123c9da2015-12-30 16:33:25 -08001599 raise _CallSequenceException("Error in Hanging-Up Call")
Ang Li73697b32015-12-03 00:41:53 +00001600
1601 log.info("Wait for voice mail indicator on callee.")
1602 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08001603 event = ad_callee.ed.wait_for_event(
1604 EventMessageWaitingIndicatorChanged,
1605 _is_on_message_waiting_event_true)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07001606 ad_callee.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001607 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001608 ad_callee.log.warning("No expected event %s",
1609 EventMessageWaitingIndicatorChanged)
Nathan Harold123c9da2015-12-30 16:33:25 -08001610 raise _CallSequenceException("No expected event {}.".format(
1611 EventMessageWaitingIndicatorChanged))
Yang Liuaed3eef2015-12-15 18:40:25 -08001612 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001613 subid_callee)
Betty Zhoua37acd32017-02-23 20:04:24 -08001614 ad_callee.log.info(
1615 "telephonyGetVoiceMailCount output - before: %s, after: %s",
1616 voice_mail_count_before, voice_mail_count_after)
Ang Li73697b32015-12-03 00:41:53 +00001617
1618 # voice_mail_count_after should:
1619 # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
1620 # or equals to -1 [For TMO]
1621 # -1 means there are unread voice mail, but the count is unknown
Nathan Harold123c9da2015-12-30 16:33:25 -08001622 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
Ang Li73697b32015-12-03 00:41:53 +00001623 voice_mail_count_after):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001624 log.error("before and after voice mail count is not incorrect.")
Ang Li73697b32015-12-03 00:41:53 +00001625 return False
1626
1627 except _CallSequenceException as e:
1628 log.error(e)
1629 return False
1630 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001631 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00001632 subid_callee)
1633 return True
1634
Nathan Harold123c9da2015-12-30 16:33:25 -08001635
Ang Li73697b32015-12-03 00:41:53 +00001636def call_voicemail_erase_all_pending_voicemail(log, ad):
1637 """Script for phone to erase all pending voice mail.
1638 This script only works for TMO and ATT and SPT currently.
1639 This script only works if phone have already set up voice mail options,
1640 and phone should disable password protection for voice mail.
1641
1642 1. If phone don't have pending voice message, return True.
1643 2. Dial voice mail number.
1644 For TMO, the number is '123'
1645 For ATT, the number is phone's number
1646 For SPT, the number is phone's number
1647 3. Wait for voice mail connection setup.
1648 4. Wait for voice mail play pending voice message.
1649 5. Send DTMF to delete one message.
1650 The digit is '7'.
1651 6. Repeat steps 4 and 5 until voice mail server drop this call.
1652 (No pending message)
Yang Liuaed3eef2015-12-15 18:40:25 -08001653 6. Check telephonyGetVoiceMailCount result. it should be 0.
Ang Li73697b32015-12-03 00:41:53 +00001654
1655 Args:
1656 log: log object
1657 ad: android device object
1658 Returns:
1659 False if error happens. True is succeed.
1660 """
1661 log.info("Erase all pending voice mail.")
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001662 count = ad.droid.telephonyGetVoiceMailCount()
1663 if count == 0:
1664 ad.log.info("No Pending voice mail.")
Ang Li73697b32015-12-03 00:41:53 +00001665 return True
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001666 if count == -1:
1667 ad.log.info("There is pending voice mail, but the count is unknown")
1668 count = MAX_SAVED_VOICE_MAIL
1669 else:
1670 ad.log.info("There are %s voicemails", count)
Ang Li73697b32015-12-03 00:41:53 +00001671
1672 voice_mail_number = get_voice_mail_number(log, ad)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001673 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00001674 if not initiate_call(log, ad, voice_mail_number):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001675 log.error("Initiate call to voice mail failed.")
Ang Li73697b32015-12-03 00:41:53 +00001676 return False
Yang Liudf164e32016-01-07 16:49:32 -08001677 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00001678 callId = ad.droid.telecomCallGetCallIds()[0]
Yang Liudf164e32016-01-07 16:49:32 -08001679 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Nathan Harold123c9da2015-12-30 16:33:25 -08001680 while (is_phone_in_call(log, ad) and (count > 0)):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001681 ad.log.info("Press %s to delete voice mail.", delete_digit)
1682 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit)
Ang Li73697b32015-12-03 00:41:53 +00001683 ad.droid.telecomCallStopDtmfTone(callId)
Yang Liudf164e32016-01-07 16:49:32 -08001684 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00001685 count -= 1
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001686 if is_phone_in_call(log, ad):
1687 hangup_call(log, ad)
1688
Yang Liuaed3eef2015-12-15 18:40:25 -08001689 # wait for telephonyGetVoiceMailCount to update correct result
Yang Liudf164e32016-01-07 16:49:32 -08001690 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
Betty Zhouee311052017-12-19 13:09:56 -08001691 while ((remaining_time > 0)
1692 and (ad.droid.telephonyGetVoiceMailCount() != 0)):
Ang Li73697b32015-12-03 00:41:53 +00001693 time.sleep(1)
1694 remaining_time -= 1
Yang Liuaed3eef2015-12-15 18:40:25 -08001695 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
Betty Zhoua37acd32017-02-23 20:04:24 -08001696 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
Ang Li73697b32015-12-03 00:41:53 +00001697 return (current_voice_mail_count == 0)
1698
Nathan Harold123c9da2015-12-30 16:33:25 -08001699
Ang Li73697b32015-12-03 00:41:53 +00001700def _is_on_message_waiting_event_true(event):
1701 """Private function to return if the received EventMessageWaitingIndicatorChanged
Yang Liudc8564b2016-01-27 14:15:37 -08001702 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
Ang Li73697b32015-12-03 00:41:53 +00001703 """
Yang Liudc8564b2016-01-27 14:15:37 -08001704 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
Ang Li73697b32015-12-03 00:41:53 +00001705
Nathan Harold123c9da2015-12-30 16:33:25 -08001706
1707def call_setup_teardown(log,
1708 ad_caller,
1709 ad_callee,
1710 ad_hangup=None,
1711 verify_caller_func=None,
1712 verify_callee_func=None,
1713 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07001714 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou3b2de072018-03-15 16:46:26 -07001715 dialing_number_length=None):
Ang Li73697b32015-12-03 00:41:53 +00001716 """ Call process, including make a phone call from caller,
1717 accept from callee, and hang up. The call is on default voice subscription
1718
1719 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08001720 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00001721
1722 Args:
1723 ad_caller: Caller Android Device Object.
1724 ad_callee: Callee Android Device Object.
1725 ad_hangup: Android Device Object end the phone call.
1726 Optional. Default value is None, and phone call will continue.
1727 verify_call_mode_caller: func_ptr to verify caller in correct mode
1728 Optional. Default is None
1729 verify_call_mode_caller: func_ptr to verify caller in correct mode
1730 Optional. Default is None
1731 incall_ui_display: after answer the call, bring in-call UI to foreground or
1732 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1733 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1734 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1735 else, do nothing.
1736
1737 Returns:
1738 True if call process without any error.
1739 False if error happened.
1740
1741 """
Yang Liu963c93c2016-04-05 10:52:00 -07001742 subid_caller = get_outgoing_voice_sub_id(ad_caller)
1743 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08001744 return call_setup_teardown_for_subscription(
1745 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
1746 verify_caller_func, verify_callee_func, wait_time_in_call,
Betty Zhouf7da39e2018-04-16 16:28:58 -07001747 incall_ui_display, dialing_number_length)
Ang Li73697b32015-12-03 00:41:53 +00001748
1749
Nathan Harold123c9da2015-12-30 16:33:25 -08001750def call_setup_teardown_for_subscription(
1751 log,
1752 ad_caller,
1753 ad_callee,
1754 subid_caller,
1755 subid_callee,
1756 ad_hangup=None,
1757 verify_caller_func=None,
1758 verify_callee_func=None,
1759 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07001760 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou3b2de072018-03-15 16:46:26 -07001761 dialing_number_length=None):
Ang Li73697b32015-12-03 00:41:53 +00001762 """ Call process, including make a phone call from caller,
1763 accept from callee, and hang up. The call is on specified subscription
1764
1765 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08001766 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00001767
1768 Args:
1769 ad_caller: Caller Android Device Object.
1770 ad_callee: Callee Android Device Object.
1771 subid_caller: Caller subscription ID
1772 subid_callee: Callee subscription ID
1773 ad_hangup: Android Device Object end the phone call.
1774 Optional. Default value is None, and phone call will continue.
1775 verify_call_mode_caller: func_ptr to verify caller in correct mode
1776 Optional. Default is None
1777 verify_call_mode_caller: func_ptr to verify caller in correct mode
1778 Optional. Default is None
1779 incall_ui_display: after answer the call, bring in-call UI to foreground or
1780 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1781 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1782 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1783 else, do nothing.
1784
1785 Returns:
1786 True if call process without any error.
1787 False if error happened.
1788
1789 """
Betty Zhouf27f5482017-07-24 18:56:17 -07001790 CHECK_INTERVAL = 5
Betty Zhoua301c202018-02-13 15:11:47 -08001791 begin_time = get_current_epoch_time()
Betty Zhou74481722018-04-13 16:19:25 -07001792 if not verify_caller_func:
1793 verify_caller_func = is_phone_in_call
1794 if not verify_callee_func:
1795 verify_callee_func = is_phone_in_call
Nathan Harold123c9da2015-12-30 16:33:25 -08001796
Betty Zhou3b2de072018-03-15 16:46:26 -07001797 caller_number = ad_caller.telephony['subscription'][subid_caller][
1798 'phone_num']
1799 callee_number = ad_callee.telephony['subscription'][subid_callee][
1800 'phone_num']
1801 if dialing_number_length:
1802 skip_test = False
1803 trunc_position = 0 - int(dialing_number_length)
1804 try:
1805 caller_area_code = caller_number[:trunc_position]
1806 callee_area_code = callee_number[:trunc_position]
1807 callee_dial_number = callee_number[trunc_position:]
1808 except:
1809 skip_test = True
1810 if caller_area_code != callee_area_code:
1811 skip_test = True
1812 if skip_test:
1813 msg = "Cannot make call from %s to %s by %s digits" % (
1814 caller_number, callee_number, dialing_number_length)
1815 ad_caller.log.info(msg)
1816 raise signals.TestSkip(msg)
1817 else:
1818 callee_number = callee_dial_number
Ang Li73697b32015-12-03 00:41:53 +00001819
Betty Zhouf27f5482017-07-24 18:56:17 -07001820 result = True
Betty Zhou628b98e2018-01-08 15:45:25 -08001821 msg = "Call from %s to %s" % (caller_number, callee_number)
1822 if ad_hangup:
1823 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
1824 ad_caller.log.info(msg)
Ang Li73697b32015-12-03 00:41:53 +00001825
Betty Zhou0d774582018-03-01 17:46:44 -08001826 for ad in (ad_caller, ad_callee):
1827 call_ids = ad.droid.telecomCallGetCallIds()
1828 setattr(ad, "call_ids", call_ids)
1829 ad.log.info("Before making call, existing phone calls %s", call_ids)
Ang Li73697b32015-12-03 00:41:53 +00001830 try:
Betty Zhouf7da39e2018-04-16 16:28:58 -07001831 if not initiate_call(log, ad_caller, callee_number):
Betty Zhouf27f5482017-07-24 18:56:17 -07001832 ad_caller.log.error("Initiate call failed.")
Betty Zhouf27f5482017-07-24 18:56:17 -07001833 return False
Betty Zhou94023182017-06-07 18:02:14 -07001834 else:
1835 ad_caller.log.info("Caller initate call successfully")
Ang Li73697b32015-12-03 00:41:53 +00001836 if not wait_and_answer_call_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08001837 log,
1838 ad_callee,
1839 subid_callee,
1840 incoming_number=caller_number,
Betty Zhou2e01bc82017-03-17 10:55:57 -07001841 caller=ad_caller,
Ang Li73697b32015-12-03 00:41:53 +00001842 incall_ui_display=incall_ui_display):
Betty Zhouf27f5482017-07-24 18:56:17 -07001843 ad_callee.log.error("Answer call fail.")
Betty Zhouf27f5482017-07-24 18:56:17 -07001844 return False
Betty Zhou94023182017-06-07 18:02:14 -07001845 else:
1846 ad_callee.log.info("Callee answered the call successfully")
Ang Li73697b32015-12-03 00:41:53 +00001847
Betty Zhou74481722018-04-13 16:19:25 -07001848 for ad, call_func in zip([ad_caller, ad_callee],
1849 [verify_caller_func, verify_callee_func]):
Betty Zhou0d774582018-03-01 17:46:44 -08001850 call_ids = ad.droid.telecomCallGetCallIds()
Betty Zhou5dd53c02018-03-22 20:08:33 -07001851 new_call_ids = set(call_ids) - set(ad.call_ids)
1852 if not new_call_ids:
1853 ad.log.error(
1854 "No new call ids are found after call establishment")
Betty Zhouf25fdab2018-04-23 19:20:17 -07001855 ad.log.error("telecomCallGetCallIds returns %s",
1856 ad.droid.telecomCallGetCallIds())
Betty Zhoucf048542018-02-22 17:14:08 -08001857 result = False
Betty Zhou5dd53c02018-03-22 20:08:33 -07001858 for new_call_id in new_call_ids:
1859 if not wait_for_in_call_active(ad, call_id=new_call_id):
1860 result = False
Betty Zhouc4dfad12018-04-11 18:36:49 -07001861
Betty Zhouf31dffe2018-02-23 19:29:28 -08001862 if not ad.droid.telecomCallGetAudioState():
1863 ad.log.error("Audio is not in call state")
1864 result = False
Betty Zhoucf048542018-02-22 17:14:08 -08001865
Betty Zhou74481722018-04-13 16:19:25 -07001866 if call_func(log, ad):
1867 ad.log.info("Call is in %s state", call_func.__name__)
1868 else:
1869 ad.log.error("Call is not in %s state", call_func.__name__)
1870 result = False
Betty Zhoud749f812018-04-24 12:11:02 -07001871 if not result:
1872 return False
Yang Liu13406292016-02-23 14:58:25 -08001873 elapsed_time = 0
Nathan Harold7642fc92016-05-02 18:29:11 -07001874 while (elapsed_time < wait_time_in_call):
1875 CHECK_INTERVAL = min(CHECK_INTERVAL,
1876 wait_time_in_call - elapsed_time)
Yang Liu13406292016-02-23 14:58:25 -08001877 time.sleep(CHECK_INTERVAL)
1878 elapsed_time += CHECK_INTERVAL
Betty Zhou94023182017-06-07 18:02:14 -07001879 time_message = "at <%s>/<%s> second." % (elapsed_time,
1880 wait_time_in_call)
Betty Zhouc2801992018-01-30 16:40:28 -08001881 for ad, call_func in [(ad_caller, verify_caller_func),
1882 (ad_callee, verify_callee_func)]:
1883 if not call_func(log, ad):
1884 ad.log.error("NOT in correct %s state at %s",
1885 call_func.__name__, time_message)
1886 result = False
1887 else:
1888 ad.log.info("In correct %s state at %s",
1889 call_func.__name__, time_message)
1890 if not ad.droid.telecomCallGetAudioState():
1891 ad.log.error("Audio is not in call state at %s",
1892 time_message)
1893 result = False
1894 if not result:
Betty Zhoud749f812018-04-24 12:11:02 -07001895 return False
Betty Zhoufe726dc2018-04-25 19:31:33 -07001896 if ad_hangup:
1897 ad_callee_ids = ad_callee.droid.telecomCallGetCallIds()
1898 ad_caller_ids = ad_caller.droid.telecomCallGetCallIds()
1899 if not hangup_call(log, ad_hangup):
1900 ad_hangup.log.info("Failed to hang up the call")
1901 result = False
1902 else:
1903 if not wait_for_call_id_clearing(ad_caller, ad_caller_ids):
1904 result = False
1905 if not wait_for_call_id_clearing(ad_callee, ad_callee_ids):
1906 result = False
Betty Zhoufd1e0da2018-02-20 14:39:35 -08001907 return result
1908 finally:
Betty Zhouf27f5482017-07-24 18:56:17 -07001909 if not result:
Ang Li73697b32015-12-03 00:41:53 +00001910 for ad in [ad_caller, ad_callee]:
Betty Zhoua301c202018-02-13 15:11:47 -08001911 reasons = ad.search_logcat(
1912 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause",
1913 begin_time)
1914 if reasons:
1915 ad.log.info(reasons[-1]["log_message"])
Ang Li73697b32015-12-03 00:41:53 +00001916 try:
1917 if ad.droid.telecomIsInCall():
Betty Zhoufe726dc2018-04-25 19:31:33 -07001918 ad.log.info("In call. End now.")
Ang Li73697b32015-12-03 00:41:53 +00001919 ad.droid.telecomEndCall()
1920 except Exception as e:
1921 log.error(str(e))
1922
Nathan Harold123c9da2015-12-30 16:33:25 -08001923
Betty Zhoue7cc3672018-04-26 16:58:56 -07001924def wait_for_call_id_clearing(ad,
1925 previous_ids,
1926 timeout=MAX_WAIT_TIME_CALL_DROP):
Betty Zhoufe726dc2018-04-25 19:31:33 -07001927 while timeout > 0:
1928 new_call_ids = ad.droid.telecomCallGetCallIds()
1929 if len(new_call_ids) < len(previous_ids):
1930 return True
1931 time.sleep(5)
1932 timeout = timeout - 5
Betty Zhoue7cc3672018-04-26 16:58:56 -07001933 ad.log.error("There is no call id clearing: %s vs. %s", previous_ids,
1934 new_call_ids)
Betty Zhoufe726dc2018-04-25 19:31:33 -07001935 return False
1936
1937
Betty Zhoua37acd32017-02-23 20:04:24 -08001938def phone_number_formatter(input_string, formatter=None):
Ang Li73697b32015-12-03 00:41:53 +00001939 """Get expected format of input phone number string.
1940
1941 Args:
1942 input_string: (string) input phone number.
1943 The input could be 10/11/12 digital, with or without " "/"-"/"."
Betty Zhoua37acd32017-02-23 20:04:24 -08001944 formatter: (int) expected format, this could be 7/10/11/12
1945 if formatter is 7: output string would be 7 digital number.
1946 if formatter is 10: output string would be 10 digital (standard) number.
1947 if formatter is 11: output string would be "1" + 10 digital number.
1948 if formatter is 12: output string would be "+1" + 10 digital number.
Ang Li73697b32015-12-03 00:41:53 +00001949
1950 Returns:
1951 If no error happen, return phone number in expected format.
1952 Else, return None.
1953 """
Betty Zhouddb361d2017-09-07 17:07:20 -07001954 if not input_string:
1955 return ""
Ang Li73697b32015-12-03 00:41:53 +00001956 # make sure input_string is 10 digital
1957 # Remove white spaces, dashes, dots
Betty Zhoue955be22017-04-12 17:28:05 -07001958 input_string = input_string.replace(" ", "").replace("-", "").replace(
Betty Zhou77aa5f52017-05-08 20:23:35 -07001959 ".", "").lstrip("0")
Betty Zhoua37acd32017-02-23 20:04:24 -08001960 if not formatter:
Nathan Haroldae6a0da2016-03-16 20:56:47 +00001961 return input_string
Ang Li73697b32015-12-03 00:41:53 +00001962 # Remove "1" or "+1"from front
Betty Zhouee311052017-12-19 13:09:56 -08001963 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT
1964 and input_string[0] == "1"):
Ang Li73697b32015-12-03 00:41:53 +00001965 input_string = input_string[1:]
Betty Zhouee311052017-12-19 13:09:56 -08001966 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT
1967 and input_string[0:2] == "+1"):
Ang Li73697b32015-12-03 00:41:53 +00001968 input_string = input_string[2:]
Betty Zhouee311052017-12-19 13:09:56 -08001969 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT
1970 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT):
Ang Li73697b32015-12-03 00:41:53 +00001971 return input_string
1972 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
1973 return None
1974 # change input_string according to format
Betty Zhoua37acd32017-02-23 20:04:24 -08001975 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08001976 input_string = "+1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001977 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08001978 input_string = "1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001979 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00001980 input_string = input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08001981 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00001982 input_string = input_string[3:]
1983 else:
1984 return None
1985 return input_string
1986
Nathan Harold123c9da2015-12-30 16:33:25 -08001987
Ang Li73697b32015-12-03 00:41:53 +00001988def get_internet_connection_type(log, ad):
1989 """Get current active connection type name.
1990
1991 Args:
1992 log: Log object.
1993 ad: Android Device Object.
1994 Returns:
1995 current active connection type name.
1996 """
1997 if not ad.droid.connectivityNetworkIsConnected():
1998 return 'none'
1999 return connection_type_from_type_string(
2000 ad.droid.connectivityNetworkGetActiveConnectionTypeName())
2001
Nathan Harold123c9da2015-12-30 16:33:25 -08002002
2003def verify_http_connection(log,
2004 ad,
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002005 url="https://www.google.com",
Betty Zhouf809c5c2017-03-21 14:55:59 -07002006 retry=5,
Betty Zhou32e403a2017-10-25 20:08:12 -07002007 retry_interval=15,
2008 expected_state=True):
Ang Li73697b32015-12-03 00:41:53 +00002009 """Make ping request and return status.
2010
2011 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07002012 log: log object
Ang Li73697b32015-12-03 00:41:53 +00002013 ad: Android Device Object.
2014 url: Optional. The ping request will be made to this URL.
2015 Default Value is "http://www.google.com/".
2016
2017 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002018 for i in range(0, retry + 1):
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002019 try:
2020 http_response = ad.droid.httpPing(url)
2021 except:
2022 http_response = None
Betty Zhoue7cc3672018-04-26 16:58:56 -07002023 ad.log.info("Http ping response for %s is %s, expecting %s", url,
2024 http_response, expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002025 if (expected_state and http_response) or (not expected_state
2026 and not http_response):
Ang Li73697b32015-12-03 00:41:53 +00002027 return True
Betty Zhou32e403a2017-10-25 20:08:12 -07002028 if i < retry:
Betty Zhou32e403a2017-10-25 20:08:12 -07002029 time.sleep(retry_interval)
Betty Zhoue7cc3672018-04-26 16:58:56 -07002030 ad.log.error("Http ping to %s is %s after %s second, expecting %s", url,
2031 http_response, i * retry_interval, expected_state)
Ang Li73697b32015-12-03 00:41:53 +00002032 return False
2033
2034
Betty Zhoucea4b432017-07-20 18:29:24 -07002035def _generate_file_directory_and_file_name(url, out_path):
Betty Zhouccd171d2017-02-13 15:11:33 -08002036 file_name = url.split("/")[-1]
2037 if not out_path:
Betty Zhoucea4b432017-07-20 18:29:24 -07002038 file_directory = "/sdcard/Download/"
2039 elif not out_path.endswith("/"):
2040 file_directory, file_name = os.path.split(out_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08002041 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002042 file_directory = out_path
2043 return file_directory, file_name
Betty Zhouccd171d2017-02-13 15:11:33 -08002044
2045
Betty Zhoucea4b432017-07-20 18:29:24 -07002046def _check_file_existance(ad, file_path, expected_file_size=None):
2047 """Check file existance by file_path. If expected_file_size
Betty Zhouccd171d2017-02-13 15:11:33 -08002048 is provided, then also check if the file meet the file size requirement.
2049 """
Girish Moturu2c21eb32017-05-25 14:37:55 +05302050 out = None
2051 try:
2052 out = ad.adb.shell('stat -c "%%s" %s' % file_path)
2053 except AdbError:
2054 pass
Betty Zhouccd171d2017-02-13 15:11:33 -08002055 # Handle some old version adb returns error message "No such" into std_out
Betty Zhouf17f0692017-06-28 13:10:31 -07002056 if out and "No such" not in out:
Betty Zhouccd171d2017-02-13 15:11:33 -08002057 if expected_file_size:
Betty Zhouf17f0692017-06-28 13:10:31 -07002058 file_size = int(out)
Betty Zhouccd171d2017-02-13 15:11:33 -08002059 if file_size >= expected_file_size:
Betty Zhoucea4b432017-07-20 18:29:24 -07002060 ad.log.info("File %s of size %s exists", file_path, file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08002061 return True
2062 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002063 ad.log.info("File %s is of size %s, does not meet expected %s",
2064 file_path, file_size, expected_file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08002065 return False
2066 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002067 ad.log.info("File %s exists", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08002068 return True
2069 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002070 ad.log.info("File %s does not exist.", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08002071 return False
2072
2073
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002074def check_curl_availability(ad):
Betty Zhouf3b7d252017-07-19 17:51:06 -07002075 if not hasattr(ad, "curl_capable"):
2076 try:
Jaineel3ee37012017-08-21 15:21:57 -07002077 out = ad.adb.shell("/data/curl --version")
Betty Zhouf3b7d252017-07-19 17:51:06 -07002078 if not out or "not found" in out:
2079 setattr(ad, "curl_capable", False)
2080 ad.log.info("curl is unavailable, use chrome to download file")
2081 else:
2082 setattr(ad, "curl_capable", True)
2083 except Exception:
2084 setattr(ad, "curl_capable", False)
2085 ad.log.info("curl is unavailable, use chrome to download file")
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002086 return ad.curl_capable
Betty Zhouf3b7d252017-07-19 17:51:06 -07002087
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002088
Betty Zhouf50cab32018-03-05 19:18:15 -08002089def start_youtube_video(ad, url="https://www.youtube.com/watch?v=VHF-XK0Vg1s"):
2090 ad.log.info("Open an youtube video")
2091 ad.ensure_screen_on()
2092 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
2093 if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
2094 ad.log.info("Started a video in youtube, audio is in MUSIC_state")
2095 else:
2096 ad.log.warning(
2097 "Started a video in youtube, but audio is not in MUSIC state")
2098
2099
Betty Zhou3b2de072018-03-15 16:46:26 -07002100def active_file_download_task(log, ad, file_name="5MB", method="curl"):
Betty Zhou86671922017-05-10 15:32:10 -07002101 # files available for download on the same website:
2102 # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
2103 # download file by adb command, as phone call will use sl4a
Betty Zhou86671922017-05-10 15:32:10 -07002104 file_map_dict = {
2105 '5MB': 5000000,
2106 '10MB': 10000000,
2107 '20MB': 20000000,
2108 '50MB': 50000000,
Betty Zhou461f3102017-08-04 17:04:44 -07002109 '100MB': 100000000,
Betty Zhou86671922017-05-10 15:32:10 -07002110 '200MB': 200000000,
Betty Zhou461f3102017-08-04 17:04:44 -07002111 '512MB': 512000000
Betty Zhou86671922017-05-10 15:32:10 -07002112 }
2113 file_size = file_map_dict.get(file_name)
2114 if not file_size:
2115 log.warning("file_name %s for download is not available", file_name)
2116 return False
Jaineel5719eb52017-09-12 12:57:07 -07002117 timeout = min(max(file_size / 100000, 600), 3600)
Betty Zhou86671922017-05-10 15:32:10 -07002118 output_path = "/sdcard/Download/" + file_name + ".zip"
Betty Zhou3468a8b2018-02-14 14:34:56 -08002119 url = "http://ipv4.download.thinkbroadband.com/" + file_name + ".zip"
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002120 if method == "sl4a":
2121 return (http_file_download_by_sl4a, (ad, url, output_path, file_size,
2122 True, timeout))
2123 if method == "curl" and check_curl_availability(ad):
2124 url = "http://146.148.91.8/download/" + file_name + ".zip"
2125 return (http_file_download_by_curl, (ad, url, output_path, file_size,
2126 True, timeout))
2127 elif method == "sl4a":
2128 return (http_file_download_by_sl4a, (ad, url, output_path, file_size,
2129 True, timeout))
2130 else:
2131 return (http_file_download_by_chrome, (ad, url, file_size, True,
2132 timeout))
Betty Zhou2e01bc82017-03-17 10:55:57 -07002133
2134
Betty Zhoua3f248f2018-03-05 17:33:49 -08002135def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002136 task = active_file_download_task(log, ad, file_name, method=method)
Betty Zhou2e01bc82017-03-17 10:55:57 -07002137 return task[0](*task[1])
2138
2139
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002140def verify_internet_connection_by_ping(log, ad, retries=1,
2141 expected_state=True):
Betty Zhou8e11e442017-03-30 20:00:34 -07002142 """Verify internet connection by ping test.
2143
2144 Args:
2145 log: log object
2146 ad: Android Device Object.
2147
2148 """
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002149 ip_addr = "54.230.144.105"
2150 for dest in ("www.google.com", "www.amazon.com", ip_addr):
2151 for i in range(retries):
2152 ad.log.info("Ping %s - attempt %d", dest, i + 1)
Jaineel6d747722017-11-20 15:03:02 -08002153 result = adb_shell_ping(
2154 ad, count=5, timeout=60, loss_tolerance=40, dest_ip=dest)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002155 if result == expected_state:
2156 ad.log.info(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07002157 "Internet connection by pinging to %s is %s as expected",
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002158 dest, expected_state)
2159 if dest == ip_addr:
2160 ad.log.warning("Suspect dns failure")
2161 ad.log.info("DNS config: %s",
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07002162 ad.adb.shell("getprop | grep dns").replace(
2163 "\n", " "))
2164 return False
Jaineel6d747722017-11-20 15:03:02 -08002165 return True
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002166 else:
2167 ad.log.error(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07002168 "Internet connection test by pinging %s is %s, expecting %s",
2169 dest, result, expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07002170 return False
2171
2172
2173def verify_internet_connection(log, ad, retries=3, expected_state=True):
2174 """Verify internet connection by ping test and http connection.
2175
2176 Args:
2177 log: log object
2178 ad: Android Device Object.
2179
2180 """
2181 if verify_internet_connection_by_ping(
2182 log, ad, retries=retries, expected_state=expected_state):
2183 return True
2184 for url in ("https://www.google.com", "https://www.amazon.com"):
2185 if verify_http_connection(
2186 log, ad, url=url, retry=retries,
2187 expected_state=expected_state):
2188 return True
Betty Zhoue123c672018-03-21 19:57:11 -07002189 ad.log.info("DNS config: %s", " ".join(
2190 ad.adb.shell("getprop | grep dns").split()))
Betty Zhoufe726dc2018-04-25 19:31:33 -07002191 ad.log.info("Interface info:\n%s", ad.adb.shell("ifconfig"))
Betty Zhoue123c672018-03-21 19:57:11 -07002192 ad.log.info("NetworkAgentInfo: %s",
2193 ad.adb.shell("dumpsys connectivity | grep NetworkAgentInfo"))
Jaineel6c576c92017-09-11 10:02:23 -07002194 return False
Betty Zhou8e11e442017-03-30 20:00:34 -07002195
2196
Betty Zhou2e01bc82017-03-17 10:55:57 -07002197def iperf_test_by_adb(log,
2198 ad,
2199 iperf_server,
Jaineel6f88b5b2017-04-17 09:58:46 -07002200 port_num=None,
2201 reverse=False,
Betty Zhou2e01bc82017-03-17 10:55:57 -07002202 timeout=180,
Jaineel6f88b5b2017-04-17 09:58:46 -07002203 limit_rate=None,
Betty Zhou2e01bc82017-03-17 10:55:57 -07002204 omit=10,
Jaineele74e8e12017-05-08 15:59:42 -07002205 ipv6=False,
Patrick Chiang75b89862017-10-13 17:02:29 -07002206 rate_dict=None,
2207 blocking=True,
2208 log_file_path=None):
Betty Zhou2e01bc82017-03-17 10:55:57 -07002209 """Iperf test by adb.
2210
2211 Args:
2212 log: log object
2213 ad: Android Device Object.
Jaineel6f88b5b2017-04-17 09:58:46 -07002214 iperf_Server: The iperf host url".
2215 port_num: TCP/UDP server port
Betty Zhou2e01bc82017-03-17 10:55:57 -07002216 timeout: timeout for file download to complete.
2217 limit_rate: iperf bandwidth option. None by default
2218 omit: the omit option provided in iperf command.
2219 """
2220 iperf_option = "-t %s -O %s -J" % (timeout, omit)
2221 if limit_rate: iperf_option += " -b %s" % limit_rate
Jaineel6f88b5b2017-04-17 09:58:46 -07002222 if port_num: iperf_option += " -p %s" % port_num
Betty Zhou2e01bc82017-03-17 10:55:57 -07002223 if ipv6: iperf_option += " -6"
Jaineel6f88b5b2017-04-17 09:58:46 -07002224 if reverse: iperf_option += " -R"
Betty Zhou2e01bc82017-03-17 10:55:57 -07002225 try:
Patrick Chiang75b89862017-10-13 17:02:29 -07002226 if log_file_path:
2227 ad.adb.shell("rm %s" % log_file_path, ignore_status=True)
Betty Zhou2e01bc82017-03-17 10:55:57 -07002228 ad.log.info("Running adb iperf test with server %s", iperf_server)
Patrick Chiang75b89862017-10-13 17:02:29 -07002229 if not blocking:
2230 ad.run_iperf_client_nb(
2231 iperf_server,
2232 iperf_option,
2233 timeout=timeout + 60,
2234 log_file_path=log_file_path)
2235 return True
Betty Zhou2e01bc82017-03-17 10:55:57 -07002236 result, data = ad.run_iperf_client(
2237 iperf_server, iperf_option, timeout=timeout + 60)
2238 ad.log.info("Iperf test result with server %s is %s", iperf_server,
2239 result)
2240 if result:
2241 data_json = json.loads(''.join(data))
2242 tx_rate = data_json['end']['sum_sent']['bits_per_second']
2243 rx_rate = data_json['end']['sum_received']['bits_per_second']
2244 ad.log.info(
2245 'iPerf3 upload speed is %sbps, download speed is %sbps',
2246 tx_rate, rx_rate)
Jaineele74e8e12017-05-08 15:59:42 -07002247 if rate_dict is not None:
2248 rate_dict["Uplink"] = tx_rate
2249 rate_dict["Downlink"] = rx_rate
Betty Zhou2e01bc82017-03-17 10:55:57 -07002250 return result
2251 except Exception as e:
Betty Zhouf809c5c2017-03-21 14:55:59 -07002252 ad.log.warning("Fail to run iperf test with exception %s", e)
Betty Zhou2e01bc82017-03-17 10:55:57 -07002253 return False
2254
Betty Zhoue955be22017-04-12 17:28:05 -07002255
Betty Zhou86671922017-05-10 15:32:10 -07002256def http_file_download_by_curl(ad,
2257 url,
2258 out_path=None,
2259 expected_file_size=None,
2260 remove_file_after_check=True,
Betty Zhou35ea5952017-06-26 10:01:09 -07002261 timeout=3600,
Betty Zhou86671922017-05-10 15:32:10 -07002262 limit_rate=None,
2263 retry=3):
Betty Zhouccd171d2017-02-13 15:11:33 -08002264 """Download http file by adb curl.
2265
2266 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08002267 ad: Android Device Object.
2268 url: The url that file to be downloaded from".
2269 out_path: Optional. Where to download file to.
2270 out_path is /sdcard/Download/ by default.
2271 expected_file_size: Optional. Provided if checking the download file meet
2272 expected file size in unit of byte.
2273 remove_file_after_check: Whether to remove the downloaded file after
2274 check.
2275 timeout: timeout for file download to complete.
2276 limit_rate: download rate in bps. None, if do not apply rate limit.
2277 retry: the retry request times provided in curl command.
2278 """
Betty Zhoucea4b432017-07-20 18:29:24 -07002279 file_directory, file_name = _generate_file_directory_and_file_name(
2280 url, out_path)
2281 file_path = os.path.join(file_directory, file_name)
Jaineel3ee37012017-08-21 15:21:57 -07002282 curl_cmd = "/data/curl"
Betty Zhouccd171d2017-02-13 15:11:33 -08002283 if limit_rate:
2284 curl_cmd += " --limit-rate %s" % limit_rate
2285 if retry:
2286 curl_cmd += " --retry %s" % retry
Betty Zhoucea4b432017-07-20 18:29:24 -07002287 curl_cmd += " --url %s > %s" % (url, file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08002288 try:
Betty Zhoucea4b432017-07-20 18:29:24 -07002289 ad.log.info("Download %s to %s by adb shell command %s", url,
2290 file_path, curl_cmd)
Betty Zhouccd171d2017-02-13 15:11:33 -08002291 ad.adb.shell(curl_cmd, timeout=timeout)
Betty Zhoucea4b432017-07-20 18:29:24 -07002292 if _check_file_existance(ad, file_path, expected_file_size):
2293 ad.log.info("%s is downloaded to %s successfully", url, file_path)
Betty Zhoue57ab692018-03-09 18:39:30 -08002294 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08002295 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002296 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08002297 return False
2298 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07002299 ad.log.warning("Download %s failed with exception %s", url, e)
Betty Zhouccd171d2017-02-13 15:11:33 -08002300 return False
2301 finally:
2302 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07002303 ad.log.info("Remove the downloaded file %s", file_path)
2304 ad.adb.shell("rm %s" % file_path, ignore_status=True)
2305
2306
2307def open_url_by_adb(ad, url):
Betty Zhou8da03782017-07-28 18:02:24 -07002308 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
Betty Zhouccd171d2017-02-13 15:11:33 -08002309
2310
Betty Zhou86671922017-05-10 15:32:10 -07002311def http_file_download_by_chrome(ad,
2312 url,
2313 expected_file_size=None,
2314 remove_file_after_check=True,
Betty Zhou35ea5952017-06-26 10:01:09 -07002315 timeout=3600):
Betty Zhou86671922017-05-10 15:32:10 -07002316 """Download http file by chrome.
2317
2318 Args:
2319 ad: Android Device Object.
2320 url: The url that file to be downloaded from".
Betty Zhou86671922017-05-10 15:32:10 -07002321 expected_file_size: Optional. Provided if checking the download file meet
2322 expected file size in unit of byte.
2323 remove_file_after_check: Whether to remove the downloaded file after
2324 check.
2325 timeout: timeout for file download to complete.
2326 """
Betty Zhou92437702018-02-07 19:49:07 -08002327 chrome_apk = "com.android.chrome"
Betty Zhoucea4b432017-07-20 18:29:24 -07002328 file_directory, file_name = _generate_file_directory_and_file_name(
Betty Zhoubcffe442017-07-05 17:27:55 -07002329 url, "/sdcard/Download/")
Betty Zhoucea4b432017-07-20 18:29:24 -07002330 file_path = os.path.join(file_directory, file_name)
Betty Zhouf17f0692017-06-28 13:10:31 -07002331 # Remove pre-existing file
Betty Zhou92437702018-02-07 19:49:07 -08002332 ad.force_stop_apk(chrome_apk)
markdr6607bf12018-01-02 14:45:38 -08002333 file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
Betty Zhoue5f61b32018-01-26 10:48:00 -08002334 ad.adb.shell("rm -f %s" % file_to_be_delete)
2335 ad.adb.shell("rm -rf /sdcard/Download/.*")
2336 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou92437702018-02-07 19:49:07 -08002337 data_accounting = {
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002338 "total_rx_bytes": ad.droid.getTotalRxBytes(),
2339 "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
2340 "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
2341 "chrome_mobile_data_usage": get_mobile_data_usage(
2342 ad, None, chrome_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08002343 }
Betty Zhou92437702018-02-07 19:49:07 -08002344 ad.log.info("Before downloading: %s", data_accounting)
Betty Zhoucea4b432017-07-20 18:29:24 -07002345 ad.log.info("Download %s with timeout %s", url, timeout)
Betty Zhouc80af152018-04-27 18:22:17 -07002346 ad.ensure_screen_on()
Betty Zhoucea4b432017-07-20 18:29:24 -07002347 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07002348 elapse_time = 0
Betty Zhou92437702018-02-07 19:49:07 -08002349 result = True
Betty Zhou86671922017-05-10 15:32:10 -07002350 while elapse_time < timeout:
2351 time.sleep(30)
Betty Zhoucea4b432017-07-20 18:29:24 -07002352 if _check_file_existance(ad, file_path, expected_file_size):
2353 ad.log.info("%s is downloaded successfully", url)
Betty Zhou86671922017-05-10 15:32:10 -07002354 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07002355 ad.log.info("Remove the downloaded file %s", file_path)
Betty Zhoue5f61b32018-01-26 10:48:00 -08002356 ad.adb.shell("rm -f %s" % file_to_be_delete)
2357 ad.adb.shell("rm -rf /sdcard/Download/.*")
2358 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou08c1a572018-02-13 20:07:55 -08002359 #time.sleep(30)
Betty Zhou92437702018-02-07 19:49:07 -08002360 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08002361 "mobile_rx_bytes":
2362 ad.droid.getMobileRxBytes(),
2363 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002364 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08002365 "chrome_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002366 get_mobile_data_usage(ad, None, chrome_apk)
Betty Zhou92437702018-02-07 19:49:07 -08002367 }
2368 ad.log.info("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08002369 accounting_diff = {
2370 key: value - data_accounting[key]
2371 for key, value in new_data_accounting.items()
2372 }
Betty Zhou92437702018-02-07 19:49:07 -08002373 ad.log.info("Data accounting difference: %s", accounting_diff)
Betty Zhou1b302fd2017-11-17 11:43:09 -08002374 if getattr(ad, "on_mobile_data", False):
Betty Zhou92437702018-02-07 19:49:07 -08002375 for key, value in accounting_diff.items():
2376 if value < expected_file_size:
Betty Zhou02571f52018-02-16 14:11:16 -08002377 ad.log.warning("%s diff is %s less than %s", key,
2378 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08002379 ad.data_accounting["%s_failure" % key] += 1
Betty Zhou1b302fd2017-11-17 11:43:09 -08002380 else:
Betty Zhou92437702018-02-07 19:49:07 -08002381 for key, value in accounting_diff.items():
2382 if value >= expected_file_size:
2383 ad.log.error("%s diff is %s. File download is "
2384 "consuming mobile data", key, value)
2385 result = False
2386 return result
Betty Zhoucea4b432017-07-20 18:29:24 -07002387 elif _check_file_existance(ad, "%s.crdownload" % file_path):
2388 ad.log.info("Chrome is downloading %s", url)
2389 elif elapse_time < 60:
2390 # download not started, retry download wit chrome again
2391 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07002392 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002393 ad.log.error("Unable to download file from %s", url)
2394 break
2395 elapse_time += 30
Betty Zhouf3366012017-11-21 18:23:20 -08002396 ad.log.warning("Fail to download file from %s", url)
Betty Zhou95ed1862017-07-21 13:29:02 -07002397 ad.force_stop_apk("com.android.chrome")
Betty Zhoue5f61b32018-01-26 10:48:00 -08002398 ad.adb.shell("rm -f %s" % file_to_be_delete)
2399 ad.adb.shell("rm -rf /sdcard/Download/.*")
2400 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou86671922017-05-10 15:32:10 -07002401 return False
2402
2403
Betty Zhou92437702018-02-07 19:49:07 -08002404def http_file_download_by_sl4a(ad,
Betty Zhouccd171d2017-02-13 15:11:33 -08002405 url,
2406 out_path=None,
2407 expected_file_size=None,
2408 remove_file_after_check=True,
2409 timeout=300):
2410 """Download http file by sl4a RPC call.
2411
2412 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08002413 ad: Android Device Object.
2414 url: The url that file to be downloaded from".
2415 out_path: Optional. Where to download file to.
2416 out_path is /sdcard/Download/ by default.
2417 expected_file_size: Optional. Provided if checking the download file meet
2418 expected file size in unit of byte.
2419 remove_file_after_check: Whether to remove the downloaded file after
2420 check.
2421 timeout: timeout for file download to complete.
2422 """
Betty Zhouee311052017-12-19 13:09:56 -08002423 file_folder, file_name = _generate_file_directory_and_file_name(
2424 url, out_path)
Betty Zhoucea4b432017-07-20 18:29:24 -07002425 file_path = os.path.join(file_folder, file_name)
Betty Zhou08c1a572018-02-13 20:07:55 -08002426 ad.adb.shell("rm -f %s" % file_path)
Betty Zhou92437702018-02-07 19:49:07 -08002427 accounting_apk = SL4A_APK_NAME
2428 result = True
Betty Zhouccd171d2017-02-13 15:11:33 -08002429 try:
Betty Zhou08c1a572018-02-13 20:07:55 -08002430 if not getattr(ad, "downloading_droid", None):
2431 ad.downloading_droid, ad.downloading_ed = ad.get_droid()
2432 ad.downloading_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08002433 else:
2434 try:
2435 if not ad.downloading_droid.is_live:
2436 ad.downloading_droid, ad.downloading_ed = ad.get_droid()
2437 ad.downloading_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08002438 except Exception:
2439 ad.log.info("Start new sl4a session for file download")
Betty Zhouf31dffe2018-02-23 19:29:28 -08002440 ad.downloading_droid, ad.downloading_ed = ad.get_droid()
2441 ad.downloading_ed.start()
Betty Zhou92437702018-02-07 19:49:07 -08002442 data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08002443 "mobile_rx_bytes":
2444 ad.droid.getMobileRxBytes(),
2445 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002446 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08002447 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002448 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08002449 }
Betty Zhou92437702018-02-07 19:49:07 -08002450 ad.log.info("Before downloading: %s", data_accounting)
Betty Zhouccd171d2017-02-13 15:11:33 -08002451 ad.log.info("Download file from %s to %s by sl4a RPC call", url,
Betty Zhoucea4b432017-07-20 18:29:24 -07002452 file_path)
Betty Zhou14c08372018-02-15 10:26:23 -08002453 try:
Betty Zhou02571f52018-02-16 14:11:16 -08002454 ad.downloading_droid.httpDownloadFile(
2455 url, file_path, timeout=timeout)
Betty Zhou14c08372018-02-15 10:26:23 -08002456 except Exception as e:
2457 ad.log.warning("SL4A file download error: %s", e)
2458 return False
Betty Zhoucea4b432017-07-20 18:29:24 -07002459 if _check_file_existance(ad, file_path, expected_file_size):
2460 ad.log.info("%s is downloaded successfully", url)
Betty Zhou92437702018-02-07 19:49:07 -08002461 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08002462 "mobile_rx_bytes":
2463 ad.droid.getMobileRxBytes(),
2464 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002465 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08002466 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002467 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou92437702018-02-07 19:49:07 -08002468 }
2469 ad.log.info("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08002470 accounting_diff = {
2471 key: value - data_accounting[key]
2472 for key, value in new_data_accounting.items()
2473 }
Betty Zhou92437702018-02-07 19:49:07 -08002474 ad.log.info("Data accounting difference: %s", accounting_diff)
2475 if getattr(ad, "on_mobile_data", False):
2476 for key, value in accounting_diff.items():
2477 if value < expected_file_size:
Betty Zhou02571f52018-02-16 14:11:16 -08002478 ad.log.warning("%s diff is %s less than %s", key,
2479 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08002480 ad.data_accounting["%s_failure"] += 1
2481 else:
2482 for key, value in accounting_diff.items():
2483 if value >= expected_file_size:
2484 ad.log.error("%s diff is %s. File download is "
2485 "consuming mobile data", key, value)
2486 result = False
2487 return result
Betty Zhouccd171d2017-02-13 15:11:33 -08002488 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07002489 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08002490 return False
2491 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07002492 ad.log.error("Download %s failed with exception %s", url, e)
Betty Zhouccd171d2017-02-13 15:11:33 -08002493 raise
2494 finally:
2495 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07002496 ad.log.info("Remove the downloaded file %s", file_path)
2497 ad.adb.shell("rm %s" % file_path, ignore_status=True)
Betty Zhouccd171d2017-02-13 15:11:33 -08002498
Betty Zhou2cf788e2017-06-27 17:25:53 -07002499
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002500def get_mobile_data_usage(ad, subscriber_id=None, apk=None):
Betty Zhouf3366012017-11-21 18:23:20 -08002501 if not subscriber_id:
2502 subscriber_id = ad.droid.telephonyGetSubscriberId()
Betty Zhoua3f248f2018-03-05 17:33:49 -08002503
Betty Zhouf1cc3b62018-02-28 12:02:05 -08002504 if not getattr(ad, "data_metering_begin_time", None) or not getattr(
2505 ad, "data_metering_end_time", None):
2506 current_time = int(time.time() * 1000)
2507 setattr(ad, "data_metering_begin_time",
2508 current_time - 24 * 60 * 60 * 1000)
2509 setattr(ad, "data_metering_end_time",
2510 current_time + 30 * 24 * 60 * 60 * 1000)
2511 begin_time = ad.data_metering_begin_time
2512 end_time = ad.data_metering_end_time
Betty Zhoua3f248f2018-03-05 17:33:49 -08002513
Betty Zhou92437702018-02-07 19:49:07 -08002514 if apk:
2515 uid = ad.get_apk_uid(apk)
Betty Zhoua3f248f2018-03-05 17:33:49 -08002516 ad.log.info("apk %s uid = %s", apk, uid)
2517 func = ad.droid.connectivityQueryDetailsForUid
2518 func_args = [[TYPE_MOBILE, subscriber_id, begin_time, end_time, uid],
2519 [subscriber_id, begin_time, end_time, uid]]
Betty Zhou92437702018-02-07 19:49:07 -08002520 else:
Betty Zhoua3f248f2018-03-05 17:33:49 -08002521 func = ad.droid.connectivityQuerySummaryForDevice
2522 func_args = [[TYPE_MOBILE, subscriber_id, begin_time, end_time],
2523 [subscriber_id, begin_time, end_time]]
2524 for args in func_args:
Betty Zhou92437702018-02-07 19:49:07 -08002525 try:
Betty Zhoua3f248f2018-03-05 17:33:49 -08002526 usage = func(*args)
2527 ad.log.info("%s mobile data usage is %s", apk
2528 if apk else "Subscriber", usage)
2529 return usage
2530 except Exception as e:
2531 ad.log.warning(e)
2532 return None
Betty Zhouf3366012017-11-21 18:23:20 -08002533
2534
2535def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
2536 if not subscriber_id:
2537 subscriber_id = ad.droid.telephonyGetSubscriberId()
2538 ad.log.info("Set subscriber mobile data usage limit to %s", limit)
Betty Zhou10f887e2018-04-10 12:45:00 -07002539 ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
Betty Zhouf3366012017-11-21 18:23:20 -08002540 ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
2541
2542
2543def remove_mobile_data_usage_limit(ad, subscriber_id=None):
2544 if not subscriber_id:
2545 subscriber_id = ad.droid.telephonyGetSubscriberId()
Betty Zhoue57ab692018-03-09 18:39:30 -08002546 ad.log.debug("Remove subscriber mobile data usage limit")
Betty Zhou10f887e2018-04-10 12:45:00 -07002547 ad.droid.logV(
2548 "Setting subscriber mobile data usage limit to -1, unlimited")
Betty Zhouf3366012017-11-21 18:23:20 -08002549 ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
2550
2551
Betty Zhouae9d6a82018-02-15 20:05:34 -08002552def trigger_modem_crash(ad, timeout=120):
Jaineel40884782017-06-08 15:53:39 -07002553 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem"
Betty Zhouae9d6a82018-02-15 20:05:34 -08002554 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd)
2555 ad.adb.shell(cmd)
2556 time.sleep(timeout)
Jaineel40884782017-06-08 15:53:39 -07002557 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08002558
Betty Zhou2cf788e2017-06-27 17:25:53 -07002559
Betty Zhouae9d6a82018-02-15 20:05:34 -08002560def trigger_modem_crash_by_modem(ad, timeout=120):
2561 begin_time = get_current_epoch_time()
2562 ad.adb.shell(
2563 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
2564 stop_qxdm_logger(ad)
Betty Zhou02571f52018-02-16 14:11:16 -08002565 cmd = ('am instrument -w -e request "4b 25 03 00" '
2566 '"com.google.mdstest/com.google.mdstest.instrument.'
2567 'ModemCommandInstrumentation"')
2568 ad.log.info("Crash modem by %s", cmd)
2569 ad.adb.shell(cmd, ignore_status=True)
2570 time.sleep(timeout) # sleep time for sl4a stability
Betty Zhouae9d6a82018-02-15 20:05:34 -08002571 reasons = ad.search_logcat("modem subsystem failure reason", begin_time)
2572 if reasons:
2573 ad.log.info("Modem crash is triggered successfully")
2574 ad.log.info(reasons[-1]["log_message"])
2575 return True
2576 else:
Betty Zhoufe726dc2018-04-25 19:31:33 -07002577 ad.log.warning("There is no modem subsystem failure reason logcat")
Betty Zhouae9d6a82018-02-15 20:05:34 -08002578 return False
2579
2580
Ang Li73697b32015-12-03 00:41:53 +00002581def _connection_state_change(_event, target_state, connection_type):
2582 if connection_type:
2583 if 'TypeName' not in _event['data']:
2584 return False
2585 connection_type_string_in_event = _event['data']['TypeName']
Nathan Harold123c9da2015-12-30 16:33:25 -08002586 cur_type = connection_type_from_type_string(
2587 connection_type_string_in_event)
Ang Li73697b32015-12-03 00:41:53 +00002588 if cur_type != connection_type:
2589 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08002590 "_connection_state_change expect: %s, received: %s <type %s>",
2591 connection_type, connection_type_string_in_event, cur_type)
Ang Li73697b32015-12-03 00:41:53 +00002592 return False
2593
Betty Zhouee311052017-12-19 13:09:56 -08002594 if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
Ang Li73697b32015-12-03 00:41:53 +00002595 return True
2596 return False
2597
2598
Nathan Harold123c9da2015-12-30 16:33:25 -08002599def wait_for_cell_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08002600 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00002601 """Wait for data connection status to be expected value for default
2602 data subscription.
2603
2604 Wait for the data connection status to be DATA_STATE_CONNECTED
2605 or DATA_STATE_DISCONNECTED.
2606
2607 Args:
2608 log: Log object.
2609 ad: Android Device Object.
2610 state: Expected status: True or False.
2611 If True, it will wait for status to be DATA_STATE_CONNECTED.
2612 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2613 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08002614 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00002615
2616 Returns:
2617 True if success.
2618 False if failed.
2619 """
Yang Liu963c93c2016-04-05 10:52:00 -07002620 sub_id = get_default_data_sub_id(ad)
Betty Zhouee311052017-12-19 13:09:56 -08002621 return wait_for_cell_data_connection_for_subscription(
2622 log, ad, sub_id, state, timeout_value)
Nathan Harold123c9da2015-12-30 16:33:25 -08002623
Ang Li73697b32015-12-03 00:41:53 +00002624
2625def _is_data_connection_state_match(log, ad, expected_data_connection_state):
Nathan Harold123c9da2015-12-30 16:33:25 -08002626 return (expected_data_connection_state ==
2627 ad.droid.telephonyGetDataConnectionState())
Ang Li73697b32015-12-03 00:41:53 +00002628
Ang Li73697b32015-12-03 00:41:53 +00002629
Nathan Harold123c9da2015-12-30 16:33:25 -08002630def _is_network_connected_state_match(log, ad,
2631 expected_network_connected_state):
2632 return (expected_network_connected_state ==
2633 ad.droid.connectivityNetworkIsConnected())
2634
2635
2636def wait_for_cell_data_connection_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08002637 log,
2638 ad,
2639 sub_id,
2640 state,
2641 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00002642 """Wait for data connection status to be expected value for specified
2643 subscrption id.
2644
2645 Wait for the data connection status to be DATA_STATE_CONNECTED
2646 or DATA_STATE_DISCONNECTED.
2647
2648 Args:
2649 log: Log object.
2650 ad: Android Device Object.
2651 sub_id: subscription Id
2652 state: Expected status: True or False.
2653 If True, it will wait for status to be DATA_STATE_CONNECTED.
2654 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2655 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08002656 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00002657
2658 Returns:
2659 True if success.
2660 False if failed.
2661 """
Yang Liu8e6adff2016-02-05 10:24:04 -08002662 state_str = {
2663 True: DATA_STATE_CONNECTED,
2664 False: DATA_STATE_DISCONNECTED
Ang Li73697b32015-12-03 00:41:53 +00002665 }[state]
2666
Betty Zhou68fc0d02017-04-26 13:42:54 -07002667 data_state = ad.droid.telephonyGetDataConnectionState()
2668 if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
2669 return True
Betty Zhouc9f723b2018-04-10 18:08:21 -07002670
Betty Zhou287f9df2018-01-23 10:57:55 -08002671 ad.ed.clear_events(EventDataConnectionStateChanged)
Nathan Harold123c9da2015-12-30 16:33:25 -08002672 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
2673 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00002674 ad.droid.connectivityStartTrackingConnectivityStateChange()
2675 try:
Betty Zhouc9f723b2018-04-10 18:08:21 -07002676 ad.log.info("User data enabled for sub_id %s: %s", sub_id,
2677 ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
Yang Liuaed3eef2015-12-15 18:40:25 -08002678 data_state = ad.droid.telephonyGetDataConnectionState()
Betty Zhouc9f723b2018-04-10 18:08:21 -07002679 ad.log.info("Data connection state is %s", data_state)
2680 ad.log.info("Network is connected: %s",
2681 ad.droid.connectivityNetworkIsConnected())
Ang Li73697b32015-12-03 00:41:53 +00002682 if data_state == state_str:
Nathan Harold123c9da2015-12-30 16:33:25 -08002683 return _wait_for_nw_data_connection(
2684 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00002685
2686 try:
Betty Zhou1c8c8d42018-03-14 12:43:50 -07002687 ad.ed.wait_for_event(
Nathan Harold7642fc92016-05-02 18:29:11 -07002688 EventDataConnectionStateChanged,
2689 is_event_match,
2690 timeout=timeout_value,
Yang Liu8e6adff2016-02-05 10:24:04 -08002691 field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
2692 value=state_str)
Ang Li73697b32015-12-03 00:41:53 +00002693 except Empty:
Betty Zhouf25ce442017-03-03 14:28:36 -08002694 ad.log.info("No expected event EventDataConnectionStateChanged %s",
2695 state_str)
Ang Li73697b32015-12-03 00:41:53 +00002696
Yang Liudf164e32016-01-07 16:49:32 -08002697 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00002698 # data connection state.
2699 # Otherwise, the network state will not be correct.
2700 # The bug is tracked here: b/20921915
Ang Li73697b32015-12-03 00:41:53 +00002701
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002702 # Previously we use _is_data_connection_state_match,
2703 # but telephonyGetDataConnectionState sometimes return wrong value.
2704 # The bug is tracked here: b/22612607
2705 # So we use _is_network_connected_state_match.
Ang Li73697b32015-12-03 00:41:53 +00002706
Betty Zhou58ad52a2018-02-08 16:38:16 -08002707 if _wait_for_droid_in_state(log, ad, timeout_value,
Nathan Harold123c9da2015-12-30 16:33:25 -08002708 _is_network_connected_state_match, state):
2709 return _wait_for_nw_data_connection(
2710 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00002711 else:
2712 return False
2713
2714 finally:
Nathan Harold123c9da2015-12-30 16:33:25 -08002715 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
2716 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00002717
Nathan Harold123c9da2015-12-30 16:33:25 -08002718
2719def wait_for_wifi_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08002720 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00002721 """Wait for data connection status to be expected value and connection is by WiFi.
2722
2723 Args:
2724 log: Log object.
2725 ad: Android Device Object.
2726 state: Expected status: True or False.
2727 If True, it will wait for status to be DATA_STATE_CONNECTED.
2728 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2729 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08002730 This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
Ang Li73697b32015-12-03 00:41:53 +00002731
2732 Returns:
2733 True if success.
2734 False if failed.
2735 """
Betty Zhoua37acd32017-02-23 20:04:24 -08002736 ad.log.info("wait_for_wifi_data_connection")
Nathan Harold123c9da2015-12-30 16:33:25 -08002737 return _wait_for_nw_data_connection(
2738 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00002739
2740
Betty Zhou02571f52018-02-16 14:11:16 -08002741def wait_for_data_connection(
2742 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00002743 """Wait for data connection status to be expected value.
2744
2745 Wait for the data connection status to be DATA_STATE_CONNECTED
2746 or DATA_STATE_DISCONNECTED.
2747
2748 Args:
2749 log: Log object.
2750 ad: Android Device Object.
2751 state: Expected status: True or False.
2752 If True, it will wait for status to be DATA_STATE_CONNECTED.
2753 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2754 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08002755 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00002756
2757 Returns:
2758 True if success.
2759 False if failed.
2760 """
2761 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
2762
2763
Nathan Harold123c9da2015-12-30 16:33:25 -08002764def _wait_for_nw_data_connection(
2765 log,
2766 ad,
2767 is_connected,
2768 connection_type=None,
Betty Zhou58ad52a2018-02-08 16:38:16 -08002769 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00002770 """Wait for data connection status to be expected value.
2771
2772 Wait for the data connection status to be DATA_STATE_CONNECTED
2773 or DATA_STATE_DISCONNECTED.
2774
2775 Args:
2776 log: Log object.
2777 ad: Android Device Object.
2778 is_connected: Expected connection status: True or False.
2779 If True, it will wait for status to be DATA_STATE_CONNECTED.
2780 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
2781 connection_type: expected connection type.
2782 This is optional, if it is None, then any connection type will return True.
2783 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08002784 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00002785
2786 Returns:
2787 True if success.
2788 False if failed.
2789 """
Betty Zhoue34f9e22018-01-23 18:58:24 -08002790 ad.ed.clear_events(EventConnectivityChanged)
Ang Li73697b32015-12-03 00:41:53 +00002791 ad.droid.connectivityStartTrackingConnectivityStateChange()
2792 try:
2793 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
2794 if is_connected == cur_data_connection_state:
2795 current_type = get_internet_connection_type(log, ad)
Betty Zhoue955be22017-04-12 17:28:05 -07002796 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00002797 if not connection_type:
2798 return True
2799 else:
2800 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08002801 ad.log.info("data connection not on %s!", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00002802 return True
2803 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08002804 ad.log.info("data connection on %s as expected",
2805 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00002806 return True
2807 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08002808 ad.log.info("current data connection state: %s target: %s",
2809 cur_data_connection_state, is_connected)
Ang Li73697b32015-12-03 00:41:53 +00002810
2811 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08002812 event = ad.ed.wait_for_event(
2813 EventConnectivityChanged, _connection_state_change,
2814 timeout_value, is_connected, connection_type)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07002815 ad.log.info("Got event: %s", event)
Ang Li73697b32015-12-03 00:41:53 +00002816 except Empty:
2817 pass
2818
Nathan Harold123c9da2015-12-30 16:33:25 -08002819 log.info(
2820 "_wait_for_nw_data_connection: check connection after wait event.")
Yang Liudf164e32016-01-07 16:49:32 -08002821 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00002822 # data connection state.
2823 # Otherwise, the network state will not be correct.
2824 # The bug is tracked here: b/20921915
Betty Zhou02571f52018-02-16 14:11:16 -08002825 if _wait_for_droid_in_state(log, ad, timeout_value,
2826 _is_network_connected_state_match,
2827 is_connected):
Ang Li73697b32015-12-03 00:41:53 +00002828 current_type = get_internet_connection_type(log, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08002829 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00002830 if not connection_type:
2831 return True
2832 else:
2833 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08002834 ad.log.info("data connection not on %s", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00002835 return True
2836 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08002837 ad.log.info("after event wait, data connection on %s",
2838 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00002839 return True
2840 else:
2841 return False
2842 else:
2843 return False
2844 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -08002845 ad.log.error("Exception error %s", str(e))
Ang Li73697b32015-12-03 00:41:53 +00002846 return False
2847 finally:
2848 ad.droid.connectivityStopTrackingConnectivityStateChange()
2849
Nathan Harold123c9da2015-12-30 16:33:25 -08002850
Betty Zhou2cf788e2017-06-27 17:25:53 -07002851def get_cell_data_roaming_state_by_adb(ad):
2852 """Get Cell Data Roaming state. True for enabled, False for disabled"""
2853 adb_str = {"1": True, "0": False}
2854 out = ad.adb.shell("settings get global data_roaming")
2855 return adb_str[out]
2856
2857
2858def get_cell_data_roaming_state_by_adb(ad):
2859 """Get Cell Data Roaming state. True for enabled, False for disabled"""
2860 state_mapping = {"1": True, "0": False}
2861 return state_mapping[ad.adb.shell("settings get global data_roaming")]
2862
2863
2864def set_cell_data_roaming_state_by_adb(ad, state):
2865 """Set Cell Data Roaming state."""
2866 state_mapping = {True: "1", False: "0"}
2867 ad.log.info("Set data roaming to %s", state)
2868 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state])
2869
2870
Betty Zhou9e2bf402017-02-01 19:04:09 -08002871def toggle_cell_data_roaming(ad, state):
2872 """Enable cell data roaming for default data subscription.
2873
2874 Wait for the data roaming status to be DATA_STATE_CONNECTED
2875 or DATA_STATE_DISCONNECTED.
2876
2877 Args:
2878 log: Log object.
2879 ad: Android Device Object.
2880 state: True or False for enable or disable cell data roaming.
2881
2882 Returns:
2883 True if success.
2884 False if failed.
2885 """
2886 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state]
2887 action_str = {True: "Enable", False: "Disable"}[state]
2888 if ad.droid.connectivityCheckDataRoamingMode() == state:
2889 ad.log.info("Data roaming is already in state %s", state)
2890 return True
2891 if not ad.droid.connectivitySetDataRoaming(state_int):
2892 ad.error.info("Fail to config data roaming into state %s", state)
2893 return False
2894 if ad.droid.connectivityCheckDataRoamingMode() == state:
2895 ad.log.info("Data roaming is configured into state %s", state)
2896 return True
2897 else:
2898 ad.log.error("Data roaming is not configured into state %s", state)
2899 return False
2900
2901
Ang Li73697b32015-12-03 00:41:53 +00002902def verify_incall_state(log, ads, expected_status):
2903 """Verify phones in incall state or not.
2904
2905 Verify if all phones in the array <ads> are in <expected_status>.
2906
2907 Args:
2908 log: Log object.
2909 ads: Array of Android Device Object. All droid in this array will be tested.
2910 expected_status: If True, verify all Phones in incall state.
2911 If False, verify all Phones not in incall state.
2912
2913 """
2914 result = True
2915 for ad in ads:
2916 if ad.droid.telecomIsInCall() is not expected_status:
Betty Zhoua37acd32017-02-23 20:04:24 -08002917 ad.log.error("InCall status:%s, expected:%s",
2918 ad.droid.telecomIsInCall(), expected_status)
Ang Li73697b32015-12-03 00:41:53 +00002919 result = False
2920 return result
2921
Nathan Harold123c9da2015-12-30 16:33:25 -08002922
Ang Li73697b32015-12-03 00:41:53 +00002923def verify_active_call_number(log, ad, expected_number):
2924 """Verify the number of current active call.
2925
2926 Verify if the number of current active call in <ad> is
2927 equal to <expected_number>.
2928
2929 Args:
2930 ad: Android Device Object.
2931 expected_number: Expected active call number.
2932 """
2933 calls = ad.droid.telecomCallGetCallIds()
2934 if calls is None:
2935 actual_number = 0
2936 else:
2937 actual_number = len(calls)
2938 if actual_number != expected_number:
Betty Zhoua37acd32017-02-23 20:04:24 -08002939 ad.log.error("Active Call number is %s, expecting", actual_number,
2940 expected_number)
Ang Li73697b32015-12-03 00:41:53 +00002941 return False
2942 return True
2943
Nathan Harold123c9da2015-12-30 16:33:25 -08002944
Ang Li73697b32015-12-03 00:41:53 +00002945def num_active_calls(log, ad):
2946 """Get the count of current active calls.
2947
2948 Args:
2949 log: Log object.
2950 ad: Android Device Object.
2951
2952 Returns:
2953 Count of current active calls.
2954 """
2955 calls = ad.droid.telecomCallGetCallIds()
2956 return len(calls) if calls else 0
2957
Nathan Harold123c9da2015-12-30 16:33:25 -08002958
Ang Li73697b32015-12-03 00:41:53 +00002959def toggle_volte(log, ad, new_state=None):
2960 """Toggle enable/disable VoLTE for default voice subscription.
2961
2962 Args:
2963 ad: Android device object.
2964 new_state: VoLTE mode state to set to.
2965 True for enable, False for disable.
2966 If None, opposite of the current state.
2967
2968 Raises:
2969 TelTestUtilsError if platform does not support VoLTE.
2970 """
Betty Zhouee311052017-12-19 13:09:56 -08002971 return toggle_volte_for_subscription(
2972 log, ad, get_outgoing_voice_sub_id(ad), new_state)
Ang Li73697b32015-12-03 00:41:53 +00002973
2974
2975def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
2976 """Toggle enable/disable VoLTE for specified voice subscription.
2977
2978 Args:
2979 ad: Android device object.
2980 sub_id: subscription ID
2981 new_state: VoLTE mode state to set to.
2982 True for enable, False for disable.
2983 If None, opposite of the current state.
2984
Ang Li73697b32015-12-03 00:41:53 +00002985 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002986 # TODO: b/26293960 No framework API available to set IMS by SubId.
Ang Li73697b32015-12-03 00:41:53 +00002987 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
Betty Zhoub14c1012018-04-20 11:27:00 -07002988 ad.log.info("Enhanced 4G Lte Mode Setting is not enabled by platform.")
2989 return False
Ang Li73697b32015-12-03 00:41:53 +00002990 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
2991 if new_state is None:
2992 new_state = not current_state
2993 if new_state != current_state:
Betty Zhou5dd53c02018-03-22 20:08:33 -07002994 ad.log.info("Toggle Enhanced 4G LTE Mode")
Ang Li73697b32015-12-03 00:41:53 +00002995 ad.droid.imsSetEnhanced4gMode(new_state)
2996 return True
2997
Nathan Harold123c9da2015-12-30 16:33:25 -08002998
Betty Zhoub14c1012018-04-20 11:27:00 -07002999def wait_for_enhanced_4g_lte_setting(log,
3000 ad,
3001 max_time=MAX_WAIT_TIME_FOR_STATE_CHANGE):
3002 """Wait for android device to enable enhance 4G LTE setting.
3003
3004 Args:
3005 log: log object.
3006 ad: android device.
3007 max_time: maximal wait time.
3008
3009 Returns:
3010 Return True if device report VoLTE enabled bit true within max_time.
3011 Return False if timeout.
3012 """
3013 return wait_for_state(
3014 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform,
3015 True,
3016 max_wait_time=max_time)
3017
3018
Ang Li73697b32015-12-03 00:41:53 +00003019def set_wfc_mode(log, ad, wfc_mode):
3020 """Set WFC enable/disable and mode.
3021
3022 Args:
3023 log: Log object
3024 ad: Android device object.
3025 wfc_mode: WFC mode to set to.
3026 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
3027 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
3028
3029 Returns:
3030 True if success. False if ad does not support WFC or error happened.
3031 """
3032 try:
Betty Zhoua37acd32017-02-23 20:04:24 -08003033 ad.log.info("Set wfc mode to %s", wfc_mode)
Betty Zhou96b5bf42018-03-23 19:18:41 -07003034 if wfc_mode != WFC_MODE_DISABLED:
Betty Zhou2bb11682018-04-19 17:05:30 -07003035 start_adb_tcpdump(ad, interface="wlan0", mask="all")
Ang Li73697b32015-12-03 00:41:53 +00003036 if not ad.droid.imsIsWfcEnabledByPlatform():
3037 if wfc_mode == WFC_MODE_DISABLED:
3038 return True
3039 else:
Betty Zhou94023182017-06-07 18:02:14 -07003040 ad.log.error("WFC not supported by platform.")
Ang Li73697b32015-12-03 00:41:53 +00003041 return False
Ang Li73697b32015-12-03 00:41:53 +00003042 ad.droid.imsSetWfcMode(wfc_mode)
Betty Zhou94023182017-06-07 18:02:14 -07003043 mode = ad.droid.imsGetWfcMode()
3044 if mode != wfc_mode:
3045 ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode)
3046 return False
Ang Li73697b32015-12-03 00:41:53 +00003047 except Exception as e:
3048 log.error(e)
3049 return False
Ang Li73697b32015-12-03 00:41:53 +00003050 return True
3051
Nathan Harold123c9da2015-12-30 16:33:25 -08003052
Nathan Harold0a011532016-08-24 19:17:44 -07003053def toggle_video_calling(log, ad, new_state=None):
3054 """Toggle enable/disable Video calling for default voice subscription.
3055
3056 Args:
3057 ad: Android device object.
3058 new_state: Video mode state to set to.
3059 True for enable, False for disable.
3060 If None, opposite of the current state.
3061
3062 Raises:
3063 TelTestUtilsError if platform does not support Video calling.
3064 """
3065 if not ad.droid.imsIsVtEnabledByPlatform():
3066 if new_state is not False:
3067 raise TelTestUtilsError("VT not supported by platform.")
3068 # if the user sets VT false and it's unavailable we just let it go
3069 return False
3070
3071 current_state = ad.droid.imsIsVtEnabledByUser()
3072 if new_state is None:
3073 new_state = not current_state
3074 if new_state != current_state:
3075 ad.droid.imsSetVtSetting(new_state)
3076 return True
Nathan Harold123c9da2015-12-30 16:33:25 -08003077
Nathan Harold72f9bff2016-09-19 14:16:24 -07003078
Nathan Harold123c9da2015-12-30 16:33:25 -08003079def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args,
3080 **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07003081 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00003082 if state_check_func(log, ad, *args, **kwargs):
3083 return True
3084
Betty Zhouf25ce442017-03-03 14:28:36 -08003085 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
3086 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00003087
3088 return False
3089
3090
Nathan Harold123c9da2015-12-30 16:33:25 -08003091def _wait_for_droid_in_state_for_subscription(
3092 log, ad, sub_id, max_time, state_check_func, *args, **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07003093 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00003094 if state_check_func(log, ad, sub_id, *args, **kwargs):
3095 return True
3096
Betty Zhouf25ce442017-03-03 14:28:36 -08003097 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
3098 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00003099
3100 return False
3101
3102
Nathan Harold123c9da2015-12-30 16:33:25 -08003103def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args,
3104 **kwargs):
Ang Li73697b32015-12-03 00:41:53 +00003105 while max_time > 0:
3106 success = True
3107 for ad in ads:
3108 if not state_check_func(log, ad, *args, **kwargs):
3109 success = False
3110 break
3111 if success:
3112 return True
3113
Betty Zhouf25ce442017-03-03 14:28:36 -08003114 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
3115 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00003116
3117 return False
3118
Nathan Harold123c9da2015-12-30 16:33:25 -08003119
Ang Li73697b32015-12-03 00:41:53 +00003120def is_phone_in_call(log, ad):
3121 """Return True if phone in call.
3122
3123 Args:
3124 log: log object.
3125 ad: android device.
3126 """
Betty Zhou377f72b2018-01-12 19:43:26 -08003127 try:
3128 return ad.droid.telecomIsInCall()
3129 except:
3130 return "mCallState=2" in ad.adb.shell(
3131 "dumpsys telephony.registry | grep mCallState")
Ang Li73697b32015-12-03 00:41:53 +00003132
Nathan Harold123c9da2015-12-30 16:33:25 -08003133
Ang Li73697b32015-12-03 00:41:53 +00003134def is_phone_not_in_call(log, ad):
3135 """Return True if phone not in call.
3136
3137 Args:
3138 log: log object.
3139 ad: android device.
3140 """
Betty Zhou94023182017-06-07 18:02:14 -07003141 in_call = ad.droid.telecomIsInCall()
3142 call_state = ad.droid.telephonyGetCallState()
3143 if in_call:
3144 ad.log.info("Device is In Call")
3145 if call_state != TELEPHONY_STATE_IDLE:
3146 ad.log.info("Call_state is %s, not %s", call_state,
3147 TELEPHONY_STATE_IDLE)
3148 return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))
Ang Li73697b32015-12-03 00:41:53 +00003149
Nathan Harold123c9da2015-12-30 16:33:25 -08003150
Ang Li73697b32015-12-03 00:41:53 +00003151def wait_for_droid_in_call(log, ad, max_time):
3152 """Wait for android to be in call state.
3153
3154 Args:
3155 log: log object.
3156 ad: android device.
3157 max_time: maximal wait time.
3158
3159 Returns:
3160 If phone become in call state within max_time, return True.
3161 Return False if timeout.
3162 """
3163 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
3164
Nathan Harold7642fc92016-05-02 18:29:11 -07003165
Betty Zhoucf048542018-02-22 17:14:08 -08003166def is_phone_in_call_active(ad, call_id=None):
3167 """Return True if phone in active call.
3168
3169 Args:
3170 log: log object.
3171 ad: android device.
3172 call_id: the call id
3173 """
Jaineel78b05dd2018-03-27 13:54:17 -07003174 if ad.droid.telecomIsInCall():
3175 if not call_id:
3176 call_id = ad.droid.telecomCallGetCallIds()[0]
3177 call_state = ad.droid.telecomCallGetCallState(call_id)
3178 ad.log.info("%s state is %s", call_id, call_state)
3179 return call_state == "ACTIVE"
3180 else:
3181 ad.log.error("No calls are found on this device to check state")
3182 return False
Betty Zhoucf048542018-02-22 17:14:08 -08003183
Betty Zhou4411c202018-03-29 18:27:25 -07003184
Betty Zhoucf048542018-02-22 17:14:08 -08003185def wait_for_in_call_active(ad, timeout=5, interval=1, call_id=None):
3186 """Wait for call reach active state.
3187
3188 Args:
3189 log: log object.
3190 ad: android device.
3191 call_id: the call id
3192 """
3193 if not call_id:
3194 call_id = ad.droid.telecomCallGetCallIds()[0]
3195 args = [ad, call_id]
3196 if not wait_for_state(is_phone_in_call_active, True, timeout, interval,
3197 *args):
3198 ad.log.error("Call did not reach ACTIVE state")
3199 return False
3200 else:
3201 return True
3202
3203
Yang Liu855d5f82016-01-27 15:35:48 -08003204def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
3205 """Wait for android to be in telecom ringing state.
3206
3207 Args:
3208 log: log object.
3209 ad: android device.
3210 max_time: maximal wait time. This is optional.
3211 Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
3212
3213 Returns:
3214 If phone become in telecom ringing state within max_time, return True.
3215 Return False if timeout.
3216 """
Nathan Harold7642fc92016-05-02 18:29:11 -07003217 return _wait_for_droid_in_state(
3218 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
Yang Liu855d5f82016-01-27 15:35:48 -08003219
Nathan Harold123c9da2015-12-30 16:33:25 -08003220
Nathan Haroldeb60b192016-08-24 14:41:55 -07003221def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00003222 """Wait for android to be not in call state.
3223
3224 Args:
3225 log: log object.
3226 ad: android device.
3227 max_time: maximal wait time.
3228
3229 Returns:
3230 If phone become not in call state within max_time, return True.
3231 Return False if timeout.
3232 """
3233 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
3234
Nathan Harold123c9da2015-12-30 16:33:25 -08003235
Ang Li73697b32015-12-03 00:41:53 +00003236def _is_attached(log, ad, voice_or_data):
3237 return _is_attached_for_subscription(
3238 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
3239
Nathan Harold123c9da2015-12-30 16:33:25 -08003240
Ang Li73697b32015-12-03 00:41:53 +00003241def _is_attached_for_subscription(log, ad, sub_id, voice_or_data):
Betty Zhouf25ce442017-03-03 14:28:36 -08003242 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)
Betty Zhoucb2cbc42017-06-29 14:39:34 -07003243 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat,
Betty Zhouf25ce442017-03-03 14:28:36 -08003244 voice_or_data)
3245 return rat != RAT_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00003246
Nathan Harold123c9da2015-12-30 16:33:25 -08003247
Betty Zhou33c05292017-05-24 15:12:43 -07003248def is_voice_attached(log, ad):
3249 return _is_attached_for_subscription(
3250 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE)
3251
3252
Ang Li73697b32015-12-03 00:41:53 +00003253def wait_for_voice_attach(log, ad, max_time):
3254 """Wait for android device to attach on voice.
3255
3256 Args:
3257 log: log object.
3258 ad: android device.
3259 max_time: maximal wait time.
3260
3261 Returns:
3262 Return True if device attach voice within max_time.
3263 Return False if timeout.
3264 """
3265 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
3266 NETWORK_SERVICE_VOICE)
3267
Nathan Harold123c9da2015-12-30 16:33:25 -08003268
Ang Li73697b32015-12-03 00:41:53 +00003269def wait_for_voice_attach_for_subscription(log, ad, sub_id, max_time):
3270 """Wait for android device to attach on voice in subscription id.
3271
3272 Args:
3273 log: log object.
3274 ad: android device.
3275 sub_id: subscription id.
3276 max_time: maximal wait time.
3277
3278 Returns:
3279 Return True if device attach voice within max_time.
3280 Return False if timeout.
3281 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003282 if not _wait_for_droid_in_state_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08003283 log, ad, sub_id, max_time, _is_attached_for_subscription,
3284 NETWORK_SERVICE_VOICE):
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003285 return False
3286
3287 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
3288 # receive incoming call immediately.
3289 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
Yang Liudf164e32016-01-07 16:49:32 -08003290 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
Yang Liu7a2e7ee2015-12-28 15:32:44 -08003291 return True
Ang Li73697b32015-12-03 00:41:53 +00003292
Nathan Harold123c9da2015-12-30 16:33:25 -08003293
Ang Li73697b32015-12-03 00:41:53 +00003294def wait_for_data_attach(log, ad, max_time):
3295 """Wait for android device to attach on data.
3296
3297 Args:
3298 log: log object.
3299 ad: android device.
3300 max_time: maximal wait time.
3301
3302 Returns:
3303 Return True if device attach data within max_time.
3304 Return False if timeout.
3305 """
3306 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
3307 NETWORK_SERVICE_DATA)
3308
Nathan Harold123c9da2015-12-30 16:33:25 -08003309
Ang Li73697b32015-12-03 00:41:53 +00003310def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time):
3311 """Wait for android device to attach on data in subscription id.
3312
3313 Args:
3314 log: log object.
3315 ad: android device.
3316 sub_id: subscription id.
3317 max_time: maximal wait time.
3318
3319 Returns:
3320 Return True if device attach data within max_time.
3321 Return False if timeout.
3322 """
3323 return _wait_for_droid_in_state_for_subscription(
3324 log, ad, sub_id, max_time, _is_attached_for_subscription,
3325 NETWORK_SERVICE_DATA)
3326
Nathan Harold123c9da2015-12-30 16:33:25 -08003327
Yang Liu9b85ce52016-02-16 12:25:11 -08003328def is_ims_registered(log, ad):
3329 """Return True if IMS registered.
3330
3331 Args:
3332 log: log object.
3333 ad: android device.
3334
3335 Returns:
3336 Return True if IMS registered.
3337 Return False if IMS not registered.
3338 """
Yang Liuaed3eef2015-12-15 18:40:25 -08003339 return ad.droid.telephonyIsImsRegistered()
Ang Li73697b32015-12-03 00:41:53 +00003340
Nathan Harold123c9da2015-12-30 16:33:25 -08003341
Ang Li73697b32015-12-03 00:41:53 +00003342def wait_for_ims_registered(log, ad, max_time):
3343 """Wait for android device to register on ims.
3344
3345 Args:
3346 log: log object.
3347 ad: android device.
3348 max_time: maximal wait time.
3349
3350 Returns:
3351 Return True if device register ims successfully within max_time.
3352 Return False if timeout.
3353 """
Yang Liu9b85ce52016-02-16 12:25:11 -08003354 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered)
Ang Li73697b32015-12-03 00:41:53 +00003355
Nathan Harold123c9da2015-12-30 16:33:25 -08003356
Yang Liu9b85ce52016-02-16 12:25:11 -08003357def is_volte_enabled(log, ad):
3358 """Return True if VoLTE feature bit is True.
3359
3360 Args:
3361 log: log object.
3362 ad: android device.
3363
3364 Returns:
3365 Return True if VoLTE feature bit is True and IMS registered.
3366 Return False if VoLTE feature bit is False or IMS not registered.
3367 """
Betty Zhoue32dd3b2017-11-28 19:05:55 -08003368 if not is_ims_registered(log, ad):
3369 ad.log.info("IMS is not registered.")
Betty Zhoub66d48f2018-04-09 12:00:53 -07003370 return False
3371 if not ad.droid.telephonyIsVolteAvailable():
3372 ad.log.info("IsVolteCallingAvailble is False")
3373 return False
Betty Zhoue32dd3b2017-11-28 19:05:55 -08003374 else:
Betty Zhoub66d48f2018-04-09 12:00:53 -07003375 ad.log.info("IsVolteCallingAvailble is True")
3376 return True
Ang Li73697b32015-12-03 00:41:53 +00003377
Nathan Harold123c9da2015-12-30 16:33:25 -08003378
Yang Liu9b85ce52016-02-16 12:25:11 -08003379def is_video_enabled(log, ad):
3380 """Return True if Video Calling feature bit is True.
3381
3382 Args:
3383 log: log object.
3384 ad: android device.
3385
3386 Returns:
3387 Return True if Video Calling feature bit is True and IMS registered.
3388 Return False if Video Calling feature bit is False or IMS not registered.
3389 """
Yang Liub93d7292016-02-19 10:41:40 -08003390 video_status = ad.droid.telephonyIsVideoCallingAvailable()
3391 if video_status is True and is_ims_registered(log, ad) is False:
Yang Liu9b85ce52016-02-16 12:25:11 -08003392 log.error("Error! Video Call is Available, but IMS is not registered.")
3393 return False
Yang Liub93d7292016-02-19 10:41:40 -08003394 return video_status
Ang Li73697b32015-12-03 00:41:53 +00003395
Nathan Harold123c9da2015-12-30 16:33:25 -08003396
Ang Li73697b32015-12-03 00:41:53 +00003397def wait_for_volte_enabled(log, ad, max_time):
3398 """Wait for android device to report VoLTE enabled bit true.
3399
3400 Args:
3401 log: log object.
3402 ad: android device.
3403 max_time: maximal wait time.
3404
3405 Returns:
3406 Return True if device report VoLTE enabled bit true within max_time.
3407 Return False if timeout.
3408 """
Yang Liu9b85ce52016-02-16 12:25:11 -08003409 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled)
Ang Li73697b32015-12-03 00:41:53 +00003410
Nathan Harold123c9da2015-12-30 16:33:25 -08003411
Ang Li73697b32015-12-03 00:41:53 +00003412def wait_for_video_enabled(log, ad, max_time):
3413 """Wait for android device to report Video Telephony enabled bit true.
3414
3415 Args:
3416 log: log object.
3417 ad: android device.
3418 max_time: maximal wait time.
3419
3420 Returns:
3421 Return True if device report Video Telephony enabled bit true within max_time.
3422 Return False if timeout.
3423 """
Yang Liu9b85ce52016-02-16 12:25:11 -08003424 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
Ang Li73697b32015-12-03 00:41:53 +00003425
Nathan Harold123c9da2015-12-30 16:33:25 -08003426
Ang Li73697b32015-12-03 00:41:53 +00003427def is_wfc_enabled(log, ad):
3428 """Return True if WiFi Calling feature bit is True.
3429
3430 Args:
3431 log: log object.
3432 ad: android device.
3433
3434 Returns:
Yang Liu9b85ce52016-02-16 12:25:11 -08003435 Return True if WiFi Calling feature bit is True and IMS registered.
3436 Return False if WiFi Calling feature bit is False or IMS not registered.
Ang Li73697b32015-12-03 00:41:53 +00003437 """
Betty Zhoub66d48f2018-04-09 12:00:53 -07003438 if not is_ims_registered(log, ad):
3439 ad.log.info("IMS is not registered.")
3440 return False
Betty Zhou94023182017-06-07 18:02:14 -07003441 if not ad.droid.telephonyIsWifiCallingAvailable():
3442 ad.log.info("IsWifiCallingAvailble is False")
Yang Liu9b85ce52016-02-16 12:25:11 -08003443 return False
Betty Zhou94023182017-06-07 18:02:14 -07003444 else:
3445 ad.log.info("IsWifiCallingAvailble is True")
Betty Zhou94023182017-06-07 18:02:14 -07003446 return True
Ang Li73697b32015-12-03 00:41:53 +00003447
Nathan Harold123c9da2015-12-30 16:33:25 -08003448
Yang Liudfc37b62016-01-20 18:08:47 -08003449def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00003450 """Wait for android device to report WiFi Calling enabled bit true.
3451
3452 Args:
3453 log: log object.
3454 ad: android device.
3455 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08003456 Default value is MAX_WAIT_TIME_WFC_ENABLED.
Ang Li73697b32015-12-03 00:41:53 +00003457
3458 Returns:
3459 Return True if device report WiFi Calling enabled bit true within max_time.
3460 Return False if timeout.
3461 """
3462 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
3463
Nathan Harold123c9da2015-12-30 16:33:25 -08003464
Yang Liudfc37b62016-01-20 18:08:47 -08003465def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
Ang Li73697b32015-12-03 00:41:53 +00003466 """Wait for android device to report WiFi Calling enabled bit false.
3467
3468 Args:
3469 log: log object.
3470 ad: android device.
3471 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08003472 Default value is MAX_WAIT_TIME_WFC_DISABLED.
Ang Li73697b32015-12-03 00:41:53 +00003473
3474 Returns:
3475 Return True if device report WiFi Calling enabled bit false within max_time.
3476 Return False if timeout.
3477 """
Nathan Harold123c9da2015-12-30 16:33:25 -08003478 return _wait_for_droid_in_state(
3479 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
3480
Ang Li73697b32015-12-03 00:41:53 +00003481
3482def get_phone_number(log, ad):
3483 """Get phone number for default subscription
3484
3485 Args:
3486 log: log object.
3487 ad: Android device object.
3488
3489 Returns:
3490 Phone number.
3491 """
Nathan Harold7642fc92016-05-02 18:29:11 -07003492 return get_phone_number_for_subscription(log, ad,
3493 get_outgoing_voice_sub_id(ad))
Nathan Harold123c9da2015-12-30 16:33:25 -08003494
Ang Li73697b32015-12-03 00:41:53 +00003495
3496def get_phone_number_for_subscription(log, ad, subid):
3497 """Get phone number for subscription
3498
3499 Args:
3500 log: log object.
3501 ad: Android device object.
3502 subid: subscription id.
3503
3504 Returns:
3505 Phone number.
3506 """
3507 number = None
3508 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07003509 number = ad.telephony['subscription'][subid]['phone_num']
Ang Li73697b32015-12-03 00:41:53 +00003510 except KeyError:
Yang Liuaed3eef2015-12-15 18:40:25 -08003511 number = ad.droid.telephonyGetLine1NumberForSubscription(subid)
Ang Li73697b32015-12-03 00:41:53 +00003512 return number
3513
Nathan Harold123c9da2015-12-30 16:33:25 -08003514
Ang Li73697b32015-12-03 00:41:53 +00003515def set_phone_number(log, ad, phone_num):
3516 """Set phone number for default subscription
3517
3518 Args:
3519 log: log object.
3520 ad: Android device object.
3521 phone_num: phone number string.
3522
3523 Returns:
3524 True if success.
3525 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07003526 return set_phone_number_for_subscription(log, ad,
3527 get_outgoing_voice_sub_id(ad),
3528 phone_num)
Nathan Harold123c9da2015-12-30 16:33:25 -08003529
Ang Li73697b32015-12-03 00:41:53 +00003530
3531def set_phone_number_for_subscription(log, ad, subid, phone_num):
3532 """Set phone number for subscription
3533
3534 Args:
3535 log: log object.
3536 ad: Android device object.
3537 subid: subscription id.
3538 phone_num: phone number string.
3539
3540 Returns:
3541 True if success.
3542 """
3543 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07003544 ad.telephony['subscription'][subid]['phone_num'] = phone_num
Ang Li73697b32015-12-03 00:41:53 +00003545 except Exception:
3546 return False
3547 return True
3548
Nathan Harold123c9da2015-12-30 16:33:25 -08003549
Ang Li73697b32015-12-03 00:41:53 +00003550def get_operator_name(log, ad, subId=None):
3551 """Get operator name (e.g. vzw, tmo) of droid.
3552
3553 Args:
3554 ad: Android device object.
3555 sub_id: subscription ID
3556 Optional, default is None
3557
3558 Returns:
3559 Operator name.
3560 """
3561 try:
3562 if subId is not None:
3563 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003564 ad.droid.telephonyGetNetworkOperatorForSubscription(subId))
Ang Li73697b32015-12-03 00:41:53 +00003565 else:
3566 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003567 ad.droid.telephonyGetNetworkOperator())
Ang Li73697b32015-12-03 00:41:53 +00003568 except KeyError:
Betty Zhou3ea56122018-03-14 17:37:24 -07003569 try:
3570 if subId is not None:
3571 result = ad.droid.telephonyGetNetworkOperatorNameForSubscription(
3572 sub_id)
3573 else:
3574 result = ad.droid.telephonyGetNetworkOperatorName()
Betty Zhoub14c1012018-04-20 11:27:00 -07003575 result = operator_name_from_network_name(result)
Betty Zhou3ea56122018-03-14 17:37:24 -07003576 except Exception:
3577 result = CARRIER_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00003578 return result
3579
Nathan Harold123c9da2015-12-30 16:33:25 -08003580
Yang Liu9a9a4f72016-02-19 10:45:04 -08003581def get_model_name(ad):
3582 """Get android device model name
3583
3584 Args:
3585 ad: Android device object
3586
3587 Returns:
3588 model name string
3589 """
3590 # TODO: Create translate table.
3591 model = ad.model
Nathan Harold7642fc92016-05-02 18:29:11 -07003592 if (model.startswith(AOSP_PREFIX)):
Yang Liu9a9a4f72016-02-19 10:45:04 -08003593 model = model[len(AOSP_PREFIX):]
3594 return model
3595
3596
Ang Li73697b32015-12-03 00:41:53 +00003597def is_sms_match(event, phonenumber_tx, text):
3598 """Return True if 'text' equals to event['data']['Text']
3599 and phone number match.
3600
3601 Args:
3602 event: Event object to verify.
3603 phonenumber_tx: phone number for sender.
3604 text: text string to verify.
3605
3606 Returns:
3607 Return True if 'text' equals to event['data']['Text']
3608 and phone number match.
3609 """
Betty Zhouee311052017-12-19 13:09:56 -08003610 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
3611 and event['data']['Text'] == text)
Nathan Harold123c9da2015-12-30 16:33:25 -08003612
Ang Li73697b32015-12-03 00:41:53 +00003613
3614def is_sms_partial_match(event, phonenumber_tx, text):
3615 """Return True if 'text' starts with event['data']['Text']
3616 and phone number match.
3617
3618 Args:
3619 event: Event object to verify.
3620 phonenumber_tx: phone number for sender.
3621 text: text string to verify.
3622
3623 Returns:
3624 Return True if 'text' starts with event['data']['Text']
3625 and phone number match.
3626 """
Betty Zhou1bc12092018-03-19 14:00:23 -07003627 event_text = event['data']['Text']
3628 if event_text.startswith("("):
3629 event_text = event_text.split(")")[-1]
Betty Zhouee311052017-12-19 13:09:56 -08003630 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
Betty Zhou1bc12092018-03-19 14:00:23 -07003631 and text.startswith(event_text))
Nathan Harold123c9da2015-12-30 16:33:25 -08003632
Ang Li73697b32015-12-03 00:41:53 +00003633
Betty Zhou02571f52018-02-16 14:11:16 -08003634def sms_send_receive_verify(log,
3635 ad_tx,
3636 ad_rx,
3637 array_message,
Betty Zhou632793c2018-02-09 18:45:39 -08003638 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Ang Li73697b32015-12-03 00:41:53 +00003639 """Send SMS, receive SMS, and verify content and sender's number.
3640
3641 Send (several) SMS from droid_tx to droid_rx.
3642 Verify SMS is sent, delivered and received.
3643 Verify received content and sender's number are correct.
3644
3645 Args:
3646 log: Log object.
3647 ad_tx: Sender's Android Device Object
3648 ad_rx: Receiver's Android Device Object
3649 array_message: the array of message to send/receive
3650 """
Yang Liu963c93c2016-04-05 10:52:00 -07003651 subid_tx = get_outgoing_message_sub_id(ad_tx)
3652 subid_rx = get_incoming_message_sub_id(ad_rx)
Betty Zhou74cf9922018-04-18 20:18:12 -07003653 result = sms_send_receive_verify_for_subscription(
Betty Zhou632793c2018-02-09 18:45:39 -08003654 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
Betty Zhou74cf9922018-04-18 20:18:12 -07003655 if not result:
3656 log_messaging_screen_shot(ad_tx, test_name="sms_tx")
3657 log_messaging_screen_shot(ad_rx, test_name="sms_rx")
3658 return result
Ang Li73697b32015-12-03 00:41:53 +00003659
Nathan Harold123c9da2015-12-30 16:33:25 -08003660
3661def wait_for_matching_sms(log,
3662 ad_rx,
3663 phonenumber_tx,
3664 text,
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003665 allow_multi_part_long_sms=True,
Betty Zhou632793c2018-02-09 18:45:39 -08003666 begin_time=None,
3667 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Ang Li73697b32015-12-03 00:41:53 +00003668 """Wait for matching incoming SMS.
3669
3670 Args:
3671 log: Log object.
3672 ad_rx: Receiver's Android Device Object
3673 phonenumber_tx: Sender's phone number.
3674 text: SMS content string.
3675 allow_multi_part_long_sms: is long SMS allowed to be received as
3676 multiple short SMS. This is optional, default value is True.
3677
3678 Returns:
3679 True if matching incoming SMS is received.
3680 """
3681 if not allow_multi_part_long_sms:
3682 try:
Betty Zhou632793c2018-02-09 18:45:39 -08003683 ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
3684 max_wait_time, phonenumber_tx,
3685 text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07003686 ad_rx.log.info("Got event %s", EventSmsReceived)
Ang Li73697b32015-12-03 00:41:53 +00003687 return True
3688 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07003689 ad_rx.log.error("No matched SMS received event.")
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003690 if begin_time:
Betty Zhou4c1c4b12017-12-21 17:06:13 -08003691 if sms_mms_receive_logcat_check(ad_rx, "sms", begin_time):
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003692 ad_rx.log.info("Receivd SMS message is seen in logcat")
Ang Li73697b32015-12-03 00:41:53 +00003693 return False
3694 else:
3695 try:
3696 received_sms = ''
Betty Zhou1bc12092018-03-19 14:00:23 -07003697 remaining_text = text
3698 while (remaining_text != ''):
Betty Zhou1c8c8d42018-03-14 12:43:50 -07003699 event = ad_rx.messaging_ed.wait_for_event(
Betty Zhou02571f52018-02-16 14:11:16 -08003700 EventSmsReceived, is_sms_partial_match, max_wait_time,
Betty Zhou1bc12092018-03-19 14:00:23 -07003701 phonenumber_tx, remaining_text)
3702 event_text = event['data']['Text'].split(")")[-1]
3703 event_text_length = len(event_text)
3704 ad_rx.log.info("Got event %s of text length %s from %s",
3705 EventSmsReceived, event_text_length,
3706 phonenumber_tx)
3707 remaining_text = remaining_text[event_text_length:]
3708 received_sms += event_text
3709 ad_rx.log.info("Received SMS of length %s", len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00003710 return True
3711 except Empty:
Betty Zhou1bc12092018-03-19 14:00:23 -07003712 ad_rx.log.error(
3713 "Missing SMS received event of text length %s from %s",
3714 len(remaining_text), phonenumber_tx)
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003715 if begin_time:
Betty Zhou4c1c4b12017-12-21 17:06:13 -08003716 if sms_mms_receive_logcat_check(ad_rx, "sms", begin_time):
Betty Zhou1bc12092018-03-19 14:00:23 -07003717 ad_rx.log.info("Received SMS message is seen in logcat")
Ang Li73697b32015-12-03 00:41:53 +00003718 if received_sms != '':
Betty Zhou1bc12092018-03-19 14:00:23 -07003719 ad_rx.log.error(
3720 "Only received partial matched SMS of length %s",
3721 len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00003722 return False
3723
Nathan Harold123c9da2015-12-30 16:33:25 -08003724
Betty Zhoua27e5d42017-01-17 11:33:04 -08003725def is_mms_match(event, phonenumber_tx, text):
3726 """Return True if 'text' equals to event['data']['Text']
3727 and phone number match.
3728
3729 Args:
3730 event: Event object to verify.
3731 phonenumber_tx: phone number for sender.
3732 text: text string to verify.
3733
3734 Returns:
3735 Return True if 'text' equals to event['data']['Text']
3736 and phone number match.
3737 """
3738 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
3739 return True
3740
3741
Betty Zhou02571f52018-02-16 14:11:16 -08003742def wait_for_matching_mms(log,
3743 ad_rx,
3744 phonenumber_tx,
3745 text,
3746 begin_time=None,
Betty Zhou632793c2018-02-09 18:45:39 -08003747 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhoua27e5d42017-01-17 11:33:04 -08003748 """Wait for matching incoming SMS.
3749
3750 Args:
3751 log: Log object.
3752 ad_rx: Receiver's Android Device Object
3753 phonenumber_tx: Sender's phone number.
3754 text: SMS content string.
3755 allow_multi_part_long_sms: is long SMS allowed to be received as
3756 multiple short SMS. This is optional, default value is True.
3757
3758 Returns:
3759 True if matching incoming SMS is received.
3760 """
3761 try:
3762 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08003763 ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
3764 max_wait_time, phonenumber_tx, text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07003765 ad_rx.log.info("Got event %s", EventMmsDownloaded)
Betty Zhou6b3593f2018-03-16 20:13:55 -07003766 smshandle_logs = ad_rx.search_logcat(
Betty Zhou1bc12092018-03-19 14:00:23 -07003767 "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
Betty Zhou6b3593f2018-03-16 20:13:55 -07003768 begin_time=begin_time)
3769 if smshandle_logs:
3770 ad_rx.log.warning("Found %s", smshandle_logs[-1]["log_message"])
Betty Zhoua27e5d42017-01-17 11:33:04 -08003771 return True
3772 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07003773 ad_rx.log.warning("No matched MMS downloaded event.")
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003774 if begin_time:
Betty Zhou4c1c4b12017-12-21 17:06:13 -08003775 if sms_mms_receive_logcat_check(ad_rx, "mms", begin_time):
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003776 return True
Betty Zhoua27e5d42017-01-17 11:33:04 -08003777 return False
3778
3779
Betty Zhou632793c2018-02-09 18:45:39 -08003780def sms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08003781 log,
3782 ad_tx,
3783 ad_rx,
3784 subid_tx,
3785 subid_rx,
3786 array_message,
3787 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Ang Li73697b32015-12-03 00:41:53 +00003788 """Send SMS, receive SMS, and verify content and sender's number.
3789
3790 Send (several) SMS from droid_tx to droid_rx.
3791 Verify SMS is sent, delivered and received.
3792 Verify received content and sender's number are correct.
3793
3794 Args:
3795 log: Log object.
3796 ad_tx: Sender's Android Device Object..
3797 ad_rx: Receiver's Android Device Object.
3798 subid_tx: Sender's subsciption ID to be used for SMS
3799 subid_rx: Receiver's subsciption ID to be used for SMS
3800 array_message: the array of message to send/receive
3801 """
Betty Zhou3b2de072018-03-15 16:46:26 -07003802 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
3803 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003804
Betty Zhou632793c2018-02-09 18:45:39 -08003805 for ad in (ad_tx, ad_rx):
3806 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08003807 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
3808 ad.messaging_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08003809 else:
3810 try:
3811 if not ad.messaging_droid.is_live:
3812 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
3813 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07003814 else:
3815 ad.messaging_ed.clear_all_events()
3816 ad.messaging_droid.logI(
3817 "Start sms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08003818 except Exception:
3819 ad.log.info("Create new sl4a session for messaging")
Betty Zhouf31dffe2018-02-23 19:29:28 -08003820 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
3821 ad.messaging_ed.start()
3822
Ang Li73697b32015-12-03 00:41:53 +00003823 for text in array_message:
Betty Zhoucbea0252018-01-17 19:07:22 -08003824 # set begin_time 300ms before current time to system time discrepency
3825 begin_time = get_current_epoch_time() - 300
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003826 length = len(text)
Betty Zhoua37acd32017-02-23 20:04:24 -08003827 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003828 phonenumber_tx, phonenumber_rx, length, text)
Ang Li73697b32015-12-03 00:41:53 +00003829 try:
Betty Zhou632793c2018-02-09 18:45:39 -08003830 ad_rx.messaging_ed.clear_events(EventSmsReceived)
3831 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07003832 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08003833 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003834 time.sleep(1) #sleep 100ms after starting event tracking
Betty Zhou4411c202018-03-29 18:27:25 -07003835 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
3836 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
Betty Zhou02571f52018-02-16 14:11:16 -08003837 ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
Betty Zhou4411c202018-03-29 18:27:25 -07003838 True)
Ang Li73697b32015-12-03 00:41:53 +00003839 try:
Betty Zhou4411c202018-03-29 18:27:25 -07003840 events = ad_tx.messaging_ed.pop_events(
Betty Zhouc9f723b2018-04-10 18:08:21 -07003841 "(%s|%s|%s|%s)" %
3842 (EventSmsSentSuccess, EventSmsSentFailure,
3843 EventSmsDeliverSuccess,
3844 EventSmsDeliverFailure), max_wait_time)
Betty Zhou4411c202018-03-29 18:27:25 -07003845 for event in events:
3846 ad_tx.log.info("Got event %s", event["name"])
Betty Zhouc9f723b2018-04-10 18:08:21 -07003847 if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
Betty Zhou4411c202018-03-29 18:27:25 -07003848 if event.get("data") and event["data"].get("Reason"):
3849 ad_tx.log.error("%s with reason: %s",
3850 event["name"],
3851 event["data"]["Reason"])
3852 return False
Betty Zhouc9f723b2018-04-10 18:08:21 -07003853 elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
Betty Zhou4411c202018-03-29 18:27:25 -07003854 break
Ang Li73697b32015-12-03 00:41:53 +00003855 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07003856 ad_tx.log.error("No %s or %s event for SMS of length %s.",
3857 EventSmsSentSuccess, EventSmsSentFailure,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003858 length)
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003859 # check log message as a work around for the missing sl4a
3860 # event dispatcher event
Betty Zhou6b91ab22017-12-21 18:16:36 -08003861 if not sms_mms_send_logcat_check(ad_tx, "sms", begin_time):
3862 return False
Ang Li73697b32015-12-03 00:41:53 +00003863
Nathan Harold4a144a42016-09-19 14:16:24 -07003864 if not wait_for_matching_sms(
3865 log,
3866 ad_rx,
3867 phonenumber_tx,
3868 text,
Betty Zhoud32e0bd2017-12-19 19:44:58 -08003869 allow_multi_part_long_sms=True,
3870 begin_time=begin_time):
Betty Zhoud2da7ba2017-03-24 12:54:34 -07003871 ad_rx.log.error("No matching received SMS of length %s.",
3872 length)
Ang Li73697b32015-12-03 00:41:53 +00003873 return False
Betty Zhou632793c2018-02-09 18:45:39 -08003874 except Exception as e:
3875 log.error("Exception error %s", e)
3876 raise
Ang Li73697b32015-12-03 00:41:53 +00003877 finally:
Betty Zhou632793c2018-02-09 18:45:39 -08003878 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00003879 return True
3880
Nathan Harold123c9da2015-12-30 16:33:25 -08003881
Betty Zhou02571f52018-02-16 14:11:16 -08003882def mms_send_receive_verify(log,
3883 ad_tx,
3884 ad_rx,
3885 array_message,
Betty Zhou632793c2018-02-09 18:45:39 -08003886 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08003887 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00003888
Betty Zhou2e08ac32017-01-27 14:21:29 -08003889 Send (several) MMS from droid_tx to droid_rx.
3890 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00003891 Verify received content and sender's number are correct.
3892
3893 Args:
3894 log: Log object.
3895 ad_tx: Sender's Android Device Object
3896 ad_rx: Receiver's Android Device Object
3897 array_message: the array of message to send/receive
3898 """
Betty Zhou74cf9922018-04-18 20:18:12 -07003899 result = mms_send_receive_verify_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08003900 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
Betty Zhou632793c2018-02-09 18:45:39 -08003901 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
Betty Zhou74cf9922018-04-18 20:18:12 -07003902 if not result:
3903 log_messaging_screen_shot(ad_tx, test_name="mms_tx")
3904 log_messaging_screen_shot(ad_rx, test_name="mms_rx")
3905 return result
Nathan Harold123c9da2015-12-30 16:33:25 -08003906
Ang Li73697b32015-12-03 00:41:53 +00003907
Betty Zhou38028b72017-12-20 17:54:12 -08003908def sms_mms_send_logcat_check(ad, type, begin_time):
3909 type = type.upper()
3910 log_results = ad.search_logcat(
3911 "%s Message sent successfully" % type, begin_time=begin_time)
3912 if log_results:
Betty Zhou1bc12092018-03-19 14:00:23 -07003913 ad.log.info("Found %s sent successful log message: %s", type,
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003914 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08003915 return True
3916 else:
3917 log_results = ad.search_logcat(
3918 "ProcessSentMessageAction: Done sending %s message" % type,
3919 begin_time=begin_time)
3920 if log_results:
3921 for log_result in log_results:
3922 if "status is SUCCEEDED" in log_result["log_message"]:
3923 ad.log.info(
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003924 "Found BugleDataModel %s send succeed log message: %s",
3925 type, log_result["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08003926 return True
3927 return False
3928
3929
3930def sms_mms_receive_logcat_check(ad, type, begin_time):
3931 type = type.upper()
Betty Zhou6b3593f2018-03-16 20:13:55 -07003932 smshandle_logs = ad.search_logcat(
Betty Zhou1bc12092018-03-19 14:00:23 -07003933 "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
Betty Zhou6b3593f2018-03-16 20:13:55 -07003934 begin_time=begin_time)
3935 if smshandle_logs:
3936 ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08003937 log_results = ad.search_logcat(
Jaineel6cd6d442018-01-08 14:50:44 -08003938 "New %s Received" % type, begin_time=begin_time) or \
3939 ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
Betty Zhou38028b72017-12-20 17:54:12 -08003940 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003941 ad.log.info("Found SL4A %s received log message: %s", type,
3942 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08003943 return True
3944 else:
3945 log_results = ad.search_logcat(
3946 "Received %s message" % type, begin_time=begin_time)
3947 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003948 ad.log.info("Found %s received log message: %s", type,
3949 log_results[-1]["log_message"])
Betty Zhou10f887e2018-04-10 12:45:00 -07003950 log_results = ad.search_logcat(
3951 "ProcessDownloadedMmsAction", begin_time=begin_time)
3952 for log_result in log_results:
3953 ad.log.info("Found %s", log_result["log_message"])
3954 if "status is SUCCEEDED" in log_result["log_message"]:
3955 ad.log.info("Download succeed with ProcessDownloadedMmsAction")
3956 return True
Betty Zhou38028b72017-12-20 17:54:12 -08003957 return False
3958
3959
Betty Zhoua27e5d42017-01-17 11:33:04 -08003960#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08003961def mms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08003962 log,
3963 ad_tx,
3964 ad_rx,
3965 subid_tx,
3966 subid_rx,
3967 array_payload,
3968 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08003969 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00003970
Betty Zhou2e08ac32017-01-27 14:21:29 -08003971 Send (several) MMS from droid_tx to droid_rx.
3972 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00003973 Verify received content and sender's number are correct.
3974
3975 Args:
3976 log: Log object.
3977 ad_tx: Sender's Android Device Object..
3978 ad_rx: Receiver's Android Device Object.
3979 subid_tx: Sender's subsciption ID to be used for SMS
3980 subid_rx: Receiver's subsciption ID to be used for SMS
3981 array_message: the array of message to send/receive
3982 """
3983
Betty Zhou3b2de072018-03-15 16:46:26 -07003984 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
3985 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhouf715c792018-02-12 17:32:10 -08003986
Betty Zhoue57ab692018-03-09 18:39:30 -08003987 for ad in (ad_tx, ad_rx):
Betty Zhouc3eedd72017-11-09 17:50:01 -08003988 if "Permissive" not in ad.adb.shell("su root getenforce"):
3989 ad.adb.shell("su root setenforce 0")
Betty Zhou632793c2018-02-09 18:45:39 -08003990 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08003991 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
3992 ad.messaging_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08003993 else:
3994 try:
3995 if not ad.messaging_droid.is_live:
3996 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
3997 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07003998 else:
3999 ad.messaging_ed.clear_all_events()
4000 ad.messaging_droid.logI(
4001 "Start mms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08004002 except Exception:
4003 ad.log.info("Create new sl4a session for messaging")
4004 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
4005 ad.messaging_ed.start()
Betty Zhou38028b72017-12-20 17:54:12 -08004006
Ang Li73697b32015-12-03 00:41:53 +00004007 for subject, message, filename in array_payload:
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004008 begin_time = get_current_epoch_time()
Betty Zhou632793c2018-02-09 18:45:39 -08004009 ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07004010 ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08004011 ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
4012 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhouf715c792018-02-12 17:32:10 -08004013 ad_tx.log.info(
4014 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
4015 phonenumber_tx, phonenumber_rx, subject, message, filename)
Ang Li73697b32015-12-03 00:41:53 +00004016 try:
Betty Zhou632793c2018-02-09 18:45:39 -08004017 ad_tx.messaging_droid.smsSendMultimediaMessage(
Nathan Harold123c9da2015-12-30 16:33:25 -08004018 phonenumber_rx, subject, message, phonenumber_tx, filename)
Betty Zhoua27e5d42017-01-17 11:33:04 -08004019 try:
Betty Zhou4411c202018-03-29 18:27:25 -07004020 events = ad_tx.messaging_ed.pop_events(
4021 "(%s|%s)" % (EventMmsSentSuccess,
4022 EventMmsSentFailure), max_wait_time)
4023 for event in events:
4024 ad_tx.log.info("Got event %s", event["name"])
4025 if event["name"] == EventMmsSentFailure:
4026 if event.get("data") and event["data"].get("Reason"):
4027 ad_tx.log.error("%s with reason: %s",
4028 event["name"],
4029 event["data"]["Reason"])
4030 return False
4031 elif event["name"] == EventMmsSentSuccess:
4032 break
Betty Zhoua27e5d42017-01-17 11:33:04 -08004033 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07004034 ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
4035 EventMmsSentFailure)
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004036 # check log message as a work around for the missing sl4a
4037 # event dispatcher event
Betty Zhou38028b72017-12-20 17:54:12 -08004038 if not sms_mms_send_logcat_check(ad_tx, "mms", begin_time):
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004039 return False
Betty Zhou2e08ac32017-01-27 14:21:29 -08004040
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004041 if not wait_for_matching_mms(
4042 log, ad_rx, phonenumber_tx, message,
4043 begin_time=begin_time):
Betty Zhou2e08ac32017-01-27 14:21:29 -08004044 return False
Betty Zhou632793c2018-02-09 18:45:39 -08004045 except Exception as e:
4046 log.error("Exception error %s", e)
4047 raise
Betty Zhou2e08ac32017-01-27 14:21:29 -08004048 finally:
Betty Zhou38028b72017-12-20 17:54:12 -08004049 ad_rx.droid.smsStopTrackingIncomingMmsMessage()
Betty Zhou2e08ac32017-01-27 14:21:29 -08004050 return True
4051
4052
Betty Zhou632793c2018-02-09 18:45:39 -08004053def mms_receive_verify_after_call_hangup(
Betty Zhou02571f52018-02-16 14:11:16 -08004054 log, ad_tx, ad_rx, array_message,
4055 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08004056 """Verify the suspanded MMS during call will send out after call release.
4057
4058 Hangup call from droid_tx to droid_rx.
4059 Verify MMS is sent, delivered and received.
4060 Verify received content and sender's number are correct.
4061
4062 Args:
4063 log: Log object.
4064 ad_tx: Sender's Android Device Object
4065 ad_rx: Receiver's Android Device Object
4066 array_message: the array of message to send/receive
4067 """
4068 return mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004069 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
Betty Zhou632793c2018-02-09 18:45:39 -08004070 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
Betty Zhou2e08ac32017-01-27 14:21:29 -08004071
4072
4073#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
4074def mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08004075 log,
4076 ad_tx,
4077 ad_rx,
4078 subid_tx,
4079 subid_rx,
4080 array_payload,
Betty Zhou632793c2018-02-09 18:45:39 -08004081 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08004082 """Verify the suspanded MMS during call will send out after call release.
4083
4084 Hangup call from droid_tx to droid_rx.
4085 Verify MMS is sent, delivered and received.
4086 Verify received content and sender's number are correct.
4087
4088 Args:
4089 log: Log object.
4090 ad_tx: Sender's Android Device Object..
4091 ad_rx: Receiver's Android Device Object.
4092 subid_tx: Sender's subsciption ID to be used for SMS
4093 subid_rx: Receiver's subsciption ID to be used for SMS
4094 array_message: the array of message to send/receive
4095 """
4096
Betty Zhou3b2de072018-03-15 16:46:26 -07004097 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
4098 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhou08c1a572018-02-13 20:07:55 -08004099 for ad in (ad_tx, ad_rx):
4100 if not getattr(ad, "messaging_droid", None):
4101 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
4102 ad.messaging_ed.start()
Betty Zhou2e08ac32017-01-27 14:21:29 -08004103 for subject, message, filename in array_payload:
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004104 begin_time = get_current_epoch_time()
Betty Zhoua37acd32017-02-23 20:04:24 -08004105 ad_rx.log.info(
4106 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
4107 phonenumber_tx, phonenumber_rx, subject, message, filename)
Betty Zhou632793c2018-02-09 18:45:39 -08004108 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhou2e08ac32017-01-27 14:21:29 -08004109 time.sleep(5)
4110 try:
4111 hangup_call(log, ad_tx)
4112 hangup_call(log, ad_rx)
4113 try:
Betty Zhou3ea56122018-03-14 17:37:24 -07004114 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
4115 max_wait_time)
Betty Zhou1c8c8d42018-03-14 12:43:50 -07004116 ad_tx.log.info("Got event %s", EventMmsSentSuccess)
Betty Zhou2e08ac32017-01-27 14:21:29 -08004117 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07004118 log.warning("No sent_success event.")
Betty Zhou38028b72017-12-20 17:54:12 -08004119 if not sms_mms_send_logcat_check(ad_tx, "mms", begin_time):
Betty Zhoud32e0bd2017-12-19 19:44:58 -08004120 return False
4121 if not wait_for_matching_mms(
4122 log, ad_rx, phonenumber_tx, message,
4123 begin_time=begin_time):
Ang Li73697b32015-12-03 00:41:53 +00004124 return False
4125 finally:
Betty Zhou38028b72017-12-20 17:54:12 -08004126 ad_rx.droid.smsStopTrackingIncomingMmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00004127 return True
4128
Nathan Harold123c9da2015-12-30 16:33:25 -08004129
4130def ensure_network_rat(log,
4131 ad,
4132 network_preference,
4133 rat_family,
4134 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08004135 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004136 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004137 """Ensure ad's current network is in expected rat_family.
4138 """
Nathan Harold123c9da2015-12-30 16:33:25 -08004139 return ensure_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004140 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
4141 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
Ang Li73697b32015-12-03 00:41:53 +00004142
Nathan Harold123c9da2015-12-30 16:33:25 -08004143
Nathan Harold7642fc92016-05-02 18:29:11 -07004144def ensure_network_rat_for_subscription(
4145 log,
4146 ad,
4147 sub_id,
4148 network_preference,
4149 rat_family,
4150 voice_or_data=None,
4151 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
4152 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004153 """Ensure ad's current network is in expected rat_family.
4154 """
Nathan Harold123c9da2015-12-30 16:33:25 -08004155 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
4156 network_preference, sub_id):
Betty Zhoua37acd32017-02-23 20:04:24 -08004157 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
4158 sub_id, network_preference)
Yang Liue23e5b12015-12-07 17:17:27 -08004159 return False
4160 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
Nathan Harold123c9da2015-12-30 16:33:25 -08004161 voice_or_data):
Betty Zhoua37acd32017-02-23 20:04:24 -08004162 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
4163 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08004164 return True
4165
4166 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08004167 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004168 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08004169 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004170
4171 result = wait_for_network_rat_for_subscription(
4172 log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
4173
Nathan Harold123c9da2015-12-30 16:33:25 -08004174 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08004175 "End of ensure_network_rat_for_subscription for %s. "
4176 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
4177 "data: %s(family: %s)", ad.serial, network_preference, rat_family,
4178 voice_or_data,
4179 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
4180 rat_family_from_rat(
4181 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
4182 sub_id)),
4183 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
4184 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08004185 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08004186 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08004187 return result
4188
Nathan Harold123c9da2015-12-30 16:33:25 -08004189
4190def ensure_network_preference(log,
4191 ad,
4192 network_preference,
4193 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08004194 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004195 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004196 """Ensure that current rat is within the device's preferred network rats.
4197 """
Nathan Harold123c9da2015-12-30 16:33:25 -08004198 return ensure_network_preference_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004199 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08004200 voice_or_data, max_wait_time, toggle_apm_after_setting)
4201
Nathan Harold123c9da2015-12-30 16:33:25 -08004202
4203def ensure_network_preference_for_subscription(
4204 log,
4205 ad,
4206 sub_id,
4207 network_preference,
4208 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08004209 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004210 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004211 """Ensure ad's network preference is <network_preference> for sub_id.
4212 """
4213 rat_family_list = rat_families_for_network_preference(network_preference)
Nathan Harold123c9da2015-12-30 16:33:25 -08004214 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
4215 network_preference, sub_id):
Yang Liue23e5b12015-12-07 17:17:27 -08004216 log.error("Set Preferred Networks failed.")
4217 return False
Nathan Harold123c9da2015-12-30 16:33:25 -08004218 if is_droid_in_rat_family_list_for_subscription(
4219 log, ad, sub_id, rat_family_list, voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08004220 return True
4221
4222 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08004223 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004224 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08004225 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004226
4227 result = wait_for_preferred_network_for_subscription(
4228 log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
4229
Betty Zhoua37acd32017-02-23 20:04:24 -08004230 ad.log.info(
4231 "End of ensure_network_preference_for_subscription. "
4232 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
4233 "data: %s(family: %s)", network_preference, rat_family_list,
4234 voice_or_data,
4235 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
4236 rat_family_from_rat(
4237 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
4238 sub_id)),
4239 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
4240 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08004241 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08004242 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08004243 return result
4244
Nathan Harold123c9da2015-12-30 16:33:25 -08004245
4246def ensure_network_generation(log,
4247 ad,
4248 generation,
Yang Liudf164e32016-01-07 16:49:32 -08004249 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004250 voice_or_data=None,
4251 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004252 """Ensure ad's network is <network generation> for default subscription ID.
4253
4254 Set preferred network generation to <generation>.
4255 Toggle ON/OFF airplane mode if necessary.
4256 Wait for ad in expected network type.
4257 """
4258 return ensure_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004259 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
4260 max_wait_time, voice_or_data, toggle_apm_after_setting)
Yang Liue23e5b12015-12-07 17:17:27 -08004261
Nathan Harold123c9da2015-12-30 16:33:25 -08004262
4263def ensure_network_generation_for_subscription(
4264 log,
4265 ad,
4266 sub_id,
4267 generation,
Yang Liudf164e32016-01-07 16:49:32 -08004268 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004269 voice_or_data=None,
4270 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08004271 """Ensure ad's network is <network generation> for specified subscription ID.
4272
4273 Set preferred network generation to <generation>.
4274 Toggle ON/OFF airplane mode if necessary.
4275 Wait for ad in expected network type.
4276 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004277 ad.log.info(
4278 "RAT network type voice: %s, data: %s",
4279 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
4280 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
Betty Zhoua37acd32017-02-23 20:04:24 -08004281
Yang Liue23e5b12015-12-07 17:17:27 -08004282 try:
Betty Zhoud2da7ba2017-03-24 12:54:34 -07004283 ad.log.info("Finding the network preference for generation %s for "
4284 "operator %s phone type %s", generation,
Betty Zhou3b2de072018-03-15 16:46:26 -07004285 ad.telephony["subscription"][sub_id]["operator"],
4286 ad.telephony["subscription"][sub_id]["phone_type"])
Jaineelc52d6852017-10-27 15:03:54 -07004287 network_preference = network_preference_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07004288 generation, ad.telephony["subscription"][sub_id]["operator"],
4289 ad.telephony["subscription"][sub_id]["phone_type"])
Betty Zhoud2da7ba2017-03-24 12:54:34 -07004290 ad.log.info("Network preference for %s is %s", generation,
4291 network_preference)
4292 rat_family = rat_family_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07004293 generation, ad.telephony["subscription"][sub_id]["operator"],
4294 ad.telephony["subscription"][sub_id]["phone_type"])
Betty Zhoud2da7ba2017-03-24 12:54:34 -07004295 except KeyError as e:
4296 ad.log.error("Failed to find a rat_family entry for generation %s"
4297 " for subscriber %s with error %s", generation,
Betty Zhou3b2de072018-03-15 16:46:26 -07004298 ad.telephony["subscription"][sub_id], e)
Yang Liue23e5b12015-12-07 17:17:27 -08004299 return False
4300
Betty Zhou1eedf722018-04-27 14:27:04 -07004301 if not set_preferred_network_mode_pref(log, ad, sub_id,
4302 network_preference):
4303 return False
Yang Liue23e5b12015-12-07 17:17:27 -08004304
Nathan Harold4a144a42016-09-19 14:16:24 -07004305 if is_droid_in_network_generation_for_subscription(
4306 log, ad, sub_id, generation, voice_or_data):
4307 return True
4308
Yang Liue23e5b12015-12-07 17:17:27 -08004309 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08004310 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004311 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08004312 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08004313
4314 result = wait_for_network_generation_for_subscription(
4315 log, ad, sub_id, generation, max_wait_time, voice_or_data)
4316
Betty Zhoua37acd32017-02-23 20:04:24 -08004317 ad.log.info(
Betty Zhou0f5efc42017-04-10 18:38:14 -07004318 "Ensure network %s %s %s. With network preference %s, "
Betty Zhoue955be22017-04-12 17:28:05 -07004319 "current: voice: %s(family: %s), data: %s(family: %s)", generation,
4320 voice_or_data, result, network_preference,
Betty Zhoua37acd32017-02-23 20:04:24 -08004321 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
4322 rat_generation_from_rat(
4323 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
4324 sub_id)),
4325 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
4326 rat_generation_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08004327 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08004328 sub_id)))
Betty Zhou351d1792017-11-10 16:26:30 -08004329 if not result:
Betty Zhoufe726dc2018-04-25 19:31:33 -07004330 get_telephony_signal_strength(ad)
Yang Liue23e5b12015-12-07 17:17:27 -08004331 return result
4332
Yang Liue23e5b12015-12-07 17:17:27 -08004333
Nathan Harold123c9da2015-12-30 16:33:25 -08004334def wait_for_network_rat(log,
4335 ad,
4336 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08004337 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004338 voice_or_data=None):
4339 return wait_for_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004340 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
4341 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08004342
4343
Nathan Harold7642fc92016-05-02 18:29:11 -07004344def wait_for_network_rat_for_subscription(
4345 log,
4346 ad,
4347 sub_id,
4348 rat_family,
4349 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
4350 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08004351 return _wait_for_droid_in_state_for_subscription(
4352 log, ad, sub_id, max_wait_time,
4353 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
4354
Yang Liue23e5b12015-12-07 17:17:27 -08004355
Nathan Harold123c9da2015-12-30 16:33:25 -08004356def wait_for_not_network_rat(log,
4357 ad,
4358 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08004359 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004360 voice_or_data=None):
4361 return wait_for_not_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004362 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
4363 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08004364
4365
4366def wait_for_not_network_rat_for_subscription(
4367 log,
4368 ad,
4369 sub_id,
4370 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08004371 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004372 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08004373 return _wait_for_droid_in_state_for_subscription(
4374 log, ad, sub_id, max_wait_time,
Betty Zhouf809c5c2017-03-21 14:55:59 -07004375 lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)
Betty Zhoua27e5d42017-01-17 11:33:04 -08004376 )
Yang Liue23e5b12015-12-07 17:17:27 -08004377
Nathan Harold123c9da2015-12-30 16:33:25 -08004378
4379def wait_for_preferred_network(log,
4380 ad,
4381 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08004382 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004383 voice_or_data=None):
4384 return wait_for_preferred_network_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004385 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08004386 max_wait_time, voice_or_data)
4387
Nathan Harold123c9da2015-12-30 16:33:25 -08004388
4389def wait_for_preferred_network_for_subscription(
4390 log,
4391 ad,
4392 sub_id,
4393 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08004394 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004395 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08004396 rat_family_list = rat_families_for_network_preference(network_preference)
4397 return _wait_for_droid_in_state_for_subscription(
4398 log, ad, sub_id, max_wait_time,
4399 is_droid_in_rat_family_list_for_subscription, rat_family_list,
4400 voice_or_data)
4401
Nathan Harold123c9da2015-12-30 16:33:25 -08004402
4403def wait_for_network_generation(log,
4404 ad,
4405 generation,
Yang Liudf164e32016-01-07 16:49:32 -08004406 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004407 voice_or_data=None):
4408 return wait_for_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004409 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
4410 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08004411
4412
4413def wait_for_network_generation_for_subscription(
4414 log,
4415 ad,
4416 sub_id,
4417 generation,
Yang Liudf164e32016-01-07 16:49:32 -08004418 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08004419 voice_or_data=None):
4420 return _wait_for_droid_in_state_for_subscription(
4421 log, ad, sub_id, max_wait_time,
4422 is_droid_in_network_generation_for_subscription, generation,
Yang Liue23e5b12015-12-07 17:17:27 -08004423 voice_or_data)
4424
Yang Liue23e5b12015-12-07 17:17:27 -08004425
4426def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None):
Nathan Harold123c9da2015-12-30 16:33:25 -08004427 return is_droid_in_rat_family_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004428 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
4429 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08004430
Yang Liue23e5b12015-12-07 17:17:27 -08004431
Nathan Harold123c9da2015-12-30 16:33:25 -08004432def is_droid_in_rat_family_for_subscription(log,
4433 ad,
4434 sub_id,
4435 rat_family,
4436 voice_or_data=None):
4437 return is_droid_in_rat_family_list_for_subscription(
4438 log, ad, sub_id, [rat_family], voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08004439
Nathan Harold123c9da2015-12-30 16:33:25 -08004440
4441def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None):
4442 return is_droid_in_rat_family_list_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08004443 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list,
4444 voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08004445
4446
4447def is_droid_in_rat_family_list_for_subscription(log,
4448 ad,
4449 sub_id,
4450 rat_family_list,
4451 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08004452 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
4453 if voice_or_data:
4454 service_list = [voice_or_data]
4455
4456 for service in service_list:
4457 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
4458 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
4459 continue
Yang Liu7a2e7ee2015-12-28 15:32:44 -08004460 if rat_family_from_rat(nw_rat) in rat_family_list:
Yang Liue23e5b12015-12-07 17:17:27 -08004461 return True
4462 return False
4463
Nathan Harold123c9da2015-12-30 16:33:25 -08004464
Yang Liue23e5b12015-12-07 17:17:27 -08004465def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data):
4466 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00004467
4468 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08004469 log: log object.
4470 ad: android device.
4471 nw_gen: expected generation "4g", "3g", "2g".
4472 voice_or_data: check voice network generation or data network generation
4473 This parameter is optional. If voice_or_data is None, then if
4474 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00004475
4476 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08004477 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00004478 """
Yang Liue23e5b12015-12-07 17:17:27 -08004479 return is_droid_in_network_generation_for_subscription(
4480 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data)
Ang Li73697b32015-12-03 00:41:53 +00004481
Nathan Harold123c9da2015-12-30 16:33:25 -08004482
4483def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen,
4484 voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08004485 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00004486
4487 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08004488 log: log object.
4489 ad: android device.
4490 nw_gen: expected generation "4g", "3g", "2g".
4491 voice_or_data: check voice network generation or data network generation
4492 This parameter is optional. If voice_or_data is None, then if
4493 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00004494
4495 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08004496 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00004497 """
Yang Liue23e5b12015-12-07 17:17:27 -08004498 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
Ang Li73697b32015-12-03 00:41:53 +00004499
Yang Liue23e5b12015-12-07 17:17:27 -08004500 if voice_or_data:
4501 service_list = [voice_or_data]
Ang Li73697b32015-12-03 00:41:53 +00004502
Yang Liue23e5b12015-12-07 17:17:27 -08004503 for service in service_list:
4504 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
Betty Zhou89d090b2017-05-23 11:12:19 -07004505 ad.log.info("%s network rat is %s", service, nw_rat)
Yang Liue23e5b12015-12-07 17:17:27 -08004506 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
4507 continue
4508
Yang Liu7a2e7ee2015-12-28 15:32:44 -08004509 if rat_generation_from_rat(nw_rat) == nw_gen:
Betty Zhou89d090b2017-05-23 11:12:19 -07004510 ad.log.info("%s network rat %s is expected %s", service, nw_rat,
4511 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08004512 return True
4513 else:
Betty Zhou89d090b2017-05-23 11:12:19 -07004514 ad.log.info("%s network rat %s is %s, does not meet expected %s",
Betty Zhouee311052017-12-19 13:09:56 -08004515 service, nw_rat, rat_generation_from_rat(nw_rat),
4516 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08004517 return False
4518
4519 return False
Ang Li73697b32015-12-03 00:41:53 +00004520
Nathan Harold123c9da2015-12-30 16:33:25 -08004521
Ang Li73697b32015-12-03 00:41:53 +00004522def get_network_rat(log, ad, voice_or_data):
4523 """Get current network type (Voice network type, or data network type)
4524 for default subscription id
4525
4526 Args:
4527 ad: Android Device Object
4528 voice_or_data: Input parameter indicating to get voice network type or
4529 data network type.
4530
4531 Returns:
4532 Current voice/data network type.
4533 """
4534 return get_network_rat_for_subscription(
4535 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
4536
Nathan Harold123c9da2015-12-30 16:33:25 -08004537
Ang Li73697b32015-12-03 00:41:53 +00004538def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data):
4539 """Get current network type (Voice network type, or data network type)
4540 for specified subscription id
4541
4542 Args:
4543 ad: Android Device Object
4544 sub_id: subscription ID
4545 voice_or_data: Input parameter indicating to get voice network type or
4546 data network type.
4547
4548 Returns:
4549 Current voice/data network type.
4550 """
4551 if voice_or_data == NETWORK_SERVICE_VOICE:
Nathan Harold123c9da2015-12-30 16:33:25 -08004552 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
4553 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004554 elif voice_or_data == NETWORK_SERVICE_DATA:
Nathan Harold123c9da2015-12-30 16:33:25 -08004555 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
4556 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004557 else:
Yang Liuaed3eef2015-12-15 18:40:25 -08004558 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004559
4560 if ret_val is None:
4561 log.error("get_network_rat(): Unexpected null return value")
4562 return RAT_UNKNOWN
4563 else:
4564 return ret_val
4565
Nathan Harold123c9da2015-12-30 16:33:25 -08004566
Ang Li73697b32015-12-03 00:41:53 +00004567def get_network_gen(log, ad, voice_or_data):
4568 """Get current network generation string (Voice network type, or data network type)
4569
4570 Args:
4571 ad: Android Device Object
4572 voice_or_data: Input parameter indicating to get voice network generation
4573 or data network generation.
4574
4575 Returns:
4576 Current voice/data network generation.
4577 """
4578 return get_network_gen_for_subscription(
4579 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
4580
Nathan Harold123c9da2015-12-30 16:33:25 -08004581
Ang Li73697b32015-12-03 00:41:53 +00004582def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data):
4583 """Get current network generation string (Voice network type, or data network type)
4584
4585 Args:
4586 ad: Android Device Object
4587 voice_or_data: Input parameter indicating to get voice network generation
4588 or data network generation.
4589
4590 Returns:
4591 Current voice/data network generation.
4592 """
4593 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07004594 return rat_generation_from_rat(
4595 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data))
Betty Zhoua37acd32017-02-23 20:04:24 -08004596 except KeyError as e:
4597 ad.log.error("KeyError %s", e)
Yang Liue23e5b12015-12-07 17:17:27 -08004598 return GEN_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00004599
Nathan Harold123c9da2015-12-30 16:33:25 -08004600
4601def check_voice_mail_count(log, ad, voice_mail_count_before,
4602 voice_mail_count_after):
Ang Li73697b32015-12-03 00:41:53 +00004603 """function to check if voice mail count is correct after leaving a new voice message.
4604 """
4605 return get_voice_mail_count_check_function(get_operator_name(log, ad))(
4606 voice_mail_count_before, voice_mail_count_after)
4607
Nathan Harold123c9da2015-12-30 16:33:25 -08004608
Ang Li73697b32015-12-03 00:41:53 +00004609def get_voice_mail_number(log, ad):
4610 """function to get the voice mail number
4611 """
Betty Zhou94023182017-06-07 18:02:14 -07004612 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00004613 if voice_mail_number is None:
4614 return get_phone_number(log, ad)
4615 return voice_mail_number
4616
Nathan Harold123c9da2015-12-30 16:33:25 -08004617
Betty Zhouf809c5c2017-03-21 14:55:59 -07004618def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00004619 """Ensure ads idle (not in call).
4620 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07004621 result = True
Ang Li73697b32015-12-03 00:41:53 +00004622 for ad in ads:
Betty Zhouf809c5c2017-03-21 14:55:59 -07004623 if not ensure_phone_idle(log, ad, max_time=max_time):
4624 result = False
4625 return result
Ang Li73697b32015-12-03 00:41:53 +00004626
Nathan Harold123c9da2015-12-30 16:33:25 -08004627
Betty Zhouf809c5c2017-03-21 14:55:59 -07004628def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00004629 """Ensure ad idle (not in call).
4630 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07004631 if ad.droid.telecomIsInCall():
4632 ad.droid.telecomEndCall()
4633 if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
Betty Zhou94023182017-06-07 18:02:14 -07004634 ad.log.error("Failed to end call")
Betty Zhouf809c5c2017-03-21 14:55:59 -07004635 return False
4636 return True
Ang Li73697b32015-12-03 00:41:53 +00004637
Nathan Harold123c9da2015-12-30 16:33:25 -08004638
Betty Zhou7f45f552017-03-15 19:12:52 -07004639def ensure_phone_subscription(log, ad):
4640 """Ensure Phone Subscription.
4641 """
4642 #check for sim and service
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07004643 duration = 0
4644 while duration < MAX_WAIT_TIME_NW_SELECTION:
4645 subInfo = ad.droid.subscriptionGetAllSubInfoList()
4646 if subInfo and len(subInfo) >= 1:
Betty Zhoue32dd3b2017-11-28 19:05:55 -08004647 ad.log.debug("Find valid subcription %s", subInfo)
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07004648 break
4649 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07004650 ad.log.info("Did not find any subscription")
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07004651 time.sleep(5)
4652 duration += 5
4653 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07004654 ad.log.error("Unable to find a valid subscription!")
Betty Zhou7f45f552017-03-15 19:12:52 -07004655 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07004656 while duration < MAX_WAIT_TIME_NW_SELECTION:
4657 data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
4658 voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
4659 if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
4660 ad.log.debug("Find valid voice or data sub id")
4661 break
4662 else:
4663 ad.log.info("Did not find valid data or voice sub id")
4664 time.sleep(5)
4665 duration += 5
4666 else:
4667 ad.log.error("Unable to find valid data or voice sub id")
Betty Zhou7f45f552017-03-15 19:12:52 -07004668 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07004669 while duration < MAX_WAIT_TIME_NW_SELECTION:
4670 data_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
4671 if data_sub_id > INVALID_SUB_ID:
4672 data_rat = get_network_rat_for_subscription(
4673 log, ad, data_sub_id, NETWORK_SERVICE_DATA)
4674 else:
4675 data_rat = RAT_UNKNOWN
4676 if voice_sub_id > INVALID_SUB_ID:
4677 voice_rat = get_network_rat_for_subscription(
4678 log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
4679 else:
4680 voice_rat = RAT_UNKNOWN
4681 if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
4682 ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
4683 data_sub_id, data_rat, voice_sub_id, voice_rat)
4684 return True
4685 else:
4686 ad.log.info("Did not attach for data or voice service")
4687 time.sleep(5)
4688 duration += 5
4689 else:
4690 ad.log.error("Did not attach for voice or data service")
Betty Zhou7f45f552017-03-15 19:12:52 -07004691 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07004692
4693
Betty Zhou68fc0d02017-04-26 13:42:54 -07004694def ensure_phone_default_state(log, ad, check_subscription=True):
Ang Li73697b32015-12-03 00:41:53 +00004695 """Ensure ad in default state.
4696 Phone not in call.
4697 Phone have no stored WiFi network and WiFi disconnected.
4698 Phone not in airplane mode.
4699 """
4700 result = True
Betty Zhouf25ce442017-03-03 14:28:36 -08004701 if not toggle_airplane_mode(log, ad, False, False):
4702 ad.log.error("Fail to turn off airplane mode")
4703 result = False
Betty Zhou94023182017-06-07 18:02:14 -07004704 try:
Betty Zhou77f2bed2017-10-04 18:39:07 -07004705 set_wifi_to_default(log, ad)
Betty Zhou94023182017-06-07 18:02:14 -07004706 if ad.droid.telecomIsInCall():
4707 ad.droid.telecomEndCall()
4708 if not wait_for_droid_not_in_call(log, ad):
4709 ad.log.error("Failed to end call")
4710 ad.droid.telephonyFactoryReset()
4711 ad.droid.imsFactoryReset()
Betty Zhou2cf788e2017-06-27 17:25:53 -07004712 data_roaming = getattr(ad, 'roaming', False)
4713 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
4714 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Betty Zhouf3366012017-11-21 18:23:20 -08004715 remove_mobile_data_usage_limit(ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07004716 if not wait_for_not_network_rat(
4717 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
4718 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
4719 RAT_FAMILY_WLAN)
4720 result = False
4721
4722 if check_subscription and not ensure_phone_subscription(log, ad):
4723 ad.log.error("Unable to find a valid subscription!")
4724 result = False
Betty Zhou94023182017-06-07 18:02:14 -07004725 except Exception as e:
4726 ad.log.error("%s failure, toggle APM instead", e)
Betty Zhou77f2bed2017-10-04 18:39:07 -07004727 toggle_airplane_mode_by_adb(log, ad, True)
4728 toggle_airplane_mode_by_adb(log, ad, False)
4729 ad.send_keycode("ENDCALL")
4730 ad.adb.shell("settings put global wfc_ims_enabled 0")
4731 ad.adb.shell("settings put global mobile_data 1")
Betty Zhouf809c5c2017-03-21 14:55:59 -07004732
Ang Li73697b32015-12-03 00:41:53 +00004733 return result
4734
Nathan Harold123c9da2015-12-30 16:33:25 -08004735
Betty Zhou68fc0d02017-04-26 13:42:54 -07004736def ensure_phones_default_state(log, ads, check_subscription=True):
Ang Li73697b32015-12-03 00:41:53 +00004737 """Ensure ads in default state.
4738 Phone not in call.
4739 Phone have no stored WiFi network and WiFi disconnected.
4740 Phone not in airplane mode.
Nathan Haroldeb60b192016-08-24 14:41:55 -07004741
4742 Returns:
4743 True if all steps of restoring default state succeed.
4744 False if any of the steps to restore default state fails.
Ang Li73697b32015-12-03 00:41:53 +00004745 """
4746 tasks = []
4747 for ad in ads:
Betty Zhou68fc0d02017-04-26 13:42:54 -07004748 tasks.append((ensure_phone_default_state, (log, ad,
4749 check_subscription)))
Ang Li73697b32015-12-03 00:41:53 +00004750 if not multithread_func(log, tasks):
4751 log.error("Ensure_phones_default_state Fail.")
4752 return False
4753 return True
4754
Nathan Harold123c9da2015-12-30 16:33:25 -08004755
Betty Zhoua37acd32017-02-23 20:04:24 -08004756def check_is_wifi_connected(log, ad, wifi_ssid):
4757 """Check if ad is connected to wifi wifi_ssid.
Ang Li73697b32015-12-03 00:41:53 +00004758
4759 Args:
4760 log: Log object.
4761 ad: Android device object.
4762 wifi_ssid: WiFi network SSID.
Ang Li73697b32015-12-03 00:41:53 +00004763
Betty Zhoua37acd32017-02-23 20:04:24 -08004764 Returns:
4765 True if wifi is connected to wifi_ssid
4766 False if wifi is not connected to wifi_ssid
Ang Li73697b32015-12-03 00:41:53 +00004767 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004768 wifi_info = ad.droid.wifiGetConnectionInfo()
Betty Zhouee311052017-12-19 13:09:56 -08004769 if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid:
Betty Zhoua37acd32017-02-23 20:04:24 -08004770 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou1b302fd2017-11-17 11:43:09 -08004771 ad.on_mobile_data = False
Betty Zhouccd171d2017-02-13 15:11:33 -08004772 return True
Betty Zhoua37acd32017-02-23 20:04:24 -08004773 else:
4774 ad.log.info("Wifi is not connected to %s", wifi_ssid)
4775 ad.log.debug("Wifi connection_info=%s", wifi_info)
Betty Zhou1b302fd2017-11-17 11:43:09 -08004776 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08004777 return False
4778
4779
4780def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3):
4781 """Ensure ad connected to wifi on network wifi_ssid.
4782
4783 Args:
4784 log: Log object.
4785 ad: Android device object.
4786 wifi_ssid: WiFi network SSID.
4787 wifi_pwd: optional secure network password.
4788 retries: the number of retries.
4789
4790 Returns:
4791 True if wifi is connected to wifi_ssid
4792 False if wifi is not connected to wifi_ssid
4793 """
Betty Zhouf987b8f2017-03-09 16:34:00 -08004794 network = {WIFI_SSID_KEY: wifi_ssid}
Betty Zhouf25ce442017-03-03 14:28:36 -08004795 if wifi_pwd:
Betty Zhouf987b8f2017-03-09 16:34:00 -08004796 network[WIFI_PWD_KEY] = wifi_pwd
Betty Zhouf25ce442017-03-03 14:28:36 -08004797 for i in range(retries):
4798 if not ad.droid.wifiCheckState():
4799 ad.log.info("Wifi state is down. Turn on Wifi")
4800 ad.droid.wifiToggleState(True)
4801 if check_is_wifi_connected(log, ad, wifi_ssid):
4802 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07004803 return verify_internet_connection(log, ad, retries=3)
Betty Zhouf25ce442017-03-03 14:28:36 -08004804 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08004805 ad.log.info("Connecting to wifi %s", wifi_ssid)
Betty Zhou9a27c6a2017-05-22 12:55:50 -07004806 try:
4807 ad.droid.wifiConnectByConfig(network)
4808 except Exception:
Betty Zhou94023182017-06-07 18:02:14 -07004809 ad.log.info("Connecting to wifi by wifiConnect instead")
Betty Zhou9a27c6a2017-05-22 12:55:50 -07004810 ad.droid.wifiConnect(network)
Betty Zhoua37acd32017-02-23 20:04:24 -08004811 time.sleep(20)
4812 if check_is_wifi_connected(log, ad, wifi_ssid):
Betty Zhou68fc0d02017-04-26 13:42:54 -07004813 ad.log.info("Connected to Wifi %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07004814 return verify_internet_connection(log, ad, retries=3)
Betty Zhoua37acd32017-02-23 20:04:24 -08004815 ad.log.info("Fail to connected to wifi %s", wifi_ssid)
Ang Li73697b32015-12-03 00:41:53 +00004816 return False
4817
Nathan Harold123c9da2015-12-30 16:33:25 -08004818
Betty Zhoua37acd32017-02-23 20:04:24 -08004819def forget_all_wifi_networks(log, ad):
4820 """Forget all stored wifi network information
4821
4822 Args:
4823 log: log object
4824 ad: AndroidDevice object
4825
4826 Returns:
4827 boolean success (True) or failure (False)
4828 """
4829 if not ad.droid.wifiGetConfiguredNetworks():
Betty Zhou1b302fd2017-11-17 11:43:09 -08004830 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08004831 return True
4832 try:
4833 old_state = ad.droid.wifiCheckState()
Betty Zhouf987b8f2017-03-09 16:34:00 -08004834 wifi_test_utils.reset_wifi(ad)
Betty Zhou7f45f552017-03-15 19:12:52 -07004835 wifi_toggle_state(log, ad, old_state)
Betty Zhoua37acd32017-02-23 20:04:24 -08004836 except Exception as e:
4837 log.error("forget_all_wifi_networks with exception: %s", e)
4838 return False
Betty Zhou1b302fd2017-11-17 11:43:09 -08004839 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08004840 return True
4841
4842
Betty Zhouf987b8f2017-03-09 16:34:00 -08004843def wifi_reset(log, ad, disable_wifi=True):
4844 """Forget all stored wifi networks and (optionally) disable WiFi
4845
4846 Args:
4847 log: log object
4848 ad: AndroidDevice object
4849 disable_wifi: boolean to disable wifi, defaults to True
4850 Returns:
4851 boolean success (True) or failure (False)
4852 """
4853 if not forget_all_wifi_networks(log, ad):
4854 ad.log.error("Unable to forget all networks")
4855 return False
4856 if not wifi_toggle_state(log, ad, not disable_wifi):
4857 ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi)
4858 return False
4859 return True
4860
4861
Betty Zhoua37acd32017-02-23 20:04:24 -08004862def set_wifi_to_default(log, ad):
4863 """Set wifi to default state (Wifi disabled and no configured network)
4864
4865 Args:
4866 log: log object
4867 ad: AndroidDevice object
4868
4869 Returns:
4870 boolean success (True) or failure (False)
4871 """
Betty Zhouf25ce442017-03-03 14:28:36 -08004872 ad.droid.wifiFactoryReset()
Betty Zhoua37acd32017-02-23 20:04:24 -08004873 ad.droid.wifiToggleState(False)
Betty Zhou1b302fd2017-11-17 11:43:09 -08004874 ad.on_mobile_data = True
Betty Zhouf987b8f2017-03-09 16:34:00 -08004875
4876
4877def wifi_toggle_state(log, ad, state, retries=3):
4878 """Toggle the WiFi State
4879
4880 Args:
4881 log: log object
4882 ad: AndroidDevice object
4883 state: True, False, or None
4884
4885 Returns:
4886 boolean success (True) or failure (False)
4887 """
4888 for i in range(retries):
4889 if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False):
Betty Zhou1b302fd2017-11-17 11:43:09 -08004890 ad.on_mobile_data = not state
Betty Zhouf987b8f2017-03-09 16:34:00 -08004891 return True
4892 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
4893 return False
4894
4895
4896def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
4897 """Start a Tethering Session
4898
4899 Args:
4900 log: log object
4901 ad: AndroidDevice object
4902 ssid: the name of the WiFi network
4903 password: optional password, used for secure networks.
4904 ap_band=DEPRECATED specification of 2G or 5G tethering
4905 Returns:
4906 boolean success (True) or failure (False)
4907 """
4908 return wifi_test_utils._assert_on_fail_handler(
4909 wifi_test_utils.start_wifi_tethering,
4910 False,
4911 ad,
4912 ssid,
4913 password,
4914 band=ap_band)
4915
4916
4917def stop_wifi_tethering(log, ad):
4918 """Stop a Tethering Session
4919
4920 Args:
4921 log: log object
4922 ad: AndroidDevice object
4923 Returns:
4924 boolean success (True) or failure (False)
4925 """
4926 return wifi_test_utils._assert_on_fail_handler(
4927 wifi_test_utils.stop_wifi_tethering, False, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08004928
4929
Yang Liu98fd9d72016-03-04 12:14:49 -08004930def reset_preferred_network_type_to_allowable_range(log, ad):
4931 """If preferred network type is not in allowable range, reset to GEN_4G
4932 preferred network type.
4933
4934 Args:
4935 log: log object
4936 ad: android device object
4937
4938 Returns:
4939 None
4940 """
Betty Zhou3b2de072018-03-15 16:46:26 -07004941 for sub_id, sub_info in ad.telephony["subscription"].items():
Yang Liu98fd9d72016-03-04 12:14:49 -08004942 current_preference = \
4943 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id)
Betty Zhoubb192482017-03-01 14:38:56 -08004944 ad.log.debug("sub_id network preference is %s", current_preference)
Yang Liu4072cfa2016-04-06 11:25:07 -07004945 try:
Nathan Harold7642fc92016-05-02 18:29:11 -07004946 if current_preference not in get_allowable_network_preference(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07004947 sub_info["operator"], sub_info["phone_type"]):
Jaineelc52d6852017-10-27 15:03:54 -07004948 network_preference = network_preference_for_generation(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07004949 GEN_4G, sub_info["operator"], sub_info["phone_type"])
Yang Liu4072cfa2016-04-06 11:25:07 -07004950 ad.droid.telephonySetPreferredNetworkTypesForSubscription(
4951 network_preference, sub_id)
4952 except KeyError:
4953 pass
Yang Liu98fd9d72016-03-04 12:14:49 -08004954
Nathan Harold7642fc92016-05-02 18:29:11 -07004955
Ang Li73697b32015-12-03 00:41:53 +00004956def task_wrapper(task):
4957 """Task wrapper for multithread_func
4958
4959 Args:
4960 task[0]: function to be wrapped.
4961 task[1]: function args.
4962
4963 Returns:
4964 Return value of wrapped function call.
4965 """
4966 func = task[0]
4967 params = task[1]
4968 return func(*params)
4969
Nathan Harold123c9da2015-12-30 16:33:25 -08004970
Patrick Chiang75b89862017-10-13 17:02:29 -07004971def run_multithread_func_async(log, task):
4972 """Starts a multi-threaded function asynchronously.
4973
4974 Args:
4975 log: log object.
4976 task: a task to be executed in parallel.
4977
4978 Returns:
4979 Future object representing the execution of the task.
4980 """
4981 executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
4982 try:
4983 future_object = executor.submit(task_wrapper, task)
4984 except Exception as e:
4985 log.error("Exception error %s", e)
4986 raise
4987 return future_object
4988
4989
Betty Zhouccd171d2017-02-13 15:11:33 -08004990def run_multithread_func(log, tasks):
4991 """Run multi-thread functions and return results.
4992
4993 Args:
4994 log: log object.
4995 tasks: a list of tasks to be executed in parallel.
4996
4997 Returns:
4998 results for tasks.
4999 """
Betty Zhouee311052017-12-19 13:09:56 -08005000 MAX_NUMBER_OF_WORKERS = 10
Betty Zhouccd171d2017-02-13 15:11:33 -08005001 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
5002 executor = concurrent.futures.ThreadPoolExecutor(
5003 max_workers=number_of_workers)
Betty Zhou8802ec62017-12-18 19:44:29 -08005004 if not log: log = logging
Betty Zhou95ed1862017-07-21 13:29:02 -07005005 try:
5006 results = list(executor.map(task_wrapper, tasks))
5007 except Exception as e:
5008 log.error("Exception error %s", e)
5009 raise
Betty Zhouccd171d2017-02-13 15:11:33 -08005010 executor.shutdown()
Betty Zhou0111ae02017-11-29 20:37:26 -08005011 if log:
5012 log.info("multithread_func %s result: %s",
5013 [task[0].__name__ for task in tasks], results)
Betty Zhouccd171d2017-02-13 15:11:33 -08005014 return results
5015
5016
Ang Li73697b32015-12-03 00:41:53 +00005017def multithread_func(log, tasks):
5018 """Multi-thread function wrapper.
5019
5020 Args:
5021 log: log object.
5022 tasks: tasks to be executed in parallel.
5023
5024 Returns:
5025 True if all tasks return True.
5026 False if any task return False.
5027 """
Betty Zhouccd171d2017-02-13 15:11:33 -08005028 results = run_multithread_func(log, tasks)
Ang Li73697b32015-12-03 00:41:53 +00005029 for r in results:
5030 if not r:
5031 return False
5032 return True
5033
Nathan Harold123c9da2015-12-30 16:33:25 -08005034
Betty Zhouccd171d2017-02-13 15:11:33 -08005035def multithread_func_and_check_results(log, tasks, expected_results):
5036 """Multi-thread function wrapper.
5037
5038 Args:
5039 log: log object.
5040 tasks: tasks to be executed in parallel.
5041 expected_results: check if the results from tasks match expected_results.
5042
5043 Returns:
5044 True if expected_results are met.
5045 False if expected_results are not met.
5046 """
5047 return_value = True
5048 results = run_multithread_func(log, tasks)
5049 log.info("multithread_func result: %s, expecting %s", results,
5050 expected_results)
5051 for task, result, expected_result in zip(tasks, results, expected_results):
5052 if result != expected_result:
5053 logging.info("Result for task %s is %s, expecting %s", task[0],
5054 result, expected_result)
5055 return_value = False
5056 return return_value
5057
5058
Ang Li73697b32015-12-03 00:41:53 +00005059def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME):
5060 """Set phone screen on time.
5061
5062 Args:
5063 log: Log object.
5064 ad: Android device object.
5065 screen_on_time: screen on time.
5066 This is optional, default value is MAX_SCREEN_ON_TIME.
5067 Returns:
5068 True if set successfully.
5069 """
5070 ad.droid.setScreenTimeout(screen_on_time)
5071 return screen_on_time == ad.droid.getScreenTimeout()
5072
Nathan Harold123c9da2015-12-30 16:33:25 -08005073
Ang Li73697b32015-12-03 00:41:53 +00005074def set_phone_silent_mode(log, ad, silent_mode=True):
5075 """Set phone silent mode.
5076
5077 Args:
5078 log: Log object.
5079 ad: Android device object.
5080 silent_mode: set phone silent or not.
5081 This is optional, default value is True (silent mode on).
5082 Returns:
5083 True if set successfully.
5084 """
5085 ad.droid.toggleRingerSilentMode(silent_mode)
Betty Zhoua37acd32017-02-23 20:04:24 -08005086 ad.droid.setMediaVolume(0)
5087 ad.droid.setVoiceCallVolume(0)
5088 ad.droid.setAlarmVolume(0)
Betty Zhou38391dc2017-07-17 17:25:37 -07005089 out = ad.adb.shell("settings list system | grep volume")
5090 for attr in re.findall(r"(volume_.*)=\d+", out):
5091 ad.adb.shell("settings put system %s 0" % attr)
Ang Li73697b32015-12-03 00:41:53 +00005092 return silent_mode == ad.droid.checkRingerSilentMode()
5093
Nathan Harold123c9da2015-12-30 16:33:25 -08005094
Betty Zhou1eedf722018-04-27 14:27:04 -07005095def set_preferred_network_mode_pref(log,
5096 ad,
5097 sub_id,
5098 network_preference,
5099 timeout=WAIT_TIME_ANDROID_STATE_SETTLING):
Jaineelcd748202017-08-10 12:23:42 -07005100 """Set Preferred Network Mode for Sub_id
5101 Args:
5102 log: Log object.
5103 ad: Android device object.
5104 sub_id: Subscription ID.
5105 network_preference: Network Mode Type
5106 """
Betty Zhou1eedf722018-04-27 14:27:04 -07005107 begin_time = get_device_epoch_time(ad)
5108 if ad.droid.telephonyGetPreferredNetworkTypesForSubscription(
5109 sub_id) == network_preference:
5110 ad.log.info("Current ModePref for Sub %s is in %s", sub_id,
5111 network_preference)
5112 return True
Jaineelcd748202017-08-10 12:23:42 -07005113 ad.log.info("Setting ModePref to %s for Sub %s", network_preference,
5114 sub_id)
Betty Zhou1eedf722018-04-27 14:27:04 -07005115 while timeout >= 0:
5116 if ad.droid.telephonySetPreferredNetworkTypesForSubscription(
5117 network_preference, sub_id):
5118 return True
5119 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5120 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
5121 error_msg = "Failed to set sub_id %s PreferredNetworkType to %s" % (
5122 sub_id, network_preference)
5123 search_results = ad.search_logcat(
5124 "REQUEST_SET_PREFERRED_NETWORK_TYPE error", begin_time=begin_time)
5125 if search_results:
5126 log_message = search_results[-1]["log_message"]
5127 if "DEVICE_IN_USE" in log_message:
5128 error_msg = "%s due to DEVICE_IN_USE" % error_msg
5129 else:
5130 error_msg = "%s due to %s" % (error_msg, log_message)
5131 ad.log.error(error_msg)
5132 return False
Jaineelcd748202017-08-10 12:23:42 -07005133
5134
Ang Li73697b32015-12-03 00:41:53 +00005135def set_preferred_subid_for_sms(log, ad, sub_id):
5136 """set subscription id for SMS
5137
5138 Args:
5139 log: Log object.
5140 ad: Android device object.
5141 sub_id :Subscription ID.
5142
5143 """
Betty Zhoua37acd32017-02-23 20:04:24 -08005144 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00005145 ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
5146 # Wait to make sure settings take effect
5147 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
5148 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId()
5149
Nathan Harold123c9da2015-12-30 16:33:25 -08005150
Ang Li73697b32015-12-03 00:41:53 +00005151def set_preferred_subid_for_data(log, ad, sub_id):
5152 """set subscription id for data
5153
5154 Args:
5155 log: Log object.
5156 ad: Android device object.
5157 sub_id :Subscription ID.
5158
5159 """
Betty Zhoua37acd32017-02-23 20:04:24 -08005160 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00005161 ad.droid.subscriptionSetDefaultDataSubId(sub_id)
5162 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
5163 # Wait to make sure settings take effect
5164 # Data SIM change takes around 1 min
5165 # Check whether data has changed to selected sim
Nathan Harold7642fc92016-05-02 18:29:11 -07005166 if not wait_for_data_connection(log, ad, True,
5167 MAX_WAIT_TIME_DATA_SUB_CHANGE):
Ang Li73697b32015-12-03 00:41:53 +00005168 log.error("Data Connection failed - Not able to switch Data SIM")
5169 return False
5170 return True
5171
Nathan Harold123c9da2015-12-30 16:33:25 -08005172
Ang Li73697b32015-12-03 00:41:53 +00005173def set_preferred_subid_for_voice(log, ad, sub_id):
5174 """set subscription id for voice
5175
5176 Args:
5177 log: Log object.
5178 ad: Android device object.
5179 sub_id :Subscription ID.
5180
5181 """
Betty Zhoua37acd32017-02-23 20:04:24 -08005182 ad.log.info("Setting subscription %s as Voice SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00005183 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
5184 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
5185 # Wait to make sure settings take effect
5186 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
5187 return True
5188
Nathan Harold123c9da2015-12-30 16:33:25 -08005189
Ang Li73697b32015-12-03 00:41:53 +00005190def set_call_state_listen_level(log, ad, value, sub_id):
5191 """Set call state listen level for subscription id.
5192
5193 Args:
5194 log: Log object.
5195 ad: Android device object.
5196 value: True or False
5197 sub_id :Subscription ID.
5198
5199 Returns:
5200 True or False
5201 """
5202 if sub_id == INVALID_SUB_ID:
5203 log.error("Invalid Subscription ID")
5204 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08005205 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08005206 "Foreground", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08005207 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08005208 "Ringing", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08005209 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08005210 "Background", value, sub_id)
Ang Li73697b32015-12-03 00:41:53 +00005211 return True
5212
Nathan Harold123c9da2015-12-30 16:33:25 -08005213
Ang Li73697b32015-12-03 00:41:53 +00005214def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False):
5215 """set subscription id for voice, sms and data
5216
5217 Args:
5218 log: Log object.
5219 ad: Android device object.
5220 sub_id :Subscription ID.
5221 voice: True if to set subscription as default voice subscription
5222 sms: True if to set subscription as default sms subscription
5223 data: True if to set subscription as default data subscription
5224
5225 """
5226 if sub_id == INVALID_SUB_ID:
5227 log.error("Invalid Subscription ID")
5228 return False
5229 else:
5230 if voice:
5231 if not set_preferred_subid_for_voice(log, ad, sub_id):
5232 return False
5233 if sms:
5234 if not set_preferred_subid_for_sms(log, ad, sub_id):
5235 return False
5236 if data:
Nathan Harold123c9da2015-12-30 16:33:25 -08005237 if not set_preferred_subid_for_data(log, ad, sub_id):
Ang Li73697b32015-12-03 00:41:53 +00005238 return False
5239 return True
5240
Nathan Harold7642fc92016-05-02 18:29:11 -07005241
Yang Liu8e6adff2016-02-05 10:24:04 -08005242def is_event_match(event, field, value):
5243 """Return if <field> in "event" match <value> or not.
Ang Li73697b32015-12-03 00:41:53 +00005244
5245 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08005246 event: event to test. This event need to have <field>.
5247 field: field to match.
5248 value: value to match.
Ang Li73697b32015-12-03 00:41:53 +00005249
5250 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08005251 True if <field> in "event" match <value>.
Ang Li73697b32015-12-03 00:41:53 +00005252 False otherwise.
5253 """
Yang Liu8e6adff2016-02-05 10:24:04 -08005254 return is_event_match_for_list(event, field, [value])
Ang Li73697b32015-12-03 00:41:53 +00005255
Nathan Harold123c9da2015-12-30 16:33:25 -08005256
Yang Liu8e6adff2016-02-05 10:24:04 -08005257def is_event_match_for_list(event, field, value_list):
5258 """Return if <field> in "event" match any one of the value
5259 in "value_list" or not.
Ang Li73697b32015-12-03 00:41:53 +00005260
5261 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08005262 event: event to test. This event need to have <field>.
5263 field: field to match.
5264 value_list: a list of value to match.
Ang Li73697b32015-12-03 00:41:53 +00005265
5266 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08005267 True if <field> in "event" match one of the value in "value_list".
Ang Li73697b32015-12-03 00:41:53 +00005268 False otherwise.
5269 """
5270 try:
Yang Liu8e6adff2016-02-05 10:24:04 -08005271 value_in_event = event['data'][field]
Ang Li73697b32015-12-03 00:41:53 +00005272 except KeyError:
5273 return False
Yang Liu8e6adff2016-02-05 10:24:04 -08005274 for value in value_list:
5275 if value_in_event == value:
Ang Li73697b32015-12-03 00:41:53 +00005276 return True
5277 return False
5278
Nathan Harold123c9da2015-12-30 16:33:25 -08005279
Yang Liu8e6adff2016-02-05 10:24:04 -08005280def is_network_call_back_event_match(event, network_callback_id,
5281 network_callback_event):
Ang Li73697b32015-12-03 00:41:53 +00005282 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07005283 return (
5284 (network_callback_id == event['data'][NetworkCallbackContainer.ID])
Betty Zhouee311052017-12-19 13:09:56 -08005285 and (network_callback_event == event['data']
5286 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT]))
Ang Li73697b32015-12-03 00:41:53 +00005287 except KeyError:
5288 return False
5289
Nathan Harold123c9da2015-12-30 16:33:25 -08005290
Ang Li73697b32015-12-03 00:41:53 +00005291def is_build_id(log, ad, build_id):
5292 """Return if ad's build id is the same as input parameter build_id.
5293
5294 Args:
5295 log: log object.
5296 ad: android device object.
5297 build_id: android build id.
5298
5299 Returns:
5300 True if ad's build id is the same as input parameter build_id.
5301 False otherwise.
5302 """
5303 actual_bid = ad.droid.getBuildID()
5304
Betty Zhoua37acd32017-02-23 20:04:24 -08005305 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay())
Ang Li73697b32015-12-03 00:41:53 +00005306 #In case we want to log more stuff/more granularity...
5307 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID()))
5308 #log.info("{} BUILD FINGERPRINT: {} "
5309 # .format(ad.serial), ad.droid.getBuildFingerprint())
5310 #log.info("{} BUILD TYPE: {} "
5311 # .format(ad.serial), ad.droid.getBuildType())
5312 #log.info("{} BUILD NUMBER: {} "
5313 # .format(ad.serial), ad.droid.getBuildNumber())
5314 if actual_bid.upper() != build_id.upper():
Betty Zhoua37acd32017-02-23 20:04:24 -08005315 ad.log.error("%s: Incorrect Build ID", ad.model)
Ang Li73697b32015-12-03 00:41:53 +00005316 return False
5317 return True
5318
Nathan Harold123c9da2015-12-30 16:33:25 -08005319
Ang Li73697b32015-12-03 00:41:53 +00005320def is_uri_equivalent(uri1, uri2):
5321 """Check whether two input uris match or not.
5322
5323 Compare Uris.
5324 If Uris are tel URI, it will only take the digit part
5325 and compare as phone number.
5326 Else, it will just do string compare.
5327
5328 Args:
5329 uri1: 1st uri to be compared.
5330 uri2: 2nd uri to be compared.
5331
5332 Returns:
5333 True if two uris match. Otherwise False.
5334 """
Nathan Harold23683d22015-12-14 16:19:08 -08005335
5336 #If either is None/empty we return false
5337 if not uri1 or not uri2:
5338 return False
5339
5340 try:
5341 if uri1.startswith('tel:') and uri2.startswith('tel:'):
Yang Liu598b93d2016-03-22 17:07:59 -07005342 uri1_number = get_number_from_tel_uri(uri1)
5343 uri2_number = get_number_from_tel_uri(uri2)
Nathan Harold23683d22015-12-14 16:19:08 -08005344 return check_phone_number_match(uri1_number, uri2_number)
5345 else:
5346 return uri1 == uri2
5347 except AttributeError as e:
5348 return False
Ang Li73697b32015-12-03 00:41:53 +00005349
Nathan Harold123c9da2015-12-30 16:33:25 -08005350
Ang Li73697b32015-12-03 00:41:53 +00005351def get_call_uri(ad, call_id):
5352 """Get call's uri field.
5353
5354 Get Uri for call_id in ad.
5355
5356 Args:
5357 ad: android device object.
5358 call_id: the call id to get Uri from.
5359
5360 Returns:
5361 call's Uri if call is active and have uri field. None otherwise.
5362 """
5363 try:
5364 call_detail = ad.droid.telecomCallGetDetails(call_id)
5365 return call_detail["Handle"]["Uri"]
5366 except:
5367 return None
5368
Nathan Harold7642fc92016-05-02 18:29:11 -07005369
Yang Liu598b93d2016-03-22 17:07:59 -07005370def get_number_from_tel_uri(uri):
5371 """Get Uri number from tel uri
5372
5373 Args:
5374 uri: input uri
5375
5376 Returns:
5377 If input uri is tel uri, return the number part.
5378 else return None.
5379 """
5380 if uri.startswith('tel:'):
Nathan Harold4a144a42016-09-19 14:16:24 -07005381 uri_number = ''.join(
5382 i for i in urllib.parse.unquote(uri) if i.isdigit())
Yang Liu598b93d2016-03-22 17:07:59 -07005383 return uri_number
5384 else:
5385 return None
Betty Zhou5cf94d82017-06-09 19:18:09 -07005386
5387
Betty Zhou9a96fc32018-02-01 16:44:05 -08005388def find_qxdm_log_mask(ad, mask="default.cfg"):
Betty Zhou550fd372017-10-16 17:22:47 -07005389 """Find QXDM logger mask."""
5390 if "/" not in mask:
Betty Zhoua18d0982017-10-18 14:30:43 -07005391 # Call nexuslogger to generate log mask
5392 start_nexuslogger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07005393 # Find the log mask path
Betty Zhou9a96fc32018-02-01 16:44:05 -08005394 for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs",
5395 "/vendor/etc/mdlog/"):
Betty Zhou02571f52018-02-16 14:11:16 -08005396 out = ad.adb.shell(
5397 "find %s -type f -iname %s" % (path, mask), ignore_status=True)
Betty Zhou9a96fc32018-02-01 16:44:05 -08005398 if out and "No such" not in out and "Permission denied" not in out:
5399 if path.startswith("/vendor/"):
Betty Zhou739d6b72018-04-18 10:38:53 -07005400 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
Betty Zhou9a96fc32018-02-01 16:44:05 -08005401 else:
Betty Zhou739d6b72018-04-18 10:38:53 -07005402 setattr(ad, "qxdm_log_path", path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08005403 return out.split("\n")[0]
5404 if mask in ad.adb.shell("ls /vendor/etc/mdlog/"):
Betty Zhou739d6b72018-04-18 10:38:53 -07005405 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
Betty Zhou9a96fc32018-02-01 16:44:05 -08005406 return "%s/%s" % ("/vendor/etc/mdlog/", mask)
Betty Zhou550fd372017-10-16 17:22:47 -07005407 else:
5408 out = ad.adb.shell("ls %s" % mask, ignore_status=True)
5409 if out and "No such" not in out:
Betty Zhou739d6b72018-04-18 10:38:53 -07005410 qxdm_log_path, cfg_name = os.path.split(mask)
5411 setattr(ad, "qxdm_log_path", qxdm_log_path)
Betty Zhoua18d0982017-10-18 14:30:43 -07005412 return mask
Betty Zhou550fd372017-10-16 17:22:47 -07005413 ad.log.warning("Could NOT find QXDM logger mask path for %s", mask)
5414
5415
5416def set_qxdm_logger_command(ad, mask=None):
5417 """Set QXDM logger always on.
5418
5419 Args:
5420 ad: android device object.
5421
5422 """
5423 ## Neet to check if log mask will be generated without starting nexus logger
Betty Zhou9a96fc32018-02-01 16:44:05 -08005424 masks = []
5425 mask_path = None
Betty Zhou550fd372017-10-16 17:22:47 -07005426 if mask:
Betty Zhou9a96fc32018-02-01 16:44:05 -08005427 masks = [mask]
5428 masks.extend(["QC_Default.cfg", "default.cfg"])
5429 for mask in masks:
5430 mask_path = find_qxdm_log_mask(ad, mask)
5431 if mask_path: break
Betty Zhou550fd372017-10-16 17:22:47 -07005432 if not mask_path:
Betty Zhou9a96fc32018-02-01 16:44:05 -08005433 ad.log.error("Cannot find QXDM mask %s", mask)
Betty Zhou550fd372017-10-16 17:22:47 -07005434 ad.qxdm_logger_command = None
Betty Zhoua18d0982017-10-18 14:30:43 -07005435 return False
Betty Zhou550fd372017-10-16 17:22:47 -07005436 else:
Betty Zhoua18d0982017-10-18 14:30:43 -07005437 ad.log.info("Use QXDM log mask %s", mask_path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08005438 ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path)
5439 output_path = os.path.join(ad.qxdm_log_path, "logs")
Betty Zhou31c402a2018-01-25 18:14:20 -08005440 ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 50 -c" %
Betty Zhou9a96fc32018-02-01 16:44:05 -08005441 (mask_path, output_path))
Betty Zhoue7cc3672018-04-26 16:58:56 -07005442 for prop in ("persist.sys.modem.diag.mdlog",
5443 "persist.vendor.sys.modem.diag.mdlog"):
5444 if ad.adb.getprop(prop):
5445 # Enable qxdm always on if supported
5446 for conf_path in ("/data/vendor/radio/diag_logs",
5447 "/vendor/etc/mdlog"):
5448 if "diag.conf" in ad.adb.shell(
5449 "ls %s" % conf_path, ignore_status=True):
5450 conf_path = "%s/diag.conf" % conf_path
5451 ad.adb.shell('echo "%s" > %s' %
5452 (ad.qxdm_logger_command, conf_path))
5453 break
5454 ad.adb.shell("%s true" % prop, ignore_status=True)
5455 break
Betty Zhoua18d0982017-10-18 14:30:43 -07005456 return True
Betty Zhou550fd372017-10-16 17:22:47 -07005457
5458
Betty Zhou0111ae02017-11-29 20:37:26 -08005459def stop_qxdm_logger(ad):
5460 """Stop QXDM logger."""
5461 for cmd in ("diag_mdlog -k", "killall diag_mdlog"):
5462 output = ad.adb.shell("ps -ef | grep mdlog") or ""
5463 if "diag_mdlog" not in output:
5464 break
5465 ad.log.debug("Kill the existing qxdm process")
5466 ad.adb.shell(cmd, ignore_status=True)
5467 time.sleep(5)
5468
5469
Betty Zhouee311052017-12-19 13:09:56 -08005470def start_qxdm_logger(ad, begin_time=None):
Betty Zhou550fd372017-10-16 17:22:47 -07005471 """Start QXDM logger."""
Betty Zhou3eceae02018-02-09 12:27:51 -08005472 if not getattr(ad, "qxdm_log", True): return
Betty Zhouee311052017-12-19 13:09:56 -08005473 # Delete existing QXDM logs 5 minutes earlier than the begin_time
Betty Zhoua9a354a2018-03-21 15:01:59 -07005474 current_time = get_current_epoch_time()
Betty Zhou9a96fc32018-02-01 16:44:05 -08005475 if getattr(ad, "qxdm_log_path", None):
5476 seconds = None
Betty Zhoua9a354a2018-03-21 15:01:59 -07005477 file_count = ad.adb.shell(
5478 "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path)
5479 if int(file_count) > 50:
5480 if begin_time:
5481 # if begin_time specified, delete old qxdm logs modified
5482 # 10 minutes before begin time
5483 seconds = int((current_time - begin_time) / 1000.0) + 10 * 60
5484 else:
5485 # if begin_time is not specified, delete old qxdm logs modified
5486 # 15 minutes before current time
5487 seconds = 15 * 60
Betty Zhou9a96fc32018-02-01 16:44:05 -08005488 if seconds:
Betty Zhoua9a354a2018-03-21 15:01:59 -07005489 # Remove qxdm logs modified more than specified seconds ago
Betty Zhou9a96fc32018-02-01 16:44:05 -08005490 ad.adb.shell(
Betty Zhou02571f52018-02-16 14:11:16 -08005491 "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" %
5492 (ad.qxdm_log_path, seconds))
Betty Zhoua9a354a2018-03-21 15:01:59 -07005493 ad.adb.shell(
5494 "find %s -type f -iname *.xml -not -mtime -%ss -delete" %
5495 (ad.qxdm_log_path, seconds))
Betty Zhou550fd372017-10-16 17:22:47 -07005496 if getattr(ad, "qxdm_logger_command", None):
5497 output = ad.adb.shell("ps -ef | grep mdlog") or ""
5498 if ad.qxdm_logger_command not in output:
5499 ad.log.debug("QXDM logging command %s is not running",
5500 ad.qxdm_logger_command)
5501 if "diag_mdlog" in output:
Betty Zhoua9a354a2018-03-21 15:01:59 -07005502 # Kill the existing non-matching diag_mdlog process
Betty Zhou550fd372017-10-16 17:22:47 -07005503 # Only one diag_mdlog process can be run
Betty Zhou0111ae02017-11-29 20:37:26 -08005504 stop_qxdm_logger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07005505 ad.log.info("Start QXDM logger")
Betty Zhou88a39392017-12-01 17:33:57 -08005506 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07005507 time.sleep(10)
Betty Zhoua9a354a2018-03-21 15:01:59 -07005508 else:
Betty Zhoua19e4442018-04-19 19:38:42 -07005509 run_time = check_qxdm_logger_run_time(ad)
5510 if run_time < 600:
5511 # the last diag_mdlog started within 10 minutes ago
5512 # no need to restart
5513 return True
Betty Zhoua9a354a2018-03-21 15:01:59 -07005514 if ad.search_logcat(
5515 "Diag_Lib: diag: In delete_log",
Betty Zhoua19e4442018-04-19 19:38:42 -07005516 begin_time=current_time -
5517 run_time) or not ad.get_file_names(
5518 ad.qxdm_log_path,
5519 begin_time=current_time - 600000,
5520 match_string="*.qmdl"):
Betty Zhoua9a354a2018-03-21 15:01:59 -07005521 # diag_mdlog starts deleting files or no qmdl logs were
Betty Zhoua19e4442018-04-19 19:38:42 -07005522 # modified in the past 10 minutes
Betty Zhoua9a354a2018-03-21 15:01:59 -07005523 ad.log.debug("Quit existing diag_mdlog and start a new one")
5524 stop_qxdm_logger(ad)
5525 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07005526 time.sleep(10)
Betty Zhou0111ae02017-11-29 20:37:26 -08005527 return True
Betty Zhou550fd372017-10-16 17:22:47 -07005528
5529
Betty Zhoua19e4442018-04-19 19:38:42 -07005530def check_qxdm_logger_run_time(ad):
5531 output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog")
5532 result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output)
5533 if result:
5534 return int(result.group(1)) * 60 * 60 + int(
5535 result.group(2)) * 60 + int(result.group(3))
5536 else:
5537 result = re.search(r"(\d+):(\d+) diag_mdlog", output)
5538 if result:
5539 return int(result.group(1)) * 60 + int(result.group(2))
5540 else:
5541 return 0
5542
5543
Betty Zhouee311052017-12-19 13:09:56 -08005544def start_qxdm_loggers(log, ads, begin_time=None):
Betty Zhou02571f52018-02-16 14:11:16 -08005545 tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads
5546 if getattr(ad, "qxdm_log", True)]
Betty Zhou3eceae02018-02-09 12:27:51 -08005547 if tasks: run_multithread_func(log, tasks)
Betty Zhou550fd372017-10-16 17:22:47 -07005548
5549
Betty Zhou0111ae02017-11-29 20:37:26 -08005550def stop_qxdm_loggers(log, ads):
5551 tasks = [(stop_qxdm_logger, [ad]) for ad in ads]
5552 run_multithread_func(log, tasks)
5553
5554
Betty Zhou550fd372017-10-16 17:22:47 -07005555def start_nexuslogger(ad):
Betty Zhou807a81f2017-11-27 14:53:48 -08005556 """Start Nexus/Pixel Logger Apk."""
5557 qxdm_logger_apk = None
Betty Zhouee311052017-12-19 13:09:56 -08005558 for apk, activity in (("com.android.nexuslogger", ".MainActivity"),
5559 ("com.android.pixellogger",
5560 ".ui.main.MainActivity")):
Betty Zhou807a81f2017-11-27 14:53:48 -08005561 if ad.is_apk_installed(apk):
5562 qxdm_logger_apk = apk
5563 break
5564 if not qxdm_logger_apk: return
5565 if ad.is_apk_running(qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07005566 if "granted=true" in ad.adb.shell(
Betty Zhou807a81f2017-11-27 14:53:48 -08005567 "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07005568 return True
5569 else:
Betty Zhou807a81f2017-11-27 14:53:48 -08005570 ad.log.info("Kill %s" % qxdm_logger_apk)
5571 ad.force_stop_apk(qxdm_logger_apk)
Betty Zhou32e403a2017-10-25 20:08:12 -07005572 time.sleep(5)
Betty Zhou807a81f2017-11-27 14:53:48 -08005573 for perm in ("READ", "WRITE"):
5574 ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" %
5575 (qxdm_logger_apk, perm))
5576 time.sleep(2)
Jaineel464a18e2017-12-21 14:37:41 -08005577 for i in range(3):
5578 ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1))
5579 ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity))
5580 time.sleep(5)
5581 if ad.is_apk_running(qxdm_logger_apk):
5582 ad.send_keycode("HOME")
5583 return True
5584 return False
Betty Zhou5cf94d82017-06-09 19:18:09 -07005585
5586
Betty Zhou8ac04da2017-10-12 15:27:15 -07005587def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"):
Betty Zhou5cf94d82017-06-09 19:18:09 -07005588 """Check if QXDM logger always on is set.
5589
5590 Args:
5591 ad: android device object.
5592
5593 """
Betty Zhou4b0f1712017-10-12 20:20:14 -07005594 output = ad.adb.shell(
5595 "ls /data/vendor/radio/diag_logs/", ignore_status=True)
5596 if not output or "No such" in output:
5597 return True
Betty Zhou5cf94d82017-06-09 19:18:09 -07005598 if mask_file not in ad.adb.shell(
5599 "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True):
5600 return False
5601 return True
Jaineel55ae6f92017-06-29 17:44:19 -07005602
5603
Betty Zhou9d0366a2018-03-26 13:49:57 -07005604def start_tcpdumps(ads,
5605 test_name="",
5606 begin_time=None,
5607 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07005608 mask="all"):
Betty Zhoue123c672018-03-21 19:57:11 -07005609 for ad in ads:
5610 start_adb_tcpdump(
Betty Zhou9d0366a2018-03-26 13:49:57 -07005611 ad,
5612 test_name=test_name,
5613 begin_time=begin_time,
5614 interface=interface,
5615 mask=mask)
Betty Zhoue123c672018-03-21 19:57:11 -07005616
5617
Betty Zhou9d0366a2018-03-26 13:49:57 -07005618def start_adb_tcpdump(ad,
5619 test_name="",
5620 begin_time=None,
5621 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07005622 mask="all"):
Jaineel55ae6f92017-06-29 17:44:19 -07005623 """Start tcpdump on any iface
5624
5625 Args:
5626 ad: android device object.
5627 test_name: tcpdump file name will have this
5628
5629 """
Jaineel7d0408e2017-12-22 15:52:59 -08005630 out = ad.adb.shell("ls -l /sdcard/tcpdump/")
5631 if "No such file" in out or not out:
5632 ad.adb.shell("mkdir /sdcard/tcpdump")
5633 else:
5634 ad.adb.shell("rm -rf /sdcard/tcpdump/*", ignore_status=True)
5635
Betty Zhoue123c672018-03-21 19:57:11 -07005636 if not begin_time:
5637 begin_time = get_current_epoch_time()
Jaineel7d0408e2017-12-22 15:52:59 -08005638
Betty Zhou5dd53c02018-03-22 20:08:33 -07005639 out = ad.adb.shell("ifconfig | grep encap")
Betty Zhoud8b8b432018-04-19 17:44:38 -07005640 if interface in ("any", "all"):
Betty Zhou5dd53c02018-03-22 20:08:33 -07005641 intfs = [
5642 intf for intf in ("wlan0", "rmnet_data0", "rmnet_data6")
5643 if intf in out
5644 ]
Jaineelc9e7bfa2017-08-07 14:11:30 -07005645 else:
Betty Zhou5dd53c02018-03-22 20:08:33 -07005646 intfs = [interface]
5647
5648 out = ad.adb.shell("ps -ef | grep tcpdump")
5649 cmds = []
5650 for intf in intfs:
5651 if intf in out:
5652 ad.log.info("tcpdump on interface %s is already running", intf)
5653 continue
5654 else:
Betty Zhou2bb11682018-04-19 17:05:30 -07005655 log_file_name = "/sdcard/tcpdump/tcpdump_%s_%s_%s_%s.pcap" % (
Betty Zhou9d0366a2018-03-26 13:49:57 -07005656 ad.serial, intf, test_name, begin_time)
Betty Zhou5dd53c02018-03-22 20:08:33 -07005657 if mask == "ims":
5658 cmds.append(
5659 "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or "
Betty Zhou9d0366a2018-03-26 13:49:57 -07005660 "udp port 4500 -w %s" % (ad.serial, intf, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07005661 else:
Betty Zhou9d0366a2018-03-26 13:49:57 -07005662 cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" %
5663 (ad.serial, intf, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07005664 for cmd in cmds:
5665 ad.log.info(cmd)
5666 try:
5667 start_standing_subprocess(cmd, 10)
5668 except Exception as e:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07005669 ad.log.error(e)
Jaineel55ae6f92017-06-29 17:44:19 -07005670
5671
Betty Zhoue123c672018-03-21 19:57:11 -07005672def stop_tcpdumps(ads):
5673 for ad in ads:
5674 stop_adb_tcpdump(ad)
5675
5676
Betty Zhou5dd53c02018-03-22 20:08:33 -07005677def stop_adb_tcpdump(ad, interface="any"):
Jaineel55ae6f92017-06-29 17:44:19 -07005678 """Stops tcpdump on any iface
5679 Pulls the tcpdump file in the tcpdump dir
5680
5681 Args:
5682 ad: android device object.
Jaineel55ae6f92017-06-29 17:44:19 -07005683
5684 """
Betty Zhou5dd53c02018-03-22 20:08:33 -07005685 if interface == "any":
5686 try:
5687 ad.adb.shell("killall -9 tcpdump")
5688 except Exception as e:
Betty Zhoua36c4352018-04-05 18:49:32 -07005689 ad.log.error("Killing tcpdump with exception %s", e)
Betty Zhou5dd53c02018-03-22 20:08:33 -07005690 else:
5691 out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface)
5692 if "tcpdump -i" in out:
5693 pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out)
5694 for pid in pids:
5695 ad.adb.shell("kill -9 %s" % pid)
Betty Zhoue123c672018-03-21 19:57:11 -07005696
5697
5698def get_tcpdump_log(ad, test_name="", begin_time=None):
5699 """Stops tcpdump on any iface
5700 Pulls the tcpdump file in the tcpdump dir
5701
5702 Args:
5703 ad: android device object.
5704 test_name: test case name
5705 begin_time: test begin time
5706 """
5707 logs = ad.get_file_names("/sdcard/tcpdump", begin_time=begin_time)
5708 if logs:
5709 ad.log.info("Pulling tcpdumps %s", logs)
Betty Zhoue62b1f12018-01-24 17:05:20 -08005710 log_path = os.path.join(ad.log_path, test_name,
5711 "TCPDUMP_%s" % ad.serial)
5712 utils.create_dir(log_path)
Betty Zhoue123c672018-03-21 19:57:11 -07005713 ad.pull_files(logs, log_path)
5714 stop_adb_tcpdump(ad)
Jaineel55ae6f92017-06-29 17:44:19 -07005715 return True
Betty Zhou166a51c2017-08-14 17:40:59 -07005716
5717
5718def fastboot_wipe(ad, skip_setup_wizard=True):
5719 """Wipe the device in fastboot mode.
5720
5721 Pull sl4a apk from device. Terminate all sl4a sessions,
5722 Reboot the device to bootloader, wipe the device by fastboot.
5723 Reboot the device. wait for device to complete booting
5724 Re-intall and start an sl4a session.
5725 """
Betty Zhou77f2bed2017-10-04 18:39:07 -07005726 status = True
Betty Zhou166a51c2017-08-14 17:40:59 -07005727 # Pull sl4a apk from device
Betty Zhou92437702018-02-07 19:49:07 -08005728 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
Betty Zhou166a51c2017-08-14 17:40:59 -07005729 result = re.search(r"package:(.*)", out)
5730 if not result:
5731 ad.log.error("Couldn't find sl4a apk")
5732 else:
5733 sl4a_apk = result.group(1)
5734 ad.log.info("Get sl4a apk from %s", sl4a_apk)
5735 ad.pull_files([sl4a_apk], "/tmp/")
5736 ad.stop_services()
Betty Zhou3e983f22018-04-09 20:37:36 -07005737 attemps = 3
5738 for i in range(1, attemps + 1):
Betty Zhou77f2bed2017-10-04 18:39:07 -07005739 try:
Betty Zhou3e983f22018-04-09 20:37:36 -07005740 ad.log.info("Reboot to bootloader")
5741 ad.adb.reboot("bootloader", ignore_status=True)
5742 ad.log.info("Wipe in fastboot")
5743 ad.fastboot._w(timeout=180)
5744 time.sleep(30)
Betty Zhou77f2bed2017-10-04 18:39:07 -07005745 ad.log.info("Reboot in fastboot")
5746 ad.fastboot.reboot()
5747 ad.wait_for_boot_completion()
Betty Zhou3e983f22018-04-09 20:37:36 -07005748 ad.root_adb()
5749 if ad.skip_sl4a:
5750 break
Betty Zhou02589bb2017-09-06 15:04:25 -07005751 if ad.is_sl4a_installed():
5752 break
Betty Zhou166a51c2017-08-14 17:40:59 -07005753 ad.log.info("Re-install sl4a")
Betty Zhou3e983f22018-04-09 20:37:36 -07005754 ad.adb.install("-r /tmp/base.apk")
Betty Zhou166a51c2017-08-14 17:40:59 -07005755 time.sleep(10)
Betty Zhou3e983f22018-04-09 20:37:36 -07005756 break
5757 except Exception as e:
5758 ad.log.warning(e)
5759 if i == attemps:
5760 raise
Betty Zhou3c2e2542018-02-21 12:23:04 -08005761 try:
5762 ad.start_adb_logcat()
5763 except:
Betty Zhoua36c4352018-04-05 18:49:32 -07005764 ad.log.error("Failed to start adb logcat!")
Betty Zhou3c2e2542018-02-21 12:23:04 -08005765 if skip_setup_wizard:
5766 ad.exit_setup_wizard()
Betty Zhoua9a354a2018-03-21 15:01:59 -07005767 start_qxdm_logger(ad)
Betty Zhou739d6b72018-04-18 10:38:53 -07005768 # Setup VoWiFi MDN for Verizon. b/33187374
Betty Zhoue7cc3672018-04-26 16:58:56 -07005769 if "Verizon" in ad.adb.getprop(
5770 "gsm.sim.operator.alpha") and ad.is_apk_installed(
5771 "com.google.android.wfcactivation"):
Betty Zhou739d6b72018-04-18 10:38:53 -07005772 ad.log.info("setup VoWiFi MDN per b/33187374")
5773 ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
5774 ad.adb.shell("am start --ei EXTRA_LAUNCH_CARRIER_APP 0 -n "
5775 "\"com.google.android.wfcactivation/"
5776 ".VzwEmergencyAddressActivity\"")
Betty Zhouf25fdab2018-04-23 19:20:17 -07005777 if ad.skip_sl4a: return status
5778 bring_up_sl4a(ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07005779 return status
Betty Zhou166a51c2017-08-14 17:40:59 -07005780
5781
Betty Zhou3c2e2542018-02-21 12:23:04 -08005782def bring_up_sl4a(ad, attemps=3):
5783 for i in range(attemps):
5784 try:
5785 droid, ed = ad.get_droid()
5786 ed.start()
5787 ad.log.info("Broght up new sl4a session")
Betty Zhou3e983f22018-04-09 20:37:36 -07005788 break
Betty Zhou3c2e2542018-02-21 12:23:04 -08005789 except Exception as e:
5790 if i < attemps - 1:
5791 ad.log.info(e)
5792 time.sleep(10)
5793 else:
5794 ad.log.error(e)
5795 raise
5796
5797
Betty Zhouae9d6a82018-02-15 20:05:34 -08005798def reboot_device(ad):
5799 ad.reboot()
Betty Zhoua9a354a2018-03-21 15:01:59 -07005800 start_qxdm_logger(ad)
Betty Zhouae9d6a82018-02-15 20:05:34 -08005801 ad.ensure_screen_on()
5802 unlock_sim(ad)
5803
5804
Betty Zhou166a51c2017-08-14 17:40:59 -07005805def unlocking_device(ad, device_password=None):
5806 """First unlock device attempt, required after reboot"""
5807 ad.unlock_screen(device_password)
5808 time.sleep(2)
5809 ad.adb.wait_for_device(timeout=180)
5810 if not ad.is_waiting_for_unlock_pin():
5811 return True
5812 else:
5813 ad.unlock_screen(device_password)
5814 time.sleep(2)
5815 ad.adb.wait_for_device(timeout=180)
5816 if ad.wait_for_window_ready():
5817 return True
5818 ad.log.error("Unable to unlock to user window")
5819 return False
5820
5821
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005822def refresh_sl4a_session(ad):
5823 try:
5824 ad.droid.logI("Checking SL4A connection")
Betty Zhou4bc31fc2018-03-12 18:28:50 -07005825 ad.log.debug("Existing sl4a session is active")
5826 return True
5827 except Exception as e:
Betty Zhoufe726dc2018-04-25 19:31:33 -07005828 ad.log.warning("Existing sl4a session is NOT active: %s", e)
Betty Zhou4bc31fc2018-03-12 18:28:50 -07005829 try:
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005830 ad.terminate_all_sessions()
Betty Zhou4bc31fc2018-03-12 18:28:50 -07005831 except Exception as e:
5832 ad.log.info("terminate_all_sessions with error %s", e)
5833 ad.ensure_screen_on()
5834 ad.log.info("Open new sl4a connection")
5835 bring_up_sl4a(ad)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005836
5837
Betty Zhou166a51c2017-08-14 17:40:59 -07005838def reset_device_password(ad, device_password=None):
5839 # Enable or Disable Device Password per test bed config
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005840 unlock_sim(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07005841 screen_lock = ad.is_screen_lock_enabled()
5842 if device_password:
Betty Zhoue66efb42018-01-31 19:45:56 -08005843 try:
Betty Zhouf715c792018-02-12 17:32:10 -08005844 refresh_sl4a_session(ad)
Betty Zhoue66efb42018-01-31 19:45:56 -08005845 ad.droid.setDevicePassword(device_password)
5846 except Exception as e:
5847 ad.log.warning("setDevicePassword failed with %s", e)
Betty Zhou3c2e2542018-02-21 12:23:04 -08005848 try:
5849 ad.droid.setDevicePassword(device_password, "1111")
5850 except Exception as e:
5851 ad.log.warning(
5852 "setDevicePassword providing previous password error: %s",
5853 e)
Betty Zhou166a51c2017-08-14 17:40:59 -07005854 time.sleep(2)
5855 if screen_lock:
5856 # existing password changed
5857 return
5858 else:
5859 # enable device password and log in for the first time
5860 ad.log.info("Enable device password")
5861 ad.adb.wait_for_device(timeout=180)
Betty Zhou166a51c2017-08-14 17:40:59 -07005862 else:
5863 if not screen_lock:
5864 # no existing password, do not set password
5865 return
5866 else:
5867 # password is enabled on the device
5868 # need to disable the password and log in on the first time
5869 # with unlocking with a swipe
5870 ad.log.info("Disable device password")
Betty Zhou688c1032017-11-20 20:08:04 -08005871 ad.unlock_screen(password="1111")
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005872 refresh_sl4a_session(ad)
Betty Zhou351d1792017-11-10 16:26:30 -08005873 ad.ensure_screen_on()
Betty Zhoue66efb42018-01-31 19:45:56 -08005874 try:
5875 ad.droid.disableDevicePassword()
5876 except Exception as e:
5877 ad.log.warning("disableDevicePassword failed with %s", e)
Betty Zhouf715c792018-02-12 17:32:10 -08005878 fastboot_wipe(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07005879 time.sleep(2)
5880 ad.adb.wait_for_device(timeout=180)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07005881 refresh_sl4a_session(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07005882 if not ad.is_adb_logcat_on:
5883 ad.start_adb_logcat()
Betty Zhou59ccab62017-08-17 18:17:29 -07005884
5885
Betty Zhoue66efb42018-01-31 19:45:56 -08005886def get_sim_state(ad):
Betty Zhou13e7adf2017-09-06 14:01:10 -07005887 try:
Betty Zhoue66efb42018-01-31 19:45:56 -08005888 state = ad.droid.telephonyGetSimState()
Betty Zhou13e7adf2017-09-06 14:01:10 -07005889 except:
Betty Zhoue66efb42018-01-31 19:45:56 -08005890 state = ad.adb.getprop("gsm.sim.state")
5891 return state
5892
5893
5894def is_sim_locked(ad):
Betty Zhoub554e342018-02-01 19:01:38 -08005895 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED
Betty Zhou59ccab62017-08-17 18:17:29 -07005896
5897
Betty Zhou28e07e12018-04-11 12:12:11 -07005898def is_sim_lock_enabled(ad):
5899 # TODO: add sl4a fascade to check if sim is locked
5900 return getattr(ad, "is_sim_locked", False)
5901
5902
Betty Zhou59ccab62017-08-17 18:17:29 -07005903def unlock_sim(ad):
5904 #The puk and pin can be provided in testbed config file.
5905 #"AndroidDevice": [{"serial": "84B5T15A29018214",
5906 # "adb_logcat_param": "-b all",
5907 # "puk": "12345678",
5908 # "puk_pin": "1234"}]
Betty Zhouc3f1f9c2017-08-18 15:50:41 -07005909 if not is_sim_locked(ad):
5910 return True
Betty Zhoue66efb42018-01-31 19:45:56 -08005911 else:
5912 ad.is_sim_locked = True
Betty Zhou59ccab62017-08-17 18:17:29 -07005913 puk_pin = getattr(ad, "puk_pin", "1111")
5914 try:
5915 if not hasattr(ad, 'puk'):
Betty Zhoub47a4ea2017-09-06 11:18:40 -07005916 ad.log.info("Enter SIM pin code")
Betty Zhoue66efb42018-01-31 19:45:56 -08005917 ad.droid.telephonySupplyPin(puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07005918 else:
5919 ad.log.info("Enter PUK code and pin")
Betty Zhoue66efb42018-01-31 19:45:56 -08005920 ad.droid.telephonySupplyPuk(ad.puk, puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07005921 except:
5922 # if sl4a is not available, use adb command
5923 ad.unlock_screen(puk_pin)
5924 if is_sim_locked(ad):
5925 ad.unlock_screen(puk_pin)
Betty Zhoub47a4ea2017-09-06 11:18:40 -07005926 time.sleep(30)
Betty Zhou59ccab62017-08-17 18:17:29 -07005927 return not is_sim_locked(ad)
Betty Zhouf3c5bc32017-08-28 17:09:19 -07005928
5929
5930def send_dialer_secret_code(ad, secret_code):
5931 """Send dialer secret code.
5932
5933 ad: android device controller
5934 secret_code: the secret code to be sent to dialer. the string between
5935 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#*
5936 """
5937 action = 'android.provider.Telephony.SECRET_CODE'
5938 uri = 'android_secret_code://%s' % secret_code
5939 intent = ad.droid.makeIntent(
5940 action,
5941 uri,
5942 None, # type
5943 None, # extras
5944 None, # categories,
5945 None, # packagename,
5946 None, # classname,
5947 0x01000000) # flags
5948 ad.log.info('Issuing dialer secret dialer code: %s', secret_code)
5949 ad.droid.sendBroadcastIntent(intent)
Betty Zhou5b5f80a2017-09-29 18:24:01 -07005950
5951
Betty Zhouf7da39e2018-04-16 16:28:58 -07005952def enable_radio_log_on(ad):
5953 if ad.adb.getprop(" persist.vendor.radio.adb_log_on") != "1":
5954 adb_disable_verity(ad)
5955 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1")
5956 reboot_device(ad)
5957
5958
5959def adb_disable_verity(ad):
5960 if ad.adb.getprop("ro.boot.veritymode") == "enforcing":
5961 ad.adb.disable_verity()
5962 reboot_device(ad)
5963 ad.adb.remount()
5964
5965
Betty Zhou5b5f80a2017-09-29 18:24:01 -07005966def system_file_push(ad, src_file_path, dst_file_path):
5967 """Push system file on a device.
5968
5969 Push system file need to change some system setting and remount.
5970 """
Betty Zhoua9a70f62017-11-16 14:53:11 -08005971 cmd = "%s %s" % (src_file_path, dst_file_path)
5972 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
markdr6607bf12018-01-02 14:45:38 -08005973 skip_sl4a = True if "sl4a.apk" in src_file_path else False
Betty Zhoua9a70f62017-11-16 14:53:11 -08005974 if "Read-only file system" in out:
5975 ad.log.info("Change read-only file system")
Betty Zhouf7da39e2018-04-16 16:28:58 -07005976 adb_disable_verity(ad)
Betty Zhoua9a70f62017-11-16 14:53:11 -08005977 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
5978 if "Read-only file system" in out:
Betty Zhou856ae212018-01-18 19:49:35 -08005979 ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08005980 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
5981 if "error" in out:
5982 ad.log.error("%s failed with %s", cmd, out)
5983 return False
5984 else:
Betty Zhou856ae212018-01-18 19:49:35 -08005985 ad.log.info("push %s succeed")
5986 if skip_sl4a: ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08005987 return True
5988 else:
5989 return True
5990 elif "error" in out:
Betty Zhou5b5f80a2017-09-29 18:24:01 -07005991 return False
Betty Zhoua9a70f62017-11-16 14:53:11 -08005992 else:
5993 return True
Betty Zhou8ecd1da2017-10-05 15:44:24 -07005994
5995
5996def flash_radio(ad, file_path, skip_setup_wizard=True):
5997 """Flash radio image."""
5998 ad.stop_services()
5999 ad.log.info("Reboot to bootloader")
6000 ad.adb.reboot_bootloader(ignore_status=True)
6001 ad.log.info("Flash radio in fastboot")
6002 try:
6003 ad.fastboot.flash("radio %s" % file_path, timeout=300)
6004 except Exception as e:
6005 ad.log.error(e)
Betty Zhoud4b75c52018-04-03 15:20:00 -07006006 ad.fastboot.reboot("bootloader")
6007 time.sleep(5)
6008 output = ad.fastboot.getvar("version-baseband")
6009 result = re.search(r"version-baseband: (\S+)", output)
6010 if not result:
6011 ad.log.error("fastboot getvar version-baseband output = %s", output)
6012 abort_all_tests(ad.log, "Radio version-baseband is not provided")
6013 fastboot_radio_version_output = result.group(1)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07006014 for _ in range(2):
6015 try:
6016 ad.log.info("Reboot in fastboot")
6017 ad.fastboot.reboot()
6018 ad.wait_for_boot_completion()
6019 break
6020 except Exception as e:
6021 ad.log.error("Exception error %s", e)
6022 ad.root_adb()
Betty Zhoud4b75c52018-04-03 15:20:00 -07006023 adb_radio_version_output = ad.adb.getprop("gsm.version.baseband")
6024 ad.log.info("adb getprop gsm.version.baseband = %s",
6025 adb_radio_version_output)
6026 if adb_radio_version_output != fastboot_radio_version_output:
6027 msg = ("fastboot radio version output %s does not match with adb"
6028 " radio version output %s" % (fastboot_radio_version_output,
6029 adb_radio_version_output))
6030 abort_all_tests(ad.log, msg)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07006031 if not ad.ensure_screen_on():
6032 ad.log.error("User window cannot come up")
6033 ad.start_services(ad.skip_sl4a, skip_setup_wizard=skip_setup_wizard)
Betty Zhou447080c2018-02-06 10:43:26 -08006034 unlock_sim(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07006035
6036
Jaineel13ac2fc2017-10-26 16:25:50 -07006037def set_preferred_apn_by_adb(ad, pref_apn_name):
6038 """Select Pref APN
6039 Set Preferred APN on UI using content query/insert
6040 It needs apn name as arg, and it will match with plmn id
6041 """
6042 try:
6043 plmn_id = get_plmn_by_adb(ad)
6044 out = ad.adb.shell("content query --uri content://telephony/carriers "
6045 "--where \"apn='%s' and numeric='%s'\"" %
6046 (pref_apn_name, plmn_id))
6047 if "No result found" in out:
6048 ad.log.warning("Cannot find APN %s on device", pref_apn_name)
6049 return False
6050 else:
6051 apn_id = re.search(r'_id=(\d+)', out).group(1)
6052 ad.log.info("APN ID is %s", apn_id)
6053 ad.adb.shell("content insert --uri content:"
6054 "//telephony/carriers/preferapn --bind apn_id:i:%s" %
6055 (apn_id))
6056 out = ad.adb.shell("content query --uri "
6057 "content://telephony/carriers/preferapn")
6058 if "No result found" in out:
6059 ad.log.error("Failed to set prefer APN %s", pref_apn_name)
6060 return False
6061 elif apn_id == re.search(r'_id=(\d+)', out).group(1):
6062 ad.log.info("Preferred APN set to %s", pref_apn_name)
6063 return True
6064 except Exception as e:
6065 ad.log.error("Exception while setting pref apn %s", e)
6066 return True
6067
6068
Jaineel13fb98d2017-10-20 12:26:50 -07006069def check_apm_mode_on_by_serial(ad, serial_id):
6070 try:
6071 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id,
6072 "grep -i airplanemodeon", "cut -f2 -d ' '"))
6073 output = exe_cmd(apm_check_cmd)
6074 if output.decode("utf-8").split("\n")[0] == "true":
6075 return True
6076 else:
6077 return False
6078 except Exception as e:
6079 ad.log.warning("Exception during check apm mode on %s", e)
Jaineel5576d432017-10-19 15:36:42 -07006080 return True
Jaineel5576d432017-10-19 15:36:42 -07006081
6082
Jaineel13fb98d2017-10-20 12:26:50 -07006083def set_apm_mode_on_by_serial(ad, serial_id):
6084 try:
6085 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id
6086 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id
6087 exe_cmd(cmd1)
6088 exe_cmd(cmd2)
6089 except Exception as e:
6090 ad.log.warning("Exception during set apm mode on %s", e)
6091 return True
Jaineel5576d432017-10-19 15:36:42 -07006092
6093
Betty Zhou8ecd1da2017-10-05 15:44:24 -07006094def print_radio_info(ad, extra_msg=""):
6095 for prop in ("gsm.version.baseband", "persist.radio.ver_info",
Betty Zhou447080c2018-02-06 10:43:26 -08006096 "persist.radio.cnv.ver_info"):
Betty Zhou8ecd1da2017-10-05 15:44:24 -07006097 output = ad.adb.getprop(prop)
Betty Zhou447080c2018-02-06 10:43:26 -08006098 ad.log.info("%s%s = %s", extra_msg, prop, output)
Betty Zhou32e403a2017-10-25 20:08:12 -07006099
6100
6101def wait_for_state(state_check_func,
6102 state,
Betty Zhouddc76402018-01-23 16:29:25 -08006103 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE,
markdr6607bf12018-01-02 14:45:38 -08006104 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK,
Betty Zhou32e403a2017-10-25 20:08:12 -07006105 *args,
6106 **kwargs):
6107 while max_wait_time >= 0:
6108 if state_check_func(*args, **kwargs) == state:
6109 return True
6110 time.sleep(checking_interval)
6111 max_wait_time -= checking_interval
6112 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006113
6114
Betty Zhou6dd0ac62018-04-27 18:59:12 -07006115def power_off_sim(ad, sim_slot_id=None,
6116 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006117 try:
6118 if sim_slot_id is None:
6119 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN)
6120 verify_func = ad.droid.telephonyGetSimState
6121 verify_args = []
6122 else:
markdr6607bf12018-01-02 14:45:38 -08006123 ad.droid.telephonySetSimStateForSlotId(sim_slot_id,
6124 CARD_POWER_DOWN)
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006125 verify_func = ad.droid.telephonyGetSimStateForSlotId
6126 verify_args = [sim_slot_id]
6127 except Exception as e:
6128 ad.log.error(e)
6129 return False
Betty Zhou6dd0ac62018-04-27 18:59:12 -07006130 while timeout > 0:
6131 sim_state = verify_func(*verify_args)
6132 if sim_state in (SIM_STATE_UNKNOWN, SIM_STATE_ABSENT):
6133 ad.log.info("SIM slot is powered off, SIM state is %s", sim_state)
6134 return True
6135 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
6136 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
6137 ad.log.warning("Fail to power off SIM slot, sim_state=%s",
6138 verify_func(*verify_args))
6139 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006140
6141
6142def power_on_sim(ad, sim_slot_id=None):
6143 try:
6144 if sim_slot_id is None:
6145 ad.droid.telephonySetSimPowerState(CARD_POWER_UP)
6146 verify_func = ad.droid.telephonyGetSimState
6147 verify_args = []
6148 else:
6149 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP)
6150 verify_func = ad.droid.telephonyGetSimStateForSlotId
6151 verify_args = [sim_slot_id]
6152 except Exception as e:
6153 ad.log.error(e)
6154 return False
Betty Zhouddc76402018-01-23 16:29:25 -08006155 if wait_for_state(verify_func, SIM_STATE_READY,
6156 MAX_WAIT_TIME_FOR_STATE_CHANGE,
6157 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args):
Betty Zhoua0469792018-01-22 18:48:02 -08006158 ad.log.info("SIM slot is powered on, SIM state is READY")
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006159 return True
6160 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED:
Betty Zhoue66efb42018-01-31 19:45:56 -08006161 ad.log.info("SIM is pin locked")
6162 return True
Betty Zhoud49a0ce2018-01-19 17:49:53 -08006163 else:
6164 ad.log.error("Fail to power on SIM slot")
markdr6607bf12018-01-02 14:45:38 -08006165 return False
Betty Zhou6357f452018-02-05 18:09:07 -08006166
6167
Betty Zhou3db27a32018-04-23 14:31:25 -07006168def extract_test_log(log, src_file, dst_file, test_tag):
6169 cmd = "grep -n '%s' %s" % (test_tag, src_file)
6170 result = job.run(cmd, ignore_status=True)
6171 if not result.stdout or result.exit_status == 1:
Betty Zhoue26fe892018-04-23 15:29:53 -07006172 log.warning("Command %s returns %s", cmd, result)
Betty Zhou3db27a32018-04-23 14:31:25 -07006173 return
6174 line_nums = re.findall(r"(\d+).*", result.stdout)
6175 if line_nums:
6176 begin_line = line_nums[0]
6177 end_line = line_nums[-1]
6178 log.info("Extract %s from line %s to line %s to %s", src_file,
6179 begin_line, end_line, dst_file)
6180 job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line,
6181 src_file, dst_file))
6182
6183
Betty Zhou0ca65c52018-04-26 15:47:38 -07006184def get_device_epoch_time(ad):
6185 return int(1000 * float(ad.adb.shell("date +%s.%N")))
6186
6187
6188def synchronize_device_time(ad):
6189 ad.adb.shell("put global auto_time 0; date `date +%m%d%H%M%G.%S` ; "
6190 "am broadcast -a android.intent.action.TIME_SET")
6191
6192
Betty Zhou74cf9922018-04-18 20:18:12 -07006193def log_messaging_screen_shot(ad, test_name=""):
6194 ad.adb.shell(
6195 "am start -n com.google.android.apps.messaging/.ui.ConversationListActivity"
6196 )
6197 log_screen_shot(ad, test_name)
6198 ad.send_keycode("ENTER")
6199 ad.send_keycode("ENTER")
6200 log_screen_shot(ad, test_name)
6201 ad.send_keycode("HOME")
6202
6203
Betty Zhoua36c4352018-04-05 18:49:32 -07006204def log_screen_shot(ad, test_name=""):
Betty Zhou74cf9922018-04-18 20:18:12 -07006205 file_name = "/sdcard/Pictures/screencap"
6206 if test_name:
6207 file_name = "%s_%s" % (file_name, test_name)
6208 file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
Betty Zhoue57ab692018-03-09 18:39:30 -08006209 try:
6210 ad.adb.shell("screencap -p %s" % file_name)
Betty Zhoue57ab692018-03-09 18:39:30 -08006211 except:
Betty Zhoue123c672018-03-21 19:57:11 -07006212 ad.log.error("Fail to log screen shot to %s", file_name)
6213
6214
6215def get_screen_shot_log(ad, test_name="", begin_time=None):
6216 logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time)
6217 if logs:
6218 ad.log.info("Pulling %s", logs)
6219 log_path = os.path.join(ad.log_path, test_name,
Betty Zhoua36c4352018-04-05 18:49:32 -07006220 "Screenshot_%s" % ad.serial)
Betty Zhoue123c672018-03-21 19:57:11 -07006221 utils.create_dir(log_path)
Betty Zhoua36c4352018-04-05 18:49:32 -07006222 ad.pull_files(logs, log_path)
Betty Zhoue123c672018-03-21 19:57:11 -07006223 ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True)
6224
6225
6226def get_screen_shot_logs(ads, test_name="", begin_time=None):
6227 for ad in ads:
6228 get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time)