blob: 32ab37c6b8738bff974dd722aa0e531c3c6ca3c7 [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
Markus Liu2bd82302021-02-01 12:03:44 +080017from datetime import datetime
Alexander Dorokhine642e63f2016-02-11 13:32:37 -080018from future import standard_library
19standard_library.install_aliases()
20
Ang Li73697b32015-12-03 00:41:53 +000021import concurrent.futures
Betty Zhou2e01bc82017-03-17 10:55:57 -070022import json
Ang Li5bd83f32016-05-23 14:39:38 -070023import logging
Betty Zhou17dcabb2017-05-25 19:14:58 -070024import re
Betty Zhouccd171d2017-02-13 15:11:33 -080025import os
Ang Li73697b32015-12-03 00:41:53 +000026import urllib.parse
27import time
monikermine61898b92019-10-31 17:21:16 -070028import acts.controllers.iperf_server as ipf
jasonkmlu2565d892019-11-12 15:31:26 +080029import shutil
Ignacio Guarna9c63ef52020-02-06 17:08:09 -030030import struct
Ang Li73697b32015-12-03 00:41:53 +000031
Betty Zhou3b2de072018-03-15 16:46:26 -070032from acts import signals
Betty Zhoue62b1f12018-01-24 17:05:20 -080033from acts import utils
Ang Li73697b32015-12-03 00:41:53 +000034from queue import Empty
Betty Zhou5534e672017-03-07 13:47:10 -080035from acts.asserts import abort_all
Ashutosh Rajmani Singh69a5f5e2018-11-13 12:38:29 -080036from acts.asserts import fail
David Goldfarb78a3b672020-03-31 12:44:01 -070037from acts.controllers.adb_lib.error import AdbError
Betty Zhoub25ba2d2018-05-03 15:52:54 -070038from acts.controllers.android_device import list_adb_devices
39from acts.controllers.android_device import list_fastboot_devices
Betty Zhou9a96fc32018-02-01 16:44:05 -080040from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
Jaineel72d2c242019-07-23 12:00:07 -070041from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
Betty Zhou92437702018-02-07 19:49:07 -080042from acts.controllers.android_device import SL4A_APK_NAME
Betty Zhou3db27a32018-04-23 14:31:25 -070043from acts.libs.proc import job
Xianyuan Jia24299b72020-10-21 13:52:47 -070044from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
45from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs, CARRIER_NTT_DOCOMO, CARRIER_KDDI, CARRIER_RAKUTEN, \
ju8230cef2020-07-29 09:48:02 -070046 CARRIER_SBM
Xianyuan Jia24299b72020-10-21 13:52:47 -070047from acts_contrib.test_utils.tel.tel_defines import AOSP_PREFIX
48from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_DOWN
49from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_UP
50from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
51from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
52from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_PROVISIONING
53from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING
54from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL
55from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VT
56from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
57from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC_MODE_CHANGE
58from acts_contrib.test_utils.tel.tel_defines import CARRIER_UNKNOWN
59from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
60from acts_contrib.test_utils.tel.tel_defines import COUNTRY_CODE_LIST
Markus Liu8dd3efa2021-04-01 19:31:27 +080061from acts_contrib.test_utils.tel.tel_defines import NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST
Xianyuan Jia24299b72020-10-21 13:52:47 -070062from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
63from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
64from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE
65from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE
66from acts_contrib.test_utils.tel.tel_defines import GEN_4G
Markus Liua3fa4f42021-03-16 20:02:14 +080067from acts_contrib.test_utils.tel.tel_defines import GEN_5G
Xianyuan Jia24299b72020-10-21 13:52:47 -070068from acts_contrib.test_utils.tel.tel_defines import GEN_UNKNOWN
69from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
70from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
71from acts_contrib.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
72from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
73from acts_contrib.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
74from acts_contrib.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME
75from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
76from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT
77from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
78from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
79from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
80from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
81from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
82from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
83from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
84from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
85from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION
86from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS
87from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION
88from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
89from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
90from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
91from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
92from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
93from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL
94from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL
95from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY
96from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
97from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
98from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
99from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
100from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
101from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT
102from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT
103from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT
104from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT
105from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
106from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
107from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
108from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
109from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
110from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
111from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
112from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
113from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING
114from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
115from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
116from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT
117from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_LOADED
118from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_NOT_READY
119from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
120from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_READY
121from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
122from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
123from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
124from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
125from acts_contrib.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT
126from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
127from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
128from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
129from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
130from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
131from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
132from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
133from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
134from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK
135from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
136from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
137from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
138from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
139from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
140from acts_contrib.test_utils.tel.tel_defines import TYPE_MOBILE
141from acts_contrib.test_utils.tel.tel_defines import TYPE_WIFI
142from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
143from acts_contrib.test_utils.tel.tel_defines import EventActiveDataSubIdChanged
144from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged
145from acts_contrib.test_utils.tel.tel_defines import EventConnectivityChanged
146from acts_contrib.test_utils.tel.tel_defines import EventDataConnectionStateChanged
147from acts_contrib.test_utils.tel.tel_defines import EventDataSmsReceived
148from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
149from acts_contrib.test_utils.tel.tel_defines import EventServiceStateChanged
150from acts_contrib.test_utils.tel.tel_defines import EventMmsSentFailure
151from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
152from acts_contrib.test_utils.tel.tel_defines import EventMmsDownloaded
153from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
154from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverFailure
155from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
156from acts_contrib.test_utils.tel.tel_defines import EventSmsSentFailure
157from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
158from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
159from acts_contrib.test_utils.tel.tel_defines import DataConnectionStateContainer
160from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
161from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackContainer
162from acts_contrib.test_utils.tel.tel_defines import ServiceStateContainer
163from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer
164from acts_contrib.test_utils.tel.tel_defines import OverrideNetworkContainer
165from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
166from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW, CARRIER_ATT, \
Shaju Sebastian0b847e72019-01-31 16:40:37 -0800167 CARRIER_BELL, CARRIER_ROGERS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_TELUS
Xianyuan Jia24299b72020-10-21 13:52:47 -0700168from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string
169from acts_contrib.test_utils.tel.tel_lookup_tables import is_valid_rat
170from acts_contrib.test_utils.tel.tel_lookup_tables import get_allowable_network_preference
171from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_count_check_function
172from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number
173from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit
174from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
175from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_network_name
176from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
177from acts_contrib.test_utils.tel.tel_lookup_tables import rat_families_for_network_preference
178from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_for_generation
179from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat
180from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
181from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id, get_subid_from_slot_index
182from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
183from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
184from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
185from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_message_sub_id
186from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
187from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id
188from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
189from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
190from acts_contrib.test_utils.wifi import wifi_test_utils
191from acts_contrib.test_utils.wifi import wifi_constants
jasonkmluc0939182021-02-19 18:34:28 +0800192from acts_contrib.test_utils.gnss import gnss_test_utils as gutils
Betty Zhou8e11e442017-03-30 20:00:34 -0700193from acts.utils import adb_shell_ping
Yang Liu46ed7222015-12-28 14:08:52 -0800194from acts.utils import load_config
Jaineel55ae6f92017-06-29 17:44:19 -0700195from acts.utils import start_standing_subprocess
196from acts.utils import stop_standing_subprocess
Jaineelc9e7bfa2017-08-07 14:11:30 -0700197from acts.logger import epoch_to_log_line_timestamp
198from acts.logger import normalize_log_line_timestamp
199from acts.utils import get_current_epoch_time
Jaineel5576d432017-10-19 15:36:42 -0700200from acts.utils import exe_cmd
Markus Liud7850222020-04-14 17:11:12 +0800201from acts.utils import rand_ascii_str
Ang Li5bd83f32016-05-23 14:39:38 -0700202
Jaineel1cde17b2019-01-04 14:26:55 -0800203
Betty Zhouf987b8f2017-03-09 16:34:00 -0800204WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY
205WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY
Jaineel08466192020-07-13 17:09:03 -0700206WIFI_CONFIG_APBAND_2G = 1
207WIFI_CONFIG_APBAND_5G = 2
Bindu Mahadevfb8fbe02018-04-06 16:23:40 -0700208WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO
Ang Li5bd83f32016-05-23 14:39:38 -0700209log = logging
Betty Zhoudd781f82017-08-08 14:46:23 -0700210STORY_LINE = "+19523521350"
Kris Rambishdfe4a3a2019-03-26 21:53:43 -0700211CallResult = TelephonyVoiceTestResult.CallResult.Value
Pratik Sheth68e4eba2021-03-23 17:10:13 -0700212voice_call_type = {}
Pratik Sheth232f7952021-04-08 12:17:30 -0700213result_dict ={}
Nathan Harold123c9da2015-12-30 16:33:25 -0800214
Ang Li73697b32015-12-03 00:41:53 +0000215class TelTestUtilsError(Exception):
216 pass
217
Nathan Harold123c9da2015-12-30 16:33:25 -0800218
Kris Rambishdfe4a3a2019-03-26 21:53:43 -0700219class TelResultWrapper(object):
220 """Test results wrapper for Telephony test utils.
221
222 In order to enable metrics reporting without refactoring
223 all of the test utils this class is used to keep the
224 current return boolean scheme in tact.
225 """
226
227 def __init__(self, result_value):
228 self._result_value = result_value
229
230 @property
231 def result_value(self):
232 return self._result_value
233
234 @result_value.setter
235 def result_value(self, result_value):
236 self._result_value = result_value
237
238 def __bool__(self):
239 return self._result_value == CallResult('SUCCESS')
240
241
Betty Zhou5534e672017-03-07 13:47:10 -0800242def abort_all_tests(log, msg):
243 log.error("Aborting all ongoing tests due to: %s.", msg)
244 abort_all(msg)
245
246
Betty Zhou5b069a02016-12-06 19:23:44 -0800247def get_phone_number_by_adb(ad):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700248 return phone_number_formatter(
249 ad.adb.shell("service call iphonesubinfo 13"))
Betty Zhou5b069a02016-12-06 19:23:44 -0800250
251
252def get_iccid_by_adb(ad):
253 return ad.adb.shell("service call iphonesubinfo 11")
254
255
256def get_operator_by_adb(ad):
Jaineel28aec0e2019-01-10 14:16:36 -0800257 operator = ad.adb.getprop("gsm.sim.operator.alpha")
258 if "," in operator:
259 operator = operator.strip()[0]
260 return operator
Betty Zhou5b069a02016-12-06 19:23:44 -0800261
262
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700263def get_plmn_by_adb(ad):
Jaineel28aec0e2019-01-10 14:16:36 -0800264 plmn_id = ad.adb.getprop("gsm.sim.operator.numeric")
265 if "," in plmn_id:
266 plmn_id = plmn_id.strip()[0]
267 return plmn_id
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700268
269
Betty Zhou5b069a02016-12-06 19:23:44 -0800270def get_sub_id_by_adb(ad):
271 return ad.adb.shell("service call iphonesubinfo 5")
272
273
274def setup_droid_properties_by_adb(log, ad, sim_filename=None):
Ang Li73697b32015-12-03 00:41:53 +0000275
Betty Zhou5b069a02016-12-06 19:23:44 -0800276 sim_data = None
277 if sim_filename:
278 try:
279 sim_data = load_config(sim_filename)
280 except Exception:
Betty Zhouccd171d2017-02-13 15:11:33 -0800281 log.warning("Failed to load %s!", sim_filename)
Betty Zhou5b069a02016-12-06 19:23:44 -0800282
Betty Zhou76a83f72016-12-20 14:21:11 -0800283 sub_id = get_sub_id_by_adb(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700284 iccid = get_iccid_by_adb(ad)
285 ad.log.info("iccid = %s", iccid)
286 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700287 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"])
288 else:
289 phone_number = get_phone_number_by_adb(ad)
Betty Zhouddb361d2017-09-07 17:07:20 -0700290 if not phone_number and hasattr(ad, phone_number):
291 phone_number = ad.phone_number
Betty Zhou5b069a02016-12-06 19:23:44 -0800292 if not phone_number:
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700293 ad.log.error("Failed to find valid phone number for %s", iccid)
Betty Zhoud4b75c52018-04-03 15:20:00 -0700294 abort_all_tests(ad.log, "Failed to find valid phone number for %s")
Betty Zhou3b2de072018-03-15 16:46:26 -0700295 sub_record = {
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700296 'phone_num': phone_number,
Betty Zhoua27e5d42017-01-17 11:33:04 -0800297 'iccid': get_iccid_by_adb(ad),
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700298 'sim_operator_name': get_operator_by_adb(ad),
299 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad))
Betty Zhoua27e5d42017-01-17 11:33:04 -0800300 }
Betty Zhou3b2de072018-03-15 16:46:26 -0700301 device_props = {'subscription': {sub_id: sub_record}}
302 ad.log.info("subId %s SIM record: %s", sub_id, sub_record)
303 setattr(ad, 'telephony', device_props)
Betty Zhou5b069a02016-12-06 19:23:44 -0800304
305
Jaineelc9ea2f32019-08-21 13:48:16 -0700306def setup_droid_properties(log, ad, sim_filename=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800307
Betty Zhou5b069a02016-12-06 19:23:44 -0800308 if ad.skip_sl4a:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800309 return setup_droid_properties_by_adb(
310 log, ad, sim_filename=sim_filename)
Jaineelc9ea2f32019-08-21 13:48:16 -0700311 refresh_droid_config(log, ad)
Ang Li73697b32015-12-03 00:41:53 +0000312 device_props = {}
313 device_props['subscription'] = {}
314
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700315 sim_data = {}
316 if sim_filename:
317 try:
318 sim_data = load_config(sim_filename)
319 except Exception:
320 log.warning("Failed to load %s!", sim_filename)
Betty Zhou3b2de072018-03-15 16:46:26 -0700321 if not ad.telephony["subscription"]:
Betty Zhou28e07e12018-04-11 12:12:11 -0700322 abort_all_tests(ad.log, "No valid subscription")
Jaineel28aec0e2019-01-10 14:16:36 -0800323 ad.log.debug("Subscription DB %s", ad.telephony["subscription"])
Betty Zhoude88d172017-10-27 18:20:29 -0700324 result = True
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800325 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhou3b2de072018-03-15 16:46:26 -0700326 for sub_id, sub_info in ad.telephony["subscription"].items():
Jaineel28aec0e2019-01-10 14:16:36 -0800327 ad.log.debug("Loop for Subid %s", sub_id)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700328 sub_info["operator"] = get_operator_name(log, ad, sub_id)
329 iccid = sub_info["iccid"]
330 if not iccid:
Betty Zhou3b2de072018-03-15 16:46:26 -0700331 ad.log.warning("Unable to find ICC-ID for subscriber %s", sub_id)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700332 continue
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800333 if sub_info.get("phone_num"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700334 if iccid in sim_data and sim_data[iccid].get("phone_num"):
335 if not check_phone_number_match(sim_data[iccid]["phone_num"],
336 sub_info["phone_num"]):
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800337 ad.log.warning(
338 "phone_num %s in sim card data file for iccid %s"
Betty Zhou3b2de072018-03-15 16:46:26 -0700339 " do not match phone_num %s from subscription",
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800340 sim_data[iccid]["phone_num"], iccid,
341 sub_info["phone_num"])
Betty Zhou3b2de072018-03-15 16:46:26 -0700342 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
343 else:
344 if iccid in sim_data and sim_data[iccid].get("phone_num"):
345 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
346 elif sub_id == active_sub_id:
347 phone_number = get_phone_number_by_secret_code(
348 ad, sub_info["sim_operator_name"])
349 if phone_number:
350 sub_info["phone_num"] = phone_number
351 elif getattr(ad, "phone_num", None):
352 sub_info["phone_num"] = ad.phone_number
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800353 if (not sub_info.get("phone_num")) and sub_id == active_sub_id:
354 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info)
355 ad.log.error(
356 "Unable to retrieve phone number for sub %s with iccid"
357 " %s from device or testbed config or sim card file %s",
358 sub_id, iccid, sim_filename)
359 result = False
Betty Zhouee311052017-12-19 13:09:56 -0800360 if not hasattr(
361 ad, 'roaming'
Betty Zhou3b2de072018-03-15 16:46:26 -0700362 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and sub_info["sim_operator_name"].strip(
363 ) not in sub_info["network_operator_name"].strip():
Betty Zhou2cf788e2017-06-27 17:25:53 -0700364 ad.log.info("roaming is not enabled, enable it")
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700365 setattr(ad, 'roaming', True)
Betty Zhou70cc4332017-09-20 15:06:13 -0700366 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items()))
Betty Zhou8aafcc12018-05-01 20:54:15 -0700367 get_phone_capability(ad)
Betty Zhou2cf788e2017-06-27 17:25:53 -0700368 data_roaming = getattr(ad, 'roaming', False)
369 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
370 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Betty Zhou739d6b72018-04-18 10:38:53 -0700371 # Setup VoWiFi MDN for Verizon. b/33187374
Betty Zhouddb361d2017-09-07 17:07:20 -0700372 if not result:
373 abort_all_tests(ad.log, "Failed to find valid phone number")
Ang Li73697b32015-12-03 00:41:53 +0000374
Betty Zhou3b2de072018-03-15 16:46:26 -0700375 ad.log.debug("telephony = %s", ad.telephony)
Ang Li73697b32015-12-03 00:41:53 +0000376
Nathan Harold7642fc92016-05-02 18:29:11 -0700377
Jaineelc9ea2f32019-08-21 13:48:16 -0700378def refresh_droid_config(log, ad):
Betty Zhou3b2de072018-03-15 16:46:26 -0700379 """ Update Android Device telephony records for each sub_id.
Yang Liuad9c63d2016-02-25 13:59:23 -0800380
381 Args:
382 log: log object
383 ad: android device object
Yang Liuad9c63d2016-02-25 13:59:23 -0800384
385 Returns:
Yang Liu6c70e022016-03-07 16:19:42 -0800386 None
Yang Liuad9c63d2016-02-25 13:59:23 -0800387 """
Betty Zhou3b2de072018-03-15 16:46:26 -0700388 if not getattr(ad, 'telephony', {}):
389 setattr(ad, 'telephony', {"subscription": {}})
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700390 droid = ad.droid
391 sub_info_list = droid.subscriptionGetAllSubInfoList()
Jaineel28aec0e2019-01-10 14:16:36 -0800392 ad.log.info("SubInfoList is %s", sub_info_list)
Betty Zhou3b2de072018-03-15 16:46:26 -0700393 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700394 for sub_info in sub_info_list:
395 sub_id = sub_info["subscriptionId"]
396 sim_slot = sub_info["simSlotIndex"]
Jaineel50c2de12019-08-27 16:33:28 -0700397 if sub_info.get("carrierId"):
398 carrier_id = sub_info["carrierId"]
399 else:
400 carrier_id = -1
Jaineel24052672020-04-16 20:37:36 -0700401 if sub_info.get("isOpportunistic"):
402 isopportunistic = sub_info["isOpportunistic"]
403 else:
404 isopportunistic = -1
Jaineel28aec0e2019-01-10 14:16:36 -0800405
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700406 if sim_slot != INVALID_SIM_SLOT_INDEX:
Betty Zhou3b2de072018-03-15 16:46:26 -0700407 if sub_id not in ad.telephony["subscription"]:
408 ad.telephony["subscription"][sub_id] = {}
409 sub_record = ad.telephony["subscription"][sub_id]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800410 if sub_info.get("iccId"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700411 sub_record["iccid"] = sub_info["iccId"]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800412 else:
Betty Zhou3b2de072018-03-15 16:46:26 -0700413 sub_record[
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800414 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription(
415 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700416 sub_record["sim_slot"] = sim_slot
417 if sub_info.get("mcc"):
418 sub_record["mcc"] = sub_info["mcc"]
419 if sub_info.get("mnc"):
420 sub_record["mnc"] = sub_info["mnc"]
421 if sub_info.get("displayName"):
422 sub_record["display_name"] = sub_info["displayName"]
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700423 try:
Betty Zhou3b2de072018-03-15 16:46:26 -0700424 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700425 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription(
426 sub_id)
427 except:
Betty Zhou3b2de072018-03-15 16:46:26 -0700428 if not sub_record.get("phone_type"):
429 sub_record["phone_type"] = droid.telephonyGetPhoneType()
430 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700431 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription(
432 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700433 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700434 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription(
435 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700436 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700437 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription(
438 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700439 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700440 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription(
441 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700442 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700443 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription(
444 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700445 if active_sub_id == sub_id:
446 try:
447 sub_record[
448 "carrier_id"] = ad.droid.telephonyGetSimCarrierId()
449 sub_record[
450 "carrier_id_name"] = ad.droid.telephonyGetSimCarrierIdName(
451 )
452 except:
453 ad.log.info("Carrier ID is not supported")
Jaineelc9ea2f32019-08-21 13:48:16 -0700454 if carrier_id == 2340:
455 ad.log.info("SubId %s info: %s", sub_id, sorted(
456 sub_record.items()))
Jaineel9fe43112019-12-12 13:18:59 -0800457 continue
Jaineel24052672020-04-16 20:37:36 -0700458 if carrier_id == 1989 and isopportunistic == "true":
459 ad.log.info("SubId %s info: %s", sub_id, sorted(
460 sub_record.items()))
461 continue
Betty Zhou3b2de072018-03-15 16:46:26 -0700462 if not sub_info.get("number"):
463 sub_info[
464 "number"] = droid.telephonyGetLine1NumberForSubscription(
465 sub_id)
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800466 if sub_info.get("number"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700467 if sub_record.get("phone_num"):
468 # Use the phone number provided in sim info file by default
469 # as the sub_info["number"] may not be formatted in a
470 # dialable number
471 if not check_phone_number_match(sub_info["number"],
472 sub_record["phone_num"]):
473 ad.log.info(
474 "Subscriber phone number changed from %s to %s",
475 sub_record["phone_num"], sub_info["number"])
476 sub_record["phone_num"] = sub_info["number"]
477 else:
478 sub_record["phone_num"] = phone_number_formatter(
479 sub_info["number"])
480 #ad.telephony['subscription'][sub_id] = sub_record
481 ad.log.info("SubId %s info: %s", sub_id, sorted(
482 sub_record.items()))
Nathan Harold7642fc92016-05-02 18:29:11 -0700483
Nathan Harold123c9da2015-12-30 16:33:25 -0800484
Betty Zhouddb361d2017-09-07 17:07:20 -0700485def get_phone_number_by_secret_code(ad, operator):
486 if "T-Mobile" in operator:
487 ad.droid.telecomDialNumber("#686#")
488 ad.send_keycode("ENTER")
Betty Zhoub4062372017-09-08 11:29:38 -0700489 for _ in range(12):
490 output = ad.search_logcat("mobile number")
491 if output:
492 result = re.findall(r"mobile number is (\S+)",
493 output[-1]["log_message"])
Betty Zhou70cc4332017-09-20 15:06:13 -0700494 ad.send_keycode("BACK")
Betty Zhoub4062372017-09-08 11:29:38 -0700495 return result[0]
496 else:
497 time.sleep(5)
498 return ""
Betty Zhouddb361d2017-09-07 17:07:20 -0700499
500
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700501def get_user_config_profile(ad):
502 return {
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700503 "Airplane Mode":
504 ad.droid.connectivityCheckAirplaneMode(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700505 "IMS Registered":
506 ad.droid.telephonyIsImsRegistered(),
Betty Zhoued13b712018-05-02 19:40:10 -0700507 "Preferred Network Type":
508 ad.droid.telephonyGetPreferredNetworkTypes(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700509 "VoLTE Platform Enabled":
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700510 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(),
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700511 "VoLTE Enabled":
Betty Zhou8aafcc12018-05-01 20:54:15 -0700512 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser(),
513 "VoLTE Available":
514 ad.droid.telephonyIsVolteAvailable(),
515 "VT Available":
516 ad.droid.telephonyIsVideoCallingAvailable(),
517 "VT Enabled":
518 ad.droid.imsIsVtEnabledByUser(),
519 "VT Platform Enabled":
520 ad.droid.imsIsVtEnabledByPlatform(),
Markus Liu1cca96e2019-11-26 15:05:25 +0800521 "WiFi State":
522 ad.droid.wifiCheckState(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700523 "WFC Available":
524 ad.droid.telephonyIsWifiCallingAvailable(),
525 "WFC Enabled":
526 ad.droid.imsIsWfcEnabledByUser(),
527 "WFC Platform Enabled":
528 ad.droid.imsIsWfcEnabledByPlatform(),
529 "WFC Mode":
530 ad.droid.imsGetWfcMode()
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700531 }
532
533
Yang Liu7ce19982016-03-09 12:20:41 -0800534def get_slot_index_from_subid(log, ad, sub_id):
535 try:
536 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
537 return info['simSlotIndex']
tturney10eda2e2016-03-30 19:55:57 -0700538 except KeyError:
Yang Liu7ce19982016-03-09 12:20:41 -0800539 return INVALID_SIM_SLOT_INDEX
540
Nathan Harold123c9da2015-12-30 16:33:25 -0800541
Ang Li73697b32015-12-03 00:41:53 +0000542def get_num_active_sims(log, ad):
543 """ Get the number of active SIM cards by counting slots
544
545 Args:
546 ad: android_device object.
547
548 Returns:
549 result: The number of loaded (physical) SIM cards
550 """
551 # using a dictionary as a cheap way to prevent double counting
552 # in the situation where multiple subscriptions are on the same SIM.
553 # yes, this is a corner corner case.
554 valid_sims = {}
555 subInfo = ad.droid.subscriptionGetAllSubInfoList()
556 for info in subInfo:
557 ssidx = info['simSlotIndex']
558 if ssidx == INVALID_SIM_SLOT_INDEX:
559 continue
560 valid_sims[ssidx] = True
561 return len(valid_sims.keys())
562
Nathan Harold123c9da2015-12-30 16:33:25 -0800563
Betty Zhoua37acd32017-02-23 20:04:24 -0800564def toggle_airplane_mode_by_adb(log, ad, new_state=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800565 """ Toggle the state of airplane mode.
566
567 Args:
568 log: log handler.
569 ad: android_device object.
570 new_state: Airplane mode state to set to.
571 If None, opposite of the current state.
572 strict_checking: Whether to turn on strict checking that checks all features.
573
574 Returns:
575 result: True if operation succeed. False if error happens.
576 """
577 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
578 if new_state == cur_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800579 ad.log.info("Airplane mode already in %s", new_state)
Betty Zhou5b069a02016-12-06 19:23:44 -0800580 return True
581 elif new_state is None:
582 new_state = not cur_state
Betty Zhou8aafcc12018-05-01 20:54:15 -0700583 ad.log.info("Change airplane mode from %s to %s", cur_state, new_state)
monikermine3eb66302019-10-29 13:46:56 -0700584 try:
585 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state))
586 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE")
587 except Exception as e:
588 ad.log.error(e)
589 return False
590 changed_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
591 return changed_state == new_state
Betty Zhou5b069a02016-12-06 19:23:44 -0800592
593
Betty Zhou28732962016-11-28 15:00:58 -0800594def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000595 """ Toggle the state of airplane mode.
596
597 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800598 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000599 ad: android_device object.
600 new_state: Airplane mode state to set to.
601 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800602 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000603
604 Returns:
605 result: True if operation succeed. False if error happens.
606 """
Betty Zhou5b069a02016-12-06 19:23:44 -0800607 if ad.skip_sl4a:
608 return toggle_airplane_mode_by_adb(log, ad, new_state)
609 else:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800610 return toggle_airplane_mode_msim(
611 log, ad, new_state, strict_checking=strict_checking)
Ang Li73697b32015-12-03 00:41:53 +0000612
Nathan Harold123c9da2015-12-30 16:33:25 -0800613
Betty Zhou17dcabb2017-05-25 19:14:58 -0700614def get_telephony_signal_strength(ad):
Betty Zhou17dcabb2017-05-25 19:14:58 -0700615 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0,
616 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160,
617 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0,
618 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0,
619 # 'lteDbm': -112, 'gsmSignalStrength': 99}
Betty Zhouf7da39e2018-04-16 16:28:58 -0700620 try:
621 signal_strength = ad.droid.telephonyGetSignalStrength()
622 if not signal_strength:
623 signal_strength = {}
624 except Exception as e:
625 ad.log.error(e)
626 signal_strength = {}
Betty Zhou17dcabb2017-05-25 19:14:58 -0700627 return signal_strength
628
629
Jaineele64be822017-11-30 16:36:36 -0800630def get_wifi_signal_strength(ad):
631 signal_strength = ad.droid.wifiGetConnectionInfo()['rssi']
632 ad.log.info("WiFi Signal Strength is %s" % signal_strength)
633 return signal_strength
634
635
Jaineel2947eaf2019-04-03 11:18:53 -0700636def get_lte_rsrp(ad):
637 try:
638 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
639 out = ad.adb.shell(
640 "dumpsys telephony.registry | grep -i signalstrength")
641 if out:
642 lte_rsrp = out.split()[9]
643 if lte_rsrp:
644 ad.log.info("lte_rsrp: %s ", lte_rsrp)
645 return lte_rsrp
646 else:
647 out = ad.adb.shell(
648 "dumpsys telephony.registry |grep -i primary=CellSignalStrengthLte")
649 if out:
650 lte_cell_info = out.split('mLte=')[1]
651 lte_rsrp = re.match(r'.*rsrp=(\S+).*', lte_cell_info).group(1)
652 if lte_rsrp:
653 ad.log.info("lte_rsrp: %s ", lte_rsrp)
654 return lte_rsrp
655 except Exception as e:
656 ad.log.error(e)
657 return None
658
659
Jaineel22508f22019-01-31 18:30:21 -0800660def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL):
661 data_stall_detected = False
662 time_var = 1
663 try:
664 while (time_var < wait_time):
665 out = ad.adb.shell("dumpsys network_stack " \
666 "| grep \"Suspecting data stall\"",
667 ignore_status=True)
668 ad.log.debug("Output is %s", out)
669 if out:
670 ad.log.info("NetworkMonitor detected - %s", out)
Jaineel22508f22019-01-31 18:30:21 -0800671 data_stall_detected = True
672 break
673 time.sleep(30)
674 time_var += 30
675 except Exception as e:
676 ad.log.error(e)
677 return data_stall_detected
678
679
680def check_network_validation_fail(ad, begin_time=None,
681 wait_time=WAIT_TIME_FOR_NW_VALID_FAIL):
682 network_validation_fail = False
683 time_var = 1
684 try:
685 while (time_var < wait_time):
686 time_var += 30
687 nw_valid = ad.search_logcat("validation failed",
688 begin_time)
689 if nw_valid:
690 ad.log.info("Validation Failed received here - %s",
691 nw_valid[0]["log_message"])
692 network_validation_fail = True
693 break
694 time.sleep(30)
695 except Exception as e:
696 ad.log.error(e)
697 return network_validation_fail
698
699
700def check_data_stall_recovery(ad, begin_time=None,
701 wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY):
702 data_stall_recovery = False
703 time_var = 1
704 try:
705 while (time_var < wait_time):
706 time_var += 30
707 recovery = ad.search_logcat("doRecovery() cleanup all connections",
708 begin_time)
709 if recovery:
710 ad.log.info("Recovery Performed here - %s",
711 recovery[-1]["log_message"])
712 data_stall_recovery = True
713 break
714 time.sleep(30)
715 except Exception as e:
716 ad.log.error(e)
717 return data_stall_recovery
718
719
720def break_internet_except_sl4a_port(ad, sl4a_port):
721 ad.log.info("Breaking internet using iptables rules")
722 ad.adb.shell("iptables -I INPUT 1 -p tcp --dport %s -j ACCEPT" % sl4a_port,
723 ignore_status=True)
724 ad.adb.shell("iptables -I INPUT 2 -p tcp --sport %s -j ACCEPT" % sl4a_port,
725 ignore_status=True)
726 ad.adb.shell("iptables -I INPUT 3 -j DROP", ignore_status=True)
727 ad.adb.shell("ip6tables -I INPUT -j DROP", ignore_status=True)
728 return True
729
730
731def resume_internet_with_sl4a_port(ad, sl4a_port):
732 ad.log.info("Bring internet back using iptables rules")
733 ad.adb.shell("iptables -D INPUT -p tcp --dport %s -j ACCEPT" % sl4a_port,
734 ignore_status=True)
735 ad.adb.shell("iptables -D INPUT -p tcp --sport %s -j ACCEPT" % sl4a_port,
736 ignore_status=True)
737 ad.adb.shell("iptables -D INPUT -j DROP", ignore_status=True)
738 ad.adb.shell("ip6tables -D INPUT -j DROP", ignore_status=True)
739 return True
740
741
742def test_data_browsing_success_using_sl4a(log, ad):
743 result = True
744 web_page_list = ['https://www.google.com', 'https://www.yahoo.com',
745 'https://www.amazon.com', 'https://www.nike.com',
746 'https://www.facebook.com']
747 for website in web_page_list:
748 if not verify_http_connection(log, ad, website, retry=0):
749 ad.log.error("Failed to browse %s successfully!", website)
750 result = False
751 return result
752
753
754def test_data_browsing_failure_using_sl4a(log, ad):
755 result = True
756 web_page_list = ['https://www.youtube.com', 'https://www.cnn.com',
757 'https://www.att.com', 'https://www.nbc.com',
758 'https://www.verizonwireless.com']
759 for website in web_page_list:
760 if not verify_http_connection(log, ad, website, retry=0,
761 expected_state=False):
762 ad.log.error("Browsing to %s worked!", website)
763 result = False
764 return result
765
766
Ang Li73697b32015-12-03 00:41:53 +0000767def is_expected_event(event_to_check, events_list):
768 """ check whether event is present in the event list
769
770 Args:
771 event_to_check: event to be checked.
772 events_list: list of events
773 Returns:
774 result: True if event present in the list. False if not.
775 """
776 for event in events_list:
777 if event in event_to_check['name']:
778 return True
779 return False
780
Nathan Harold123c9da2015-12-30 16:33:25 -0800781
Ang Li73697b32015-12-03 00:41:53 +0000782def is_sim_ready(log, ad, sim_slot_id=None):
783 """ check whether SIM is ready.
784
785 Args:
786 ad: android_device object.
787 sim_slot_id: check the SIM status for sim_slot_id
788 This is optional. If this is None, check default SIM.
789
790 Returns:
791 result: True if all SIMs are ready. False if not.
792 """
793 if sim_slot_id is None:
Yang Liuaed3eef2015-12-15 18:40:25 -0800794 status = ad.droid.telephonyGetSimState()
Ang Li73697b32015-12-03 00:41:53 +0000795 else:
Yang Liuaed3eef2015-12-15 18:40:25 -0800796 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id)
Ang Li73697b32015-12-03 00:41:53 +0000797 if status != SIM_STATE_READY:
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700798 ad.log.info("Sim state is %s, not ready", status)
Nathan Harold123c9da2015-12-30 16:33:25 -0800799 return False
Ang Li73697b32015-12-03 00:41:53 +0000800 return True
801
Nathan Harold123c9da2015-12-30 16:33:25 -0800802
Betty Zhou688c1032017-11-20 20:08:04 -0800803def is_sim_ready_by_adb(log, ad):
Betty Zhoue66efb42018-01-31 19:45:56 -0800804 state = ad.adb.getprop("gsm.sim.state")
Betty Zhou28e07e12018-04-11 12:12:11 -0700805 ad.log.info("gsm.sim.state = %s", state)
Betty Zhoue66efb42018-01-31 19:45:56 -0800806 return state == SIM_STATE_READY or state == SIM_STATE_LOADED
Betty Zhou688c1032017-11-20 20:08:04 -0800807
808
809def wait_for_sim_ready_by_adb(log, ad, wait_time=90):
810 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb)
811
812
Visweswara Kumar541c0c72018-09-05 12:53:31 -0700813def is_sims_ready_by_adb(log, ad):
814 states = list(ad.adb.getprop("gsm.sim.state").split(","))
815 ad.log.info("gsm.sim.state = %s", states)
816 for state in states:
817 if state != SIM_STATE_READY and state != SIM_STATE_LOADED:
818 return False
819 return True
820
821
822def wait_for_sims_ready_by_adb(log, ad, wait_time=90):
823 return _wait_for_droid_in_state(log, ad, wait_time, is_sims_ready_by_adb)
824
825
Betty Zhou688c1032017-11-20 20:08:04 -0800826def get_service_state_by_adb(log, ad):
827 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState")
828 if "mVoiceRegState" in output:
Markus Liu479543e2020-12-16 15:15:28 +0800829 result = re.findall(r"mVoiceRegState=(\S+)\((\S+)\)", output)
Betty Zhou688c1032017-11-20 20:08:04 -0800830 if result:
Markus Liu479543e2020-12-16 15:15:28 +0800831 if getattr(ad, 'dsds', False):
832 default_slot = getattr(ad, 'default_slot', 0)
833 ad.log.info("mVoiceRegState is %s %s", result[default_slot][0],
834 result[default_slot][1])
835 return result[default_slot][1]
836 else:
837 ad.log.info("mVoiceRegState is %s %s", result[0][0],
838 result[0][1])
839 return result[0][1]
Betty Zhou688c1032017-11-20 20:08:04 -0800840 else:
841 result = re.search(r"mServiceState=(\S+)", output)
842 if result:
Betty Zhouee311052017-12-19 13:09:56 -0800843 ad.log.info("mServiceState=%s %s", result.group(1),
Betty Zhou688c1032017-11-20 20:08:04 -0800844 SERVICE_STATE_MAPPING[result.group(1)])
845 return SERVICE_STATE_MAPPING[result.group(1)]
846
847
Ang Li73697b32015-12-03 00:41:53 +0000848def _is_expecting_event(event_recv_list):
849 """ check for more event is expected in event list
850
851 Args:
852 event_recv_list: list of events
853 Returns:
854 result: True if more events are expected. False if not.
855 """
856 for state in event_recv_list:
857 if state is False:
Nathan Harold123c9da2015-12-30 16:33:25 -0800858 return True
Ang Li73697b32015-12-03 00:41:53 +0000859 return False
860
Nathan Harold123c9da2015-12-30 16:33:25 -0800861
862def _set_event_list(event_recv_list, sub_id_list, sub_id, value):
Ang Li73697b32015-12-03 00:41:53 +0000863 """ set received event in expected event list
864
865 Args:
866 event_recv_list: list of received events
867 sub_id_list: subscription ID list
868 sub_id: subscription id of current event
869 value: True or False
870 Returns:
871 None.
872 """
873 for i in range(len(sub_id_list)):
874 if sub_id_list[i] == sub_id:
875 event_recv_list[i] = value
876
Nathan Harold123c9da2015-12-30 16:33:25 -0800877
Nathan Harold54129bb2016-09-29 19:40:52 -0700878def _wait_for_bluetooth_in_state(log, ad, state, max_wait):
879 # FIXME: These event names should be defined in a common location
880 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn'
881 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff'
Nathan Harold9b1b2f12016-10-14 12:42:57 -0700882 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT)
883 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT)
884
Nathan Harold54129bb2016-09-29 19:40:52 -0700885 ad.droid.bluetoothStartListeningForAdapterStateChange()
886 try:
887 bt_state = ad.droid.bluetoothCheckState()
888 if bt_state == state:
889 return True
890 if max_wait <= 0:
Betty Zhoua37acd32017-02-23 20:04:24 -0800891 ad.log.error("Time out: bluetooth state still %s, expecting %s",
892 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700893 return False
894
Betty Zhoua27e5d42017-01-17 11:33:04 -0800895 event = {
896 False: _BLUETOOTH_STATE_OFF_EVENT,
897 True: _BLUETOOTH_STATE_ON_EVENT
898 }[state]
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700899 event = ad.ed.pop_event(event, max_wait)
900 ad.log.info("Got event %s", event['name'])
Nathan Harold54129bb2016-09-29 19:40:52 -0700901 return True
902 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800903 ad.log.error("Time out: bluetooth state still in %s, expecting %s",
904 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700905 return False
906 finally:
907 ad.droid.bluetoothStopListeningForAdapterStateChange()
908
909
910# TODO: replace this with an event-based function
911def _wait_for_wifi_in_state(log, ad, state, max_wait):
912 return _wait_for_droid_in_state(log, ad, max_wait,
913 lambda log, ad, state: \
914 (True if ad.droid.wifiCheckState() == state else False),
915 state)
916
917
Betty Zhou28732962016-11-28 15:00:58 -0800918def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000919 """ Toggle the state of airplane mode.
920
921 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800922 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000923 ad: android_device object.
924 new_state: Airplane mode state to set to.
925 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800926 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000927
928 Returns:
929 result: True if operation succeed. False if error happens.
930 """
Ang Li73697b32015-12-03 00:41:53 +0000931
Ang Li73697b32015-12-03 00:41:53 +0000932 cur_state = ad.droid.connectivityCheckAirplaneMode()
933 if cur_state == new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800934 ad.log.info("Airplane mode already in %s", new_state)
Ang Li73697b32015-12-03 00:41:53 +0000935 return True
936 elif new_state is None:
Ang Li73697b32015-12-03 00:41:53 +0000937 new_state = not cur_state
Betty Zhoub66d48f2018-04-09 12:00:53 -0700938 ad.log.info("Toggle APM mode, from current tate %s to %s", cur_state,
939 new_state)
Betty Zhoue123c672018-03-21 19:57:11 -0700940 sub_id_list = []
941 active_sub_info = ad.droid.subscriptionGetAllSubInfoList()
codycaldwell555da912020-01-27 15:08:46 -0800942 if active_sub_info:
943 for info in active_sub_info:
944 sub_id_list.append(info['subscriptionId'])
Betty Zhoue123c672018-03-21 19:57:11 -0700945
946 ad.ed.clear_all_events()
947 time.sleep(0.1)
Yang Liu8e6adff2016-02-05 10:24:04 -0800948 service_state_list = []
Ang Li73697b32015-12-03 00:41:53 +0000949 if new_state:
Yang Liu8e6adff2016-02-05 10:24:04 -0800950 service_state_list.append(SERVICE_STATE_POWER_OFF)
Betty Zhoua37acd32017-02-23 20:04:24 -0800951 ad.log.info("Turn on airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000952
953 else:
954 # If either one of these 3 events show up, it should be OK.
955 # Normal SIM, phone in service
Yang Liu8e6adff2016-02-05 10:24:04 -0800956 service_state_list.append(SERVICE_STATE_IN_SERVICE)
Ang Li73697b32015-12-03 00:41:53 +0000957 # NO SIM, or Dead SIM, or no Roaming coverage.
Yang Liu8e6adff2016-02-05 10:24:04 -0800958 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE)
959 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY)
Betty Zhoua37acd32017-02-23 20:04:24 -0800960 ad.log.info("Turn off airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000961
962 for sub_id in sub_id_list:
Nathan Harold123c9da2015-12-30 16:33:25 -0800963 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription(
964 sub_id)
Nathan Harold54129bb2016-09-29 19:40:52 -0700965
966 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Ang Li73697b32015-12-03 00:41:53 +0000967 ad.droid.connectivityToggleAirplaneMode(new_state)
968
Ang Li73697b32015-12-03 00:41:53 +0000969 try:
970 try:
Nathan Harold7642fc92016-05-02 18:29:11 -0700971 event = ad.ed.wait_for_event(
972 EventServiceStateChanged,
973 is_event_match_for_list,
974 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT,
975 field=ServiceStateContainer.SERVICE_STATE,
976 value_list=service_state_list)
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700977 ad.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +0000978 except Empty:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700979 ad.log.warning("Did not get expected service state change to %s",
980 service_state_list)
Betty Zhoua36c4352018-04-05 18:49:32 -0700981 finally:
982 for sub_id in sub_id_list:
983 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
984 sub_id)
985 except Exception as e:
986 ad.log.error(e)
Ang Li73697b32015-12-03 00:41:53 +0000987
Nathan Harold54129bb2016-09-29 19:40:52 -0700988 # APM on (new_state=True) will turn off bluetooth but may not turn it on
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800989 try:
990 if new_state and not _wait_for_bluetooth_in_state(
Betty Zhoua27e5d42017-01-17 11:33:04 -0800991 log, ad, False, timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800992 ad.log.error(
993 "Failed waiting for bluetooth during airplane mode toggle")
Betty Zhou28732962016-11-28 15:00:58 -0800994 if strict_checking: return False
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800995 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -0800996 ad.log.error("Failed to check bluetooth state due to %s", e)
Betty Zhou28732962016-11-28 15:00:58 -0800997 if strict_checking:
998 raise
Nathan Harold54129bb2016-09-29 19:40:52 -0700999
1000 # APM on (new_state=True) will turn off wifi but may not turn it on
Nathan Harold450a7682016-10-12 12:57:17 -07001001 if new_state and not _wait_for_wifi_in_state(log, ad, False,
1002 timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -08001003 ad.log.error("Failed waiting for wifi during airplane mode toggle on")
1004 if strict_checking: return False
Nathan Harold54129bb2016-09-29 19:40:52 -07001005
1006 if ad.droid.connectivityCheckAirplaneMode() != new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -08001007 ad.log.error("Set airplane mode to %s failed", new_state)
Nathan Harold54129bb2016-09-29 19:40:52 -07001008 return False
Ang Li73697b32015-12-03 00:41:53 +00001009 return True
1010
Nathan Harold123c9da2015-12-30 16:33:25 -08001011
1012def wait_and_answer_call(log,
1013 ad,
1014 incoming_number=None,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001015 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07001016 caller=None,
1017 video_state=None):
Ang Li73697b32015-12-03 00:41:53 +00001018 """Wait for an incoming call on default voice subscription and
1019 accepts the call.
1020
1021 Args:
1022 ad: android device object.
1023 incoming_number: Expected incoming number.
1024 Optional. Default is None
Ang Li73697b32015-12-03 00:41:53 +00001025 incall_ui_display: after answer the call, bring in-call UI to foreground or
1026 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1027 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1028 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1029 else, do nothing.
1030
1031 Returns:
1032 True: if incoming call is received and answered successfully.
1033 False: for errors
1034 """
1035 return wait_and_answer_call_for_subscription(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001036 log,
1037 ad,
1038 get_incoming_voice_sub_id(ad),
1039 incoming_number,
1040 incall_ui_display=incall_ui_display,
Betty Zhou48557582018-05-14 13:19:23 -07001041 caller=caller,
1042 video_state=video_state)
Nathan Harold123c9da2015-12-30 16:33:25 -08001043
Ang Li73697b32015-12-03 00:41:53 +00001044
Nathan Harold54c7c742016-08-04 19:40:44 -07001045def _wait_for_ringing_event(log, ad, wait_time):
Ang Li73697b32015-12-03 00:41:53 +00001046 """Wait for ringing event.
1047
1048 Args:
1049 log: log object.
1050 ad: android device object.
1051 wait_time: max time to wait for ringing event.
1052
1053 Returns:
1054 event_ringing if received ringing event.
1055 otherwise return None.
1056 """
Ang Li73697b32015-12-03 00:41:53 +00001057 event_ringing = None
1058
Nathan Harold0111e202016-09-27 17:03:00 -07001059 try:
1060 event_ringing = ad.ed.wait_for_event(
1061 EventCallStateChanged,
1062 is_event_match,
1063 timeout=wait_time,
1064 field=CallStateContainer.CALL_STATE,
1065 value=TELEPHONY_STATE_RINGING)
Betty Zhoua37acd32017-02-23 20:04:24 -08001066 ad.log.info("Receive ringing event")
Nathan Harold0111e202016-09-27 17:03:00 -07001067 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -08001068 ad.log.info("No Ringing Event")
Nathan Harold0111e202016-09-27 17:03:00 -07001069 finally:
1070 return event_ringing
Ang Li73697b32015-12-03 00:41:53 +00001071
Nathan Harold123c9da2015-12-30 16:33:25 -08001072
Nathan Harold54c7c742016-08-04 19:40:44 -07001073def wait_for_ringing_call(log, ad, incoming_number=None):
1074 """Wait for an incoming call on default voice subscription and
Ang Li73697b32015-12-03 00:41:53 +00001075 accepts the call.
1076
1077 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001078 log: log object.
1079 ad: android device object.
1080 incoming_number: Expected incoming number.
1081 Optional. Default is None
1082
1083 Returns:
1084 True: if incoming call is received and answered successfully.
1085 False: for errors
1086 """
1087 return wait_for_ringing_call_for_subscription(
1088 log, ad, get_incoming_voice_sub_id(ad), incoming_number)
1089
1090
Betty Zhoua37acd32017-02-23 20:04:24 -08001091def wait_for_ringing_call_for_subscription(
1092 log,
1093 ad,
1094 sub_id,
1095 incoming_number=None,
Betty Zhou7f45f552017-03-15 19:12:52 -07001096 caller=None,
Betty Zhoua37acd32017-02-23 20:04:24 -08001097 event_tracking_started=False,
Betty Zhoubcffe442017-07-05 17:27:55 -07001098 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
Betty Zhou17548912018-05-31 16:09:07 -07001099 interval=WAIT_TIME_BETWEEN_STATE_CHECK):
Nathan Harold54c7c742016-08-04 19:40:44 -07001100 """Wait for an incoming call on specified subscription.
1101
1102 Args:
1103 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001104 ad: android device object.
1105 sub_id: subscription ID
Betty Zhoua37acd32017-02-23 20:04:24 -08001106 incoming_number: Expected incoming number. Default is None
1107 event_tracking_started: True if event tracking already state outside
1108 timeout: time to wait for ring
Betty Zhou17548912018-05-31 16:09:07 -07001109 interval: checking interval
Ang Li73697b32015-12-03 00:41:53 +00001110
1111 Returns:
1112 True: if incoming call is received and answered successfully.
1113 False: for errors
1114 """
Betty Zhou17548912018-05-31 16:09:07 -07001115 if not event_tracking_started:
1116 ad.ed.clear_events(EventCallStateChanged)
1117 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Betty Zhou03bd3f92018-06-06 17:37:56 -07001118 ring_event_received = False
Betty Zhou17548912018-05-31 16:09:07 -07001119 end_time = time.time() + timeout
1120 try:
1121 while time.time() < end_time:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001122 if not ring_event_received:
Betty Zhou17548912018-05-31 16:09:07 -07001123 event_ringing = _wait_for_ringing_event(log, ad, interval)
1124 if event_ringing:
Betty Zhou17548912018-05-31 16:09:07 -07001125 if incoming_number and not check_phone_number_match(
1126 event_ringing['data']
1127 [CallStateContainer.INCOMING_NUMBER], incoming_number):
1128 ad.log.error(
1129 "Incoming Number not match. Expected number:%s, actual number:%s",
1130 incoming_number, event_ringing['data'][
1131 CallStateContainer.INCOMING_NUMBER])
1132 return False
Betty Zhou03bd3f92018-06-06 17:37:56 -07001133 ring_event_received = True
1134 telephony_state = ad.droid.telephonyGetCallStateForSubscription(
1135 sub_id)
1136 telecom_state = ad.droid.telecomGetCallState()
1137 if telephony_state == TELEPHONY_STATE_RINGING and (
1138 telecom_state == TELEPHONY_STATE_RINGING):
1139 ad.log.info("callee is in telephony and telecom RINGING state")
Betty Zhou17548912018-05-31 16:09:07 -07001140 if caller:
1141 if caller.droid.telecomIsInCall():
1142 caller.log.info("Caller telecom is in call state")
1143 return True
1144 else:
1145 caller.log.info("Caller telecom is NOT in call state")
1146 else:
1147 return True
1148 else:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001149 ad.log.info(
1150 "telephony in %s, telecom in %s, expecting RINGING state",
1151 telephony_state, telecom_state)
Betty Zhou17548912018-05-31 16:09:07 -07001152 time.sleep(interval)
1153 finally:
Betty Zhou9a0840d2018-05-24 18:01:00 -07001154 if not event_tracking_started:
1155 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1156 sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -08001157
1158
Betty Zhou03bd3f92018-06-06 17:37:56 -07001159def wait_for_call_offhook_for_subscription(
1160 log,
1161 ad,
1162 sub_id,
1163 event_tracking_started=False,
1164 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
1165 interval=WAIT_TIME_BETWEEN_STATE_CHECK):
1166 """Wait for an incoming call on specified subscription.
1167
1168 Args:
1169 log: log object.
1170 ad: android device object.
1171 sub_id: subscription ID
1172 timeout: time to wait for ring
1173 interval: checking interval
1174
1175 Returns:
1176 True: if incoming call is received and answered successfully.
1177 False: for errors
1178 """
1179 if not event_tracking_started:
1180 ad.ed.clear_events(EventCallStateChanged)
1181 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
1182 offhook_event_received = False
1183 end_time = time.time() + timeout
1184 try:
1185 while time.time() < end_time:
1186 if not offhook_event_received:
1187 if wait_for_call_offhook_event(log, ad, sub_id, True,
1188 interval):
1189 offhook_event_received = True
1190 telephony_state = ad.droid.telephonyGetCallStateForSubscription(
1191 sub_id)
1192 telecom_state = ad.droid.telecomGetCallState()
1193 if telephony_state == TELEPHONY_STATE_OFFHOOK and (
1194 telecom_state == TELEPHONY_STATE_OFFHOOK):
1195 ad.log.info("telephony and telecom are in OFFHOOK state")
1196 return True
1197 else:
1198 ad.log.info(
1199 "telephony in %s, telecom in %s, expecting OFFHOOK state",
1200 telephony_state, telecom_state)
1201 if offhook_event_received:
1202 time.sleep(interval)
1203 finally:
1204 if not event_tracking_started:
1205 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1206 sub_id)
1207
1208
Betty Zhoua37acd32017-02-23 20:04:24 -08001209def wait_for_call_offhook_event(
1210 log,
1211 ad,
Betty Zhoubb192482017-03-01 14:38:56 -08001212 sub_id,
Betty Zhoua37acd32017-02-23 20:04:24 -08001213 event_tracking_started=False,
1214 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
1215 """Wait for an incoming call on specified subscription.
1216
1217 Args:
1218 log: log object.
1219 ad: android device object.
1220 event_tracking_started: True if event tracking already state outside
1221 timeout: time to wait for event
1222
1223 Returns:
1224 True: if call offhook event is received.
1225 False: if call offhook event is not received.
1226 """
1227 if not event_tracking_started:
Betty Zhou287f9df2018-01-23 10:57:55 -08001228 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoua37acd32017-02-23 20:04:24 -08001229 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
1230 try:
1231 ad.ed.wait_for_event(
1232 EventCallStateChanged,
1233 is_event_match,
1234 timeout=timeout,
1235 field=CallStateContainer.CALL_STATE,
1236 value=TELEPHONY_STATE_OFFHOOK)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07001237 ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK)
Betty Zhoua37acd32017-02-23 20:04:24 -08001238 except Empty:
Betty Zhoubb192482017-03-01 14:38:56 -08001239 ad.log.info("No event for call state change to OFFHOOK")
Betty Zhoua37acd32017-02-23 20:04:24 -08001240 return False
1241 finally:
1242 if not event_tracking_started:
1243 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1244 sub_id)
Nathan Harold54c7c742016-08-04 19:40:44 -07001245 return True
1246
1247
1248def wait_and_answer_call_for_subscription(
1249 log,
1250 ad,
1251 sub_id,
1252 incoming_number=None,
Betty Zhoua37acd32017-02-23 20:04:24 -08001253 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001254 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
Betty Zhou48557582018-05-14 13:19:23 -07001255 caller=None,
1256 video_state=None):
Nathan Harold54c7c742016-08-04 19:40:44 -07001257 """Wait for an incoming call on specified subscription and
1258 accepts the call.
1259
1260 Args:
1261 log: log object.
1262 ad: android device object.
1263 sub_id: subscription ID
1264 incoming_number: Expected incoming number.
1265 Optional. Default is None
1266 incall_ui_display: after answer the call, bring in-call UI to foreground or
1267 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1268 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1269 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1270 else, do nothing.
1271
1272 Returns:
1273 True: if incoming call is received and answered successfully.
1274 False: for errors
1275 """
Betty Zhou287f9df2018-01-23 10:57:55 -08001276 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001277 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001278 try:
Betty Zhou17548912018-05-31 16:09:07 -07001279 if not wait_for_ringing_call_for_subscription(
Betty Zhouf25ce442017-03-03 14:28:36 -08001280 log,
1281 ad,
Betty Zhouf25ce442017-03-03 14:28:36 -08001282 sub_id,
Betty Zhou17548912018-05-31 16:09:07 -07001283 incoming_number=incoming_number,
Betty Zhou7f45f552017-03-15 19:12:52 -07001284 caller=caller,
Betty Zhoue5c0b232017-03-14 18:55:40 -07001285 event_tracking_started=True,
Betty Zhou17548912018-05-31 16:09:07 -07001286 timeout=timeout):
1287 ad.log.info("Incoming call ringing check failed.")
Betty Zhoua37acd32017-02-23 20:04:24 -08001288 return False
Betty Zhoubb192482017-03-01 14:38:56 -08001289 ad.log.info("Accept the ring call")
Betty Zhou48557582018-05-14 13:19:23 -07001290 ad.droid.telecomAcceptRingingCall(video_state)
Betty Zhouf25ce442017-03-03 14:28:36 -08001291
Betty Zhou03bd3f92018-06-06 17:37:56 -07001292 if wait_for_call_offhook_for_subscription(
1293 log, ad, sub_id, event_tracking_started=True):
Betty Zhoua37acd32017-02-23 20:04:24 -08001294 return True
1295 else:
1296 ad.log.error("Could not answer the call.")
Ang Li73697b32015-12-03 00:41:53 +00001297 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07001298 except Exception as e:
1299 log.error(e)
1300 return False
Ang Li73697b32015-12-03 00:41:53 +00001301 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001302 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -08001303 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
1304 ad.droid.telecomShowInCallScreen()
1305 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
1306 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +00001307
Nathan Harold123c9da2015-12-30 16:33:25 -08001308
1309def wait_and_reject_call(log,
1310 ad,
1311 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001312 delay_reject=WAIT_TIME_REJECT_CALL,
1313 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001314 """Wait for an incoming call on default voice subscription and
1315 reject the call.
1316
1317 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001318 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001319 ad: android device object.
1320 incoming_number: Expected incoming number.
1321 Optional. Default is None
1322 delay_reject: time to wait before rejecting the call
1323 Optional. Default is WAIT_TIME_REJECT_CALL
1324
1325 Returns:
1326 True: if incoming call is received and reject successfully.
1327 False: for errors
1328 """
Betty Zhouee311052017-12-19 13:09:56 -08001329 return wait_and_reject_call_for_subscription(log, ad,
1330 get_incoming_voice_sub_id(ad),
1331 incoming_number, delay_reject,
1332 reject)
Ang Li73697b32015-12-03 00:41:53 +00001333
Nathan Harold123c9da2015-12-30 16:33:25 -08001334
1335def wait_and_reject_call_for_subscription(log,
1336 ad,
1337 sub_id,
1338 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001339 delay_reject=WAIT_TIME_REJECT_CALL,
1340 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001341 """Wait for an incoming call on specific subscription and
1342 reject the call.
1343
1344 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001345 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001346 ad: android device object.
1347 sub_id: subscription ID
1348 incoming_number: Expected incoming number.
1349 Optional. Default is None
1350 delay_reject: time to wait before rejecting the call
1351 Optional. Default is WAIT_TIME_REJECT_CALL
1352
1353 Returns:
1354 True: if incoming call is received and reject successfully.
1355 False: for errors
1356 """
Ang Li73697b32015-12-03 00:41:53 +00001357
Nathan Harold54c7c742016-08-04 19:40:44 -07001358 if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
1359 incoming_number):
Betty Zhou17548912018-05-31 16:09:07 -07001360 ad.log.error(
1361 "Could not reject a call: incoming call in ringing check failed.")
Nathan Harold54c7c742016-08-04 19:40:44 -07001362 return False
Ang Li73697b32015-12-03 00:41:53 +00001363
Betty Zhou287f9df2018-01-23 10:57:55 -08001364 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001365 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Yang Liu598b93d2016-03-22 17:07:59 -07001366 if reject is True:
1367 # Delay between ringing and reject.
1368 time.sleep(delay_reject)
Yang Liu598b93d2016-03-22 17:07:59 -07001369 is_find = False
1370 # Loop the call list and find the matched one to disconnect.
1371 for call in ad.droid.telecomCallGetCallIds():
1372 if check_phone_number_match(
1373 get_number_from_tel_uri(get_call_uri(ad, call)),
1374 incoming_number):
1375 ad.droid.telecomCallDisconnect(call)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001376 ad.log.info("Callee reject the call")
Yang Liu598b93d2016-03-22 17:07:59 -07001377 is_find = True
1378 if is_find is False:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001379 ad.log.error("Callee did not find matching call to reject.")
Yang Liu598b93d2016-03-22 17:07:59 -07001380 return False
1381 else:
1382 # don't reject on callee. Just ignore the incoming call.
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001383 ad.log.info("Callee received incoming call. Ignore it.")
Ang Li73697b32015-12-03 00:41:53 +00001384 try:
Yang Liu598b93d2016-03-22 17:07:59 -07001385 ad.ed.wait_for_event(
1386 EventCallStateChanged,
1387 is_event_match_for_list,
1388 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1389 field=CallStateContainer.CALL_STATE,
1390 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
Ang Li73697b32015-12-03 00:41:53 +00001391 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001392 ad.log.error("No onCallStateChangedIdle event received.")
Ang Li73697b32015-12-03 00:41:53 +00001393 return False
1394 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001395 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001396 return True
1397
Nathan Harold123c9da2015-12-30 16:33:25 -08001398
Jaineel720448a2019-05-22 18:21:54 -07001399def hangup_call(log, ad, is_emergency=False):
Ang Li73697b32015-12-03 00:41:53 +00001400 """Hang up ongoing active call.
Nathan Harold54c7c742016-08-04 19:40:44 -07001401
1402 Args:
1403 log: log object.
1404 ad: android device object.
1405
1406 Returns:
Nathan Haroldd2d30092016-10-12 12:45:55 -07001407 True: if all calls are cleared
Nathan Harold54c7c742016-08-04 19:40:44 -07001408 False: for errors
Ang Li73697b32015-12-03 00:41:53 +00001409 """
Nathan Haroldd2d30092016-10-12 12:45:55 -07001410 # short circuit in case no calls are active
1411 if not ad.droid.telecomIsInCall():
Markus Liu2b5a59e2021-02-02 15:45:58 +08001412 ad.log.warning("No active call exists.")
Nathan Haroldd2d30092016-10-12 12:45:55 -07001413 return True
Betty Zhou287f9df2018-01-23 10:57:55 -08001414 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001415 ad.droid.telephonyStartTrackingCallState()
Betty Zhouf27f5482017-07-24 18:56:17 -07001416 ad.log.info("Hangup call.")
Jaineel720448a2019-05-22 18:21:54 -07001417 if is_emergency:
1418 for call in ad.droid.telecomCallGetCallIds():
1419 ad.droid.telecomCallDisconnect(call)
1420 else:
1421 ad.droid.telecomEndCall()
Ang Li73697b32015-12-03 00:41:53 +00001422
1423 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07001424 ad.ed.wait_for_event(
1425 EventCallStateChanged,
1426 is_event_match,
1427 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1428 field=CallStateContainer.CALL_STATE,
1429 value=TELEPHONY_STATE_IDLE)
Ang Li73697b32015-12-03 00:41:53 +00001430 except Empty:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001431 ad.log.warning("Call state IDLE event is not received after hang up.")
Ang Li73697b32015-12-03 00:41:53 +00001432 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001433 ad.droid.telephonyStopTrackingCallStateChange()
Betty Zhoufe726dc2018-04-25 19:31:33 -07001434 if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1):
1435 ad.log.error("Telecom is in call, hangup call failed.")
1436 return False
1437 return True
Ang Li73697b32015-12-03 00:41:53 +00001438
Nathan Harold123c9da2015-12-30 16:33:25 -08001439
Jaineel15879c92019-06-03 17:08:13 -07001440def wait_for_cbrs_data_active_sub_change_event(
1441 ad,
1442 event_tracking_started=False,
1443 timeout=120):
1444 """Wait for an data change event on specified subscription.
1445
1446 Args:
1447 ad: android device object.
1448 event_tracking_started: True if event tracking already state outside
1449 timeout: time to wait for event
1450
1451 Returns:
1452 True: if data change event is received.
1453 False: if data change event is not received.
1454 """
1455 if not event_tracking_started:
1456 ad.ed.clear_events(EventActiveDataSubIdChanged)
1457 ad.droid.telephonyStartTrackingActiveDataChange()
1458 try:
1459 ad.ed.wait_for_event(
1460 EventActiveDataSubIdChanged,
1461 is_event_match,
1462 timeout=timeout)
1463 ad.log.info("Got event activedatasubidchanged")
1464 except Empty:
1465 ad.log.info("No event for data subid change")
1466 return False
1467 finally:
1468 if not event_tracking_started:
1469 ad.droid.telephonyStopTrackingActiveDataChange()
1470 return True
1471
1472
1473def is_current_data_on_cbrs(ad, cbrs_subid):
1474 """Verifies if current data sub is on CBRS
1475
1476 Args:
1477 ad: android device object.
1478 cbrs_subid: sub_id against which we need to check
1479
1480 Returns:
1481 True: if data is on cbrs
1482 False: if data is not on cbrs
1483 """
1484 if cbrs_subid is None:
1485 return False
Jaineel07447192019-07-01 17:06:05 -07001486 current_data = ad.droid.subscriptionGetActiveDataSubscriptionId()
Jaineel15879c92019-06-03 17:08:13 -07001487 ad.log.info("Current Data subid %s cbrs_subid %s", current_data, cbrs_subid)
Jaineel5dfd44a2019-06-10 10:48:23 -07001488 if current_data == cbrs_subid:
Jaineel15879c92019-06-03 17:08:13 -07001489 return True
1490 else:
1491 return False
1492
1493
Jaineel305b2ac2020-04-20 12:06:44 -07001494def get_current_override_network_type(ad, timeout=30):
1495 """Returns current override network type
1496
1497 Args:
1498 ad: android device object.
1499 timeout: max time to wait for event
1500
1501 Returns:
1502 value: current override type
1503 -1: if no event received
1504 """
1505 override_value_list = [OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA,
1506 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NONE,
1507 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE,
1508 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_CA,
1509 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO]
1510 ad.ed.clear_events(EventDisplayInfoChanged)
1511 ad.droid.telephonyStartTrackingDisplayInfoChange()
1512 try:
1513 event = ad.ed.wait_for_event(
1514 EventDisplayInfoChanged,
1515 is_event_match_for_list,
1516 timeout=timeout,
1517 field=DisplayInfoContainer.OVERRIDE,
1518 value_list=override_value_list)
1519 override_type = event['data']['override']
1520 ad.log.info("Current Override Type is %s", override_type)
1521 return override_type
1522 except Empty:
1523 ad.log.info("No event for display info change")
1524 return -1
1525 finally:
1526 ad.droid.telephonyStopTrackingDisplayInfoChange()
1527 return -1
1528
1529
1530def is_current_network_5g_nsa(ad, timeout=30):
1531 """Verifies 5G NSA override network type
1532
1533 Args:
1534 ad: android device object.
1535 timeout: max time to wait for event
1536
1537 Returns:
1538 True: if data is on 5g NSA
1539 False: if data is not on 5g NSA
1540 """
1541 ad.ed.clear_events(EventDisplayInfoChanged)
1542 ad.droid.telephonyStartTrackingDisplayInfoChange()
1543 try:
1544 event = ad.ed.wait_for_event(
1545 EventDisplayInfoChanged,
1546 is_event_match,
1547 timeout=timeout,
1548 field=DisplayInfoContainer.OVERRIDE,
1549 value=OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA)
1550 ad.log.info("Got expected event %s", event)
1551 return True
1552 except Empty:
1553 ad.log.info("No event for display info change")
1554 return False
1555 finally:
1556 ad.droid.telephonyStopTrackingDisplayInfoChange()
1557 return None
1558
Markus Liu8a65ea02021-03-18 16:33:41 +08001559def is_current_network_5g_nsa_for_subscription(ad, timeout=30, sub_id=None):
1560 return change_voice_subid_temporarily(ad, sub_id, is_current_network_5g_nsa, params=[ad, timeout])
Jaineel305b2ac2020-04-20 12:06:44 -07001561
Ang Li73697b32015-12-03 00:41:53 +00001562def disconnect_call_by_id(log, ad, call_id):
1563 """Disconnect call by call id.
1564 """
1565 ad.droid.telecomCallDisconnect(call_id)
1566 return True
1567
Nathan Harold54c7c742016-08-04 19:40:44 -07001568
Yang Liu3197de22016-04-11 13:59:41 -07001569def _phone_number_remove_prefix(number):
1570 """Remove the country code and other prefix from the input phone number.
1571 Currently only handle phone number with the following formats:
1572 (US phone number format)
1573 +1abcxxxyyyy
1574 1abcxxxyyyy
1575 abcxxxyyyy
1576 abc xxx yyyy
1577 abc.xxx.yyyy
1578 abc-xxx-yyyy
1579 (EEUK phone number format)
1580 +44abcxxxyyyy
1581 0abcxxxyyyy
1582
1583 Args:
1584 number: input phone number
1585
1586 Returns:
1587 Phone number without country code or prefix
1588 """
Yang Liu8fcffd52016-05-31 18:38:35 -07001589 if number is None:
1590 return None, None
Betty Zhou9e54fc22017-01-19 12:15:53 -08001591 for country_code in COUNTRY_CODE_LIST:
Yang Liu3197de22016-04-11 13:59:41 -07001592 if number.startswith(country_code):
1593 return number[len(country_code):], country_code
1594 if number[0] == "1" or number[0] == "0":
1595 return number[1:], None
Yang Liu8fcffd52016-05-31 18:38:35 -07001596 return number, None
Yang Liu3197de22016-04-11 13:59:41 -07001597
Nathan Harold123c9da2015-12-30 16:33:25 -08001598
Ang Li73697b32015-12-03 00:41:53 +00001599def check_phone_number_match(number1, number2):
1600 """Check whether two input phone numbers match or not.
1601
1602 Compare the two input phone numbers.
1603 If they match, return True; otherwise, return False.
1604 Currently only handle phone number with the following formats:
1605 (US phone number format)
1606 +1abcxxxyyyy
1607 1abcxxxyyyy
1608 abcxxxyyyy
1609 abc xxx yyyy
1610 abc.xxx.yyyy
1611 abc-xxx-yyyy
Yang Liu3197de22016-04-11 13:59:41 -07001612 (EEUK phone number format)
1613 +44abcxxxyyyy
1614 0abcxxxyyyy
1615
1616 There are some scenarios we can not verify, one example is:
1617 number1 = +15555555555, number2 = 5555555555
1618 (number2 have no country code)
Ang Li73697b32015-12-03 00:41:53 +00001619
1620 Args:
1621 number1: 1st phone number to be compared.
1622 number2: 2nd phone number to be compared.
1623
1624 Returns:
1625 True if two phone numbers match. Otherwise False.
1626 """
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001627 number1 = phone_number_formatter(number1)
1628 number2 = phone_number_formatter(number2)
Betty Zhou9e54fc22017-01-19 12:15:53 -08001629 # Handle extra country code attachment when matching phone number
Betty Zhoue32dd3b2017-11-28 19:05:55 -08001630 if number1[-7:] in number2 or number2[-7:] in number1:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001631 return True
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001632 else:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001633 logging.info("phone number1 %s and number2 %s does not match" %
1634 (number1, number2))
1635 return False
Ang Li73697b32015-12-03 00:41:53 +00001636
1637
Betty Zhoubb192482017-03-01 14:38:56 -08001638def initiate_call(log,
1639 ad,
1640 callee_number,
1641 emergency=False,
1642 timeout=MAX_WAIT_TIME_CALL_INITIATION,
Betty Zhou1ffbc832018-05-08 19:02:56 -07001643 checking_interval=5,
Betty Zhou48557582018-05-14 13:19:23 -07001644 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Pratik Sheth68e4eba2021-03-23 17:10:13 -07001645 video=False,
1646 voice_type_init=None,
Pratik Sheth232f7952021-04-08 12:17:30 -07001647 call_stats_check=False,
Pratik Shethffd15372021-04-29 15:03:47 -07001648 result_info=result_dict,
1649 nsa_5g_for_stress=False):
Ang Li73697b32015-12-03 00:41:53 +00001650 """Make phone call from caller to callee.
1651
1652 Args:
1653 ad_caller: Caller android device object.
1654 callee_number: Callee phone number.
1655 emergency : specify the call is emergency.
1656 Optional. Default value is False.
Betty Zhou1ffbc832018-05-08 19:02:56 -07001657 incall_ui_display: show the dialer UI foreground or backgroud
Betty Zhou48557582018-05-14 13:19:23 -07001658 video: whether to initiate as video call
Ang Li73697b32015-12-03 00:41:53 +00001659
1660 Returns:
1661 result: if phone call is placed successfully.
1662 """
Betty Zhou287f9df2018-01-23 10:57:55 -08001663 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoubb192482017-03-01 14:38:56 -08001664 sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhou16e8e662018-05-08 18:26:18 -07001665 begin_time = get_device_epoch_time(ad)
Betty Zhoubb192482017-03-01 14:38:56 -08001666 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001667 try:
1668 # Make a Call
Betty Zhoubb192482017-03-01 14:38:56 -08001669 ad.log.info("Make a phone call to %s", callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001670 if emergency:
Betty Zhoubb192482017-03-01 14:38:56 -08001671 ad.droid.telecomCallEmergencyNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001672 else:
Betty Zhou48557582018-05-14 13:19:23 -07001673 ad.droid.telecomCallNumber(callee_number, video)
Ang Li73697b32015-12-03 00:41:53 +00001674
Betty Zhou03bd3f92018-06-06 17:37:56 -07001675 # Verify OFFHOOK state
1676 if not wait_for_call_offhook_for_subscription(
1677 log, ad, sub_id, event_tracking_started=True):
1678 ad.log.info("sub_id %s not in call offhook state", sub_id)
1679 last_call_drop_reason(ad, begin_time=begin_time)
1680 return False
1681 else:
1682 return True
Pratik Sheth68e4eba2021-03-23 17:10:13 -07001683
1684 if call_stats_check:
1685 voice_type_in_call = ad.droid.telephonyGetCurrentVoiceNetworkType()
1686 phone_call_type = check_call_status(ad,
1687 voice_type_init,
1688 voice_type_in_call)
Pratik Sheth232f7952021-04-08 12:17:30 -07001689 result_info["Call Stats"] = phone_call_type
Pratik Sheth68e4eba2021-03-23 17:10:13 -07001690 ad.log.debug("Voice Call Type: %s", phone_call_type)
1691
Ang Li73697b32015-12-03 00:41:53 +00001692 finally:
Sarah Boechat2be72ce2019-09-27 12:21:27 -07001693 if hasattr(ad, "sdm_log") and getattr(ad, "sdm_log"):
1694 ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
1695 ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
Betty Zhoubb192482017-03-01 14:38:56 -08001696 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Pratik Shethffd15372021-04-29 15:03:47 -07001697
1698 if nsa_5g_for_stress:
1699 if not is_current_network_5g_nsa(ad):
1700 ad.log.error("Phone is not attached on 5G NSA")
1701
Betty Zhou1ffbc832018-05-08 19:02:56 -07001702 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
1703 ad.droid.telecomShowInCallScreen()
1704 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
1705 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +00001706
Nathan Harold123c9da2015-12-30 16:33:25 -08001707
Betty Zhou8da03782017-07-28 18:02:24 -07001708def dial_phone_number(ad, callee_number):
1709 for number in str(callee_number):
1710 if number == "#":
1711 ad.send_keycode("POUND")
1712 elif number == "*":
1713 ad.send_keycode("STAR")
1714 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]:
1715 ad.send_keycode("%s" % number)
1716
1717
1718def get_call_state_by_adb(ad):
Markus Liuf3410172019-08-06 19:40:32 +08001719 slot_index_of_default_voice_subid = get_slot_index_from_subid(ad.log, ad,
1720 get_incoming_voice_sub_id(ad))
1721 output = ad.adb.shell("dumpsys telephony.registry | grep mCallState")
1722 if "mCallState" in output:
1723 call_state_list = re.findall("mCallState=(\d)", output)
1724 if call_state_list:
1725 return call_state_list[slot_index_of_default_voice_subid]
Betty Zhou8da03782017-07-28 18:02:24 -07001726
1727
1728def check_call_state_connected_by_adb(ad):
1729 return "2" in get_call_state_by_adb(ad)
1730
1731
1732def check_call_state_idle_by_adb(ad):
1733 return "0" in get_call_state_by_adb(ad)
1734
1735
1736def check_call_state_ring_by_adb(ad):
1737 return "1" in get_call_state_by_adb(ad)
1738
1739
1740def get_incoming_call_number_by_adb(ad):
1741 output = ad.adb.shell(
1742 "dumpsys telephony.registry | grep mCallIncomingNumber")
1743 return re.search(r"mCallIncomingNumber=(.*)", output).group(1)
1744
1745
1746def emergency_dialer_call_by_keyevent(ad, callee_number):
1747 for i in range(3):
1748 if "EmergencyDialer" in ad.get_my_current_focus_window():
1749 ad.log.info("EmergencyDialer is the current focus window")
1750 break
1751 elif i <= 2:
1752 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
1753 time.sleep(1)
1754 else:
1755 ad.log.error("Unable to bring up EmergencyDialer")
1756 return False
1757 ad.log.info("Make a phone call to %s", callee_number)
1758 dial_phone_number(ad, callee_number)
1759 ad.send_keycode("CALL")
1760
1761
1762def initiate_emergency_dialer_call_by_adb(
1763 log,
1764 ad,
1765 callee_number,
1766 timeout=MAX_WAIT_TIME_CALL_INITIATION,
1767 checking_interval=5):
1768 """Make emergency call by EmergencyDialer.
1769
1770 Args:
1771 ad: Caller android device object.
1772 callee_number: Callee phone number.
1773 emergency : specify the call is emergency.
1774 Optional. Default value is False.
1775
1776 Returns:
1777 result: if phone call is placed successfully.
1778 """
1779 try:
1780 # Make a Call
1781 ad.wakeup_screen()
Betty Zhou3c2e2542018-02-21 12:23:04 -08001782 ad.send_keycode("MENU")
Betty Zhou8da03782017-07-28 18:02:24 -07001783 ad.log.info("Call %s", callee_number)
Betty Zhou4617cba2017-08-10 11:58:39 -07001784 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
Betty Zhou8da03782017-07-28 18:02:24 -07001785 ad.adb.shell(
1786 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" %
1787 callee_number)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001788 if not timeout: return True
Betty Zhou8da03782017-07-28 18:02:24 -07001789 ad.log.info("Check call state")
1790 # Verify Call State
1791 elapsed_time = 0
1792 while elapsed_time < timeout:
1793 time.sleep(checking_interval)
1794 elapsed_time += checking_interval
1795 if check_call_state_connected_by_adb(ad):
1796 ad.log.info("Call to %s is connected", callee_number)
1797 return True
Betty Zhou13e7adf2017-09-06 14:01:10 -07001798 if check_call_state_idle_by_adb(ad):
1799 ad.log.info("Call to %s failed", callee_number)
1800 return False
Betty Zhou8da03782017-07-28 18:02:24 -07001801 ad.log.info("Make call to %s failed", callee_number)
1802 return False
1803 except Exception as e:
1804 ad.log.error("initiate emergency call failed with error %s", e)
1805
1806
Betty Zhoucbda4122018-01-16 19:15:42 -08001807def hangup_call_by_adb(ad):
Betty Zhou8da03782017-07-28 18:02:24 -07001808 """Make emergency call by EmergencyDialer.
1809
1810 Args:
1811 ad: Caller android device object.
1812 callee_number: Callee phone number.
1813 """
1814 ad.log.info("End call by adb")
1815 ad.send_keycode("ENDCALL")
1816
1817
Betty Zhouf7da39e2018-04-16 16:28:58 -07001818def dumpsys_all_call_info(ad):
Betty Zhoudd781f82017-08-08 14:46:23 -07001819 """ Get call information by dumpsys telecom. """
Betty Zhou8da03782017-07-28 18:02:24 -07001820 output = ad.adb.shell("dumpsys telecom")
1821 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL)
1822 calls_info = []
1823 for call in calls:
1824 call_info = {}
Betty Zhoudd781f82017-08-08 14:46:23 -07001825 for attr in ("startTime", "endTime", "direction", "isInterrupted",
Betty Zhou8da03782017-07-28 18:02:24 -07001826 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001827 "connectionService", "isVideoCall", "callProperties"):
Betty Zhou8da03782017-07-28 18:02:24 -07001828 match = re.search(r"%s: (.*)" % attr, call)
1829 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001830 if attr in ("startTime", "endTime"):
1831 call_info[attr] = epoch_to_log_line_timestamp(
1832 int(match.group(1)))
1833 else:
1834 call_info[attr] = match.group(1)
Betty Zhou8da03782017-07-28 18:02:24 -07001835 call_info["inCallServices"] = re.findall(r"name: (.*)", call)
1836 calls_info.append(call_info)
1837 ad.log.debug("calls_info = %s", calls_info)
1838 return calls_info
1839
1840
Betty Zhouf7da39e2018-04-16 16:28:58 -07001841def dumpsys_last_call_info(ad):
1842 """ Get call information by dumpsys telecom. """
1843 num = dumpsys_last_call_number(ad)
1844 output = ad.adb.shell("dumpsys telecom")
1845 result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL)
Betty Zhou739d6b72018-04-18 10:38:53 -07001846 call_info = {"TC": num}
Betty Zhouf7da39e2018-04-16 16:28:58 -07001847 if result:
1848 result = result.group(1)
1849 for attr in ("startTime", "endTime", "direction", "isInterrupted",
1850 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001851 "isVideoCall", "callProperties"):
Betty Zhouf7da39e2018-04-16 16:28:58 -07001852 match = re.search(r"%s: (.*)" % attr, result)
1853 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001854 if attr in ("startTime", "endTime"):
1855 call_info[attr] = epoch_to_log_line_timestamp(
1856 int(match.group(1)))
1857 else:
1858 call_info[attr] = match.group(1)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001859 ad.log.debug("call_info = %s", call_info)
1860 return call_info
1861
1862
1863def dumpsys_last_call_number(ad):
1864 output = ad.adb.shell("dumpsys telecom")
1865 call_nums = re.findall("Call TC@(\d+):", output)
1866 if not call_nums:
1867 return 0
1868 else:
1869 return int(call_nums[-1])
1870
1871
Betty Zhoufe726dc2018-04-25 19:31:33 -07001872def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5):
1873 for i in range(retries):
1874 if dumpsys_last_call_number(ad) > last_tc_number:
1875 call_info = dumpsys_last_call_info(ad)
1876 ad.log.info("New call info = %s", sorted(call_info.items()))
1877 return call_info
1878 else:
1879 time.sleep(interval)
1880 ad.log.error("New call is not in sysdump telecom")
1881 return {}
1882
1883
Betty Zhou8aafcc12018-05-01 20:54:15 -07001884def dumpsys_carrier_config(ad):
Markus Liuf3410172019-08-06 19:40:32 +08001885 output = ad.adb.shell("dumpsys carrier_config").split("\n")
1886 output_phone_id_0 = []
1887 output_phone_id_1 = []
1888 current_output = []
1889 for line in output:
1890 if "Phone Id = 0" in line:
1891 current_output = output_phone_id_0
1892 elif "Phone Id = 1" in line:
1893 current_output = output_phone_id_1
1894 current_output.append(line.strip())
1895
Betty Zhou8aafcc12018-05-01 20:54:15 -07001896 configs = {}
Jaineel64b4ce92019-08-20 14:17:43 -07001897 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
1898 phone_count = 1
1899 if "," in ad.adb.getprop("gsm.network.type"):
1900 phone_count = 2
1901 else:
1902 phone_count = ad.droid.telephonyGetPhoneCount()
1903
Markus Liuf3410172019-08-06 19:40:32 +08001904 slot_0_subid = get_subid_from_slot_index(ad.log, ad, 0)
1905 if slot_0_subid != INVALID_SUB_ID:
1906 configs[slot_0_subid] = {}
1907
1908 if phone_count == 2:
1909 slot_1_subid = get_subid_from_slot_index(ad.log, ad, 1)
1910 if slot_1_subid != INVALID_SUB_ID:
1911 configs[slot_1_subid] = {}
1912
Betty Zhou8aafcc12018-05-01 20:54:15 -07001913 attrs = [attr for attr in dir(CarrierConfigs) if not attr.startswith("__")]
1914 for attr in attrs:
1915 attr_string = getattr(CarrierConfigs, attr)
Markus Liuf3410172019-08-06 19:40:32 +08001916 values = re.findall(
1917 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_0))
1918
1919 if slot_0_subid != INVALID_SUB_ID:
1920 if values:
1921 value = values[-1]
1922 if value == "true":
1923 configs[slot_0_subid][attr_string] = True
1924 elif value == "false":
1925 configs[slot_0_subid][attr_string] = False
1926 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT:
1927 if value == "0":
1928 configs[slot_0_subid][attr_string] = WFC_MODE_WIFI_ONLY
1929 elif value == "1":
1930 configs[slot_0_subid][attr_string] = \
1931 WFC_MODE_CELLULAR_PREFERRED
1932 elif value == "2":
1933 configs[slot_0_subid][attr_string] = \
1934 WFC_MODE_WIFI_PREFERRED
1935 else:
1936 try:
1937 configs[slot_0_subid][attr_string] = int(value)
1938 except Exception:
1939 configs[slot_0_subid][attr_string] = value
Betty Zhou8aafcc12018-05-01 20:54:15 -07001940 else:
Markus Liuf3410172019-08-06 19:40:32 +08001941 configs[slot_0_subid][attr_string] = None
1942
1943 if phone_count == 2:
1944 if slot_1_subid != INVALID_SUB_ID:
1945 values = re.findall(
1946 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_1))
1947 if values:
1948 value = values[-1]
1949 if value == "true":
1950 configs[slot_1_subid][attr_string] = True
1951 elif value == "false":
1952 configs[slot_1_subid][attr_string] = False
1953 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT:
1954 if value == "0":
1955 configs[slot_1_subid][attr_string] = \
1956 WFC_MODE_WIFI_ONLY
1957 elif value == "1":
1958 configs[slot_1_subid][attr_string] = \
1959 WFC_MODE_CELLULAR_PREFERRED
1960 elif value == "2":
1961 configs[slot_1_subid][attr_string] = \
1962 WFC_MODE_WIFI_PREFERRED
1963 else:
1964 try:
1965 configs[slot_1_subid][attr_string] = int(value)
1966 except Exception:
1967 configs[slot_1_subid][attr_string] = value
1968 else:
1969 configs[slot_1_subid][attr_string] = None
Betty Zhou8aafcc12018-05-01 20:54:15 -07001970 return configs
1971
1972
1973def get_phone_capability(ad):
Betty Zhou8aafcc12018-05-01 20:54:15 -07001974 carrier_configs = dumpsys_carrier_config(ad)
Markus Liuf3410172019-08-06 19:40:32 +08001975 for sub_id in carrier_configs:
1976 capabilities = []
1977 if carrier_configs[sub_id][CarrierConfigs.VOLTE_AVAILABLE_BOOL]:
1978 capabilities.append(CAPABILITY_VOLTE)
1979 if carrier_configs[sub_id][CarrierConfigs.WFC_IMS_AVAILABLE_BOOL]:
1980 capabilities.append(CAPABILITY_WFC)
1981 if carrier_configs[sub_id][CarrierConfigs.EDITABLE_WFC_MODE_BOOL]:
1982 capabilities.append(CAPABILITY_WFC_MODE_CHANGE)
1983 if carrier_configs[sub_id][CarrierConfigs.SUPPORT_CONFERENCE_CALL_BOOL]:
1984 capabilities.append(CAPABILITY_CONFERENCE)
1985 if carrier_configs[sub_id][CarrierConfigs.VT_AVAILABLE_BOOL]:
1986 capabilities.append(CAPABILITY_VT)
1987 if carrier_configs[sub_id][CarrierConfigs.VOLTE_PROVISIONED_BOOL]:
1988 capabilities.append(CAPABILITY_VOLTE_PROVISIONING)
1989 if carrier_configs[sub_id][CarrierConfigs.VOLTE_OVERRIDE_WFC_BOOL]:
1990 capabilities.append(CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING)
Markus Liu2cf8d0b2019-10-04 11:13:17 +08001991 if carrier_configs[sub_id][CarrierConfigs.HIDE_ENHANCED_4G_LTE_BOOL]:
1992 capabilities.append(CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL)
1993
Markus Liuf3410172019-08-06 19:40:32 +08001994 ad.log.info("Capabilities of sub ID %s: %s", sub_id, capabilities)
1995 if not getattr(ad, 'telephony', {}):
1996 ad.telephony["subscription"] = {}
1997 ad.telephony["subscription"][sub_id] = {}
1998 setattr(
1999 ad.telephony["subscription"][sub_id],
2000 'capabilities', capabilities)
2001
Betty Zhou4418a332018-05-15 13:11:18 -07002002 else:
Markus Liuf3410172019-08-06 19:40:32 +08002003 ad.telephony["subscription"][sub_id]["capabilities"] = capabilities
2004 if CAPABILITY_WFC not in capabilities:
2005 wfc_modes = []
2006 else:
2007 if carrier_configs[sub_id].get(
2008 CarrierConfigs.EDITABLE_WFC_MODE_BOOL, False):
2009 wfc_modes = [
2010 WFC_MODE_CELLULAR_PREFERRED,
2011 WFC_MODE_WIFI_PREFERRED]
2012 else:
2013 wfc_modes = [
2014 carrier_configs[sub_id].get(
2015 CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT,
2016 WFC_MODE_CELLULAR_PREFERRED)
2017 ]
2018 if carrier_configs[sub_id].get(
2019 CarrierConfigs.WFC_SUPPORTS_WIFI_ONLY_BOOL,
2020 False) and WFC_MODE_WIFI_ONLY not in wfc_modes:
2021 wfc_modes.append(WFC_MODE_WIFI_ONLY)
2022 ad.telephony["subscription"][sub_id]["wfc_modes"] = wfc_modes
2023 if wfc_modes:
2024 ad.log.info("Supported WFC modes for sub ID %s: %s", sub_id,
2025 wfc_modes)
2026
2027
2028def get_capability_for_subscription(ad, capability, subid):
2029 if capability in ad.telephony["subscription"][subid].get(
2030 "capabilities", []):
2031 ad.log.info('Capability "%s" is available for sub ID %s.',
2032 capability, subid)
2033 return True
2034 else:
2035 ad.log.info('Capability "%s" is NOT available for sub ID %s.',
2036 capability, subid)
2037 return False
Betty Zhou8aafcc12018-05-01 20:54:15 -07002038
2039
Yang Liu598b93d2016-03-22 17:07:59 -07002040def call_reject(log, ad_caller, ad_callee, reject=True):
2041 """Caller call Callee, then reject on callee.
2042
2043
2044 """
2045 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
2046 subid_callee = ad_callee.incoming_voice_sub_id
Betty Zhoua37acd32017-02-23 20:04:24 -08002047 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
2048 subid_callee)
Yang Liu598b93d2016-03-22 17:07:59 -07002049 return call_reject_for_subscription(log, ad_caller, ad_callee,
2050 subid_caller, subid_callee, reject)
2051
2052
2053def call_reject_for_subscription(log,
2054 ad_caller,
2055 ad_callee,
2056 subid_caller,
2057 subid_callee,
2058 reject=True):
2059 """
2060 """
2061
Betty Zhou3b2de072018-03-15 16:46:26 -07002062 caller_number = ad_caller.telephony['subscription'][subid_caller][
2063 'phone_num']
2064 callee_number = ad_callee.telephony['subscription'][subid_callee][
2065 'phone_num']
Yang Liu598b93d2016-03-22 17:07:59 -07002066
Betty Zhoua37acd32017-02-23 20:04:24 -08002067 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Betty Zhou48557582018-05-14 13:19:23 -07002068 if not initiate_call(log, ad_caller, callee_number):
2069 ad_caller.log.error("Initiate call failed")
Yang Liu598b93d2016-03-22 17:07:59 -07002070 return False
Betty Zhou48557582018-05-14 13:19:23 -07002071
2072 if not wait_and_reject_call_for_subscription(
2073 log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL,
2074 reject):
2075 ad_callee.log.error("Reject call fail.")
2076 return False
2077 # Check if incoming call is cleared on callee or not.
2078 if ad_callee.droid.telephonyGetCallStateForSubscription(
2079 subid_callee) == TELEPHONY_STATE_RINGING:
2080 ad_callee.log.error("Incoming call is not cleared")
2081 return False
2082 # Hangup on caller
2083 hangup_call(log, ad_caller)
Yang Liu598b93d2016-03-22 17:07:59 -07002084 return True
2085
2086
Nathan Harold123c9da2015-12-30 16:33:25 -08002087def call_reject_leave_message(log,
2088 ad_caller,
2089 ad_callee,
2090 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08002091 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00002092 """On default voice subscription, Call from caller to callee,
2093 reject on callee, caller leave a voice mail.
2094
2095 1. Caller call Callee.
2096 2. Callee reject incoming call.
2097 3. Caller leave a voice mail.
2098 4. Verify callee received the voice mail notification.
2099
2100 Args:
2101 ad_caller: caller android device object.
2102 ad_callee: callee android device object.
2103 verify_caller_func: function to verify caller is in correct state while in-call.
2104 This is optional, default is None.
2105 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08002106 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00002107
2108 Returns:
2109 True: if voice message is received on callee successfully.
2110 False: for errors
2111 """
Yang Liu963c93c2016-04-05 10:52:00 -07002112 subid_caller = get_outgoing_voice_sub_id(ad_caller)
2113 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08002114 return call_reject_leave_message_for_subscription(
2115 log, ad_caller, ad_callee, subid_caller, subid_callee,
2116 verify_caller_func, wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00002117
Nathan Harold123c9da2015-12-30 16:33:25 -08002118
ju8230cef2020-07-29 09:48:02 -07002119def check_reject_needed_for_voice_mail(log, ad_callee):
2120 """Check if the carrier requires reject call to receive voice mail or just keep ringing
2121 Requested in b//155935290
2122 Four Japan carriers do not need to reject
2123 SBM, KDDI, Ntt Docomo, Rakuten
2124 Args:
2125 log: log object
2126 ad_callee: android device object
2127 Returns:
2128 True if callee's carrier is not one of the four Japan carriers
2129 False if callee's carrier is one of the four Japan carriers
2130 """
2131
2132 operators_no_reject = [CARRIER_NTT_DOCOMO,
2133 CARRIER_KDDI,
2134 CARRIER_RAKUTEN,
2135 CARRIER_SBM]
2136 operator_name = get_operator_name(log, ad_callee)
2137
2138 return operator_name not in operators_no_reject
2139
2140
Nathan Harold123c9da2015-12-30 16:33:25 -08002141def call_reject_leave_message_for_subscription(
2142 log,
2143 ad_caller,
2144 ad_callee,
2145 subid_caller,
2146 subid_callee,
2147 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08002148 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00002149 """On specific voice subscription, Call from caller to callee,
2150 reject on callee, caller leave a voice mail.
2151
2152 1. Caller call Callee.
2153 2. Callee reject incoming call.
2154 3. Caller leave a voice mail.
2155 4. Verify callee received the voice mail notification.
2156
2157 Args:
2158 ad_caller: caller android device object.
2159 ad_callee: callee android device object.
2160 subid_caller: caller's subscription id.
2161 subid_callee: callee's subscription id.
2162 verify_caller_func: function to verify caller is in correct state while in-call.
2163 This is optional, default is None.
2164 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08002165 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00002166
2167 Returns:
2168 True: if voice message is received on callee successfully.
2169 False: for errors
2170 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002171
Ang Li73697b32015-12-03 00:41:53 +00002172 # Currently this test utility only works for TMO and ATT and SPT.
2173 # It does not work for VZW (see b/21559800)
2174 # "with VVM TelephonyManager APIs won't work for vm"
2175
Betty Zhou3b2de072018-03-15 16:46:26 -07002176 caller_number = ad_caller.telephony['subscription'][subid_caller][
2177 'phone_num']
2178 callee_number = ad_callee.telephony['subscription'][subid_callee][
2179 'phone_num']
Ang Li73697b32015-12-03 00:41:53 +00002180
Betty Zhoua37acd32017-02-23 20:04:24 -08002181 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Ang Li73697b32015-12-03 00:41:53 +00002182
2183 try:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002184 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
2185 subid_callee)
2186 ad_callee.log.info("voice mail count is %s", voice_mail_count_before)
2187 # -1 means there are unread voice mail, but the count is unknown
2188 # 0 means either this API not working (VZW) or no unread voice mail.
2189 if voice_mail_count_before != 0:
2190 log.warning("--Pending new Voice Mail, please clear on phone.--")
Ang Li73697b32015-12-03 00:41:53 +00002191
2192 if not initiate_call(log, ad_caller, callee_number):
Betty Zhou48557582018-05-14 13:19:23 -07002193 ad_caller.log.error("Initiate call failed.")
2194 return False
ju8230cef2020-07-29 09:48:02 -07002195 if check_reject_needed_for_voice_mail(log, ad_callee):
2196 carrier_specific_delay_reject = 30
2197 else:
2198 carrier_specific_delay_reject = 2
2199 carrier_reject_call = not check_reject_needed_for_voice_mail(log, ad_callee)
Ang Li73697b32015-12-03 00:41:53 +00002200
2201 if not wait_and_reject_call_for_subscription(
ju8230cef2020-07-29 09:48:02 -07002202 log, ad_callee, subid_callee, incoming_number=caller_number, delay_reject=carrier_specific_delay_reject,
2203 reject=carrier_reject_call):
Betty Zhou48557582018-05-14 13:19:23 -07002204 ad_callee.log.error("Reject call fail.")
2205 return False
Ang Li73697b32015-12-03 00:41:53 +00002206
Yang Liuaed3eef2015-12-15 18:40:25 -08002207 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002208 subid_callee)
Ang Li73697b32015-12-03 00:41:53 +00002209
2210 # ensure that all internal states are updated in telecom
2211 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Markus Liu35df2bc2018-11-09 11:14:01 +08002212 ad_callee.ed.clear_events(EventCallStateChanged)
Ang Li73697b32015-12-03 00:41:53 +00002213
2214 if verify_caller_func and not verify_caller_func(log, ad_caller):
Betty Zhou48557582018-05-14 13:19:23 -07002215 ad_caller.log.error("Caller not in correct state!")
2216 return False
Ang Li73697b32015-12-03 00:41:53 +00002217
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002218 # TODO: b/26293512 Need to play some sound to leave message.
2219 # Otherwise carrier voice mail server may drop this voice mail.
Ang Li73697b32015-12-03 00:41:53 +00002220 time.sleep(wait_time_in_call)
2221
2222 if not verify_caller_func:
2223 caller_state_result = ad_caller.droid.telecomIsInCall()
2224 else:
2225 caller_state_result = verify_caller_func(log, ad_caller)
2226 if not caller_state_result:
Betty Zhou48557582018-05-14 13:19:23 -07002227 ad_caller.log.error("Caller not in correct state after %s seconds",
2228 wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00002229
2230 if not hangup_call(log, ad_caller):
Betty Zhou48557582018-05-14 13:19:23 -07002231 ad_caller.log.error("Error in Hanging-Up Call")
2232 return False
Ang Li73697b32015-12-03 00:41:53 +00002233
Betty Zhou48557582018-05-14 13:19:23 -07002234 ad_callee.log.info("Wait for voice mail indicator on callee.")
Ang Li73697b32015-12-03 00:41:53 +00002235 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08002236 event = ad_callee.ed.wait_for_event(
2237 EventMessageWaitingIndicatorChanged,
2238 _is_on_message_waiting_event_true)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07002239 ad_callee.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00002240 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002241 ad_callee.log.warning("No expected event %s",
2242 EventMessageWaitingIndicatorChanged)
Betty Zhou48557582018-05-14 13:19:23 -07002243 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08002244 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002245 subid_callee)
Betty Zhoua37acd32017-02-23 20:04:24 -08002246 ad_callee.log.info(
2247 "telephonyGetVoiceMailCount output - before: %s, after: %s",
2248 voice_mail_count_before, voice_mail_count_after)
Ang Li73697b32015-12-03 00:41:53 +00002249
2250 # voice_mail_count_after should:
2251 # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
2252 # or equals to -1 [For TMO]
2253 # -1 means there are unread voice mail, but the count is unknown
Nathan Harold123c9da2015-12-30 16:33:25 -08002254 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
Ang Li73697b32015-12-03 00:41:53 +00002255 voice_mail_count_after):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002256 log.error("before and after voice mail count is not incorrect.")
Ang Li73697b32015-12-03 00:41:53 +00002257 return False
Ang Li73697b32015-12-03 00:41:53 +00002258 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08002259 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002260 subid_callee)
2261 return True
2262
Nathan Harold123c9da2015-12-30 16:33:25 -08002263
Ang Li73697b32015-12-03 00:41:53 +00002264def call_voicemail_erase_all_pending_voicemail(log, ad):
2265 """Script for phone to erase all pending voice mail.
2266 This script only works for TMO and ATT and SPT currently.
2267 This script only works if phone have already set up voice mail options,
2268 and phone should disable password protection for voice mail.
2269
2270 1. If phone don't have pending voice message, return True.
2271 2. Dial voice mail number.
2272 For TMO, the number is '123'
2273 For ATT, the number is phone's number
2274 For SPT, the number is phone's number
2275 3. Wait for voice mail connection setup.
2276 4. Wait for voice mail play pending voice message.
2277 5. Send DTMF to delete one message.
2278 The digit is '7'.
2279 6. Repeat steps 4 and 5 until voice mail server drop this call.
2280 (No pending message)
Yang Liuaed3eef2015-12-15 18:40:25 -08002281 6. Check telephonyGetVoiceMailCount result. it should be 0.
Ang Li73697b32015-12-03 00:41:53 +00002282
2283 Args:
2284 log: log object
2285 ad: android device object
2286 Returns:
2287 False if error happens. True is succeed.
2288 """
2289 log.info("Erase all pending voice mail.")
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002290 count = ad.droid.telephonyGetVoiceMailCount()
2291 if count == 0:
2292 ad.log.info("No Pending voice mail.")
Ang Li73697b32015-12-03 00:41:53 +00002293 return True
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002294 if count == -1:
2295 ad.log.info("There is pending voice mail, but the count is unknown")
2296 count = MAX_SAVED_VOICE_MAIL
2297 else:
2298 ad.log.info("There are %s voicemails", count)
Ang Li73697b32015-12-03 00:41:53 +00002299
2300 voice_mail_number = get_voice_mail_number(log, ad)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002301 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00002302 if not initiate_call(log, ad, voice_mail_number):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002303 log.error("Initiate call to voice mail failed.")
Ang Li73697b32015-12-03 00:41:53 +00002304 return False
Yang Liudf164e32016-01-07 16:49:32 -08002305 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00002306 callId = ad.droid.telecomCallGetCallIds()[0]
Yang Liudf164e32016-01-07 16:49:32 -08002307 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Nathan Harold123c9da2015-12-30 16:33:25 -08002308 while (is_phone_in_call(log, ad) and (count > 0)):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002309 ad.log.info("Press %s to delete voice mail.", delete_digit)
2310 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit)
Ang Li73697b32015-12-03 00:41:53 +00002311 ad.droid.telecomCallStopDtmfTone(callId)
Yang Liudf164e32016-01-07 16:49:32 -08002312 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00002313 count -= 1
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002314 if is_phone_in_call(log, ad):
2315 hangup_call(log, ad)
2316
Yang Liuaed3eef2015-12-15 18:40:25 -08002317 # wait for telephonyGetVoiceMailCount to update correct result
Yang Liudf164e32016-01-07 16:49:32 -08002318 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
Betty Zhouee311052017-12-19 13:09:56 -08002319 while ((remaining_time > 0)
2320 and (ad.droid.telephonyGetVoiceMailCount() != 0)):
Ang Li73697b32015-12-03 00:41:53 +00002321 time.sleep(1)
2322 remaining_time -= 1
Yang Liuaed3eef2015-12-15 18:40:25 -08002323 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
Betty Zhoua37acd32017-02-23 20:04:24 -08002324 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
Ang Li73697b32015-12-03 00:41:53 +00002325 return (current_voice_mail_count == 0)
2326
Nathan Harold123c9da2015-12-30 16:33:25 -08002327
Ang Li73697b32015-12-03 00:41:53 +00002328def _is_on_message_waiting_event_true(event):
2329 """Private function to return if the received EventMessageWaitingIndicatorChanged
Yang Liudc8564b2016-01-27 14:15:37 -08002330 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
Ang Li73697b32015-12-03 00:41:53 +00002331 """
Yang Liudc8564b2016-01-27 14:15:37 -08002332 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
Ang Li73697b32015-12-03 00:41:53 +00002333
Nathan Harold123c9da2015-12-30 16:33:25 -08002334
2335def call_setup_teardown(log,
2336 ad_caller,
2337 ad_callee,
2338 ad_hangup=None,
2339 verify_caller_func=None,
2340 verify_callee_func=None,
2341 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07002342 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07002343 dialing_number_length=None,
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002344 video_state=None,
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002345 slot_id_callee=None,
2346 voice_type_init=None,
Pratik Sheth232f7952021-04-08 12:17:30 -07002347 call_stats_check=False,
Pratik Shethffd15372021-04-29 15:03:47 -07002348 result_info=result_dict,
2349 nsa_5g_for_stress=False):
Ang Li73697b32015-12-03 00:41:53 +00002350 """ Call process, including make a phone call from caller,
2351 accept from callee, and hang up. The call is on default voice subscription
2352
2353 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08002354 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00002355
2356 Args:
2357 ad_caller: Caller Android Device Object.
2358 ad_callee: Callee Android Device Object.
2359 ad_hangup: Android Device Object end the phone call.
2360 Optional. Default value is None, and phone call will continue.
2361 verify_call_mode_caller: func_ptr to verify caller in correct mode
2362 Optional. Default is None
2363 verify_call_mode_caller: func_ptr to verify caller in correct mode
2364 Optional. Default is None
2365 incall_ui_display: after answer the call, bring in-call UI to foreground or
2366 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2367 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2368 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2369 else, do nothing.
Betty Zhoued13b712018-05-02 19:40:10 -07002370 dialing_number_length: the number of digits used for dialing
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002371 slot_id_callee : the slot if of the callee to call to
Ang Li73697b32015-12-03 00:41:53 +00002372
2373 Returns:
2374 True if call process without any error.
2375 False if error happened.
2376
2377 """
Yang Liu963c93c2016-04-05 10:52:00 -07002378 subid_caller = get_outgoing_voice_sub_id(ad_caller)
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002379 if slot_id_callee is None:
2380 subid_callee = get_incoming_voice_sub_id(ad_callee)
2381 else:
2382 subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee)
2383
Nathan Harold123c9da2015-12-30 16:33:25 -08002384 return call_setup_teardown_for_subscription(
2385 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
2386 verify_caller_func, verify_callee_func, wait_time_in_call,
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002387 incall_ui_display, dialing_number_length, video_state,
Pratik Shethffd15372021-04-29 15:03:47 -07002388 voice_type_init, call_stats_check, result_info, nsa_5g_for_stress)
2389
Ang Li73697b32015-12-03 00:41:53 +00002390
2391
Nathan Harold123c9da2015-12-30 16:33:25 -08002392def call_setup_teardown_for_subscription(
2393 log,
2394 ad_caller,
2395 ad_callee,
2396 subid_caller,
2397 subid_callee,
2398 ad_hangup=None,
2399 verify_caller_func=None,
2400 verify_callee_func=None,
2401 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07002402 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07002403 dialing_number_length=None,
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002404 video_state=None,
2405 voice_type_init=None,
Pratik Sheth232f7952021-04-08 12:17:30 -07002406 call_stats_check=False,
Pratik Shethffd15372021-04-29 15:03:47 -07002407 result_info=result_dict,
2408 nsa_5g_for_stress=False):
Ang Li73697b32015-12-03 00:41:53 +00002409 """ Call process, including make a phone call from caller,
2410 accept from callee, and hang up. The call is on specified subscription
2411
2412 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08002413 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00002414
2415 Args:
2416 ad_caller: Caller Android Device Object.
2417 ad_callee: Callee Android Device Object.
2418 subid_caller: Caller subscription ID
2419 subid_callee: Callee subscription ID
2420 ad_hangup: Android Device Object end the phone call.
2421 Optional. Default value is None, and phone call will continue.
2422 verify_call_mode_caller: func_ptr to verify caller in correct mode
2423 Optional. Default is None
2424 verify_call_mode_caller: func_ptr to verify caller in correct mode
2425 Optional. Default is None
2426 incall_ui_display: after answer the call, bring in-call UI to foreground or
2427 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2428 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2429 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2430 else, do nothing.
2431
2432 Returns:
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002433 TelResultWrapper which will evaluate as False if error.
Ang Li73697b32015-12-03 00:41:53 +00002434
2435 """
Betty Zhouf27f5482017-07-24 18:56:17 -07002436 CHECK_INTERVAL = 5
Betty Zhoua301c202018-02-13 15:11:47 -08002437 begin_time = get_current_epoch_time()
Betty Zhou74481722018-04-13 16:19:25 -07002438 if not verify_caller_func:
2439 verify_caller_func = is_phone_in_call
2440 if not verify_callee_func:
2441 verify_callee_func = is_phone_in_call
Nathan Harold123c9da2015-12-30 16:33:25 -08002442
Betty Zhou3b2de072018-03-15 16:46:26 -07002443 caller_number = ad_caller.telephony['subscription'][subid_caller][
2444 'phone_num']
2445 callee_number = ad_callee.telephony['subscription'][subid_callee][
2446 'phone_num']
2447 if dialing_number_length:
2448 skip_test = False
2449 trunc_position = 0 - int(dialing_number_length)
2450 try:
2451 caller_area_code = caller_number[:trunc_position]
2452 callee_area_code = callee_number[:trunc_position]
2453 callee_dial_number = callee_number[trunc_position:]
2454 except:
2455 skip_test = True
2456 if caller_area_code != callee_area_code:
2457 skip_test = True
2458 if skip_test:
2459 msg = "Cannot make call from %s to %s by %s digits" % (
2460 caller_number, callee_number, dialing_number_length)
2461 ad_caller.log.info(msg)
2462 raise signals.TestSkip(msg)
2463 else:
2464 callee_number = callee_dial_number
Ang Li73697b32015-12-03 00:41:53 +00002465
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002466 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
Betty Zhou628b98e2018-01-08 15:45:25 -08002467 msg = "Call from %s to %s" % (caller_number, callee_number)
Betty Zhou48557582018-05-14 13:19:23 -07002468 if video_state:
2469 msg = "Video %s" % msg
2470 video = True
2471 else:
2472 video = False
Betty Zhou628b98e2018-01-08 15:45:25 -08002473 if ad_hangup:
2474 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
2475 ad_caller.log.info(msg)
Ang Li73697b32015-12-03 00:41:53 +00002476
Betty Zhou0d774582018-03-01 17:46:44 -08002477 for ad in (ad_caller, ad_callee):
2478 call_ids = ad.droid.telecomCallGetCallIds()
2479 setattr(ad, "call_ids", call_ids)
Betty Zhou774ea542018-05-16 12:45:36 -07002480 if call_ids:
2481 ad.log.info("Pre-exist CallId %s before making call", call_ids)
Ang Li73697b32015-12-03 00:41:53 +00002482 try:
Betty Zhou2186ebc2018-05-09 16:50:26 -07002483 if not initiate_call(
Betty Zhou48557582018-05-14 13:19:23 -07002484 log,
2485 ad_caller,
2486 callee_number,
2487 incall_ui_display=incall_ui_display,
2488 video=video):
Betty Zhouf27f5482017-07-24 18:56:17 -07002489 ad_caller.log.error("Initiate call failed.")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002490 tel_result_wrapper.result_value = CallResult('INITIATE_FAILED')
2491 return tel_result_wrapper
Betty Zhou94023182017-06-07 18:02:14 -07002492 else:
2493 ad_caller.log.info("Caller initate call successfully")
Ang Li73697b32015-12-03 00:41:53 +00002494 if not wait_and_answer_call_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08002495 log,
2496 ad_callee,
2497 subid_callee,
2498 incoming_number=caller_number,
Betty Zhou2e01bc82017-03-17 10:55:57 -07002499 caller=ad_caller,
Betty Zhou48557582018-05-14 13:19:23 -07002500 incall_ui_display=incall_ui_display,
2501 video_state=video_state):
Betty Zhouf27f5482017-07-24 18:56:17 -07002502 ad_callee.log.error("Answer call fail.")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002503 tel_result_wrapper.result_value = CallResult(
2504 'NO_RING_EVENT_OR_ANSWER_FAILED')
2505 return tel_result_wrapper
Betty Zhou94023182017-06-07 18:02:14 -07002506 else:
2507 ad_callee.log.info("Callee answered the call successfully")
Ang Li73697b32015-12-03 00:41:53 +00002508
Betty Zhou74481722018-04-13 16:19:25 -07002509 for ad, call_func in zip([ad_caller, ad_callee],
2510 [verify_caller_func, verify_callee_func]):
Betty Zhou0d774582018-03-01 17:46:44 -08002511 call_ids = ad.droid.telecomCallGetCallIds()
Betty Zhou5dd53c02018-03-22 20:08:33 -07002512 new_call_ids = set(call_ids) - set(ad.call_ids)
2513 if not new_call_ids:
2514 ad.log.error(
2515 "No new call ids are found after call establishment")
Betty Zhouf25fdab2018-04-23 19:20:17 -07002516 ad.log.error("telecomCallGetCallIds returns %s",
2517 ad.droid.telecomCallGetCallIds())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002518 tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND')
Betty Zhou5dd53c02018-03-22 20:08:33 -07002519 for new_call_id in new_call_ids:
2520 if not wait_for_in_call_active(ad, call_id=new_call_id):
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002521 tel_result_wrapper.result_value = CallResult(
2522 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
Betty Zhou8aafcc12018-05-01 20:54:15 -07002523 else:
2524 ad.log.info("callProperties = %s",
2525 ad.droid.telecomCallGetProperties(new_call_id))
Betty Zhouc4dfad12018-04-11 18:36:49 -07002526
Betty Zhouf31dffe2018-02-23 19:29:28 -08002527 if not ad.droid.telecomCallGetAudioState():
2528 ad.log.error("Audio is not in call state")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002529 tel_result_wrapper.result_value = CallResult(
2530 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
Betty Zhoucf048542018-02-22 17:14:08 -08002531
Betty Zhou74481722018-04-13 16:19:25 -07002532 if call_func(log, ad):
2533 ad.log.info("Call is in %s state", call_func.__name__)
2534 else:
Betty Zhou16e8e662018-05-08 18:26:18 -07002535 ad.log.error("Call is not in %s state, voice in RAT %s",
2536 call_func.__name__,
2537 ad.droid.telephonyGetCurrentVoiceNetworkType())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002538 tel_result_wrapper.result_value = CallResult(
2539 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
2540 if not tel_result_wrapper:
2541 return tel_result_wrapper
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002542
2543 if call_stats_check:
2544 voice_type_in_call = check_voice_network_type([ad_caller, ad_callee], voice_init=False)
2545 phone_a_call_type = check_call_status(ad_caller,
2546 voice_type_init[0],
2547 voice_type_in_call[0])
Pratik Sheth232f7952021-04-08 12:17:30 -07002548 result_info["Call Stats"] = phone_a_call_type
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002549 ad_caller.log.debug("Voice Call Type: %s", phone_a_call_type)
2550 phone_b_call_type = check_call_status(ad_callee,
2551 voice_type_init[1],
2552 voice_type_in_call[1])
Pratik Sheth232f7952021-04-08 12:17:30 -07002553 result_info["Call Stats"] = phone_b_call_type
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002554 ad_callee.log.debug("Voice Call Type: %s", phone_b_call_type)
2555
Yang Liu13406292016-02-23 14:58:25 -08002556 elapsed_time = 0
Nathan Harold7642fc92016-05-02 18:29:11 -07002557 while (elapsed_time < wait_time_in_call):
2558 CHECK_INTERVAL = min(CHECK_INTERVAL,
2559 wait_time_in_call - elapsed_time)
Yang Liu13406292016-02-23 14:58:25 -08002560 time.sleep(CHECK_INTERVAL)
2561 elapsed_time += CHECK_INTERVAL
Betty Zhou94023182017-06-07 18:02:14 -07002562 time_message = "at <%s>/<%s> second." % (elapsed_time,
2563 wait_time_in_call)
Betty Zhouc2801992018-01-30 16:40:28 -08002564 for ad, call_func in [(ad_caller, verify_caller_func),
2565 (ad_callee, verify_callee_func)]:
2566 if not call_func(log, ad):
Betty Zhou16e8e662018-05-08 18:26:18 -07002567 ad.log.error(
2568 "NOT in correct %s state at %s, voice in RAT %s",
2569 call_func.__name__, time_message,
2570 ad.droid.telephonyGetCurrentVoiceNetworkType())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002571 tel_result_wrapper.result_value = CallResult(
2572 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
Betty Zhouc2801992018-01-30 16:40:28 -08002573 else:
2574 ad.log.info("In correct %s state at %s",
2575 call_func.__name__, time_message)
2576 if not ad.droid.telecomCallGetAudioState():
2577 ad.log.error("Audio is not in call state at %s",
2578 time_message)
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002579 tel_result_wrapper.result_value = CallResult(
2580 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
2581 if not tel_result_wrapper:
2582 return tel_result_wrapper
Betty Zhoub707ef22018-05-14 16:47:05 -07002583
Betty Zhoufe726dc2018-04-25 19:31:33 -07002584 if ad_hangup:
Betty Zhoufe726dc2018-04-25 19:31:33 -07002585 if not hangup_call(log, ad_hangup):
2586 ad_hangup.log.info("Failed to hang up the call")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002587 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
2588 return tel_result_wrapper
Betty Zhoufd1e0da2018-02-20 14:39:35 -08002589 finally:
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002590 if not tel_result_wrapper:
Betty Zhou16e8e662018-05-08 18:26:18 -07002591 for ad in (ad_caller, ad_callee):
2592 last_call_drop_reason(ad, begin_time)
Ang Li73697b32015-12-03 00:41:53 +00002593 try:
2594 if ad.droid.telecomIsInCall():
Betty Zhoufe726dc2018-04-25 19:31:33 -07002595 ad.log.info("In call. End now.")
Ang Li73697b32015-12-03 00:41:53 +00002596 ad.droid.telecomEndCall()
2597 except Exception as e:
2598 log.error(str(e))
Pratik Shethffd15372021-04-29 15:03:47 -07002599
2600 if nsa_5g_for_stress:
2601 for ad in (ad_caller, ad_callee):
2602 if not is_current_network_5g_nsa(ad):
2603 ad.log.error("Phone not attached on 5G NSA")
2604
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002605 if ad_hangup or not tel_result_wrapper:
Betty Zhou16e8e662018-05-08 18:26:18 -07002606 for ad in (ad_caller, ad_callee):
2607 if not wait_for_call_id_clearing(
2608 ad, getattr(ad, "caller_ids", [])):
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002609 tel_result_wrapper.result_value = CallResult(
2610 'CALL_ID_CLEANUP_FAIL')
2611 return tel_result_wrapper
Ang Li73697b32015-12-03 00:41:53 +00002612
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002613
Markus Liu1cca96e2019-11-26 15:05:25 +08002614def call_setup_teardown_for_call_forwarding(
2615 log,
2616 ad_caller,
2617 ad_callee,
2618 forwarded_callee,
2619 ad_hangup=None,
2620 verify_callee_func=None,
2621 verify_after_cf_disabled=None,
2622 wait_time_in_call=WAIT_TIME_IN_CALL,
2623 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
2624 dialing_number_length=None,
2625 video_state=None,
2626 call_forwarding_type="unconditional"):
2627 """ Call process for call forwarding, including make a phone call from
2628 caller, forward from callee, accept from the forwarded callee and hang up.
2629 The call is on default voice subscription
2630
2631 In call process, call from <ad_caller> to <ad_callee>, forwarded to
2632 <forwarded_callee>, accept the call, (optional) and then hang up from
2633 <ad_hangup>.
2634
2635 Args:
2636 ad_caller: Caller Android Device Object.
2637 ad_callee: Callee Android Device Object which forwards the call.
2638 forwarded_callee: Callee Android Device Object which answers the call.
2639 ad_hangup: Android Device Object end the phone call.
2640 Optional. Default value is None, and phone call will continue.
2641 verify_callee_func: func_ptr to verify callee in correct mode
2642 Optional. Default is None
2643 verify_after_cf_disabled: If True the test of disabling call forwarding
2644 will be appended.
2645 wait_time_in_call: the call duration of a connected call
2646 incall_ui_display: after answer the call, bring in-call UI to foreground
2647 or background.
2648 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2649 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2650 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2651 else, do nothing.
2652 dialing_number_length: the number of digits used for dialing
2653 video_state: video call or voice call. Default is voice call.
2654 call_forwarding_type: type of call forwarding listed below:
2655 - unconditional
2656 - busy
2657 - not_answered
2658 - not_reachable
2659
2660 Returns:
2661 True if call process without any error.
2662 False if error happened.
2663
2664 """
2665 subid_caller = get_outgoing_voice_sub_id(ad_caller)
2666 subid_callee = get_incoming_voice_sub_id(ad_callee)
2667 subid_forwarded_callee = get_incoming_voice_sub_id(forwarded_callee)
2668 return call_setup_teardown_for_call_forwarding_for_subscription(
2669 log,
2670 ad_caller,
2671 ad_callee,
2672 forwarded_callee,
2673 subid_caller,
2674 subid_callee,
2675 subid_forwarded_callee,
2676 ad_hangup,
2677 verify_callee_func,
2678 wait_time_in_call,
2679 incall_ui_display,
2680 dialing_number_length,
2681 video_state,
2682 call_forwarding_type,
2683 verify_after_cf_disabled)
2684
Pratik Sheth68e4eba2021-03-23 17:10:13 -07002685
Markus Liu1cca96e2019-11-26 15:05:25 +08002686def call_setup_teardown_for_call_forwarding_for_subscription(
2687 log,
2688 ad_caller,
2689 ad_callee,
2690 forwarded_callee,
2691 subid_caller,
2692 subid_callee,
2693 subid_forwarded_callee,
2694 ad_hangup=None,
2695 verify_callee_func=None,
2696 wait_time_in_call=WAIT_TIME_IN_CALL,
2697 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
2698 dialing_number_length=None,
2699 video_state=None,
2700 call_forwarding_type="unconditional",
2701 verify_after_cf_disabled=None):
2702 """ Call process for call forwarding, including make a phone call from caller,
2703 forward from callee, accept from the forwarded callee and hang up.
2704 The call is on specified subscription
2705
2706 In call process, call from <ad_caller> to <ad_callee>, forwarded to
2707 <forwarded_callee>, accept the call, (optional) and then hang up from
2708 <ad_hangup>.
2709
2710 Args:
2711 ad_caller: Caller Android Device Object.
2712 ad_callee: Callee Android Device Object which forwards the call.
2713 forwarded_callee: Callee Android Device Object which answers the call.
2714 subid_caller: Caller subscription ID
2715 subid_callee: Callee subscription ID
2716 subid_forwarded_callee: Forwarded callee subscription ID
2717 ad_hangup: Android Device Object end the phone call.
2718 Optional. Default value is None, and phone call will continue.
2719 verify_callee_func: func_ptr to verify callee in correct mode
2720 Optional. Default is None
2721 wait_time_in_call: the call duration of a connected call
2722 incall_ui_display: after answer the call, bring in-call UI to foreground
2723 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2724 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2725 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2726 else, do nothing.
2727 dialing_number_length: the number of digits used for dialing
2728 video_state: video call or voice call. Default is voice call.
2729 call_forwarding_type: type of call forwarding listed below:
2730 - unconditional
2731 - busy
2732 - not_answered
2733 - not_reachable
2734 verify_after_cf_disabled: If True the call forwarding will not be
2735 enabled. This argument is used to verify if the call can be received
2736 successfully after call forwarding was disabled.
2737
2738 Returns:
2739 True if call process without any error.
2740 False if error happened.
2741
2742 """
2743 CHECK_INTERVAL = 5
2744 begin_time = get_current_epoch_time()
2745 verify_caller_func = is_phone_in_call
2746 if not verify_callee_func:
2747 verify_callee_func = is_phone_in_call
2748 verify_forwarded_callee_func = is_phone_in_call
2749
2750 caller_number = ad_caller.telephony['subscription'][subid_caller][
2751 'phone_num']
2752 callee_number = ad_callee.telephony['subscription'][subid_callee][
2753 'phone_num']
2754 forwarded_callee_number = forwarded_callee.telephony['subscription'][
2755 subid_forwarded_callee]['phone_num']
2756
2757 if dialing_number_length:
2758 skip_test = False
2759 trunc_position = 0 - int(dialing_number_length)
2760 try:
2761 caller_area_code = caller_number[:trunc_position]
2762 callee_area_code = callee_number[:trunc_position]
2763 callee_dial_number = callee_number[trunc_position:]
2764 except:
2765 skip_test = True
2766 if caller_area_code != callee_area_code:
2767 skip_test = True
2768 if skip_test:
2769 msg = "Cannot make call from %s to %s by %s digits" % (
2770 caller_number, callee_number, dialing_number_length)
2771 ad_caller.log.info(msg)
2772 raise signals.TestSkip(msg)
2773 else:
2774 callee_number = callee_dial_number
2775
2776 result = True
2777 msg = "Call from %s to %s (forwarded to %s)" % (
2778 caller_number, callee_number, forwarded_callee_number)
2779 if video_state:
2780 msg = "Video %s" % msg
2781 video = True
2782 else:
2783 video = False
2784 if ad_hangup:
2785 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
2786 ad_caller.log.info(msg)
2787
2788 for ad in (ad_caller, forwarded_callee):
2789 call_ids = ad.droid.telecomCallGetCallIds()
2790 setattr(ad, "call_ids", call_ids)
2791 if call_ids:
2792 ad.log.info("Pre-exist CallId %s before making call", call_ids)
2793
2794 if not verify_after_cf_disabled:
2795 if not set_call_forwarding_by_mmi(
2796 log,
2797 ad_callee,
2798 forwarded_callee,
2799 call_forwarding_type=call_forwarding_type):
2800 raise signals.TestFailure(
2801 "Failed to register or activate call forwarding.",
2802 extras={"fail_reason": "Failed to register or activate call"
2803 " forwarding."})
2804
2805 if call_forwarding_type == "not_reachable":
2806 if not toggle_airplane_mode_msim(
2807 log,
2808 ad_callee,
2809 new_state=True,
2810 strict_checking=True):
2811 return False
2812
2813 if call_forwarding_type == "busy":
2814 ad_callee.log.info("Callee is making a phone call to 0000000000 to make"
2815 " itself busy.")
2816 ad_callee.droid.telecomCallNumber("0000000000", False)
2817 time.sleep(2)
2818
2819 if check_call_state_idle_by_adb(ad_callee):
2820 ad_callee.log.error("Call state of the callee is idle.")
2821 if not verify_after_cf_disabled:
2822 erase_call_forwarding_by_mmi(
2823 log,
2824 ad_callee,
2825 call_forwarding_type=call_forwarding_type)
2826 return False
2827
2828 try:
2829 if not initiate_call(
2830 log,
2831 ad_caller,
2832 callee_number,
2833 incall_ui_display=incall_ui_display,
2834 video=video):
2835
2836 ad_caller.log.error("Caller failed to initiate the call.")
2837 result = False
2838
2839 if call_forwarding_type == "not_reachable":
2840 if toggle_airplane_mode_msim(
2841 log,
2842 ad_callee,
2843 new_state=False,
2844 strict_checking=True):
2845 time.sleep(10)
2846 elif call_forwarding_type == "busy":
2847 hangup_call(log, ad_callee)
2848
2849 if not verify_after_cf_disabled:
2850 erase_call_forwarding_by_mmi(
2851 log,
2852 ad_callee,
2853 call_forwarding_type=call_forwarding_type)
2854 return False
2855 else:
2856 ad_caller.log.info("Caller initated the call successfully.")
2857
2858 if call_forwarding_type == "not_answered":
2859 if not wait_for_ringing_call_for_subscription(
2860 log,
2861 ad_callee,
2862 subid_callee,
2863 incoming_number=caller_number,
2864 caller=ad_caller,
2865 event_tracking_started=True):
2866 ad.log.info("Incoming call ringing check failed.")
2867 return False
2868
2869 _timeout = 30
2870 while check_call_state_ring_by_adb(ad_callee) == 1 and _timeout >= 0:
2871 time.sleep(1)
2872 _timeout = _timeout - 1
2873
2874 if not wait_and_answer_call_for_subscription(
2875 log,
2876 forwarded_callee,
2877 subid_forwarded_callee,
2878 incoming_number=caller_number,
2879 caller=ad_caller,
2880 incall_ui_display=incall_ui_display,
2881 video_state=video_state):
2882
2883 if not verify_after_cf_disabled:
2884 forwarded_callee.log.error("Forwarded callee failed to receive"
2885 "or answer the call.")
2886 result = False
2887 else:
2888 forwarded_callee.log.info("Forwarded callee did not receive or"
2889 " answer the call.")
2890
2891 if call_forwarding_type == "not_reachable":
2892 if toggle_airplane_mode_msim(
2893 log,
2894 ad_callee,
2895 new_state=False,
2896 strict_checking=True):
2897 time.sleep(10)
2898 elif call_forwarding_type == "busy":
2899 hangup_call(log, ad_callee)
2900
2901 if not verify_after_cf_disabled:
2902 erase_call_forwarding_by_mmi(
2903 log,
2904 ad_callee,
2905 call_forwarding_type=call_forwarding_type)
2906 return False
2907
2908 else:
2909 if not verify_after_cf_disabled:
2910 forwarded_callee.log.info("Forwarded callee answered the call"
2911 " successfully.")
2912 else:
2913 forwarded_callee.log.error("Forwarded callee should not be able"
2914 " to answer the call.")
2915 hangup_call(log, ad_caller)
2916 result = False
2917
2918 for ad, subid, call_func in zip(
2919 [ad_caller, forwarded_callee],
2920 [subid_caller, subid_forwarded_callee],
2921 [verify_caller_func, verify_forwarded_callee_func]):
2922 call_ids = ad.droid.telecomCallGetCallIds()
2923 new_call_ids = set(call_ids) - set(ad.call_ids)
2924 if not new_call_ids:
2925 if not verify_after_cf_disabled:
2926 ad.log.error(
2927 "No new call ids are found after call establishment")
2928 ad.log.error("telecomCallGetCallIds returns %s",
2929 ad.droid.telecomCallGetCallIds())
2930 result = False
2931 for new_call_id in new_call_ids:
2932 if not verify_after_cf_disabled:
2933 if not wait_for_in_call_active(ad, call_id=new_call_id):
2934 result = False
2935 else:
2936 ad.log.info("callProperties = %s",
2937 ad.droid.telecomCallGetProperties(new_call_id))
2938 else:
2939 ad.log.error("No new call id should be found.")
2940
2941 if not ad.droid.telecomCallGetAudioState():
2942 if not verify_after_cf_disabled:
2943 ad.log.error("Audio is not in call state")
2944 result = False
2945
2946 if call_func(log, ad):
2947 if not verify_after_cf_disabled:
2948 ad.log.info("Call is in %s state", call_func.__name__)
2949 else:
2950 ad.log.error("Call is in %s state", call_func.__name__)
2951 else:
2952 if not verify_after_cf_disabled:
2953 ad.log.error(
2954 "Call is not in %s state, voice in RAT %s",
2955 call_func.__name__,
2956 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
2957 result = False
2958
2959 if not result:
2960 if call_forwarding_type == "not_reachable":
2961 if toggle_airplane_mode_msim(
2962 log,
2963 ad_callee,
2964 new_state=False,
2965 strict_checking=True):
2966 time.sleep(10)
2967 elif call_forwarding_type == "busy":
2968 hangup_call(log, ad_callee)
2969
2970 if not verify_after_cf_disabled:
2971 erase_call_forwarding_by_mmi(
2972 log,
2973 ad_callee,
2974 call_forwarding_type=call_forwarding_type)
2975 return False
2976
2977 elapsed_time = 0
2978 while (elapsed_time < wait_time_in_call):
2979 CHECK_INTERVAL = min(CHECK_INTERVAL,
2980 wait_time_in_call - elapsed_time)
2981 time.sleep(CHECK_INTERVAL)
2982 elapsed_time += CHECK_INTERVAL
2983 time_message = "at <%s>/<%s> second." % (elapsed_time,
2984 wait_time_in_call)
2985 for ad, subid, call_func in [
2986 (ad_caller, subid_caller, verify_caller_func),
2987 (forwarded_callee, subid_forwarded_callee,
2988 verify_forwarded_callee_func)]:
2989 if not call_func(log, ad):
2990 if not verify_after_cf_disabled:
2991 ad.log.error(
2992 "NOT in correct %s state at %s, voice in RAT %s",
2993 call_func.__name__, time_message,
2994 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
2995 result = False
2996 else:
2997 if not verify_after_cf_disabled:
2998 ad.log.info("In correct %s state at %s",
2999 call_func.__name__, time_message)
3000 else:
3001 ad.log.error("In correct %s state at %s",
3002 call_func.__name__, time_message)
3003
3004 if not ad.droid.telecomCallGetAudioState():
3005 if not verify_after_cf_disabled:
3006 ad.log.error("Audio is not in call state at %s",
3007 time_message)
3008 result = False
3009
3010 if not result:
3011 if call_forwarding_type == "not_reachable":
3012 if toggle_airplane_mode_msim(
3013 log,
3014 ad_callee,
3015 new_state=False,
3016 strict_checking=True):
3017 time.sleep(10)
3018 elif call_forwarding_type == "busy":
3019 hangup_call(log, ad_callee)
3020
3021 if not verify_after_cf_disabled:
3022 erase_call_forwarding_by_mmi(
3023 log,
3024 ad_callee,
3025 call_forwarding_type=call_forwarding_type)
3026 return False
3027
3028 if ad_hangup:
3029 if not hangup_call(log, ad_hangup):
3030 ad_hangup.log.info("Failed to hang up the call")
3031 result = False
3032 if call_forwarding_type == "not_reachable":
3033 if toggle_airplane_mode_msim(
3034 log,
3035 ad_callee,
3036 new_state=False,
3037 strict_checking=True):
3038 time.sleep(10)
3039 elif call_forwarding_type == "busy":
3040 hangup_call(log, ad_callee)
3041
3042 if not verify_after_cf_disabled:
3043 erase_call_forwarding_by_mmi(
3044 log,
3045 ad_callee,
3046 call_forwarding_type=call_forwarding_type)
3047 return False
3048 finally:
3049 if not result:
3050 if verify_after_cf_disabled:
3051 result = True
3052 else:
3053 for ad in (ad_caller, forwarded_callee):
3054 last_call_drop_reason(ad, begin_time)
3055 try:
3056 if ad.droid.telecomIsInCall():
3057 ad.log.info("In call. End now.")
3058 ad.droid.telecomEndCall()
3059 except Exception as e:
3060 log.error(str(e))
3061
3062 if ad_hangup or not result:
3063 for ad in (ad_caller, forwarded_callee):
3064 if not wait_for_call_id_clearing(
3065 ad, getattr(ad, "caller_ids", [])):
3066 result = False
3067
3068 if call_forwarding_type == "not_reachable":
3069 if toggle_airplane_mode_msim(
3070 log,
3071 ad_callee,
3072 new_state=False,
3073 strict_checking=True):
3074 time.sleep(10)
3075 elif call_forwarding_type == "busy":
3076 hangup_call(log, ad_callee)
3077
3078 if not verify_after_cf_disabled:
3079 erase_call_forwarding_by_mmi(
3080 log,
3081 ad_callee,
3082 call_forwarding_type=call_forwarding_type)
3083
3084 if not result:
3085 return result
3086
3087 ad_caller.log.info(
3088 "Make a normal call to callee to ensure the call can be connected after"
3089 " call forwarding was disabled")
3090 return call_setup_teardown_for_subscription(
3091 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_caller,
3092 verify_caller_func, verify_callee_func, wait_time_in_call,
3093 incall_ui_display, dialing_number_length, video_state)
Nathan Harold123c9da2015-12-30 16:33:25 -08003094
Pratik Sheth68e4eba2021-03-23 17:10:13 -07003095
Markus Liude6e5db2019-12-18 15:31:54 +08003096def call_setup_teardown_for_call_waiting(log,
3097 ad_caller,
3098 ad_callee,
3099 ad_caller2,
3100 ad_hangup=None,
3101 ad_hangup2=None,
3102 verify_callee_func=None,
3103 end_first_call_before_answering_second_call=True,
3104 wait_time_in_call=WAIT_TIME_IN_CALL,
3105 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
3106 dialing_number_length=None,
3107 video_state=None,
3108 call_waiting=True):
3109 """ Call process for call waiting, including make the 1st phone call from
3110 caller, answer the call by the callee, and receive the 2nd call from the
3111 caller2. The call is on default voice subscription
3112
3113 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
3114 <ad_caller2> to <ad_callee>, hang up the existing call or reject the
3115 incoming call according to the test scenario.
3116
3117 Args:
3118 ad_caller: Caller Android Device Object.
3119 ad_callee: Callee Android Device Object.
3120 ad_caller2: Caller2 Android Device Object.
3121 ad_hangup: Android Device Object end the 1st phone call.
3122 Optional. Default value is None, and phone call will continue.
3123 ad_hangup2: Android Device Object end the 2nd phone call.
3124 Optional. Default value is None, and phone call will continue.
3125 verify_callee_func: func_ptr to verify callee in correct mode
3126 Optional. Default is None
3127 end_first_call_before_answering_second_call: If True the 2nd call will
3128 be rejected on the ringing stage.
3129 wait_time_in_call: the call duration of a connected call
3130 incall_ui_display: after answer the call, bring in-call UI to foreground
3131 or background.
3132 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
3133 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
3134 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
3135 else, do nothing.
3136 dialing_number_length: the number of digits used for dialing
3137 video_state: video call or voice call. Default is voice call.
3138 call_waiting: True to enable call waiting and False to disable.
3139
3140 Returns:
3141 True if call process without any error.
3142 False if error happened.
3143
3144 """
3145 subid_caller = get_outgoing_voice_sub_id(ad_caller)
3146 subid_callee = get_incoming_voice_sub_id(ad_callee)
3147 subid_caller2 = get_incoming_voice_sub_id(ad_caller2)
3148 return call_setup_teardown_for_call_waiting_for_subscription(
3149 log,
3150 ad_caller,
3151 ad_callee,
3152 ad_caller2,
3153 subid_caller,
3154 subid_callee,
3155 subid_caller2,
3156 ad_hangup, ad_hangup2,
3157 verify_callee_func,
3158 end_first_call_before_answering_second_call,
3159 wait_time_in_call,
3160 incall_ui_display,
3161 dialing_number_length,
3162 video_state,
3163 call_waiting)
3164
Pratik Sheth68e4eba2021-03-23 17:10:13 -07003165
Markus Liude6e5db2019-12-18 15:31:54 +08003166def call_setup_teardown_for_call_waiting_for_subscription(
3167 log,
3168 ad_caller,
3169 ad_callee,
3170 ad_caller2,
3171 subid_caller,
3172 subid_callee,
3173 subid_caller2,
3174 ad_hangup=None,
3175 ad_hangup2=None,
3176 verify_callee_func=None,
3177 end_first_call_before_answering_second_call=True,
3178 wait_time_in_call=WAIT_TIME_IN_CALL,
3179 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
3180 dialing_number_length=None,
3181 video_state=None,
3182 call_waiting=True):
3183 """ Call process for call waiting, including make the 1st phone call from
3184 caller, answer the call by the callee, and receive the 2nd call from the
3185 caller2. The call is on specified subscription.
3186
3187 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
3188 <ad_caller2> to <ad_callee>, hang up the existing call or reject the
3189 incoming call according to the test scenario.
3190
3191 Args:
3192 ad_caller: Caller Android Device Object.
3193 ad_callee: Callee Android Device Object.
3194 ad_caller2: Caller2 Android Device Object.
3195 subid_caller: Caller subscription ID.
3196 subid_callee: Callee subscription ID.
3197 subid_caller2: Caller2 subscription ID.
3198 ad_hangup: Android Device Object end the 1st phone call.
3199 Optional. Default value is None, and phone call will continue.
3200 ad_hangup2: Android Device Object end the 2nd phone call.
3201 Optional. Default value is None, and phone call will continue.
3202 verify_callee_func: func_ptr to verify callee in correct mode
3203 Optional. Default is None
3204 end_first_call_before_answering_second_call: If True the 2nd call will
3205 be rejected on the ringing stage.
3206 wait_time_in_call: the call duration of a connected call
3207 incall_ui_display: after answer the call, bring in-call UI to foreground
3208 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
3209 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
3210 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
3211 else, do nothing.
3212 dialing_number_length: the number of digits used for dialing
3213 video_state: video call or voice call. Default is voice call.
3214 call_waiting: True to enable call waiting and False to disable.
3215
3216 Returns:
3217 True if call process without any error.
3218 False if error happened.
3219
3220 """
3221
3222 CHECK_INTERVAL = 5
3223 begin_time = get_current_epoch_time()
3224 verify_caller_func = is_phone_in_call
3225 if not verify_callee_func:
3226 verify_callee_func = is_phone_in_call
3227 verify_caller2_func = is_phone_in_call
3228
3229 caller_number = ad_caller.telephony['subscription'][subid_caller][
3230 'phone_num']
3231 callee_number = ad_callee.telephony['subscription'][subid_callee][
3232 'phone_num']
3233 caller2_number = ad_caller2.telephony['subscription'][subid_caller2][
3234 'phone_num']
3235 if dialing_number_length:
3236 skip_test = False
3237 trunc_position = 0 - int(dialing_number_length)
3238 try:
3239 caller_area_code = caller_number[:trunc_position]
3240 callee_area_code = callee_number[:trunc_position]
3241 callee_dial_number = callee_number[trunc_position:]
3242 except:
3243 skip_test = True
3244 if caller_area_code != callee_area_code:
3245 skip_test = True
3246 if skip_test:
3247 msg = "Cannot make call from %s to %s by %s digits" % (
3248 caller_number, callee_number, dialing_number_length)
3249 ad_caller.log.info(msg)
3250 raise signals.TestSkip(msg)
3251 else:
3252 callee_number = callee_dial_number
3253
3254 result = True
3255 msg = "Call from %s to %s" % (caller_number, callee_number)
3256 if video_state:
3257 msg = "Video %s" % msg
3258 video = True
3259 else:
3260 video = False
3261 if ad_hangup:
3262 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
3263 ad_caller.log.info(msg)
3264
3265 for ad in (ad_caller, ad_callee, ad_caller2):
3266 call_ids = ad.droid.telecomCallGetCallIds()
3267 setattr(ad, "call_ids", call_ids)
3268 if call_ids:
3269 ad.log.info("Pre-exist CallId %s before making call", call_ids)
3270
3271 if not call_waiting:
3272 set_call_waiting(log, ad_callee, enable=0)
3273 else:
3274 set_call_waiting(log, ad_callee, enable=1)
3275
3276 first_call_ids = []
3277 try:
3278 if not initiate_call(
3279 log,
3280 ad_caller,
3281 callee_number,
3282 incall_ui_display=incall_ui_display,
3283 video=video):
3284 ad_caller.log.error("Initiate call failed.")
3285 if not call_waiting:
3286 set_call_waiting(log, ad_callee, enable=1)
3287 result = False
3288 return False
3289 else:
3290 ad_caller.log.info("Caller initate call successfully")
3291 if not wait_and_answer_call_for_subscription(
3292 log,
3293 ad_callee,
3294 subid_callee,
3295 incoming_number=caller_number,
3296 caller=ad_caller,
3297 incall_ui_display=incall_ui_display,
3298 video_state=video_state):
3299 ad_callee.log.error("Answer call fail.")
3300 if not call_waiting:
3301 set_call_waiting(log, ad_callee, enable=1)
3302 result = False
3303 return False
3304 else:
3305 ad_callee.log.info("Callee answered the call successfully")
3306
3307 for ad, subid, call_func in zip(
3308 [ad_caller, ad_callee],
3309 [subid_caller, subid_callee],
3310 [verify_caller_func, verify_callee_func]):
3311 call_ids = ad.droid.telecomCallGetCallIds()
3312 new_call_ids = set(call_ids) - set(ad.call_ids)
3313 if not new_call_ids:
3314 ad.log.error(
3315 "No new call ids are found after call establishment")
3316 ad.log.error("telecomCallGetCallIds returns %s",
3317 ad.droid.telecomCallGetCallIds())
3318 result = False
3319 for new_call_id in new_call_ids:
3320 first_call_ids.append(new_call_id)
3321 if not wait_for_in_call_active(ad, call_id=new_call_id):
3322 result = False
3323 else:
3324 ad.log.info("callProperties = %s",
3325 ad.droid.telecomCallGetProperties(new_call_id))
3326
3327 if not ad.droid.telecomCallGetAudioState():
3328 ad.log.error("Audio is not in call state")
3329 result = False
3330
3331 if call_func(log, ad):
3332 ad.log.info("Call is in %s state", call_func.__name__)
3333 else:
3334 ad.log.error("Call is not in %s state, voice in RAT %s",
3335 call_func.__name__,
3336 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3337 result = False
3338 if not result:
3339 if not call_waiting:
3340 set_call_waiting(log, ad_callee, enable=1)
3341 return False
3342
3343 time.sleep(3)
3344 if not call_waiting:
3345 if not initiate_call(
3346 log,
3347 ad_caller2,
3348 callee_number,
3349 incall_ui_display=incall_ui_display,
3350 video=video):
3351 ad_caller2.log.info("Initiate call failed.")
3352 if not call_waiting:
3353 set_call_waiting(log, ad_callee, enable=1)
3354 result = False
3355 return False
3356 else:
3357 ad_caller2.log.info("Caller 2 initate 2nd call successfully")
3358
3359 if not wait_and_answer_call_for_subscription(
3360 log,
3361 ad_callee,
3362 subid_callee,
3363 incoming_number=caller2_number,
3364 caller=ad_caller2,
3365 incall_ui_display=incall_ui_display,
3366 video_state=video_state):
3367 ad_callee.log.info(
3368 "Answering 2nd call fail due to call waiting deactivate.")
3369 else:
3370 ad_callee.log.error("Callee should not be able to answer the"
3371 " 2nd call due to call waiting deactivated.")
3372 if not call_waiting:
3373 set_call_waiting(log, ad_callee, enable=1)
3374 result = False
3375 return False
3376
3377 time.sleep(3)
3378 if not hangup_call(log, ad_caller2):
3379 ad_caller2.log.info("Failed to hang up the 2nd call")
3380 if not call_waiting:
3381 set_call_waiting(log, ad_callee, enable=1)
3382 result = False
3383 return False
3384
3385 else:
3386
3387 for ad in (ad_callee, ad_caller2):
3388 call_ids = ad.droid.telecomCallGetCallIds()
3389 setattr(ad, "call_ids", call_ids)
3390 if call_ids:
3391 ad.log.info("Current existing CallId %s before making the"
3392 " second call.", call_ids)
3393
3394 if not initiate_call(
3395 log,
3396 ad_caller2,
3397 callee_number,
3398 incall_ui_display=incall_ui_display,
3399 video=video):
3400 ad_caller2.log.info("Initiate 2nd call failed.")
3401 if not call_waiting:
3402 set_call_waiting(log, ad_callee, enable=1)
3403 result = False
3404 return False
3405 else:
3406 ad_caller2.log.info("Caller 2 initate 2nd call successfully")
3407
3408 if end_first_call_before_answering_second_call:
3409 try:
3410 if not wait_for_ringing_call_for_subscription(
3411 log,
3412 ad_callee,
3413 subid_callee,
3414 incoming_number=caller2_number,
3415 caller=ad_caller2,
3416 event_tracking_started=True):
3417 ad_callee.log.info(
3418 "2nd incoming call ringing check failed.")
3419 if not call_waiting:
3420 set_call_waiting(log, ad_callee, enable=1)
3421 return False
3422
3423 time.sleep(3)
3424
3425 ad_hangup.log.info("Disconnecting first call...")
3426 for call_id in first_call_ids:
3427 disconnect_call_by_id(log, ad_hangup, call_id)
3428 time.sleep(3)
3429
3430 ad_callee.log.info("Answering the 2nd ring call...")
3431 ad_callee.droid.telecomAcceptRingingCall(video_state)
3432
3433 if wait_for_call_offhook_for_subscription(
3434 log,
3435 ad_callee,
3436 subid_callee,
3437 event_tracking_started=True):
3438 ad_callee.log.info(
3439 "Callee answered the 2nd call successfully.")
3440 else:
3441 ad_callee.log.error("Could not answer the 2nd call.")
3442 if not call_waiting:
3443 set_call_waiting(log, ad_callee, enable=1)
3444 return False
3445 except Exception as e:
3446 log.error(e)
3447 if not call_waiting:
3448 set_call_waiting(log, ad_callee, enable=1)
3449 return False
3450
3451 else:
3452 if not wait_and_answer_call_for_subscription(
3453 log,
3454 ad_callee,
3455 subid_callee,
3456 incoming_number=caller2_number,
3457 caller=ad_caller2,
3458 incall_ui_display=incall_ui_display,
3459 video_state=video_state):
3460 ad_callee.log.error("Failed to answer 2nd call.")
3461 if not call_waiting:
3462 set_call_waiting(log, ad_callee, enable=1)
3463 result = False
3464 return False
3465 else:
3466 ad_callee.log.info(
3467 "Callee answered the 2nd call successfully.")
3468
3469 for ad, subid, call_func in zip(
3470 [ad_callee, ad_caller2],
3471 [subid_callee, subid_caller2],
3472 [verify_callee_func, verify_caller2_func]):
3473 call_ids = ad.droid.telecomCallGetCallIds()
3474 new_call_ids = set(call_ids) - set(ad.call_ids)
3475 if not new_call_ids:
3476 ad.log.error(
3477 "No new call ids are found after 2nd call establishment")
3478 ad.log.error("telecomCallGetCallIds returns %s",
3479 ad.droid.telecomCallGetCallIds())
3480 result = False
3481 for new_call_id in new_call_ids:
3482 if not wait_for_in_call_active(ad, call_id=new_call_id):
3483 result = False
3484 else:
3485 ad.log.info("callProperties = %s",
3486 ad.droid.telecomCallGetProperties(new_call_id))
3487
3488 if not ad.droid.telecomCallGetAudioState():
3489 ad.log.error("Audio is not in 2nd call state")
3490 result = False
3491
3492 if call_func(log, ad):
3493 ad.log.info("2nd call is in %s state", call_func.__name__)
3494 else:
3495 ad.log.error("2nd call is not in %s state, voice in RAT %s",
3496 call_func.__name__,
3497 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3498 result = False
3499 if not result:
3500 if not call_waiting:
3501 set_call_waiting(log, ad_callee, enable=1)
3502 return False
3503
3504 elapsed_time = 0
3505 while (elapsed_time < wait_time_in_call):
3506 CHECK_INTERVAL = min(CHECK_INTERVAL,
3507 wait_time_in_call - elapsed_time)
3508 time.sleep(CHECK_INTERVAL)
3509 elapsed_time += CHECK_INTERVAL
3510 time_message = "at <%s>/<%s> second." % (elapsed_time,
3511 wait_time_in_call)
3512
3513 if not end_first_call_before_answering_second_call or \
3514 not call_waiting:
3515 for ad, subid, call_func in [
3516 (ad_caller, subid_caller, verify_caller_func),
3517 (ad_callee, subid_callee, verify_callee_func)]:
3518 if not call_func(log, ad):
3519 ad.log.error(
3520 "The first call NOT in correct %s state at %s,"
3521 " voice in RAT %s",
3522 call_func.__name__, time_message,
3523 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3524 result = False
3525 else:
3526 ad.log.info("The first call in correct %s state at %s",
3527 call_func.__name__, time_message)
3528 if not ad.droid.telecomCallGetAudioState():
3529 ad.log.error(
3530 "The first call audio is not in call state at %s",
3531 time_message)
3532 result = False
3533 if not result:
3534 if not call_waiting:
3535 set_call_waiting(log, ad_callee, enable=1)
3536 return False
3537
3538 if call_waiting:
3539 for ad, call_func in [(ad_caller2, verify_caller2_func),
3540 (ad_callee, verify_callee_func)]:
3541 if not call_func(log, ad):
3542 ad.log.error(
3543 "The 2nd call NOT in correct %s state at %s,"
3544 " voice in RAT %s",
3545 call_func.__name__, time_message,
3546 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3547 result = False
3548 else:
3549 ad.log.info("The 2nd call in correct %s state at %s",
3550 call_func.__name__, time_message)
3551 if not ad.droid.telecomCallGetAudioState():
3552 ad.log.error(
3553 "The 2nd call audio is not in call state at %s",
3554 time_message)
3555 result = False
3556 if not result:
3557 if not call_waiting:
3558 set_call_waiting(log, ad_callee, enable=1)
3559 return False
3560
3561 if not end_first_call_before_answering_second_call or not call_waiting:
3562 ad_hangup.log.info("Hanging up the first call...")
3563 for call_id in first_call_ids:
3564 disconnect_call_by_id(log, ad_hangup, call_id)
3565 time.sleep(5)
3566
3567 if ad_hangup2 and call_waiting:
3568 if not hangup_call(log, ad_hangup2):
3569 ad_hangup2.log.info("Failed to hang up the 2nd call")
3570 if not call_waiting:
3571 set_call_waiting(log, ad_callee, enable=1)
3572 result = False
3573 return False
3574 finally:
3575 if not result:
3576 for ad in (ad_caller, ad_callee, ad_caller2):
3577 last_call_drop_reason(ad, begin_time)
3578 try:
3579 if ad.droid.telecomIsInCall():
3580 ad.log.info("In call. End now.")
3581 ad.droid.telecomEndCall()
3582 except Exception as e:
3583 log.error(str(e))
3584
3585 if ad_hangup or not result:
3586 for ad in (ad_caller, ad_callee):
3587 if not wait_for_call_id_clearing(
3588 ad, getattr(ad, "caller_ids", [])):
3589 result = False
3590
3591 if call_waiting:
3592 if ad_hangup2 or not result:
3593 for ad in (ad_caller2, ad_callee):
3594 if not wait_for_call_id_clearing(
3595 ad, getattr(ad, "caller_ids", [])):
3596 result = False
3597 if not call_waiting:
3598 set_call_waiting(log, ad_callee, enable=1)
3599 return result
3600
Pratik Sheth68e4eba2021-03-23 17:10:13 -07003601
Betty Zhoue7cc3672018-04-26 16:58:56 -07003602def wait_for_call_id_clearing(ad,
3603 previous_ids,
3604 timeout=MAX_WAIT_TIME_CALL_DROP):
Betty Zhoufe726dc2018-04-25 19:31:33 -07003605 while timeout > 0:
3606 new_call_ids = ad.droid.telecomCallGetCallIds()
Betty Zhou16e8e662018-05-08 18:26:18 -07003607 if len(new_call_ids) <= len(previous_ids):
Betty Zhoufe726dc2018-04-25 19:31:33 -07003608 return True
3609 time.sleep(5)
3610 timeout = timeout - 5
Betty Zhou16e8e662018-05-08 18:26:18 -07003611 ad.log.error("Call id clearing failed. Before: %s; After: %s",
3612 previous_ids, new_call_ids)
Betty Zhoufe726dc2018-04-25 19:31:33 -07003613 return False
3614
3615
Betty Zhou16e8e662018-05-08 18:26:18 -07003616def last_call_drop_reason(ad, begin_time=None):
3617 reasons = ad.search_logcat(
3618 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time)
Betty Zhou1113ed92018-06-07 16:40:59 -07003619 reason_string = ""
Betty Zhou16e8e662018-05-08 18:26:18 -07003620 if reasons:
3621 log_msg = "Logcat call drop reasons:"
Betty Zhou1113ed92018-06-07 16:40:59 -07003622 for reason in reasons:
3623 log_msg = "%s\n\t%s" % (log_msg, reason["log_message"])
3624 if "ril reason str" in reason["log_message"]:
3625 reason_string = reason["log_message"].split(":")[-1].strip()
Betty Zhou16e8e662018-05-08 18:26:18 -07003626 ad.log.info(log_msg)
3627 reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
3628 begin_time)
3629 if reasons:
3630 ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen")
3631 ad.log.info("last call dumpsys: %s",
3632 sorted(dumpsys_last_call_info(ad).items()))
Betty Zhou1113ed92018-06-07 16:40:59 -07003633 return reason_string
Betty Zhou16e8e662018-05-08 18:26:18 -07003634
3635
Betty Zhoua37acd32017-02-23 20:04:24 -08003636def phone_number_formatter(input_string, formatter=None):
Ang Li73697b32015-12-03 00:41:53 +00003637 """Get expected format of input phone number string.
3638
3639 Args:
3640 input_string: (string) input phone number.
3641 The input could be 10/11/12 digital, with or without " "/"-"/"."
Betty Zhoua37acd32017-02-23 20:04:24 -08003642 formatter: (int) expected format, this could be 7/10/11/12
3643 if formatter is 7: output string would be 7 digital number.
3644 if formatter is 10: output string would be 10 digital (standard) number.
3645 if formatter is 11: output string would be "1" + 10 digital number.
3646 if formatter is 12: output string would be "+1" + 10 digital number.
Ang Li73697b32015-12-03 00:41:53 +00003647
3648 Returns:
3649 If no error happen, return phone number in expected format.
3650 Else, return None.
3651 """
Betty Zhouddb361d2017-09-07 17:07:20 -07003652 if not input_string:
3653 return ""
Ang Li73697b32015-12-03 00:41:53 +00003654 # make sure input_string is 10 digital
3655 # Remove white spaces, dashes, dots
Betty Zhoue955be22017-04-12 17:28:05 -07003656 input_string = input_string.replace(" ", "").replace("-", "").replace(
Betty Zhou77aa5f52017-05-08 20:23:35 -07003657 ".", "").lstrip("0")
Betty Zhoua37acd32017-02-23 20:04:24 -08003658 if not formatter:
Nathan Haroldae6a0da2016-03-16 20:56:47 +00003659 return input_string
Ashutosh Rajmani Singha3259692019-07-15 16:24:02 -07003660 # Remove +81 and add 0 for Japan Carriers only.
3661 if (len(input_string) == 13 and input_string[0:3] == "+81"):
3662 input_string = "0" + input_string[3:]
Mark De Ruyter60b759e2019-07-17 16:04:16 -07003663 return input_string
Ang Li73697b32015-12-03 00:41:53 +00003664 # Remove "1" or "+1"from front
Betty Zhouee311052017-12-19 13:09:56 -08003665 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT
3666 and input_string[0] == "1"):
Ang Li73697b32015-12-03 00:41:53 +00003667 input_string = input_string[1:]
Betty Zhouee311052017-12-19 13:09:56 -08003668 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT
3669 and input_string[0:2] == "+1"):
Ang Li73697b32015-12-03 00:41:53 +00003670 input_string = input_string[2:]
Betty Zhouee311052017-12-19 13:09:56 -08003671 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT
3672 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT):
Ang Li73697b32015-12-03 00:41:53 +00003673 return input_string
3674 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
3675 return None
3676 # change input_string according to format
Betty Zhoua37acd32017-02-23 20:04:24 -08003677 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08003678 input_string = "+1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003679 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08003680 input_string = "1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003681 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00003682 input_string = input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003683 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00003684 input_string = input_string[3:]
3685 else:
3686 return None
3687 return input_string
3688
Nathan Harold123c9da2015-12-30 16:33:25 -08003689
Ang Li73697b32015-12-03 00:41:53 +00003690def get_internet_connection_type(log, ad):
3691 """Get current active connection type name.
3692
3693 Args:
3694 log: Log object.
3695 ad: Android Device Object.
3696 Returns:
3697 current active connection type name.
3698 """
3699 if not ad.droid.connectivityNetworkIsConnected():
3700 return 'none'
3701 return connection_type_from_type_string(
3702 ad.droid.connectivityNetworkGetActiveConnectionTypeName())
3703
Nathan Harold123c9da2015-12-30 16:33:25 -08003704
3705def verify_http_connection(log,
3706 ad,
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003707 url="https://www.google.com",
Betty Zhouf809c5c2017-03-21 14:55:59 -07003708 retry=5,
Betty Zhou32e403a2017-10-25 20:08:12 -07003709 retry_interval=15,
3710 expected_state=True):
Ang Li73697b32015-12-03 00:41:53 +00003711 """Make ping request and return status.
3712
3713 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07003714 log: log object
Ang Li73697b32015-12-03 00:41:53 +00003715 ad: Android Device Object.
3716 url: Optional. The ping request will be made to this URL.
3717 Default Value is "http://www.google.com/".
3718
3719 """
Betty Zhou03bd3f92018-06-06 17:37:56 -07003720 if not getattr(ad, "data_droid", None):
3721 ad.data_droid, ad.data_ed = ad.get_droid()
3722 ad.data_ed.start()
3723 else:
3724 try:
3725 if not ad.data_droid.is_live:
3726 ad.data_droid, ad.data_ed = ad.get_droid()
3727 ad.data_ed.start()
3728 except Exception:
3729 ad.log.info("Start new sl4a session for file download")
3730 ad.data_droid, ad.data_ed = ad.get_droid()
3731 ad.data_ed.start()
Nathan Harold123c9da2015-12-30 16:33:25 -08003732 for i in range(0, retry + 1):
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003733 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07003734 http_response = ad.data_droid.httpPing(url)
Betty Zhou3814cbc2018-06-11 19:39:36 -07003735 except Exception as e:
3736 ad.log.info("httpPing with %s", e)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003737 http_response = None
3738 if (expected_state and http_response) or (not expected_state
3739 and not http_response):
Betty Zhou8a53f0f2018-06-06 14:35:50 -07003740 ad.log.info("Http ping response for %s meet expected %s", url,
3741 expected_state)
Ang Li73697b32015-12-03 00:41:53 +00003742 return True
Betty Zhou32e403a2017-10-25 20:08:12 -07003743 if i < retry:
Betty Zhou32e403a2017-10-25 20:08:12 -07003744 time.sleep(retry_interval)
Betty Zhoue7cc3672018-04-26 16:58:56 -07003745 ad.log.error("Http ping to %s is %s after %s second, expecting %s", url,
3746 http_response, i * retry_interval, expected_state)
Ang Li73697b32015-12-03 00:41:53 +00003747 return False
3748
3749
Betty Zhoucea4b432017-07-20 18:29:24 -07003750def _generate_file_directory_and_file_name(url, out_path):
Betty Zhouccd171d2017-02-13 15:11:33 -08003751 file_name = url.split("/")[-1]
3752 if not out_path:
Betty Zhoucea4b432017-07-20 18:29:24 -07003753 file_directory = "/sdcard/Download/"
3754 elif not out_path.endswith("/"):
3755 file_directory, file_name = os.path.split(out_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003756 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003757 file_directory = out_path
3758 return file_directory, file_name
Betty Zhouccd171d2017-02-13 15:11:33 -08003759
3760
Betty Zhoucea4b432017-07-20 18:29:24 -07003761def _check_file_existance(ad, file_path, expected_file_size=None):
3762 """Check file existance by file_path. If expected_file_size
Betty Zhouccd171d2017-02-13 15:11:33 -08003763 is provided, then also check if the file meet the file size requirement.
3764 """
Girish Moturu2c21eb32017-05-25 14:37:55 +05303765 out = None
3766 try:
3767 out = ad.adb.shell('stat -c "%%s" %s' % file_path)
3768 except AdbError:
3769 pass
Betty Zhouccd171d2017-02-13 15:11:33 -08003770 # Handle some old version adb returns error message "No such" into std_out
Betty Zhouf17f0692017-06-28 13:10:31 -07003771 if out and "No such" not in out:
Betty Zhouccd171d2017-02-13 15:11:33 -08003772 if expected_file_size:
Betty Zhouf17f0692017-06-28 13:10:31 -07003773 file_size = int(out)
Betty Zhouccd171d2017-02-13 15:11:33 -08003774 if file_size >= expected_file_size:
Betty Zhoucea4b432017-07-20 18:29:24 -07003775 ad.log.info("File %s of size %s exists", file_path, file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08003776 return True
3777 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003778 ad.log.info("File %s is of size %s, does not meet expected %s",
3779 file_path, file_size, expected_file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08003780 return False
3781 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003782 ad.log.info("File %s exists", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003783 return True
3784 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003785 ad.log.info("File %s does not exist.", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003786 return False
3787
3788
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003789def check_curl_availability(ad):
Betty Zhouf3b7d252017-07-19 17:51:06 -07003790 if not hasattr(ad, "curl_capable"):
3791 try:
Jaineel3ee37012017-08-21 15:21:57 -07003792 out = ad.adb.shell("/data/curl --version")
Betty Zhouf3b7d252017-07-19 17:51:06 -07003793 if not out or "not found" in out:
3794 setattr(ad, "curl_capable", False)
3795 ad.log.info("curl is unavailable, use chrome to download file")
3796 else:
3797 setattr(ad, "curl_capable", True)
3798 except Exception:
3799 setattr(ad, "curl_capable", False)
3800 ad.log.info("curl is unavailable, use chrome to download file")
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003801 return ad.curl_capable
Betty Zhouf3b7d252017-07-19 17:51:06 -07003802
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003803
Betty Zhou71a97672018-06-19 12:54:08 -07003804def start_youtube_video(ad, url="https://www.youtube.com/watch?v=pSJoP0LR8CQ"):
Betty Zhouf50cab32018-03-05 19:18:15 -08003805 ad.log.info("Open an youtube video")
Markus Liu035648e2019-09-19 18:32:53 +08003806 for _ in range(3):
3807 ad.ensure_screen_on()
Betty Zhou71a97672018-06-19 12:54:08 -07003808 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
3809 if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
3810 ad.log.info("Started a video in youtube, audio is in MUSIC state")
3811 return True
Markus Liu035648e2019-09-19 18:32:53 +08003812 ad.log.info("Audio is not in MUSIC state. Quit Youtube.")
3813 for _ in range(3):
3814 ad.send_keycode("BACK")
3815 time.sleep(1)
3816 time.sleep(3)
3817 return False
Betty Zhouf50cab32018-03-05 19:18:15 -08003818
3819
Betty Zhou3b2de072018-03-15 16:46:26 -07003820def active_file_download_task(log, ad, file_name="5MB", method="curl"):
Betty Zhou86671922017-05-10 15:32:10 -07003821 # files available for download on the same website:
3822 # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
3823 # download file by adb command, as phone call will use sl4a
Betty Zhou5ee8e042018-06-05 20:34:12 -07003824 file_size_map = {
Jaineeld5f43e02020-02-27 11:35:19 -08003825 '1MB': 1000000,
Betty Zhou86671922017-05-10 15:32:10 -07003826 '5MB': 5000000,
3827 '10MB': 10000000,
3828 '20MB': 20000000,
3829 '50MB': 50000000,
Betty Zhou461f3102017-08-04 17:04:44 -07003830 '100MB': 100000000,
Betty Zhou86671922017-05-10 15:32:10 -07003831 '200MB': 200000000,
Betty Zhou461f3102017-08-04 17:04:44 -07003832 '512MB': 512000000
Betty Zhou86671922017-05-10 15:32:10 -07003833 }
Betty Zhou5ee8e042018-06-05 20:34:12 -07003834 url_map = {
Jaineeld5f43e02020-02-27 11:35:19 -08003835 "1MB": [
Jaineel33a11932020-07-31 17:37:03 -07003836 "http://146.148.91.8/download/1MB.zip",
Jaineeld5f43e02020-02-27 11:35:19 -08003837 "http://ipv4.download.thinkbroadband.com/1MB.zip"
3838 ],
Betty Zhou5ee8e042018-06-05 20:34:12 -07003839 "5MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003840 "http://146.148.91.8/download/5MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003841 "http://212.183.159.230/5MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003842 "http://ipv4.download.thinkbroadband.com/5MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003843 ],
3844 "10MB": [
Betty Zhou5ee8e042018-06-05 20:34:12 -07003845 "http://146.148.91.8/download/10MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003846 "http://212.183.159.230/10MB.zip",
3847 "http://ipv4.download.thinkbroadband.com/10MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003848 "http://lax.futurehosting.com/test.zip",
3849 "http://ovh.net/files/10Mio.dat"
3850 ],
3851 "20MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003852 "http://146.148.91.8/download/20MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003853 "http://212.183.159.230/20MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003854 "http://ipv4.download.thinkbroadband.com/20MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003855 ],
3856 "50MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003857 "http://146.148.91.8/download/50MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003858 "http://212.183.159.230/50MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003859 "http://ipv4.download.thinkbroadband.com/50MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003860 ],
3861 "100MB": [
Betty Zhou5ee8e042018-06-05 20:34:12 -07003862 "http://146.148.91.8/download/100MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003863 "http://212.183.159.230/100MB.zip",
3864 "http://ipv4.download.thinkbroadband.com/100MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003865 "http://speedtest-ca.turnkeyinternet.net/100mb.bin",
3866 "http://ovh.net/files/100Mio.dat",
3867 "http://lax.futurehosting.com/test100.zip"
3868 ],
3869 "200MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003870 "http://146.148.91.8/download/200MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003871 "http://212.183.159.230/200MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003872 "http://ipv4.download.thinkbroadband.com/200MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003873 ],
3874 "512MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003875 "http://146.148.91.8/download/512MB.zip",
Betty Zhouf0577582018-06-06 11:34:52 -07003876 "http://212.183.159.230/512MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003877 "http://ipv4.download.thinkbroadband.com/512MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003878 ]
3879 }
3880
3881 file_size = file_size_map.get(file_name)
3882 file_urls = url_map.get(file_name)
3883 file_url = None
3884 for url in file_urls:
3885 url_splits = url.split("/")
3886 if verify_http_connection(log, ad, url=url, retry=1):
3887 output_path = "/sdcard/Download/%s" % url_splits[-1]
3888 file_url = url
3889 break
3890 if not file_url:
Betty Zhou4d97af82018-06-07 14:05:52 -07003891 ad.log.error("No url is available to download %s", file_name)
Betty Zhou86671922017-05-10 15:32:10 -07003892 return False
Jaineel5719eb52017-09-12 12:57:07 -07003893 timeout = min(max(file_size / 100000, 600), 3600)
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003894 if method == "sl4a":
Betty Zhou5ee8e042018-06-05 20:34:12 -07003895 return (http_file_download_by_sl4a, (ad, file_url, output_path,
3896 file_size, True, timeout))
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003897 if method == "curl" and check_curl_availability(ad):
Betty Zhou5ee8e042018-06-05 20:34:12 -07003898 return (http_file_download_by_curl, (ad, file_url, output_path,
3899 file_size, True, timeout))
Betty Zhou65666862018-06-05 13:51:48 -07003900 elif method == "sl4a" or method == "curl":
Betty Zhou5ee8e042018-06-05 20:34:12 -07003901 return (http_file_download_by_sl4a, (ad, file_url, output_path,
3902 file_size, True, timeout))
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003903 else:
Betty Zhou5ee8e042018-06-05 20:34:12 -07003904 return (http_file_download_by_chrome, (ad, file_url, file_size, True,
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003905 timeout))
Betty Zhou2e01bc82017-03-17 10:55:57 -07003906
3907
Betty Zhoua3f248f2018-03-05 17:33:49 -08003908def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003909 task = active_file_download_task(log, ad, file_name, method=method)
Betty Zhouf0577582018-06-06 11:34:52 -07003910 if not task:
3911 return False
Betty Zhou2e01bc82017-03-17 10:55:57 -07003912 return task[0](*task[1])
3913
3914
Betty Zhou8aafcc12018-05-01 20:54:15 -07003915def verify_internet_connection_by_ping(log,
3916 ad,
3917 retries=1,
3918 expected_state=True,
3919 timeout=60):
Betty Zhou8e11e442017-03-30 20:00:34 -07003920 """Verify internet connection by ping test.
3921
3922 Args:
3923 log: log object
3924 ad: Android Device Object.
3925
3926 """
Betty Zhou8aafcc12018-05-01 20:54:15 -07003927 begin_time = get_current_epoch_time()
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003928 ip_addr = "54.230.144.105"
3929 for dest in ("www.google.com", "www.amazon.com", ip_addr):
3930 for i in range(retries):
3931 ad.log.info("Ping %s - attempt %d", dest, i + 1)
Jaineel6d747722017-11-20 15:03:02 -08003932 result = adb_shell_ping(
Betty Zhou8aafcc12018-05-01 20:54:15 -07003933 ad, count=5, timeout=timeout, loss_tolerance=40, dest_ip=dest)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003934 if result == expected_state:
3935 ad.log.info(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003936 "Internet connection by pinging to %s is %s as expected",
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003937 dest, expected_state)
3938 if dest == ip_addr:
3939 ad.log.warning("Suspect dns failure")
3940 ad.log.info("DNS config: %s",
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003941 ad.adb.shell("getprop | grep dns").replace(
3942 "\n", " "))
3943 return False
Jaineel6d747722017-11-20 15:03:02 -08003944 return True
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003945 else:
Betty Zhou8aafcc12018-05-01 20:54:15 -07003946 ad.log.warning(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003947 "Internet connection test by pinging %s is %s, expecting %s",
3948 dest, result, expected_state)
Betty Zhou8aafcc12018-05-01 20:54:15 -07003949 if get_current_epoch_time() - begin_time < timeout * 1000:
3950 time.sleep(5)
3951 ad.log.error("Ping test doesn't meet expected %s", expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003952 return False
3953
3954
3955def verify_internet_connection(log, ad, retries=3, expected_state=True):
3956 """Verify internet connection by ping test and http connection.
3957
3958 Args:
3959 log: log object
3960 ad: Android Device Object.
3961
3962 """
Betty Zhoub707ef22018-05-14 16:47:05 -07003963 if ad.droid.connectivityNetworkIsConnected() != expected_state:
3964 ad.log.info("NetworkIsConnected = %s, expecting %s",
3965 not expected_state, expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003966 if verify_internet_connection_by_ping(
3967 log, ad, retries=retries, expected_state=expected_state):
3968 return True
3969 for url in ("https://www.google.com", "https://www.amazon.com"):
3970 if verify_http_connection(
3971 log, ad, url=url, retry=retries,
3972 expected_state=expected_state):
3973 return True
Betty Zhoue123c672018-03-21 19:57:11 -07003974 ad.log.info("DNS config: %s", " ".join(
3975 ad.adb.shell("getprop | grep dns").split()))
Betty Zhoufe726dc2018-04-25 19:31:33 -07003976 ad.log.info("Interface info:\n%s", ad.adb.shell("ifconfig"))
Betty Zhoue123c672018-03-21 19:57:11 -07003977 ad.log.info("NetworkAgentInfo: %s",
3978 ad.adb.shell("dumpsys connectivity | grep NetworkAgentInfo"))
Jaineel6c576c92017-09-11 10:02:23 -07003979 return False
Betty Zhou8e11e442017-03-30 20:00:34 -07003980
3981
monikermine61898b92019-10-31 17:21:16 -07003982def iperf_test_with_options(log,
3983 ad,
3984 iperf_server,
3985 iperf_option,
3986 timeout=180,
3987 rate_dict=None,
3988 blocking=True,
3989 log_file_path=None):
Jaineel4d87e242021-01-21 13:28:30 -08003990 """iperf adb run helper.
monikermine61898b92019-10-31 17:21:16 -07003991
3992 Args:
3993 log: log object
3994 ad: Android Device Object.
3995 iperf_server: The iperf host url".
3996 iperf_option: The options to pass to iperf client
3997 timeout: timeout for file download to complete.
3998 rate_dict: dictionary that can be passed in to save data
3999 blocking: run iperf in blocking mode if True
4000 log_file_path: location to save logs
4001 Returns:
Jaineel4d87e242021-01-21 13:28:30 -08004002 True if iperf runs without throwing an exception
monikermine61898b92019-10-31 17:21:16 -07004003 """
4004 try:
4005 if log_file_path:
4006 ad.adb.shell("rm %s" % log_file_path, ignore_status=True)
4007 ad.log.info("Running adb iperf test with server %s", iperf_server)
Jaineel4d87e242021-01-21 13:28:30 -08004008 ad.log.info("iperf options are %s", iperf_option)
monikermine61898b92019-10-31 17:21:16 -07004009 if not blocking:
4010 ad.run_iperf_client_nb(
4011 iperf_server,
4012 iperf_option,
4013 timeout=timeout + 60,
4014 log_file_path=log_file_path)
4015 return True
4016 result, data = ad.run_iperf_client(
4017 iperf_server, iperf_option, timeout=timeout + 60)
Jaineel4d87e242021-01-21 13:28:30 -08004018 ad.log.info("iperf test result with server %s is %s", iperf_server,
monikermine61898b92019-10-31 17:21:16 -07004019 result)
4020 if result:
4021 iperf_str = ''.join(data)
Jaineel4d87e242021-01-21 13:28:30 -08004022 iperf_result = ipf.IPerfResult(iperf_str, 'None')
monikermine61898b92019-10-31 17:21:16 -07004023 if "-u" in iperf_option:
4024 udp_rate = iperf_result.avg_rate
4025 if udp_rate is None:
4026 ad.log.warning(
4027 "UDP rate is none, IPerf server returned error: %s",
4028 iperf_result.error)
Jaineel4d87e242021-01-21 13:28:30 -08004029 ad.log.info("iperf3 UDP DL speed is %.6s Mbps", (udp_rate/1000000))
monikermine61898b92019-10-31 17:21:16 -07004030 else:
4031 tx_rate = iperf_result.avg_send_rate
4032 rx_rate = iperf_result.avg_receive_rate
4033 if (tx_rate or rx_rate) is None:
4034 ad.log.warning(
Jaineel4d87e242021-01-21 13:28:30 -08004035 "A TCP rate is none, iperf server returned error: %s",
monikermine61898b92019-10-31 17:21:16 -07004036 iperf_result.error)
4037 ad.log.info(
Jaineel4d87e242021-01-21 13:28:30 -08004038 "iperf3 TCP - UL speed is %.6s Mbps, DL speed is %.6s Mbps",
4039 (tx_rate/1000000), (rx_rate/1000000))
monikermine61898b92019-10-31 17:21:16 -07004040 if rate_dict is not None:
4041 rate_dict["Uplink"] = tx_rate
4042 rate_dict["Downlink"] = rx_rate
4043 return result
4044 except AdbError as e:
4045 ad.log.warning("Fail to run iperf test with exception %s", e)
4046 raise
4047
4048
4049def iperf_udp_test_by_adb(log,
4050 ad,
4051 iperf_server,
4052 port_num=None,
4053 reverse=False,
4054 timeout=180,
4055 limit_rate=None,
Jaineel4d87e242021-01-21 13:28:30 -08004056 pacing_timer=None,
monikermine61898b92019-10-31 17:21:16 -07004057 omit=10,
4058 ipv6=False,
4059 rate_dict=None,
4060 blocking=True,
4061 log_file_path=None):
4062 """Iperf test by adb using UDP.
4063
4064 Args:
4065 log: log object
4066 ad: Android Device Object.
4067 iperf_Server: The iperf host url".
4068 port_num: TCP/UDP server port
4069 reverse: whether to test download instead of upload
4070 timeout: timeout for file download to complete.
4071 limit_rate: iperf bandwidth option. None by default
4072 omit: the omit option provided in iperf command.
4073 ipv6: whether to run the test as ipv6
4074 rate_dict: dictionary that can be passed in to save data
4075 blocking: run iperf in blocking mode if True
4076 log_file_path: location to save logs
4077 """
4078 iperf_option = "-u -i 1 -t %s -O %s -J" % (timeout, omit)
4079 if limit_rate:
4080 iperf_option += " -b %s" % limit_rate
Jaineel4d87e242021-01-21 13:28:30 -08004081 if pacing_timer:
4082 iperf_option += " --pacing-timer %s" % pacing_timer
monikermine61898b92019-10-31 17:21:16 -07004083 if port_num:
4084 iperf_option += " -p %s" % port_num
4085 if ipv6:
4086 iperf_option += " -6"
4087 if reverse:
4088 iperf_option += " -R"
4089 try:
4090 return iperf_test_with_options(log,
4091 ad,
4092 iperf_server,
4093 iperf_option,
4094 timeout,
4095 rate_dict,
4096 blocking,
4097 log_file_path)
4098 except AdbError:
4099 return False
4100
Pratik Sheth68e4eba2021-03-23 17:10:13 -07004101
Betty Zhou2e01bc82017-03-17 10:55:57 -07004102def iperf_test_by_adb(log,
4103 ad,
4104 iperf_server,
Jaineel6f88b5b2017-04-17 09:58:46 -07004105 port_num=None,
4106 reverse=False,
Betty Zhou2e01bc82017-03-17 10:55:57 -07004107 timeout=180,
Jaineel6f88b5b2017-04-17 09:58:46 -07004108 limit_rate=None,
Betty Zhou2e01bc82017-03-17 10:55:57 -07004109 omit=10,
Jaineele74e8e12017-05-08 15:59:42 -07004110 ipv6=False,
Patrick Chiang75b89862017-10-13 17:02:29 -07004111 rate_dict=None,
4112 blocking=True,
4113 log_file_path=None):
monikermine61898b92019-10-31 17:21:16 -07004114 """Iperf test by adb using TCP.
Betty Zhou2e01bc82017-03-17 10:55:57 -07004115
4116 Args:
4117 log: log object
4118 ad: Android Device Object.
monikermine61898b92019-10-31 17:21:16 -07004119 iperf_server: The iperf host url".
Jaineel6f88b5b2017-04-17 09:58:46 -07004120 port_num: TCP/UDP server port
monikermine61898b92019-10-31 17:21:16 -07004121 reverse: whether to test download instead of upload
Betty Zhou2e01bc82017-03-17 10:55:57 -07004122 timeout: timeout for file download to complete.
4123 limit_rate: iperf bandwidth option. None by default
4124 omit: the omit option provided in iperf command.
monikermine61898b92019-10-31 17:21:16 -07004125 ipv6: whether to run the test as ipv6
4126 rate_dict: dictionary that can be passed in to save data
4127 blocking: run iperf in blocking mode if True
4128 log_file_path: location to save logs
Betty Zhou2e01bc82017-03-17 10:55:57 -07004129 """
4130 iperf_option = "-t %s -O %s -J" % (timeout, omit)
monikermine61898b92019-10-31 17:21:16 -07004131 if limit_rate:
4132 iperf_option += " -b %s" % limit_rate
4133 if port_num:
4134 iperf_option += " -p %s" % port_num
4135 if ipv6:
4136 iperf_option += " -6"
4137 if reverse:
4138 iperf_option += " -R"
Betty Zhou2e01bc82017-03-17 10:55:57 -07004139 try:
monikermine61898b92019-10-31 17:21:16 -07004140 return iperf_test_with_options(log,
4141 ad,
4142 iperf_server,
4143 iperf_option,
4144 timeout,
4145 rate_dict,
4146 blocking,
4147 log_file_path)
4148 except AdbError:
Betty Zhou2e01bc82017-03-17 10:55:57 -07004149 return False
4150
Betty Zhoue955be22017-04-12 17:28:05 -07004151
Betty Zhou86671922017-05-10 15:32:10 -07004152def http_file_download_by_curl(ad,
4153 url,
4154 out_path=None,
4155 expected_file_size=None,
4156 remove_file_after_check=True,
Betty Zhou35ea5952017-06-26 10:01:09 -07004157 timeout=3600,
Betty Zhou86671922017-05-10 15:32:10 -07004158 limit_rate=None,
4159 retry=3):
Betty Zhouccd171d2017-02-13 15:11:33 -08004160 """Download http file by adb curl.
4161
4162 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08004163 ad: Android Device Object.
4164 url: The url that file to be downloaded from".
4165 out_path: Optional. Where to download file to.
4166 out_path is /sdcard/Download/ by default.
4167 expected_file_size: Optional. Provided if checking the download file meet
4168 expected file size in unit of byte.
4169 remove_file_after_check: Whether to remove the downloaded file after
4170 check.
4171 timeout: timeout for file download to complete.
4172 limit_rate: download rate in bps. None, if do not apply rate limit.
4173 retry: the retry request times provided in curl command.
4174 """
Betty Zhoucea4b432017-07-20 18:29:24 -07004175 file_directory, file_name = _generate_file_directory_and_file_name(
4176 url, out_path)
4177 file_path = os.path.join(file_directory, file_name)
Jaineel3ee37012017-08-21 15:21:57 -07004178 curl_cmd = "/data/curl"
Betty Zhouccd171d2017-02-13 15:11:33 -08004179 if limit_rate:
4180 curl_cmd += " --limit-rate %s" % limit_rate
4181 if retry:
4182 curl_cmd += " --retry %s" % retry
Betty Zhoucea4b432017-07-20 18:29:24 -07004183 curl_cmd += " --url %s > %s" % (url, file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08004184 try:
Betty Zhoucea4b432017-07-20 18:29:24 -07004185 ad.log.info("Download %s to %s by adb shell command %s", url,
4186 file_path, curl_cmd)
Jaineel667e92d2018-09-11 14:47:15 -07004187
Betty Zhouccd171d2017-02-13 15:11:33 -08004188 ad.adb.shell(curl_cmd, timeout=timeout)
Betty Zhoucea4b432017-07-20 18:29:24 -07004189 if _check_file_existance(ad, file_path, expected_file_size):
4190 ad.log.info("%s is downloaded to %s successfully", url, file_path)
Jaineel667e92d2018-09-11 14:47:15 -07004191 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08004192 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004193 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004194 return False
4195 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07004196 ad.log.warning("Download %s failed with exception %s", url, e)
Betty Zhouccd171d2017-02-13 15:11:33 -08004197 return False
4198 finally:
4199 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004200 ad.log.info("Remove the downloaded file %s", file_path)
4201 ad.adb.shell("rm %s" % file_path, ignore_status=True)
4202
4203
4204def open_url_by_adb(ad, url):
Betty Zhou8da03782017-07-28 18:02:24 -07004205 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004206
4207
Betty Zhou86671922017-05-10 15:32:10 -07004208def http_file_download_by_chrome(ad,
4209 url,
4210 expected_file_size=None,
4211 remove_file_after_check=True,
Betty Zhou35ea5952017-06-26 10:01:09 -07004212 timeout=3600):
Betty Zhou86671922017-05-10 15:32:10 -07004213 """Download http file by chrome.
4214
4215 Args:
4216 ad: Android Device Object.
4217 url: The url that file to be downloaded from".
Betty Zhou86671922017-05-10 15:32:10 -07004218 expected_file_size: Optional. Provided if checking the download file meet
4219 expected file size in unit of byte.
4220 remove_file_after_check: Whether to remove the downloaded file after
4221 check.
4222 timeout: timeout for file download to complete.
4223 """
Betty Zhou92437702018-02-07 19:49:07 -08004224 chrome_apk = "com.android.chrome"
Betty Zhoucea4b432017-07-20 18:29:24 -07004225 file_directory, file_name = _generate_file_directory_and_file_name(
Betty Zhoubcffe442017-07-05 17:27:55 -07004226 url, "/sdcard/Download/")
Betty Zhoucea4b432017-07-20 18:29:24 -07004227 file_path = os.path.join(file_directory, file_name)
Betty Zhouf17f0692017-06-28 13:10:31 -07004228 # Remove pre-existing file
Betty Zhou92437702018-02-07 19:49:07 -08004229 ad.force_stop_apk(chrome_apk)
markdr6607bf12018-01-02 14:45:38 -08004230 file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
Betty Zhoue5f61b32018-01-26 10:48:00 -08004231 ad.adb.shell("rm -f %s" % file_to_be_delete)
4232 ad.adb.shell("rm -rf /sdcard/Download/.*")
4233 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou92437702018-02-07 19:49:07 -08004234 data_accounting = {
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004235 "total_rx_bytes": ad.droid.getTotalRxBytes(),
4236 "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
4237 "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
4238 "chrome_mobile_data_usage": get_mobile_data_usage(
4239 ad, None, chrome_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08004240 }
Jaineelf8be1892019-04-04 18:19:45 -07004241 ad.log.debug("Before downloading: %s", data_accounting)
Betty Zhoucea4b432017-07-20 18:29:24 -07004242 ad.log.info("Download %s with timeout %s", url, timeout)
Betty Zhouc80af152018-04-27 18:22:17 -07004243 ad.ensure_screen_on()
Betty Zhoucea4b432017-07-20 18:29:24 -07004244 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07004245 elapse_time = 0
Betty Zhou92437702018-02-07 19:49:07 -08004246 result = True
Betty Zhou86671922017-05-10 15:32:10 -07004247 while elapse_time < timeout:
4248 time.sleep(30)
Betty Zhoucea4b432017-07-20 18:29:24 -07004249 if _check_file_existance(ad, file_path, expected_file_size):
4250 ad.log.info("%s is downloaded successfully", url)
Betty Zhou86671922017-05-10 15:32:10 -07004251 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004252 ad.log.info("Remove the downloaded file %s", file_path)
Betty Zhoue5f61b32018-01-26 10:48:00 -08004253 ad.adb.shell("rm -f %s" % file_to_be_delete)
4254 ad.adb.shell("rm -rf /sdcard/Download/.*")
4255 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou08c1a572018-02-13 20:07:55 -08004256 #time.sleep(30)
Betty Zhou92437702018-02-07 19:49:07 -08004257 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004258 "mobile_rx_bytes":
4259 ad.droid.getMobileRxBytes(),
4260 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004261 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004262 "chrome_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004263 get_mobile_data_usage(ad, None, chrome_apk)
Betty Zhou92437702018-02-07 19:49:07 -08004264 }
4265 ad.log.info("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08004266 accounting_diff = {
4267 key: value - data_accounting[key]
4268 for key, value in new_data_accounting.items()
4269 }
Jaineelf8be1892019-04-04 18:19:45 -07004270 ad.log.debug("Data accounting difference: %s", accounting_diff)
Betty Zhou1b302fd2017-11-17 11:43:09 -08004271 if getattr(ad, "on_mobile_data", False):
Betty Zhou92437702018-02-07 19:49:07 -08004272 for key, value in accounting_diff.items():
4273 if value < expected_file_size:
Betty Zhou02571f52018-02-16 14:11:16 -08004274 ad.log.warning("%s diff is %s less than %s", key,
4275 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08004276 ad.data_accounting["%s_failure" % key] += 1
Betty Zhou1b302fd2017-11-17 11:43:09 -08004277 else:
Betty Zhou92437702018-02-07 19:49:07 -08004278 for key, value in accounting_diff.items():
4279 if value >= expected_file_size:
4280 ad.log.error("%s diff is %s. File download is "
4281 "consuming mobile data", key, value)
4282 result = False
4283 return result
Betty Zhoucea4b432017-07-20 18:29:24 -07004284 elif _check_file_existance(ad, "%s.crdownload" % file_path):
4285 ad.log.info("Chrome is downloading %s", url)
4286 elif elapse_time < 60:
4287 # download not started, retry download wit chrome again
4288 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07004289 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004290 ad.log.error("Unable to download file from %s", url)
4291 break
4292 elapse_time += 30
Betty Zhouf3366012017-11-21 18:23:20 -08004293 ad.log.warning("Fail to download file from %s", url)
Betty Zhou95ed1862017-07-21 13:29:02 -07004294 ad.force_stop_apk("com.android.chrome")
Betty Zhoue5f61b32018-01-26 10:48:00 -08004295 ad.adb.shell("rm -f %s" % file_to_be_delete)
4296 ad.adb.shell("rm -rf /sdcard/Download/.*")
4297 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou86671922017-05-10 15:32:10 -07004298 return False
4299
4300
Betty Zhou92437702018-02-07 19:49:07 -08004301def http_file_download_by_sl4a(ad,
Betty Zhouccd171d2017-02-13 15:11:33 -08004302 url,
4303 out_path=None,
4304 expected_file_size=None,
4305 remove_file_after_check=True,
4306 timeout=300):
4307 """Download http file by sl4a RPC call.
4308
4309 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08004310 ad: Android Device Object.
4311 url: The url that file to be downloaded from".
4312 out_path: Optional. Where to download file to.
4313 out_path is /sdcard/Download/ by default.
4314 expected_file_size: Optional. Provided if checking the download file meet
4315 expected file size in unit of byte.
4316 remove_file_after_check: Whether to remove the downloaded file after
4317 check.
4318 timeout: timeout for file download to complete.
4319 """
Betty Zhouee311052017-12-19 13:09:56 -08004320 file_folder, file_name = _generate_file_directory_and_file_name(
4321 url, out_path)
Betty Zhoucea4b432017-07-20 18:29:24 -07004322 file_path = os.path.join(file_folder, file_name)
Betty Zhou08c1a572018-02-13 20:07:55 -08004323 ad.adb.shell("rm -f %s" % file_path)
Betty Zhou92437702018-02-07 19:49:07 -08004324 accounting_apk = SL4A_APK_NAME
4325 result = True
Betty Zhouccd171d2017-02-13 15:11:33 -08004326 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004327 if not getattr(ad, "data_droid", None):
4328 ad.data_droid, ad.data_ed = ad.get_droid()
4329 ad.data_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08004330 else:
4331 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004332 if not ad.data_droid.is_live:
4333 ad.data_droid, ad.data_ed = ad.get_droid()
4334 ad.data_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08004335 except Exception:
4336 ad.log.info("Start new sl4a session for file download")
Betty Zhou03bd3f92018-06-06 17:37:56 -07004337 ad.data_droid, ad.data_ed = ad.get_droid()
4338 ad.data_ed.start()
Betty Zhou92437702018-02-07 19:49:07 -08004339 data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004340 "mobile_rx_bytes":
4341 ad.droid.getMobileRxBytes(),
4342 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004343 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004344 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004345 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08004346 }
Jaineelf8be1892019-04-04 18:19:45 -07004347 ad.log.debug("Before downloading: %s", data_accounting)
Betty Zhouccd171d2017-02-13 15:11:33 -08004348 ad.log.info("Download file from %s to %s by sl4a RPC call", url,
Betty Zhoucea4b432017-07-20 18:29:24 -07004349 file_path)
Betty Zhou14c08372018-02-15 10:26:23 -08004350 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004351 ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout)
Betty Zhou14c08372018-02-15 10:26:23 -08004352 except Exception as e:
4353 ad.log.warning("SL4A file download error: %s", e)
Betty Zhou03bd3f92018-06-06 17:37:56 -07004354 ad.data_droid.terminate()
Betty Zhou14c08372018-02-15 10:26:23 -08004355 return False
Betty Zhoucea4b432017-07-20 18:29:24 -07004356 if _check_file_existance(ad, file_path, expected_file_size):
4357 ad.log.info("%s is downloaded successfully", url)
Betty Zhou92437702018-02-07 19:49:07 -08004358 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004359 "mobile_rx_bytes":
4360 ad.droid.getMobileRxBytes(),
4361 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004362 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004363 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004364 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou92437702018-02-07 19:49:07 -08004365 }
Jaineelf8be1892019-04-04 18:19:45 -07004366 ad.log.debug("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08004367 accounting_diff = {
4368 key: value - data_accounting[key]
4369 for key, value in new_data_accounting.items()
4370 }
Jaineelf8be1892019-04-04 18:19:45 -07004371 ad.log.debug("Data accounting difference: %s", accounting_diff)
Betty Zhou92437702018-02-07 19:49:07 -08004372 if getattr(ad, "on_mobile_data", False):
4373 for key, value in accounting_diff.items():
4374 if value < expected_file_size:
Jaineelf8be1892019-04-04 18:19:45 -07004375 ad.log.debug("%s diff is %s less than %s", key,
Betty Zhou02571f52018-02-16 14:11:16 -08004376 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08004377 ad.data_accounting["%s_failure"] += 1
4378 else:
4379 for key, value in accounting_diff.items():
4380 if value >= expected_file_size:
4381 ad.log.error("%s diff is %s. File download is "
4382 "consuming mobile data", key, value)
4383 result = False
4384 return result
Betty Zhouccd171d2017-02-13 15:11:33 -08004385 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004386 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004387 return False
4388 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07004389 ad.log.error("Download %s failed with exception %s", url, e)
Betty Zhouccd171d2017-02-13 15:11:33 -08004390 raise
4391 finally:
4392 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004393 ad.log.info("Remove the downloaded file %s", file_path)
4394 ad.adb.shell("rm %s" % file_path, ignore_status=True)
Betty Zhouccd171d2017-02-13 15:11:33 -08004395
Betty Zhou2cf788e2017-06-27 17:25:53 -07004396
Markus Liu1acb5922020-01-02 18:21:46 +08004397def get_wifi_usage(ad, sid=None, apk=None):
4398 if not sid:
4399 sid = ad.droid.subscriptionGetDefaultDataSubId()
4400 current_time = int(time.time() * 1000)
4401 begin_time = current_time - 10 * 24 * 60 * 60 * 1000
4402 end_time = current_time + 10 * 24 * 60 * 60 * 1000
4403
4404 if apk:
4405 uid = ad.get_apk_uid(apk)
4406 ad.log.debug("apk %s uid = %s", apk, uid)
4407 try:
4408 return ad.droid.connectivityQueryDetailsForUid(
4409 TYPE_WIFI,
4410 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4411 begin_time, end_time, uid)
4412 except:
4413 return ad.droid.connectivityQueryDetailsForUid(
4414 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4415 begin_time, end_time, uid)
4416 else:
4417 try:
4418 return ad.droid.connectivityQuerySummaryForDevice(
4419 TYPE_WIFI,
4420 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4421 begin_time, end_time)
4422 except:
4423 return ad.droid.connectivityQuerySummaryForDevice(
4424 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4425 begin_time, end_time)
4426
4427
Betty Zhou65666862018-06-05 13:51:48 -07004428def get_mobile_data_usage(ad, sid=None, apk=None):
4429 if not sid:
Markus Liu05a05652019-08-01 17:30:47 +08004430 sid = ad.droid.subscriptionGetDefaultDataSubId()
Betty Zhou65666862018-06-05 13:51:48 -07004431 current_time = int(time.time() * 1000)
4432 begin_time = current_time - 10 * 24 * 60 * 60 * 1000
4433 end_time = current_time + 10 * 24 * 60 * 60 * 1000
Betty Zhoua3f248f2018-03-05 17:33:49 -08004434
Betty Zhou92437702018-02-07 19:49:07 -08004435 if apk:
4436 uid = ad.get_apk_uid(apk)
Jaineelf8be1892019-04-04 18:19:45 -07004437 ad.log.debug("apk %s uid = %s", apk, uid)
Betty Zhou92437702018-02-07 19:49:07 -08004438 try:
Betty Zhou65666862018-06-05 13:51:48 -07004439 usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid)
Jaineelf8be1892019-04-04 18:19:45 -07004440 ad.log.debug("Mobile data usage info for uid %s = %s", uid,
Betty Zhou65666862018-06-05 13:51:48 -07004441 usage_info)
4442 return usage_info["UsageLevel"]
4443 except:
4444 try:
4445 return ad.droid.connectivityQueryDetailsForUid(
4446 TYPE_MOBILE,
4447 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4448 begin_time, end_time, uid)
4449 except:
4450 return ad.droid.connectivityQueryDetailsForUid(
4451 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4452 begin_time, end_time, uid)
4453 else:
4454 try:
4455 usage_info = ad.droid.getMobileDataUsageInfo(sid)
Jaineelf8be1892019-04-04 18:19:45 -07004456 ad.log.debug("Mobile data usage info = %s", usage_info)
Betty Zhou65666862018-06-05 13:51:48 -07004457 return usage_info["UsageLevel"]
4458 except:
4459 try:
4460 return ad.droid.connectivityQuerySummaryForDevice(
4461 TYPE_MOBILE,
4462 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4463 begin_time, end_time)
4464 except:
4465 return ad.droid.connectivityQuerySummaryForDevice(
4466 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4467 begin_time, end_time)
Betty Zhouf3366012017-11-21 18:23:20 -08004468
4469
4470def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
4471 if not subscriber_id:
4472 subscriber_id = ad.droid.telephonyGetSubscriberId()
Jaineelf8be1892019-04-04 18:19:45 -07004473 ad.log.debug("Set subscriber mobile data usage limit to %s", limit)
Betty Zhou10f887e2018-04-10 12:45:00 -07004474 ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
Betty Zhou65666862018-06-05 13:51:48 -07004475 try:
4476 ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
4477 except:
4478 ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit)
Betty Zhouf3366012017-11-21 18:23:20 -08004479
4480
4481def remove_mobile_data_usage_limit(ad, subscriber_id=None):
4482 if not subscriber_id:
4483 subscriber_id = ad.droid.telephonyGetSubscriberId()
Betty Zhoue57ab692018-03-09 18:39:30 -08004484 ad.log.debug("Remove subscriber mobile data usage limit")
Betty Zhou10f887e2018-04-10 12:45:00 -07004485 ad.droid.logV(
4486 "Setting subscriber mobile data usage limit to -1, unlimited")
Betty Zhou65666862018-06-05 13:51:48 -07004487 try:
4488 ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
4489 except:
4490 ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1)
Betty Zhouf3366012017-11-21 18:23:20 -08004491
4492
Betty Zhouae9d6a82018-02-15 20:05:34 -08004493def trigger_modem_crash(ad, timeout=120):
Jaineel40884782017-06-08 15:53:39 -07004494 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem"
Betty Zhouae9d6a82018-02-15 20:05:34 -08004495 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd)
4496 ad.adb.shell(cmd)
4497 time.sleep(timeout)
Jaineel40884782017-06-08 15:53:39 -07004498 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08004499
Betty Zhou2cf788e2017-06-27 17:25:53 -07004500
Betty Zhouae9d6a82018-02-15 20:05:34 -08004501def trigger_modem_crash_by_modem(ad, timeout=120):
Betty Zhoued13b712018-05-02 19:40:10 -07004502 begin_time = get_device_epoch_time(ad)
Betty Zhouae9d6a82018-02-15 20:05:34 -08004503 ad.adb.shell(
Betty Zhouc8213812018-04-02 14:06:50 -07004504 "setprop persist.vendor.sys.modem.diag.mdlog false",
4505 ignore_status=True)
Jaekyun Seok7e8ba572018-03-19 12:31:31 +09004506 # Legacy pixels use persist.sys.modem.diag.mdlog.
4507 ad.adb.shell(
Betty Zhouae9d6a82018-02-15 20:05:34 -08004508 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
Betty Zhoud8630832018-06-06 18:58:02 -07004509 disable_qxdm_logger(ad)
Betty Zhou02571f52018-02-16 14:11:16 -08004510 cmd = ('am instrument -w -e request "4b 25 03 00" '
4511 '"com.google.mdstest/com.google.mdstest.instrument.'
4512 'ModemCommandInstrumentation"')
4513 ad.log.info("Crash modem by %s", cmd)
4514 ad.adb.shell(cmd, ignore_status=True)
4515 time.sleep(timeout) # sleep time for sl4a stability
Betty Zhouae9d6a82018-02-15 20:05:34 -08004516 reasons = ad.search_logcat("modem subsystem failure reason", begin_time)
4517 if reasons:
4518 ad.log.info("Modem crash is triggered successfully")
4519 ad.log.info(reasons[-1]["log_message"])
4520 return True
4521 else:
Betty Zhoufe726dc2018-04-25 19:31:33 -07004522 ad.log.warning("There is no modem subsystem failure reason logcat")
Betty Zhouae9d6a82018-02-15 20:05:34 -08004523 return False
4524
4525
Jaineelfc5a4e02019-02-12 15:31:44 -08004526def phone_switch_to_msim_mode(ad, retries=3, timeout=60):
4527 result = False
Jaineel15c50562019-03-29 15:45:32 -07004528 if not ad.is_apk_installed("com.google.mdstest"):
Xianyuan Jia821cf572019-10-08 12:24:00 -07004529 raise signals.TestAbortClass("mdstest is not installed")
Jaineel15c50562019-03-29 15:45:32 -07004530 mode = ad.droid.telephonyGetPhoneCount()
4531 if mode == 2:
4532 ad.log.info("Device already in MSIM mode")
4533 return True
Jaineelfc5a4e02019-02-12 15:31:44 -08004534 for i in range(retries):
4535 ad.adb.shell(
4536 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True)
4537 ad.adb.shell(
4538 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
4539 disable_qxdm_logger(ad)
4540 cmd = ('am instrument -w -e request "WriteEFS" -e item '
4541 '"/google/pixel_multisim_config" -e data "02 00 00 00" '
4542 '"com.google.mdstest/com.google.mdstest.instrument.'
4543 'ModemConfigInstrumentation"')
4544 ad.log.info("Switch to MSIM mode by using %s", cmd)
4545 ad.adb.shell(cmd, ignore_status=True)
4546 time.sleep(timeout)
4547 ad.adb.shell("setprop persist.radio.multisim.config dsds")
4548 reboot_device(ad)
4549 # Verify if device is really in msim mode
Jaineel15c50562019-03-29 15:45:32 -07004550 mode = ad.droid.telephonyGetPhoneCount()
4551 if mode == 2:
Jaineelfc5a4e02019-02-12 15:31:44 -08004552 ad.log.info("Device correctly switched to MSIM mode")
4553 result = True
Jaineel12cf1952019-06-14 13:15:45 -07004554 if "Sprint" in ad.adb.getprop("gsm.sim.operator.alpha"):
4555 cmd = ('am instrument -w -e request "WriteEFS" -e item '
4556 '"/google/pixel_dsds_imei_mapping_slot_record" -e data "03"'
4557 ' "com.google.mdstest/com.google.mdstest.instrument.'
4558 'ModemConfigInstrumentation"')
4559 ad.log.info("Switch Sprint to IMEI1 slot using %s", cmd)
4560 ad.adb.shell(cmd, ignore_status=True)
4561 time.sleep(timeout)
4562 reboot_device(ad)
Jaineelfc5a4e02019-02-12 15:31:44 -08004563 break
4564 else:
4565 ad.log.warning("Attempt %d - failed to switch to MSIM", (i + 1))
4566 return result
4567
4568
4569def phone_switch_to_ssim_mode(ad, retries=3, timeout=30):
4570 result = False
Jaineel15c50562019-03-29 15:45:32 -07004571 if not ad.is_apk_installed("com.google.mdstest"):
Xianyuan Jia821cf572019-10-08 12:24:00 -07004572 raise signals.TestAbortClass("mdstest is not installed")
Jaineel15c50562019-03-29 15:45:32 -07004573 mode = ad.droid.telephonyGetPhoneCount()
4574 if mode == 1:
4575 ad.log.info("Device already in SSIM mode")
4576 return True
Jaineelfc5a4e02019-02-12 15:31:44 -08004577 for i in range(retries):
4578 ad.adb.shell(
4579 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True)
4580 ad.adb.shell(
4581 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
4582 disable_qxdm_logger(ad)
4583 cmds = ('am instrument -w -e request "WriteEFS" -e item '
4584 '"/google/pixel_multisim_config" -e data "01 00 00 00" '
4585 '"com.google.mdstest/com.google.mdstest.instrument.'
4586 'ModemConfigInstrumentation"',
4587 'am instrument -w -e request "WriteEFS" -e item "/nv/item_files'
4588 '/modem/uim/uimdrv/uim_extended_slot_mapping_config" -e data '
4589 '"00 01 02 01" "com.google.mdstest/com.google.mdstest.'
4590 'instrument.ModemConfigInstrumentation"')
4591 for cmd in cmds:
4592 ad.log.info("Switch to SSIM mode by using %s", cmd)
4593 ad.adb.shell(cmd, ignore_status=True)
4594 time.sleep(timeout)
4595 ad.adb.shell("setprop persist.radio.multisim.config ssss")
4596 reboot_device(ad)
4597 # Verify if device is really in ssim mode
Jaineel15c50562019-03-29 15:45:32 -07004598 mode = ad.droid.telephonyGetPhoneCount()
4599 if mode == 1:
Jaineelfc5a4e02019-02-12 15:31:44 -08004600 ad.log.info("Device correctly switched to SSIM mode")
4601 result = True
4602 break
4603 else:
4604 ad.log.warning("Attempt %d - failed to switch to SSIM", (i + 1))
4605 return result
4606
4607
Betty Zhou4d97af82018-06-07 14:05:52 -07004608def lock_lte_band_by_mds(ad, band):
Betty Zhoud8630832018-06-06 18:58:02 -07004609 disable_qxdm_logger(ad)
4610 ad.log.info("Write band %s locking to efs file", band)
4611 if band == "4":
4612 item_string = (
4613 "4B 13 26 00 08 00 00 00 40 00 08 00 0B 00 08 00 00 00 00 00 00 00 "
4614 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D "
4615 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00")
4616 elif band == "13":
4617 item_string = (
4618 "4B 13 26 00 08 00 00 00 40 00 08 00 0A 00 00 10 00 00 00 00 00 00 "
4619 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D "
4620 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00")
Betty Zhou4d97af82018-06-07 14:05:52 -07004621 else:
4622 ad.log.error("Band %s is not supported", band)
4623 return False
Betty Zhoud8630832018-06-06 18:58:02 -07004624 cmd = ('am instrument -w -e request "%s" com.google.mdstest/com.google.'
4625 'mdstest.instrument.ModemCommandInstrumentation')
4626 for _ in range(3):
4627 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True):
4628 break
4629 else:
4630 ad.log.error("Fail to write band by %s" % (cmd % item_string))
4631 return False
4632
Betty Zhoud8630832018-06-06 18:58:02 -07004633 # EFS Sync
4634 item_string = "4B 13 30 00 2A 00 2F 00"
4635
4636 for _ in range(3):
4637 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True):
4638 break
4639 else:
4640 ad.log.error("Fail to sync efs by %s" % (cmd % item_string))
4641 return False
4642 time.sleep(5)
4643 reboot_device(ad)
4644
4645
Ang Li73697b32015-12-03 00:41:53 +00004646def _connection_state_change(_event, target_state, connection_type):
4647 if connection_type:
4648 if 'TypeName' not in _event['data']:
4649 return False
4650 connection_type_string_in_event = _event['data']['TypeName']
Nathan Harold123c9da2015-12-30 16:33:25 -08004651 cur_type = connection_type_from_type_string(
4652 connection_type_string_in_event)
Ang Li73697b32015-12-03 00:41:53 +00004653 if cur_type != connection_type:
4654 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08004655 "_connection_state_change expect: %s, received: %s <type %s>",
4656 connection_type, connection_type_string_in_event, cur_type)
Ang Li73697b32015-12-03 00:41:53 +00004657 return False
4658
Betty Zhouee311052017-12-19 13:09:56 -08004659 if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
Ang Li73697b32015-12-03 00:41:53 +00004660 return True
4661 return False
4662
4663
Nathan Harold123c9da2015-12-30 16:33:25 -08004664def wait_for_cell_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08004665 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004666 """Wait for data connection status to be expected value for default
4667 data subscription.
4668
4669 Wait for the data connection status to be DATA_STATE_CONNECTED
4670 or DATA_STATE_DISCONNECTED.
4671
4672 Args:
4673 log: Log object.
4674 ad: Android Device Object.
4675 state: Expected status: True or False.
4676 If True, it will wait for status to be DATA_STATE_CONNECTED.
4677 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4678 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004679 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004680
4681 Returns:
4682 True if success.
4683 False if failed.
4684 """
Yang Liu963c93c2016-04-05 10:52:00 -07004685 sub_id = get_default_data_sub_id(ad)
Betty Zhouee311052017-12-19 13:09:56 -08004686 return wait_for_cell_data_connection_for_subscription(
4687 log, ad, sub_id, state, timeout_value)
Nathan Harold123c9da2015-12-30 16:33:25 -08004688
Ang Li73697b32015-12-03 00:41:53 +00004689
4690def _is_data_connection_state_match(log, ad, expected_data_connection_state):
Nathan Harold123c9da2015-12-30 16:33:25 -08004691 return (expected_data_connection_state ==
4692 ad.droid.telephonyGetDataConnectionState())
Ang Li73697b32015-12-03 00:41:53 +00004693
Ang Li73697b32015-12-03 00:41:53 +00004694
Nathan Harold123c9da2015-12-30 16:33:25 -08004695def _is_network_connected_state_match(log, ad,
4696 expected_network_connected_state):
4697 return (expected_network_connected_state ==
4698 ad.droid.connectivityNetworkIsConnected())
4699
4700
4701def wait_for_cell_data_connection_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08004702 log,
4703 ad,
4704 sub_id,
4705 state,
4706 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004707 """Wait for data connection status to be expected value for specified
4708 subscrption id.
4709
4710 Wait for the data connection status to be DATA_STATE_CONNECTED
4711 or DATA_STATE_DISCONNECTED.
4712
4713 Args:
4714 log: Log object.
4715 ad: Android Device Object.
4716 sub_id: subscription Id
4717 state: Expected status: True or False.
4718 If True, it will wait for status to be DATA_STATE_CONNECTED.
4719 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4720 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004721 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004722
4723 Returns:
4724 True if success.
4725 False if failed.
4726 """
Yang Liu8e6adff2016-02-05 10:24:04 -08004727 state_str = {
4728 True: DATA_STATE_CONNECTED,
4729 False: DATA_STATE_DISCONNECTED
Ang Li73697b32015-12-03 00:41:53 +00004730 }[state]
4731
Betty Zhou68fc0d02017-04-26 13:42:54 -07004732 data_state = ad.droid.telephonyGetDataConnectionState()
4733 if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
4734 return True
Betty Zhouc9f723b2018-04-10 18:08:21 -07004735
Betty Zhou287f9df2018-01-23 10:57:55 -08004736 ad.ed.clear_events(EventDataConnectionStateChanged)
Nathan Harold123c9da2015-12-30 16:33:25 -08004737 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
4738 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004739 ad.droid.connectivityStartTrackingConnectivityStateChange()
4740 try:
Betty Zhouc9f723b2018-04-10 18:08:21 -07004741 ad.log.info("User data enabled for sub_id %s: %s", sub_id,
4742 ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
Yang Liuaed3eef2015-12-15 18:40:25 -08004743 data_state = ad.droid.telephonyGetDataConnectionState()
Betty Zhouc9f723b2018-04-10 18:08:21 -07004744 ad.log.info("Data connection state is %s", data_state)
4745 ad.log.info("Network is connected: %s",
4746 ad.droid.connectivityNetworkIsConnected())
Ang Li73697b32015-12-03 00:41:53 +00004747 if data_state == state_str:
Nathan Harold123c9da2015-12-30 16:33:25 -08004748 return _wait_for_nw_data_connection(
4749 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004750
4751 try:
Betty Zhou1c8c8d42018-03-14 12:43:50 -07004752 ad.ed.wait_for_event(
Nathan Harold7642fc92016-05-02 18:29:11 -07004753 EventDataConnectionStateChanged,
4754 is_event_match,
4755 timeout=timeout_value,
Yang Liu8e6adff2016-02-05 10:24:04 -08004756 field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
4757 value=state_str)
Ang Li73697b32015-12-03 00:41:53 +00004758 except Empty:
Betty Zhouf25ce442017-03-03 14:28:36 -08004759 ad.log.info("No expected event EventDataConnectionStateChanged %s",
4760 state_str)
Ang Li73697b32015-12-03 00:41:53 +00004761
Yang Liudf164e32016-01-07 16:49:32 -08004762 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00004763 # data connection state.
4764 # Otherwise, the network state will not be correct.
4765 # The bug is tracked here: b/20921915
Ang Li73697b32015-12-03 00:41:53 +00004766
Yang Liu7a2e7ee2015-12-28 15:32:44 -08004767 # Previously we use _is_data_connection_state_match,
4768 # but telephonyGetDataConnectionState sometimes return wrong value.
4769 # The bug is tracked here: b/22612607
4770 # So we use _is_network_connected_state_match.
Ang Li73697b32015-12-03 00:41:53 +00004771
Betty Zhou58ad52a2018-02-08 16:38:16 -08004772 if _wait_for_droid_in_state(log, ad, timeout_value,
Nathan Harold123c9da2015-12-30 16:33:25 -08004773 _is_network_connected_state_match, state):
4774 return _wait_for_nw_data_connection(
4775 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004776 else:
4777 return False
4778
4779 finally:
Nathan Harold123c9da2015-12-30 16:33:25 -08004780 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
4781 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004782
Nathan Harold123c9da2015-12-30 16:33:25 -08004783
4784def wait_for_wifi_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08004785 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004786 """Wait for data connection status to be expected value and connection is by WiFi.
4787
4788 Args:
4789 log: Log object.
4790 ad: Android Device Object.
4791 state: Expected status: True or False.
4792 If True, it will wait for status to be DATA_STATE_CONNECTED.
4793 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4794 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004795 This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
Ang Li73697b32015-12-03 00:41:53 +00004796
4797 Returns:
4798 True if success.
4799 False if failed.
4800 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004801 ad.log.info("wait_for_wifi_data_connection")
Nathan Harold123c9da2015-12-30 16:33:25 -08004802 return _wait_for_nw_data_connection(
4803 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004804
4805
Betty Zhou02571f52018-02-16 14:11:16 -08004806def wait_for_data_connection(
4807 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004808 """Wait for data connection status to be expected value.
4809
4810 Wait for the data connection status to be DATA_STATE_CONNECTED
4811 or DATA_STATE_DISCONNECTED.
4812
4813 Args:
4814 log: Log object.
4815 ad: Android Device Object.
4816 state: Expected status: True or False.
4817 If True, it will wait for status to be DATA_STATE_CONNECTED.
4818 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4819 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004820 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004821
4822 Returns:
4823 True if success.
4824 False if failed.
4825 """
4826 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
4827
4828
Nathan Harold123c9da2015-12-30 16:33:25 -08004829def _wait_for_nw_data_connection(
4830 log,
4831 ad,
4832 is_connected,
4833 connection_type=None,
Betty Zhou58ad52a2018-02-08 16:38:16 -08004834 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004835 """Wait for data connection status to be expected value.
4836
4837 Wait for the data connection status to be DATA_STATE_CONNECTED
4838 or DATA_STATE_DISCONNECTED.
4839
4840 Args:
4841 log: Log object.
4842 ad: Android Device Object.
4843 is_connected: Expected connection status: True or False.
4844 If True, it will wait for status to be DATA_STATE_CONNECTED.
4845 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4846 connection_type: expected connection type.
4847 This is optional, if it is None, then any connection type will return True.
4848 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004849 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004850
4851 Returns:
4852 True if success.
4853 False if failed.
4854 """
Betty Zhoue34f9e22018-01-23 18:58:24 -08004855 ad.ed.clear_events(EventConnectivityChanged)
Ang Li73697b32015-12-03 00:41:53 +00004856 ad.droid.connectivityStartTrackingConnectivityStateChange()
4857 try:
4858 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
4859 if is_connected == cur_data_connection_state:
4860 current_type = get_internet_connection_type(log, ad)
Betty Zhoue955be22017-04-12 17:28:05 -07004861 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00004862 if not connection_type:
4863 return True
4864 else:
4865 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004866 ad.log.info("data connection not on %s!", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004867 return True
4868 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004869 ad.log.info("data connection on %s as expected",
4870 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004871 return True
4872 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08004873 ad.log.info("current data connection state: %s target: %s",
4874 cur_data_connection_state, is_connected)
Ang Li73697b32015-12-03 00:41:53 +00004875
4876 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08004877 event = ad.ed.wait_for_event(
4878 EventConnectivityChanged, _connection_state_change,
4879 timeout_value, is_connected, connection_type)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07004880 ad.log.info("Got event: %s", event)
Ang Li73697b32015-12-03 00:41:53 +00004881 except Empty:
4882 pass
4883
Nathan Harold123c9da2015-12-30 16:33:25 -08004884 log.info(
4885 "_wait_for_nw_data_connection: check connection after wait event.")
Yang Liudf164e32016-01-07 16:49:32 -08004886 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00004887 # data connection state.
4888 # Otherwise, the network state will not be correct.
4889 # The bug is tracked here: b/20921915
Betty Zhou02571f52018-02-16 14:11:16 -08004890 if _wait_for_droid_in_state(log, ad, timeout_value,
4891 _is_network_connected_state_match,
4892 is_connected):
Ang Li73697b32015-12-03 00:41:53 +00004893 current_type = get_internet_connection_type(log, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08004894 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00004895 if not connection_type:
4896 return True
4897 else:
4898 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004899 ad.log.info("data connection not on %s", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004900 return True
4901 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004902 ad.log.info("after event wait, data connection on %s",
4903 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004904 return True
4905 else:
4906 return False
4907 else:
4908 return False
4909 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -08004910 ad.log.error("Exception error %s", str(e))
Ang Li73697b32015-12-03 00:41:53 +00004911 return False
4912 finally:
4913 ad.droid.connectivityStopTrackingConnectivityStateChange()
4914
Nathan Harold123c9da2015-12-30 16:33:25 -08004915
Betty Zhou2cf788e2017-06-27 17:25:53 -07004916def get_cell_data_roaming_state_by_adb(ad):
4917 """Get Cell Data Roaming state. True for enabled, False for disabled"""
Betty Zhou2cf788e2017-06-27 17:25:53 -07004918 state_mapping = {"1": True, "0": False}
4919 return state_mapping[ad.adb.shell("settings get global data_roaming")]
4920
4921
4922def set_cell_data_roaming_state_by_adb(ad, state):
4923 """Set Cell Data Roaming state."""
4924 state_mapping = {True: "1", False: "0"}
4925 ad.log.info("Set data roaming to %s", state)
4926 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state])
4927
4928
Betty Zhou9e2bf402017-02-01 19:04:09 -08004929def toggle_cell_data_roaming(ad, state):
4930 """Enable cell data roaming for default data subscription.
4931
4932 Wait for the data roaming status to be DATA_STATE_CONNECTED
4933 or DATA_STATE_DISCONNECTED.
4934
4935 Args:
4936 log: Log object.
4937 ad: Android Device Object.
4938 state: True or False for enable or disable cell data roaming.
4939
4940 Returns:
4941 True if success.
4942 False if failed.
4943 """
4944 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state]
4945 action_str = {True: "Enable", False: "Disable"}[state]
4946 if ad.droid.connectivityCheckDataRoamingMode() == state:
4947 ad.log.info("Data roaming is already in state %s", state)
4948 return True
4949 if not ad.droid.connectivitySetDataRoaming(state_int):
4950 ad.error.info("Fail to config data roaming into state %s", state)
4951 return False
4952 if ad.droid.connectivityCheckDataRoamingMode() == state:
4953 ad.log.info("Data roaming is configured into state %s", state)
4954 return True
4955 else:
4956 ad.log.error("Data roaming is not configured into state %s", state)
4957 return False
4958
4959
Ang Li73697b32015-12-03 00:41:53 +00004960def verify_incall_state(log, ads, expected_status):
4961 """Verify phones in incall state or not.
4962
4963 Verify if all phones in the array <ads> are in <expected_status>.
4964
4965 Args:
4966 log: Log object.
4967 ads: Array of Android Device Object. All droid in this array will be tested.
4968 expected_status: If True, verify all Phones in incall state.
4969 If False, verify all Phones not in incall state.
4970
4971 """
4972 result = True
4973 for ad in ads:
4974 if ad.droid.telecomIsInCall() is not expected_status:
Betty Zhoua37acd32017-02-23 20:04:24 -08004975 ad.log.error("InCall status:%s, expected:%s",
4976 ad.droid.telecomIsInCall(), expected_status)
Ang Li73697b32015-12-03 00:41:53 +00004977 result = False
4978 return result
4979
Nathan Harold123c9da2015-12-30 16:33:25 -08004980
Ang Li73697b32015-12-03 00:41:53 +00004981def verify_active_call_number(log, ad, expected_number):
4982 """Verify the number of current active call.
4983
4984 Verify if the number of current active call in <ad> is
4985 equal to <expected_number>.
4986
4987 Args:
4988 ad: Android Device Object.
4989 expected_number: Expected active call number.
4990 """
4991 calls = ad.droid.telecomCallGetCallIds()
4992 if calls is None:
4993 actual_number = 0
4994 else:
4995 actual_number = len(calls)
4996 if actual_number != expected_number:
Betty Zhoua37acd32017-02-23 20:04:24 -08004997 ad.log.error("Active Call number is %s, expecting", actual_number,
4998 expected_number)
Ang Li73697b32015-12-03 00:41:53 +00004999 return False
5000 return True
5001
Nathan Harold123c9da2015-12-30 16:33:25 -08005002
Ang Li73697b32015-12-03 00:41:53 +00005003def num_active_calls(log, ad):
5004 """Get the count of current active calls.
5005
5006 Args:
5007 log: Log object.
5008 ad: Android Device Object.
5009
5010 Returns:
5011 Count of current active calls.
5012 """
5013 calls = ad.droid.telecomCallGetCallIds()
5014 return len(calls) if calls else 0
5015
Nathan Harold123c9da2015-12-30 16:33:25 -08005016
Markus Liu2cf8d0b2019-10-04 11:13:17 +08005017def show_enhanced_4g_lte(ad, sub_id):
5018 result = True
5019 capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
5020 if capabilities:
5021 if "hide_enhanced_4g_lte" in capabilities:
5022 result = False
Markus Liu6b41e092020-08-17 15:55:28 +08005023 ad.log.info(
5024 '"Enhanced 4G LTE MODE" is hidden for sub ID %s.', sub_id)
5025 show_enhanced_4g_lte_mode = getattr(
5026 ad, "show_enhanced_4g_lte_mode", False)
Markus Liu2cf8d0b2019-10-04 11:13:17 +08005027 if show_enhanced_4g_lte_mode in ["true", "True"]:
5028 current_voice_sub_id = get_outgoing_voice_sub_id(ad)
5029 if sub_id != current_voice_sub_id:
5030 set_incoming_voice_sub_id(ad, sub_id)
5031
Markus Liu6b41e092020-08-17 15:55:28 +08005032 ad.log.info(
5033 'Show "Enhanced 4G LTE MODE" forcibly for sub ID %s.',
5034 sub_id)
5035 ad.adb.shell(
5036 "am broadcast \
5037 -a com.google.android.carrier.action.LOCAL_OVERRIDE \
5038 -n com.google.android.carrier/.ConfigOverridingReceiver \
5039 --ez hide_enhanced_4g_lte_bool false")
5040 ad.telephony["subscription"][sub_id]["capabilities"].remove(
5041 "hide_enhanced_4g_lte")
Markus Liu2cf8d0b2019-10-04 11:13:17 +08005042
5043 if sub_id != current_voice_sub_id:
5044 set_incoming_voice_sub_id(ad, current_voice_sub_id)
5045
5046 result = True
5047 return result
5048
5049
Ang Li73697b32015-12-03 00:41:53 +00005050def toggle_volte(log, ad, new_state=None):
5051 """Toggle enable/disable VoLTE for default voice subscription.
Markus Liu6b41e092020-08-17 15:55:28 +08005052
Ang Li73697b32015-12-03 00:41:53 +00005053 Args:
5054 ad: Android device object.
5055 new_state: VoLTE mode state to set to.
5056 True for enable, False for disable.
5057 If None, opposite of the current state.
Markus Liu6b41e092020-08-17 15:55:28 +08005058
Ang Li73697b32015-12-03 00:41:53 +00005059 Raises:
5060 TelTestUtilsError if platform does not support VoLTE.
5061 """
Betty Zhouee311052017-12-19 13:09:56 -08005062 return toggle_volte_for_subscription(
5063 log, ad, get_outgoing_voice_sub_id(ad), new_state)
Ang Li73697b32015-12-03 00:41:53 +00005064
5065
5066def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
5067 """Toggle enable/disable VoLTE for specified voice subscription.
5068
5069 Args:
5070 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005071 sub_id: Optional. If not assigned the default sub ID for voice call will
5072 be used.
Ang Li73697b32015-12-03 00:41:53 +00005073 new_state: VoLTE mode state to set to.
5074 True for enable, False for disable.
5075 If None, opposite of the current state.
5076
Ang Li73697b32015-12-03 00:41:53 +00005077 """
Markus Liu2cf8d0b2019-10-04 11:13:17 +08005078 if not show_enhanced_4g_lte(ad, sub_id):
5079 return False
5080
Markus Liu6b41e092020-08-17 15:55:28 +08005081 current_state = None
5082 result = True
5083
5084 if sub_id is None:
5085 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5086
5087 try:
5088 current_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id)
5089 except Exception as e:
5090 ad.log.warning(e)
5091
5092 if current_state is not None:
5093 if new_state is None:
5094 new_state = not current_state
5095 if new_state != current_state:
5096 ad.log.info(
5097 "Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s",
5098 current_state, new_state, sub_id)
5099 ad.droid.imsMmTelSetAdvancedCallingEnabled(sub_id, new_state)
5100 check_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id)
5101 if check_state != new_state:
5102 ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, still \
5103 set to %s on sub_id %s", new_state, check_state, sub_id)
5104 result = False
5105 return result
5106 else:
5107 # TODO: b/26293960 No framework API available to set IMS by SubId.
5108 voice_sub_id_changed = False
5109 current_sub_id = get_incoming_voice_sub_id(ad)
5110 if current_sub_id != sub_id:
5111 set_incoming_voice_sub_id(ad, sub_id)
5112 voice_sub_id_changed = True
5113
5114 # b/139641554
5115 ad.terminate_all_sessions()
5116 bring_up_sl4a(ad)
5117
5118 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
5119 ad.log.info(
5120 "Enhanced 4G Lte Mode Setting is not enabled by platform for \
5121 sub ID %s.", sub_id)
5122 return False
5123
5124 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5125 ad.log.info("Current state of Enhanced 4G Lte Mode Setting for sub \
5126 ID %s: %s", sub_id, current_state)
5127 ad.log.info("New desired state of Enhanced 4G Lte Mode Setting for sub \
5128 ID %s: %s", sub_id, new_state)
5129
5130 if new_state is None:
5131 new_state = not current_state
5132 if new_state != current_state:
5133 ad.log.info(
5134 "Toggle Enhanced 4G LTE Mode from %s to %s for sub ID %s.",
5135 current_state, new_state, sub_id)
5136 ad.droid.imsSetEnhanced4gMode(new_state)
5137 time.sleep(5)
5138
5139 check_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5140 if check_state != new_state:
5141 ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, \
5142 still set to %s on sub_id %s", new_state, check_state, sub_id)
5143 result = False
5144
5145 if voice_sub_id_changed:
5146 set_incoming_voice_sub_id(ad, current_sub_id)
5147
5148 return result
Ang Li73697b32015-12-03 00:41:53 +00005149
Nathan Harold123c9da2015-12-30 16:33:25 -08005150
Betty Zhou8aafcc12018-05-01 20:54:15 -07005151def toggle_wfc(log, ad, new_state=None):
Jaineel002cc052020-02-07 14:04:05 -08005152 """ Toggle WFC enable/disable
5153
5154 Args:
5155 log: Log object
5156 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005157 new_state: WFC state to set to.
5158 True for enable, False for disable.
5159 If None, opposite of the current state.
Jaineel002cc052020-02-07 14:04:05 -08005160 """
Markus Liu6b41e092020-08-17 15:55:28 +08005161 return toggle_wfc_for_subscription(
5162 log, ad, new_state, get_outgoing_voice_sub_id(ad))
Betty Zhou8aafcc12018-05-01 20:54:15 -07005163
5164
Markus Liu6b41e092020-08-17 15:55:28 +08005165def toggle_wfc_for_subscription(log, ad, new_state=None, sub_id=None):
5166 """ Toggle WFC enable/disable for specified voice subscription.
Jaineel002cc052020-02-07 14:04:05 -08005167
5168 Args:
5169 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005170 sub_id: Optional. If not assigned the default sub ID for voice call will
5171 be used.
5172 new_state: WFC state to set to.
5173 True for enable, False for disable.
5174 If None, opposite of the current state.
Jaineel002cc052020-02-07 14:04:05 -08005175 """
Markus Liu6b41e092020-08-17 15:55:28 +08005176 current_state = None
5177 result = True
5178
Jaineel002cc052020-02-07 14:04:05 -08005179 if sub_id is None:
5180 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
Markus Liu6b41e092020-08-17 15:55:28 +08005181
5182 try:
5183 current_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id)
5184 except Exception as e:
5185 ad.log.warning(e)
5186
5187 if current_state is not None:
5188 if new_state is None:
5189 new_state = not current_state
5190 if new_state != current_state:
5191 ad.log.info(
Markus Liufb165362021-03-12 16:06:58 +08005192 "Toggle Wi-Fi calling from %s to %s on sub_id %s",
Markus Liu6b41e092020-08-17 15:55:28 +08005193 current_state, new_state, sub_id)
5194 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, new_state)
5195 check_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id)
5196 if check_state != new_state:
Markus Liufb165362021-03-12 16:06:58 +08005197 ad.log.error("Failed to toggle Wi-Fi calling to %s, \
Markus Liu6b41e092020-08-17 15:55:28 +08005198 still set to %s on sub_id %s", new_state, check_state, sub_id)
5199 result = False
5200 return result
5201 else:
5202 voice_sub_id_changed = False
5203 if not sub_id:
5204 sub_id = get_outgoing_voice_sub_id(ad)
5205 else:
5206 current_sub_id = get_incoming_voice_sub_id(ad)
5207 if current_sub_id != sub_id:
5208 set_incoming_voice_sub_id(ad, sub_id)
5209 voice_sub_id_changed = True
5210
5211 # b/139641554
5212 ad.terminate_all_sessions()
5213 bring_up_sl4a(ad)
5214
5215 if not ad.droid.imsIsWfcEnabledByPlatform():
5216 ad.log.info("WFC is not enabled by platform for sub ID %s.", sub_id)
5217 return False
5218
5219 current_state = ad.droid.imsIsWfcEnabledByUser()
5220 ad.log.info("Current state of WFC Setting for sub ID %s: %s",
5221 sub_id, current_state)
5222 ad.log.info("New desired state of WFC Setting for sub ID %s: %s",
5223 sub_id, new_state)
5224
5225 if new_state is None:
5226 new_state = not current_state
5227 if new_state != current_state:
5228 ad.log.info("Toggle WFC user enabled from %s to %s for sub ID %s",
5229 current_state, new_state, sub_id)
5230 ad.droid.imsSetWfcSetting(new_state)
5231
5232 if voice_sub_id_changed:
5233 set_incoming_voice_sub_id(ad, current_sub_id)
5234
5235 return True
5236
Pratik Sheth68e4eba2021-03-23 17:10:13 -07005237
Markus Liu6b41e092020-08-17 15:55:28 +08005238def is_enhanced_4g_lte_mode_setting_enabled(ad, sub_id, enabled_by="platform"):
5239 voice_sub_id_changed = False
5240 current_sub_id = get_incoming_voice_sub_id(ad)
5241 if current_sub_id != sub_id:
5242 set_incoming_voice_sub_id(ad, sub_id)
5243 voice_sub_id_changed = True
5244 if enabled_by == "platform":
5245 res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform()
5246 else:
5247 res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5248 if not res:
5249 ad.log.info("Enhanced 4G Lte Mode Setting is NOT enabled by %s for sub \
5250 ID %s.", enabled_by, sub_id)
5251 if voice_sub_id_changed:
5252 set_incoming_voice_sub_id(ad, current_sub_id)
5253 return False
5254 if voice_sub_id_changed:
5255 set_incoming_voice_sub_id(ad, current_sub_id)
5256 ad.log.info("Enhanced 4G Lte Mode Setting is enabled by %s for sub ID %s.",
5257 enabled_by, sub_id)
Jaineel002cc052020-02-07 14:04:05 -08005258 return True
5259
Markus Liu6b41e092020-08-17 15:55:28 +08005260def set_enhanced_4g_mode(ad, sub_id, state):
5261 voice_sub_id_changed = False
5262 current_sub_id = get_incoming_voice_sub_id(ad)
5263 if current_sub_id != sub_id:
5264 set_incoming_voice_sub_id(ad, sub_id)
5265 voice_sub_id_changed = True
5266
5267 ad.droid.imsSetEnhanced4gMode(state)
5268 time.sleep(5)
5269
5270 if voice_sub_id_changed:
5271 set_incoming_voice_sub_id(ad, current_sub_id)
Jaineel002cc052020-02-07 14:04:05 -08005272
Pratik Sheth68e4eba2021-03-23 17:10:13 -07005273
Betty Zhoub14c1012018-04-20 11:27:00 -07005274def wait_for_enhanced_4g_lte_setting(log,
5275 ad,
Markus Liu6b41e092020-08-17 15:55:28 +08005276 sub_id,
Betty Zhoub14c1012018-04-20 11:27:00 -07005277 max_time=MAX_WAIT_TIME_FOR_STATE_CHANGE):
5278 """Wait for android device to enable enhance 4G LTE setting.
5279
5280 Args:
5281 log: log object.
5282 ad: android device.
5283 max_time: maximal wait time.
5284
5285 Returns:
5286 Return True if device report VoLTE enabled bit true within max_time.
5287 Return False if timeout.
5288 """
5289 return wait_for_state(
Markus Liu6b41e092020-08-17 15:55:28 +08005290 is_enhanced_4g_lte_mode_setting_enabled,
Betty Zhoub14c1012018-04-20 11:27:00 -07005291 True,
Markus Liu6b41e092020-08-17 15:55:28 +08005292 max_time,
5293 WAIT_TIME_BETWEEN_STATE_CHECK,
5294 ad,
5295 sub_id,
5296 enabled_by="platform")
Betty Zhoub14c1012018-04-20 11:27:00 -07005297
5298
Ang Li73697b32015-12-03 00:41:53 +00005299def set_wfc_mode(log, ad, wfc_mode):
5300 """Set WFC enable/disable and mode.
5301
5302 Args:
5303 log: Log object
5304 ad: Android device object.
5305 wfc_mode: WFC mode to set to.
5306 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
5307 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
5308
5309 Returns:
5310 True if success. False if ad does not support WFC or error happened.
5311 """
Markus Liu6b41e092020-08-17 15:55:28 +08005312 return set_wfc_mode_for_subscription(
5313 ad, wfc_mode, get_outgoing_voice_sub_id(ad))
Ang Li73697b32015-12-03 00:41:53 +00005314
Nathan Harold123c9da2015-12-30 16:33:25 -08005315
Jaineel002cc052020-02-07 14:04:05 -08005316def set_wfc_mode_for_subscription(ad, wfc_mode, sub_id=None):
5317 """Set WFC enable/disable and mode subscription based
5318
5319 Args:
5320 ad: Android device object.
5321 wfc_mode: WFC mode to set to.
5322 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
5323 WFC_MODE_WIFI_PREFERRED.
5324 sub_id: subscription Id
5325
5326 Returns:
5327 True if success. False if ad does not support WFC or error happened.
5328 """
Markus Liu6b41e092020-08-17 15:55:28 +08005329 if wfc_mode not in [
5330 WFC_MODE_WIFI_ONLY,
5331 WFC_MODE_CELLULAR_PREFERRED,
5332 WFC_MODE_WIFI_PREFERRED,
5333 WFC_MODE_DISABLED]:
5334
5335 ad.log.error("Given WFC mode (%s) is not correct.", wfc_mode)
Jaineel002cc052020-02-07 14:04:05 -08005336 return False
Markus Liu6b41e092020-08-17 15:55:28 +08005337
5338 current_mode = None
5339 result = True
5340
5341 if sub_id is None:
5342 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5343
5344 try:
5345 current_mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
Markus Liu9b2cec82021-04-09 20:20:25 +08005346 ad.log.info("Current WFC mode of sub ID %s: %s", sub_id, current_mode)
Markus Liu6b41e092020-08-17 15:55:28 +08005347 except Exception as e:
5348 ad.log.warning(e)
5349
5350 if current_mode is not None:
5351 try:
5352 if not ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id):
5353 if wfc_mode is WFC_MODE_DISABLED:
Markus Liu9b2cec82021-04-09 20:20:25 +08005354 ad.log.info("WFC is already disabled.")
Markus Liu6b41e092020-08-17 15:55:28 +08005355 return True
5356 ad.log.info(
5357 "WFC is disabled for sub ID %s. Enabling WFC...", sub_id)
5358 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, True)
5359
5360 if wfc_mode is WFC_MODE_DISABLED:
Markus Liu9b2cec82021-04-09 20:20:25 +08005361 ad.log.info(
5362 "WFC is enabled for sub ID %s. Disabling WFC...", sub_id)
Markus Liu6b41e092020-08-17 15:55:28 +08005363 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, False)
5364 return True
5365
5366 ad.log.info("Set wfc mode to %s for sub ID %s.", wfc_mode, sub_id)
5367 ad.droid.imsMmTelSetVoWiFiModeSetting(sub_id, wfc_mode)
5368 mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
5369 if mode != wfc_mode:
5370 ad.log.error("WFC mode for sub ID %s is %s, not in %s",
5371 sub_id, mode, wfc_mode)
5372 return False
5373 except Exception as e:
5374 ad.log.error(e)
5375 return False
5376 return True
5377 else:
5378 voice_sub_id_changed = False
5379 if not sub_id:
5380 sub_id = get_outgoing_voice_sub_id(ad)
5381 else:
5382 current_sub_id = get_incoming_voice_sub_id(ad)
5383 if current_sub_id != sub_id:
5384 set_incoming_voice_sub_id(ad, sub_id)
5385 voice_sub_id_changed = True
5386
5387 # b/139641554
5388 ad.terminate_all_sessions()
5389 bring_up_sl4a(ad)
5390
5391 if wfc_mode != WFC_MODE_DISABLED and wfc_mode not in ad.telephony[
5392 "subscription"][get_outgoing_voice_sub_id(ad)].get("wfc_modes", []):
5393 ad.log.error("WFC mode %s is not supported", wfc_mode)
5394 raise signals.TestSkip("WFC mode %s is not supported" % wfc_mode)
5395 try:
5396 ad.log.info("Set wfc mode to %s", wfc_mode)
5397 if wfc_mode != WFC_MODE_DISABLED:
5398 start_adb_tcpdump(ad, interface="wlan0", mask="all")
5399 if not ad.droid.imsIsWfcEnabledByPlatform():
5400 if wfc_mode == WFC_MODE_DISABLED:
5401 if voice_sub_id_changed:
5402 set_incoming_voice_sub_id(ad, current_sub_id)
5403 return True
5404 else:
5405 ad.log.error("WFC not supported by platform.")
5406 if voice_sub_id_changed:
5407 set_incoming_voice_sub_id(ad, current_sub_id)
5408 return False
5409 ad.droid.imsSetWfcMode(wfc_mode)
5410 mode = ad.droid.imsGetWfcMode()
5411 if voice_sub_id_changed:
5412 set_incoming_voice_sub_id(ad, current_sub_id)
5413 if mode != wfc_mode:
5414 ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode)
5415 return False
5416 except Exception as e:
5417 log.error(e)
5418 if voice_sub_id_changed:
5419 set_incoming_voice_sub_id(ad, current_sub_id)
5420 return False
5421 return True
5422
Jaineel002cc052020-02-07 14:04:05 -08005423
Jaineel002cc052020-02-07 14:04:05 -08005424def set_ims_provisioning_for_subscription(ad, feature_flag, value, sub_id=None):
5425 """ Sets Provisioning Values for Subscription Id
5426
5427 Args:
5428 ad: Android device object.
5429 sub_id: Subscription Id
5430 feature_flag: voice or video
5431 value: enable or disable
5432
5433 """
5434 try:
5435 if sub_id is None:
5436 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5437 ad.log.info("SubId %s - setprovisioning for %s to %s",
5438 sub_id, feature_flag, value)
5439 result = ad.droid.provisioningSetProvisioningIntValue(sub_id,
5440 feature_flag, value)
5441 if result == 0:
5442 return True
5443 return False
5444 except Exception as e:
5445 ad.log.error(e)
5446 return False
5447
5448
5449def get_ims_provisioning_for_subscription(ad, feature_flag, tech, sub_id=None):
5450 """ Gets Provisioning Values for Subscription Id
5451
5452 Args:
5453 ad: Android device object.
5454 sub_id: Subscription Id
5455 feature_flag: voice, video, ut, sms
5456 tech: lte, iwlan
5457
5458 """
5459 try:
5460 if sub_id is None:
5461 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5462 result = ad.droid.provisioningGetProvisioningStatusForCapability(
5463 sub_id, feature_flag, tech)
5464 ad.log.info("SubId %s - getprovisioning for %s on %s - %s",
5465 sub_id, feature_flag, tech, result)
5466 return result
5467 except Exception as e:
5468 ad.log.error(e)
5469 return False
5470
5471
5472def get_carrier_provisioning_for_subscription(ad, feature_flag,
5473 tech, sub_id=None):
5474 """ Gets Provisioning Values for Subscription Id
5475
5476 Args:
5477 ad: Android device object.
5478 sub_id: Subscription Id
5479 feature_flag: voice, video, ut, sms
5480 tech: wlan, wwan
5481
5482 """
5483 try:
5484 if sub_id is None:
5485 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5486 result = ad.droid.imsMmTelIsSupported(sub_id, feature_flag, tech)
5487 ad.log.info("SubId %s - imsMmTelIsSupported for %s on %s - %s",
5488 sub_id, feature_flag, tech, result)
5489 return result
5490 except Exception as e:
5491 ad.log.error(e)
5492 return False
5493
Pratik Sheth68e4eba2021-03-23 17:10:13 -07005494
Shaju Sebastian0b847e72019-01-31 16:40:37 -08005495def activate_wfc_on_device(log, ad):
5496 """ Activates WiFi calling on device.
5497
5498 Required for certain network operators.
5499
5500 Args:
5501 log: Log object
5502 ad: Android device object
5503
5504 """
5505 activate_wfc_on_device_for_subscription(log, ad,
5506 ad.droid.subscriptionGetDefaultSubId())
5507
5508
5509def activate_wfc_on_device_for_subscription(log, ad, sub_id):
5510 """ Activates WiFi calling on device for a subscription.
5511
5512 Args:
5513 log: Log object
5514 ad: Android device object
5515 sub_id: Subscription id (integer)
5516
5517 """
5518 if not sub_id or INVALID_SUB_ID == sub_id:
5519 ad.log.error("Subscription id invalid")
5520 return
5521 operator_name = get_operator_name(log, ad, sub_id)
5522 if operator_name in (CARRIER_VZW, CARRIER_ATT, CARRIER_BELL, CARRIER_ROGERS,
5523 CARRIER_TELUS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_FRE):
5524 ad.log.info("Activating WFC on operator : %s", operator_name)
5525 if not ad.is_apk_installed("com.google.android.wfcactivation"):
5526 ad.log.error("WFC Activation Failed, wfc activation apk not installed")
5527 return
5528 wfc_activate_cmd ="am start --ei EXTRA_LAUNCH_CARRIER_APP 0 --ei " \
5529 "android.telephony.extra.SUBSCRIPTION_INDEX {} -n ".format(sub_id)
5530 if CARRIER_ATT == operator_name:
5531 ad.adb.shell("setprop dbg.att.force_wfc_nv_enabled true")
5532 wfc_activate_cmd = wfc_activate_cmd+\
5533 "\"com.google.android.wfcactivation/" \
5534 ".WfcActivationActivity\""
5535 elif CARRIER_VZW == operator_name:
5536 ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
5537 wfc_activate_cmd = wfc_activate_cmd + \
5538 "\"com.google.android.wfcactivation/" \
5539 ".VzwEmergencyAddressActivity\""
5540 else:
5541 wfc_activate_cmd = wfc_activate_cmd+ \
5542 "\"com.google.android.wfcactivation/" \
5543 ".can.WfcActivationCanadaActivity\""
5544 ad.adb.shell(wfc_activate_cmd)
5545
5546
Nathan Harold0a011532016-08-24 19:17:44 -07005547def toggle_video_calling(log, ad, new_state=None):
5548 """Toggle enable/disable Video calling for default voice subscription.
5549
5550 Args:
5551 ad: Android device object.
5552 new_state: Video mode state to set to.
5553 True for enable, False for disable.
5554 If None, opposite of the current state.
5555
5556 Raises:
5557 TelTestUtilsError if platform does not support Video calling.
5558 """
5559 if not ad.droid.imsIsVtEnabledByPlatform():
5560 if new_state is not False:
5561 raise TelTestUtilsError("VT not supported by platform.")
5562 # if the user sets VT false and it's unavailable we just let it go
5563 return False
5564
5565 current_state = ad.droid.imsIsVtEnabledByUser()
5566 if new_state is None:
5567 new_state = not current_state
5568 if new_state != current_state:
5569 ad.droid.imsSetVtSetting(new_state)
5570 return True
Nathan Harold123c9da2015-12-30 16:33:25 -08005571
Nathan Harold72f9bff2016-09-19 14:16:24 -07005572
Jaineel002cc052020-02-07 14:04:05 -08005573def toggle_video_calling_for_subscription(ad, new_state=None, sub_id=None):
5574 """Toggle enable/disable Video calling for subscription.
5575
5576 Args:
5577 ad: Android device object.
5578 new_state: Video mode state to set to.
5579 True for enable, False for disable.
5580 If None, opposite of the current state.
5581 sub_id: subscription Id
5582
5583 """
5584 try:
5585 if sub_id is None:
5586 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5587 current_state = ad.droid.imsMmTelIsVtSettingEnabled(sub_id)
5588 if new_state is None:
5589 new_state = not current_state
5590 if new_state != current_state:
5591 ad.log.info("SubId %s - Toggle VT from %s to %s", sub_id,
5592 current_state, new_state)
5593 ad.droid.imsMmTelSetVtSettingEnabled(sub_id, new_state)
5594 except Exception as e:
5595 ad.log.error(e)
5596 return False
5597 return True
5598
5599
Nathan Harold123c9da2015-12-30 16:33:25 -08005600def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args,
5601 **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07005602 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00005603 if state_check_func(log, ad, *args, **kwargs):
5604 return True
5605
Betty Zhouf25ce442017-03-03 14:28:36 -08005606 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5607 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005608
5609 return False
5610
5611
Nathan Harold123c9da2015-12-30 16:33:25 -08005612def _wait_for_droid_in_state_for_subscription(
5613 log, ad, sub_id, max_time, state_check_func, *args, **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07005614 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00005615 if state_check_func(log, ad, sub_id, *args, **kwargs):
5616 return True
5617
Betty Zhouf25ce442017-03-03 14:28:36 -08005618 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5619 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005620
5621 return False
5622
5623
Nathan Harold123c9da2015-12-30 16:33:25 -08005624def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args,
5625 **kwargs):
Ang Li73697b32015-12-03 00:41:53 +00005626 while max_time > 0:
5627 success = True
5628 for ad in ads:
5629 if not state_check_func(log, ad, *args, **kwargs):
5630 success = False
5631 break
5632 if success:
5633 return True
5634
Betty Zhouf25ce442017-03-03 14:28:36 -08005635 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5636 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005637
5638 return False
5639
Nathan Harold123c9da2015-12-30 16:33:25 -08005640
Ang Li73697b32015-12-03 00:41:53 +00005641def is_phone_in_call(log, ad):
5642 """Return True if phone in call.
5643
5644 Args:
5645 log: log object.
5646 ad: android device.
5647 """
Betty Zhou377f72b2018-01-12 19:43:26 -08005648 try:
5649 return ad.droid.telecomIsInCall()
5650 except:
5651 return "mCallState=2" in ad.adb.shell(
5652 "dumpsys telephony.registry | grep mCallState")
Ang Li73697b32015-12-03 00:41:53 +00005653
Nathan Harold123c9da2015-12-30 16:33:25 -08005654
Ang Li73697b32015-12-03 00:41:53 +00005655def is_phone_not_in_call(log, ad):
5656 """Return True if phone not in call.
5657
5658 Args:
5659 log: log object.
5660 ad: android device.
5661 """
Betty Zhou94023182017-06-07 18:02:14 -07005662 in_call = ad.droid.telecomIsInCall()
5663 call_state = ad.droid.telephonyGetCallState()
5664 if in_call:
5665 ad.log.info("Device is In Call")
5666 if call_state != TELEPHONY_STATE_IDLE:
5667 ad.log.info("Call_state is %s, not %s", call_state,
5668 TELEPHONY_STATE_IDLE)
5669 return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))
Ang Li73697b32015-12-03 00:41:53 +00005670
Nathan Harold123c9da2015-12-30 16:33:25 -08005671
Ang Li73697b32015-12-03 00:41:53 +00005672def wait_for_droid_in_call(log, ad, max_time):
5673 """Wait for android to be in call state.
5674
5675 Args:
5676 log: log object.
5677 ad: android device.
5678 max_time: maximal wait time.
5679
5680 Returns:
5681 If phone become in call state within max_time, return True.
5682 Return False if timeout.
5683 """
5684 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
5685
Nathan Harold7642fc92016-05-02 18:29:11 -07005686
Betty Zhoucf048542018-02-22 17:14:08 -08005687def is_phone_in_call_active(ad, call_id=None):
5688 """Return True if phone in active call.
5689
5690 Args:
5691 log: log object.
5692 ad: android device.
5693 call_id: the call id
5694 """
Jaineel78b05dd2018-03-27 13:54:17 -07005695 if ad.droid.telecomIsInCall():
5696 if not call_id:
5697 call_id = ad.droid.telecomCallGetCallIds()[0]
5698 call_state = ad.droid.telecomCallGetCallState(call_id)
5699 ad.log.info("%s state is %s", call_id, call_state)
5700 return call_state == "ACTIVE"
5701 else:
Betty Zhouabe4a442018-05-21 12:37:26 -07005702 ad.log.info("Not in telecomIsInCall")
Jaineel78b05dd2018-03-27 13:54:17 -07005703 return False
Betty Zhoucf048542018-02-22 17:14:08 -08005704
Betty Zhou4411c202018-03-29 18:27:25 -07005705
Betty Zhoua9e35a42018-05-22 14:57:38 -07005706def wait_for_in_call_active(ad,
5707 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
5708 interval=WAIT_TIME_BETWEEN_STATE_CHECK,
5709 call_id=None):
Betty Zhoucf048542018-02-22 17:14:08 -08005710 """Wait for call reach active state.
5711
5712 Args:
5713 log: log object.
5714 ad: android device.
5715 call_id: the call id
5716 """
5717 if not call_id:
5718 call_id = ad.droid.telecomCallGetCallIds()[0]
5719 args = [ad, call_id]
5720 if not wait_for_state(is_phone_in_call_active, True, timeout, interval,
5721 *args):
5722 ad.log.error("Call did not reach ACTIVE state")
5723 return False
5724 else:
5725 return True
5726
5727
Yang Liu855d5f82016-01-27 15:35:48 -08005728def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
5729 """Wait for android to be in telecom ringing state.
5730
5731 Args:
5732 log: log object.
5733 ad: android device.
5734 max_time: maximal wait time. This is optional.
5735 Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
5736
5737 Returns:
5738 If phone become in telecom ringing state within max_time, return True.
5739 Return False if timeout.
5740 """
Nathan Harold7642fc92016-05-02 18:29:11 -07005741 return _wait_for_droid_in_state(
5742 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
Yang Liu855d5f82016-01-27 15:35:48 -08005743
Nathan Harold123c9da2015-12-30 16:33:25 -08005744
Nathan Haroldeb60b192016-08-24 14:41:55 -07005745def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00005746 """Wait for android to be not in call state.
5747
5748 Args:
5749 log: log object.
5750 ad: android device.
5751 max_time: maximal wait time.
5752
5753 Returns:
5754 If phone become not in call state within max_time, return True.
5755 Return False if timeout.
5756 """
5757 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
5758
Nathan Harold123c9da2015-12-30 16:33:25 -08005759
Ang Li73697b32015-12-03 00:41:53 +00005760def _is_attached(log, ad, voice_or_data):
5761 return _is_attached_for_subscription(
5762 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
5763
Nathan Harold123c9da2015-12-30 16:33:25 -08005764
Ang Li73697b32015-12-03 00:41:53 +00005765def _is_attached_for_subscription(log, ad, sub_id, voice_or_data):
Betty Zhouf25ce442017-03-03 14:28:36 -08005766 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)
Betty Zhoucb2cbc42017-06-29 14:39:34 -07005767 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat,
Betty Zhouf25ce442017-03-03 14:28:36 -08005768 voice_or_data)
5769 return rat != RAT_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00005770
Nathan Harold123c9da2015-12-30 16:33:25 -08005771
Betty Zhou33c05292017-05-24 15:12:43 -07005772def is_voice_attached(log, ad):
5773 return _is_attached_for_subscription(
5774 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE)
5775
5776
Betty Zhoub25ba2d2018-05-03 15:52:54 -07005777def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION):
Ang Li73697b32015-12-03 00:41:53 +00005778 """Wait for android device to attach on voice.
5779
5780 Args:
5781 log: log object.
5782 ad: android device.
5783 max_time: maximal wait time.
5784
5785 Returns:
5786 Return True if device attach voice within max_time.
5787 Return False if timeout.
5788 """
5789 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
5790 NETWORK_SERVICE_VOICE)
5791
Nathan Harold123c9da2015-12-30 16:33:25 -08005792
Betty Zhoub25ba2d2018-05-03 15:52:54 -07005793def wait_for_voice_attach_for_subscription(
5794 log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION):
Ang Li73697b32015-12-03 00:41:53 +00005795 """Wait for android device to attach on voice in subscription id.
5796
5797 Args:
5798 log: log object.
5799 ad: android device.
5800 sub_id: subscription id.
5801 max_time: maximal wait time.
5802
5803 Returns:
5804 Return True if device attach voice within max_time.
5805 Return False if timeout.
5806 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005807 if not _wait_for_droid_in_state_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08005808 log, ad, sub_id, max_time, _is_attached_for_subscription,
5809 NETWORK_SERVICE_VOICE):
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005810 return False
5811
5812 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
5813 # receive incoming call immediately.
5814 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
Yang Liudf164e32016-01-07 16:49:32 -08005815 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005816 return True
Ang Li73697b32015-12-03 00:41:53 +00005817
Nathan Harold123c9da2015-12-30 16:33:25 -08005818
Ang Li73697b32015-12-03 00:41:53 +00005819def wait_for_data_attach(log, ad, max_time):
5820 """Wait for android device to attach on data.
5821
5822 Args:
5823 log: log object.
5824 ad: android device.
5825 max_time: maximal wait time.
5826
5827 Returns:
5828 Return True if device attach data within max_time.
5829 Return False if timeout.
5830 """
5831 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
5832 NETWORK_SERVICE_DATA)
5833
Nathan Harold123c9da2015-12-30 16:33:25 -08005834
Ang Li73697b32015-12-03 00:41:53 +00005835def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time):
5836 """Wait for android device to attach on data in subscription id.
5837
5838 Args:
5839 log: log object.
5840 ad: android device.
5841 sub_id: subscription id.
5842 max_time: maximal wait time.
5843
5844 Returns:
5845 Return True if device attach data within max_time.
5846 Return False if timeout.
5847 """
5848 return _wait_for_droid_in_state_for_subscription(
5849 log, ad, sub_id, max_time, _is_attached_for_subscription,
5850 NETWORK_SERVICE_DATA)
5851
Nathan Harold123c9da2015-12-30 16:33:25 -08005852
Markus Liu6b41e092020-08-17 15:55:28 +08005853def is_ims_registered(log, ad, sub_id=None):
Yang Liu9b85ce52016-02-16 12:25:11 -08005854 """Return True if IMS registered.
5855
5856 Args:
5857 log: log object.
5858 ad: android device.
Markus Liu6b41e092020-08-17 15:55:28 +08005859 sub_id: Optional. If not assigned the default sub ID of voice call will
5860 be used.
Yang Liu9b85ce52016-02-16 12:25:11 -08005861
5862 Returns:
5863 Return True if IMS registered.
5864 Return False if IMS not registered.
5865 """
Markus Liu6b41e092020-08-17 15:55:28 +08005866 if not sub_id:
5867 return ad.droid.telephonyIsImsRegistered()
5868 else:
5869 return change_voice_subid_temporarily(
5870 ad, sub_id, ad.droid.telephonyIsImsRegistered)
Ang Li73697b32015-12-03 00:41:53 +00005871
Nathan Harold123c9da2015-12-30 16:33:25 -08005872
Betty Zhou8aafcc12018-05-01 20:54:15 -07005873def wait_for_ims_registered(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00005874 """Wait for android device to register on ims.
5875
5876 Args:
5877 log: log object.
5878 ad: android device.
5879 max_time: maximal wait time.
5880
5881 Returns:
5882 Return True if device register ims successfully within max_time.
5883 Return False if timeout.
5884 """
Yang Liu9b85ce52016-02-16 12:25:11 -08005885 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered)
Ang Li73697b32015-12-03 00:41:53 +00005886
Pratik Sheth68e4eba2021-03-23 17:10:13 -07005887
Markus Liu6b41e092020-08-17 15:55:28 +08005888def is_volte_available(log, ad, sub_id):
5889 """Return True if VoLTE is available.
Nathan Harold123c9da2015-12-30 16:33:25 -08005890
Markus Liu6b41e092020-08-17 15:55:28 +08005891 Args:
5892 log: log object.
5893 ad: android device.
5894 sub_id: Optional. If not assigned the default sub ID of voice call will
5895 be used.
5896
5897 Returns:
5898 Return True if VoLTE is available.
5899 Return False if VoLTE is not available.
5900 """
5901 if not sub_id:
5902 return ad.droid.telephonyIsVolteAvailable()
5903 else:
5904 return change_voice_subid_temporarily(
5905 ad, sub_id, ad.droid.telephonyIsVolteAvailable)
5906
Pratik Sheth68e4eba2021-03-23 17:10:13 -07005907
Markus Liu6b41e092020-08-17 15:55:28 +08005908def is_volte_enabled(log, ad, sub_id=None):
Yang Liu9b85ce52016-02-16 12:25:11 -08005909 """Return True if VoLTE feature bit is True.
5910
5911 Args:
5912 log: log object.
5913 ad: android device.
Markus Liu6b41e092020-08-17 15:55:28 +08005914 sub_id: Optional. If not assigned the default sub ID of voice call will
5915 be used.
Yang Liu9b85ce52016-02-16 12:25:11 -08005916
5917 Returns:
5918 Return True if VoLTE feature bit is True and IMS registered.
5919 Return False if VoLTE feature bit is False or IMS not registered.
5920 """
Markus Liu6b41e092020-08-17 15:55:28 +08005921 if not is_ims_registered(log, ad, sub_id):
5922 ad.log.info("IMS is not registered for sub ID %s.", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005923 return False
Markus Liu6b41e092020-08-17 15:55:28 +08005924 if not is_volte_available(log, ad, sub_id):
Richachab7c94eb2021-04-11 17:32:44 +08005925 ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable "
5926 "is False", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005927 return False
Betty Zhoue32dd3b2017-11-28 19:05:55 -08005928 else:
Richachab7c94eb2021-04-11 17:32:44 +08005929 ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable "
5930 "is True", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005931 return True
Ang Li73697b32015-12-03 00:41:53 +00005932
Nathan Harold123c9da2015-12-30 16:33:25 -08005933
Yang Liu9b85ce52016-02-16 12:25:11 -08005934def is_video_enabled(log, ad):
5935 """Return True if Video Calling feature bit is True.
5936
5937 Args:
5938 log: log object.
5939 ad: android device.
5940
5941 Returns:
5942 Return True if Video Calling feature bit is True and IMS registered.
5943 Return False if Video Calling feature bit is False or IMS not registered.
5944 """
Yang Liub93d7292016-02-19 10:41:40 -08005945 video_status = ad.droid.telephonyIsVideoCallingAvailable()
5946 if video_status is True and is_ims_registered(log, ad) is False:
Betty Zhou8aafcc12018-05-01 20:54:15 -07005947 ad.log.error(
5948 "Error! Video Call is Available, but IMS is not registered.")
Yang Liu9b85ce52016-02-16 12:25:11 -08005949 return False
Yang Liub93d7292016-02-19 10:41:40 -08005950 return video_status
Ang Li73697b32015-12-03 00:41:53 +00005951
Nathan Harold123c9da2015-12-30 16:33:25 -08005952
Markus Liu6b41e092020-08-17 15:55:28 +08005953def wait_for_volte_enabled(
5954 log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED,sub_id=None):
Ang Li73697b32015-12-03 00:41:53 +00005955 """Wait for android device to report VoLTE enabled bit true.
5956
5957 Args:
5958 log: log object.
5959 ad: android device.
5960 max_time: maximal wait time.
5961
5962 Returns:
5963 Return True if device report VoLTE enabled bit true within max_time.
5964 Return False if timeout.
5965 """
Markus Liu6b41e092020-08-17 15:55:28 +08005966 if not sub_id:
5967 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled)
5968 else:
5969 return _wait_for_droid_in_state_for_subscription(
5970 log, ad, sub_id, max_time, is_volte_enabled)
Ang Li73697b32015-12-03 00:41:53 +00005971
Nathan Harold123c9da2015-12-30 16:33:25 -08005972
Betty Zhou8aafcc12018-05-01 20:54:15 -07005973def wait_for_video_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00005974 """Wait for android device to report Video Telephony enabled bit true.
5975
5976 Args:
5977 log: log object.
5978 ad: android device.
5979 max_time: maximal wait time.
5980
5981 Returns:
5982 Return True if device report Video Telephony enabled bit true within max_time.
5983 Return False if timeout.
5984 """
Yang Liu9b85ce52016-02-16 12:25:11 -08005985 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
Ang Li73697b32015-12-03 00:41:53 +00005986
Nathan Harold123c9da2015-12-30 16:33:25 -08005987
Ang Li73697b32015-12-03 00:41:53 +00005988def is_wfc_enabled(log, ad):
5989 """Return True if WiFi Calling feature bit is True.
5990
5991 Args:
5992 log: log object.
5993 ad: android device.
5994
5995 Returns:
Yang Liu9b85ce52016-02-16 12:25:11 -08005996 Return True if WiFi Calling feature bit is True and IMS registered.
5997 Return False if WiFi Calling feature bit is False or IMS not registered.
Ang Li73697b32015-12-03 00:41:53 +00005998 """
Betty Zhoub66d48f2018-04-09 12:00:53 -07005999 if not is_ims_registered(log, ad):
6000 ad.log.info("IMS is not registered.")
6001 return False
Betty Zhou94023182017-06-07 18:02:14 -07006002 if not ad.droid.telephonyIsWifiCallingAvailable():
Markus Liu6b41e092020-08-17 15:55:28 +08006003 ad.log.info("IMS is registered, IsWifiCallingAvailable is False")
Yang Liu9b85ce52016-02-16 12:25:11 -08006004 return False
Betty Zhou94023182017-06-07 18:02:14 -07006005 else:
Markus Liu6b41e092020-08-17 15:55:28 +08006006 ad.log.info("IMS is registered, IsWifiCallingAvailable is True")
Betty Zhou94023182017-06-07 18:02:14 -07006007 return True
Ang Li73697b32015-12-03 00:41:53 +00006008
Nathan Harold123c9da2015-12-30 16:33:25 -08006009
Yang Liudfc37b62016-01-20 18:08:47 -08006010def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00006011 """Wait for android device to report WiFi Calling enabled bit true.
6012
6013 Args:
6014 log: log object.
6015 ad: android device.
6016 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08006017 Default value is MAX_WAIT_TIME_WFC_ENABLED.
Ang Li73697b32015-12-03 00:41:53 +00006018
6019 Returns:
6020 Return True if device report WiFi Calling enabled bit true within max_time.
6021 Return False if timeout.
6022 """
6023 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
6024
Nathan Harold123c9da2015-12-30 16:33:25 -08006025
Yang Liudfc37b62016-01-20 18:08:47 -08006026def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
Ang Li73697b32015-12-03 00:41:53 +00006027 """Wait for android device to report WiFi Calling enabled bit false.
6028
6029 Args:
6030 log: log object.
6031 ad: android device.
6032 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08006033 Default value is MAX_WAIT_TIME_WFC_DISABLED.
Ang Li73697b32015-12-03 00:41:53 +00006034
6035 Returns:
6036 Return True if device report WiFi Calling enabled bit false within max_time.
6037 Return False if timeout.
6038 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006039 return _wait_for_droid_in_state(
6040 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
6041
Ang Li73697b32015-12-03 00:41:53 +00006042
6043def get_phone_number(log, ad):
6044 """Get phone number for default subscription
6045
6046 Args:
6047 log: log object.
6048 ad: Android device object.
6049
6050 Returns:
6051 Phone number.
6052 """
Nathan Harold7642fc92016-05-02 18:29:11 -07006053 return get_phone_number_for_subscription(log, ad,
6054 get_outgoing_voice_sub_id(ad))
Nathan Harold123c9da2015-12-30 16:33:25 -08006055
Ang Li73697b32015-12-03 00:41:53 +00006056
6057def get_phone_number_for_subscription(log, ad, subid):
6058 """Get phone number for subscription
6059
6060 Args:
6061 log: log object.
6062 ad: Android device object.
6063 subid: subscription id.
6064
6065 Returns:
6066 Phone number.
6067 """
6068 number = None
6069 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07006070 number = ad.telephony['subscription'][subid]['phone_num']
Ang Li73697b32015-12-03 00:41:53 +00006071 except KeyError:
Yang Liuaed3eef2015-12-15 18:40:25 -08006072 number = ad.droid.telephonyGetLine1NumberForSubscription(subid)
Ang Li73697b32015-12-03 00:41:53 +00006073 return number
6074
Nathan Harold123c9da2015-12-30 16:33:25 -08006075
Ang Li73697b32015-12-03 00:41:53 +00006076def set_phone_number(log, ad, phone_num):
6077 """Set phone number for default subscription
6078
6079 Args:
6080 log: log object.
6081 ad: Android device object.
6082 phone_num: phone number string.
6083
6084 Returns:
6085 True if success.
6086 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07006087 return set_phone_number_for_subscription(log, ad,
6088 get_outgoing_voice_sub_id(ad),
6089 phone_num)
Nathan Harold123c9da2015-12-30 16:33:25 -08006090
Ang Li73697b32015-12-03 00:41:53 +00006091
6092def set_phone_number_for_subscription(log, ad, subid, phone_num):
6093 """Set phone number for subscription
6094
6095 Args:
6096 log: log object.
6097 ad: Android device object.
6098 subid: subscription id.
6099 phone_num: phone number string.
6100
6101 Returns:
6102 True if success.
6103 """
6104 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07006105 ad.telephony['subscription'][subid]['phone_num'] = phone_num
Ang Li73697b32015-12-03 00:41:53 +00006106 except Exception:
6107 return False
6108 return True
6109
Nathan Harold123c9da2015-12-30 16:33:25 -08006110
Ang Li73697b32015-12-03 00:41:53 +00006111def get_operator_name(log, ad, subId=None):
6112 """Get operator name (e.g. vzw, tmo) of droid.
6113
6114 Args:
6115 ad: Android device object.
6116 sub_id: subscription ID
6117 Optional, default is None
6118
6119 Returns:
6120 Operator name.
6121 """
6122 try:
6123 if subId is not None:
6124 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006125 ad.droid.telephonyGetNetworkOperatorForSubscription(subId))
Ang Li73697b32015-12-03 00:41:53 +00006126 else:
6127 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006128 ad.droid.telephonyGetNetworkOperator())
Ang Li73697b32015-12-03 00:41:53 +00006129 except KeyError:
Betty Zhou3ea56122018-03-14 17:37:24 -07006130 try:
6131 if subId is not None:
6132 result = ad.droid.telephonyGetNetworkOperatorNameForSubscription(
Shaju Sebastian2f88cdc2019-01-29 19:06:18 -08006133 subId)
Betty Zhou3ea56122018-03-14 17:37:24 -07006134 else:
6135 result = ad.droid.telephonyGetNetworkOperatorName()
Betty Zhoub14c1012018-04-20 11:27:00 -07006136 result = operator_name_from_network_name(result)
Betty Zhou3ea56122018-03-14 17:37:24 -07006137 except Exception:
6138 result = CARRIER_UNKNOWN
Jaineelde547262018-08-16 14:27:43 -07006139 ad.log.info("Operator Name is %s", result)
Ang Li73697b32015-12-03 00:41:53 +00006140 return result
6141
Nathan Harold123c9da2015-12-30 16:33:25 -08006142
Yang Liu9a9a4f72016-02-19 10:45:04 -08006143def get_model_name(ad):
6144 """Get android device model name
6145
6146 Args:
6147 ad: Android device object
6148
6149 Returns:
6150 model name string
6151 """
6152 # TODO: Create translate table.
6153 model = ad.model
Nathan Harold7642fc92016-05-02 18:29:11 -07006154 if (model.startswith(AOSP_PREFIX)):
Yang Liu9a9a4f72016-02-19 10:45:04 -08006155 model = model[len(AOSP_PREFIX):]
6156 return model
6157
6158
Ang Li73697b32015-12-03 00:41:53 +00006159def is_sms_match(event, phonenumber_tx, text):
6160 """Return True if 'text' equals to event['data']['Text']
6161 and phone number match.
6162
6163 Args:
6164 event: Event object to verify.
6165 phonenumber_tx: phone number for sender.
6166 text: text string to verify.
6167
6168 Returns:
6169 Return True if 'text' equals to event['data']['Text']
6170 and phone number match.
6171 """
Betty Zhouee311052017-12-19 13:09:56 -08006172 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
Shaju Sebastian4526c892019-02-28 13:55:15 -08006173 and event['data']['Text'].strip() == text)
Nathan Harold123c9da2015-12-30 16:33:25 -08006174
Ang Li73697b32015-12-03 00:41:53 +00006175
6176def is_sms_partial_match(event, phonenumber_tx, text):
6177 """Return True if 'text' starts with event['data']['Text']
6178 and phone number match.
6179
6180 Args:
6181 event: Event object to verify.
6182 phonenumber_tx: phone number for sender.
6183 text: text string to verify.
6184
6185 Returns:
6186 Return True if 'text' starts with event['data']['Text']
6187 and phone number match.
6188 """
Shaju Sebastian4526c892019-02-28 13:55:15 -08006189 event_text = event['data']['Text'].strip()
Betty Zhou1bc12092018-03-19 14:00:23 -07006190 if event_text.startswith("("):
6191 event_text = event_text.split(")")[-1]
Betty Zhouee311052017-12-19 13:09:56 -08006192 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
Betty Zhou1bc12092018-03-19 14:00:23 -07006193 and text.startswith(event_text))
Nathan Harold123c9da2015-12-30 16:33:25 -08006194
Ang Li73697b32015-12-03 00:41:53 +00006195
Betty Zhou02571f52018-02-16 14:11:16 -08006196def sms_send_receive_verify(log,
6197 ad_tx,
6198 ad_rx,
6199 array_message,
Betty Zhoued13b712018-05-02 19:40:10 -07006200 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006201 expected_result=True,
6202 slot_id_rx=None):
Ang Li73697b32015-12-03 00:41:53 +00006203 """Send SMS, receive SMS, and verify content and sender's number.
6204
6205 Send (several) SMS from droid_tx to droid_rx.
6206 Verify SMS is sent, delivered and received.
6207 Verify received content and sender's number are correct.
6208
6209 Args:
6210 log: Log object.
6211 ad_tx: Sender's Android Device Object
6212 ad_rx: Receiver's Android Device Object
6213 array_message: the array of message to send/receive
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006214 slot_id_rx: the slot on the Receiver's android device (0/1)
Ang Li73697b32015-12-03 00:41:53 +00006215 """
Yang Liu963c93c2016-04-05 10:52:00 -07006216 subid_tx = get_outgoing_message_sub_id(ad_tx)
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006217 if slot_id_rx is None:
6218 subid_rx = get_incoming_message_sub_id(ad_rx)
6219 else:
6220 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
6221
Betty Zhou74cf9922018-04-18 20:18:12 -07006222 result = sms_send_receive_verify_for_subscription(
Betty Zhou632793c2018-02-09 18:45:39 -08006223 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
Betty Zhoued13b712018-05-02 19:40:10 -07006224 if result != expected_result:
Betty Zhou74cf9922018-04-18 20:18:12 -07006225 log_messaging_screen_shot(ad_tx, test_name="sms_tx")
6226 log_messaging_screen_shot(ad_rx, test_name="sms_rx")
Betty Zhoued13b712018-05-02 19:40:10 -07006227 return result == expected_result
Ang Li73697b32015-12-03 00:41:53 +00006228
Nathan Harold123c9da2015-12-30 16:33:25 -08006229
6230def wait_for_matching_sms(log,
6231 ad_rx,
6232 phonenumber_tx,
6233 text,
Jaineel8e978552020-06-25 19:21:56 -07006234 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
6235 allow_multi_part_long_sms=True):
Ang Li73697b32015-12-03 00:41:53 +00006236 """Wait for matching incoming SMS.
6237
6238 Args:
6239 log: Log object.
6240 ad_rx: Receiver's Android Device Object
6241 phonenumber_tx: Sender's phone number.
6242 text: SMS content string.
6243 allow_multi_part_long_sms: is long SMS allowed to be received as
6244 multiple short SMS. This is optional, default value is True.
6245
6246 Returns:
6247 True if matching incoming SMS is received.
6248 """
6249 if not allow_multi_part_long_sms:
6250 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006251 ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
6252 max_wait_time, phonenumber_tx,
6253 text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07006254 ad_rx.log.info("Got event %s", EventSmsReceived)
Ang Li73697b32015-12-03 00:41:53 +00006255 return True
6256 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006257 ad_rx.log.error("No matched SMS received event.")
Ang Li73697b32015-12-03 00:41:53 +00006258 return False
6259 else:
6260 try:
6261 received_sms = ''
Betty Zhou1bc12092018-03-19 14:00:23 -07006262 remaining_text = text
6263 while (remaining_text != ''):
Betty Zhou1c8c8d42018-03-14 12:43:50 -07006264 event = ad_rx.messaging_ed.wait_for_event(
Betty Zhou02571f52018-02-16 14:11:16 -08006265 EventSmsReceived, is_sms_partial_match, max_wait_time,
Betty Zhou1bc12092018-03-19 14:00:23 -07006266 phonenumber_tx, remaining_text)
Shaju Sebastian4526c892019-02-28 13:55:15 -08006267 event_text = event['data']['Text'].split(")")[-1].strip()
Betty Zhou1bc12092018-03-19 14:00:23 -07006268 event_text_length = len(event_text)
6269 ad_rx.log.info("Got event %s of text length %s from %s",
6270 EventSmsReceived, event_text_length,
6271 phonenumber_tx)
6272 remaining_text = remaining_text[event_text_length:]
6273 received_sms += event_text
6274 ad_rx.log.info("Received SMS of length %s", len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00006275 return True
6276 except Empty:
Betty Zhou1bc12092018-03-19 14:00:23 -07006277 ad_rx.log.error(
6278 "Missing SMS received event of text length %s from %s",
6279 len(remaining_text), phonenumber_tx)
Ang Li73697b32015-12-03 00:41:53 +00006280 if received_sms != '':
Betty Zhou1bc12092018-03-19 14:00:23 -07006281 ad_rx.log.error(
6282 "Only received partial matched SMS of length %s",
6283 len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00006284 return False
6285
Nathan Harold123c9da2015-12-30 16:33:25 -08006286
Betty Zhoua27e5d42017-01-17 11:33:04 -08006287def is_mms_match(event, phonenumber_tx, text):
6288 """Return True if 'text' equals to event['data']['Text']
6289 and phone number match.
6290
6291 Args:
6292 event: Event object to verify.
6293 phonenumber_tx: phone number for sender.
6294 text: text string to verify.
6295
6296 Returns:
6297 Return True if 'text' equals to event['data']['Text']
6298 and phone number match.
6299 """
6300 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
6301 return True
6302
6303
Betty Zhou02571f52018-02-16 14:11:16 -08006304def wait_for_matching_mms(log,
6305 ad_rx,
6306 phonenumber_tx,
6307 text,
Betty Zhou632793c2018-02-09 18:45:39 -08006308 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhoua27e5d42017-01-17 11:33:04 -08006309 """Wait for matching incoming SMS.
6310
6311 Args:
6312 log: Log object.
6313 ad_rx: Receiver's Android Device Object
6314 phonenumber_tx: Sender's phone number.
6315 text: SMS content string.
6316 allow_multi_part_long_sms: is long SMS allowed to be received as
6317 multiple short SMS. This is optional, default value is True.
6318
6319 Returns:
6320 True if matching incoming SMS is received.
6321 """
6322 try:
6323 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08006324 ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
6325 max_wait_time, phonenumber_tx, text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07006326 ad_rx.log.info("Got event %s", EventMmsDownloaded)
Betty Zhoua27e5d42017-01-17 11:33:04 -08006327 return True
6328 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006329 ad_rx.log.warning("No matched MMS downloaded event.")
Betty Zhoua27e5d42017-01-17 11:33:04 -08006330 return False
6331
6332
Betty Zhou632793c2018-02-09 18:45:39 -08006333def sms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006334 log,
6335 ad_tx,
6336 ad_rx,
6337 subid_tx,
6338 subid_rx,
6339 array_message,
6340 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Ang Li73697b32015-12-03 00:41:53 +00006341 """Send SMS, receive SMS, and verify content and sender's number.
6342
6343 Send (several) SMS from droid_tx to droid_rx.
6344 Verify SMS is sent, delivered and received.
6345 Verify received content and sender's number are correct.
6346
6347 Args:
6348 log: Log object.
6349 ad_tx: Sender's Android Device Object..
6350 ad_rx: Receiver's Android Device Object.
6351 subid_tx: Sender's subsciption ID to be used for SMS
6352 subid_rx: Receiver's subsciption ID to be used for SMS
6353 array_message: the array of message to send/receive
6354 """
Betty Zhou3b2de072018-03-15 16:46:26 -07006355 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6356 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhoud32e0bd2017-12-19 19:44:58 -08006357
Betty Zhou632793c2018-02-09 18:45:39 -08006358 for ad in (ad_tx, ad_rx):
Betty Zhoued13b712018-05-02 19:40:10 -07006359 ad.send_keycode("BACK")
Betty Zhou632793c2018-02-09 18:45:39 -08006360 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08006361 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6362 ad.messaging_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08006363 else:
6364 try:
6365 if not ad.messaging_droid.is_live:
6366 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6367 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006368 else:
6369 ad.messaging_ed.clear_all_events()
6370 ad.messaging_droid.logI(
6371 "Start sms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08006372 except Exception:
6373 ad.log.info("Create new sl4a session for messaging")
Betty Zhouf31dffe2018-02-23 19:29:28 -08006374 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6375 ad.messaging_ed.start()
6376
Ang Li73697b32015-12-03 00:41:53 +00006377 for text in array_message:
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006378 length = len(text)
Betty Zhoua37acd32017-02-23 20:04:24 -08006379 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006380 phonenumber_tx, phonenumber_rx, length, text)
Ang Li73697b32015-12-03 00:41:53 +00006381 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006382 ad_rx.messaging_ed.clear_events(EventSmsReceived)
6383 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07006384 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08006385 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006386 time.sleep(1) #sleep 100ms after starting event tracking
Betty Zhou4411c202018-03-29 18:27:25 -07006387 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
6388 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
Betty Zhou02571f52018-02-16 14:11:16 -08006389 ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
Betty Zhou4411c202018-03-29 18:27:25 -07006390 True)
Ang Li73697b32015-12-03 00:41:53 +00006391 try:
Betty Zhou4411c202018-03-29 18:27:25 -07006392 events = ad_tx.messaging_ed.pop_events(
Betty Zhouc9f723b2018-04-10 18:08:21 -07006393 "(%s|%s|%s|%s)" %
6394 (EventSmsSentSuccess, EventSmsSentFailure,
6395 EventSmsDeliverSuccess,
6396 EventSmsDeliverFailure), max_wait_time)
Betty Zhou4411c202018-03-29 18:27:25 -07006397 for event in events:
6398 ad_tx.log.info("Got event %s", event["name"])
Betty Zhouc9f723b2018-04-10 18:08:21 -07006399 if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
Betty Zhou4411c202018-03-29 18:27:25 -07006400 if event.get("data") and event["data"].get("Reason"):
6401 ad_tx.log.error("%s with reason: %s",
6402 event["name"],
6403 event["data"]["Reason"])
6404 return False
Betty Zhouc9f723b2018-04-10 18:08:21 -07006405 elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
Betty Zhou4411c202018-03-29 18:27:25 -07006406 break
Ang Li73697b32015-12-03 00:41:53 +00006407 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07006408 ad_tx.log.error("No %s or %s event for SMS of length %s.",
6409 EventSmsSentSuccess, EventSmsSentFailure,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006410 length)
Betty Zhoued13b712018-05-02 19:40:10 -07006411 return False
Ang Li73697b32015-12-03 00:41:53 +00006412
Nathan Harold4a144a42016-09-19 14:16:24 -07006413 if not wait_for_matching_sms(
6414 log,
6415 ad_rx,
6416 phonenumber_tx,
6417 text,
Jaineel8e978552020-06-25 19:21:56 -07006418 max_wait_time,
Betty Zhoued13b712018-05-02 19:40:10 -07006419 allow_multi_part_long_sms=True):
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006420 ad_rx.log.error("No matching received SMS of length %s.",
6421 length)
Ang Li73697b32015-12-03 00:41:53 +00006422 return False
Betty Zhou632793c2018-02-09 18:45:39 -08006423 except Exception as e:
6424 log.error("Exception error %s", e)
6425 raise
Ang Li73697b32015-12-03 00:41:53 +00006426 finally:
Betty Zhou632793c2018-02-09 18:45:39 -08006427 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00006428 return True
6429
Nathan Harold123c9da2015-12-30 16:33:25 -08006430
Betty Zhou02571f52018-02-16 14:11:16 -08006431def mms_send_receive_verify(log,
6432 ad_tx,
6433 ad_rx,
6434 array_message,
Betty Zhoued13b712018-05-02 19:40:10 -07006435 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
Jaineelf76b37b2019-01-15 16:08:22 -08006436 expected_result=True,
6437 slot_id_rx=None):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006438 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00006439
Betty Zhou2e08ac32017-01-27 14:21:29 -08006440 Send (several) MMS from droid_tx to droid_rx.
6441 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00006442 Verify received content and sender's number are correct.
6443
6444 Args:
6445 log: Log object.
6446 ad_tx: Sender's Android Device Object
6447 ad_rx: Receiver's Android Device Object
6448 array_message: the array of message to send/receive
6449 """
Jaineelf76b37b2019-01-15 16:08:22 -08006450 subid_tx = get_outgoing_message_sub_id(ad_tx)
6451 if slot_id_rx is None:
6452 subid_rx = get_incoming_message_sub_id(ad_rx)
6453 else:
6454 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
6455
Betty Zhou74cf9922018-04-18 20:18:12 -07006456 result = mms_send_receive_verify_for_subscription(
Jaineelf76b37b2019-01-15 16:08:22 -08006457 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
Betty Zhoued13b712018-05-02 19:40:10 -07006458 if result != expected_result:
Betty Zhou74cf9922018-04-18 20:18:12 -07006459 log_messaging_screen_shot(ad_tx, test_name="mms_tx")
6460 log_messaging_screen_shot(ad_rx, test_name="mms_rx")
Betty Zhoued13b712018-05-02 19:40:10 -07006461 return result == expected_result
Nathan Harold123c9da2015-12-30 16:33:25 -08006462
Ang Li73697b32015-12-03 00:41:53 +00006463
Betty Zhou38028b72017-12-20 17:54:12 -08006464def sms_mms_send_logcat_check(ad, type, begin_time):
6465 type = type.upper()
6466 log_results = ad.search_logcat(
6467 "%s Message sent successfully" % type, begin_time=begin_time)
6468 if log_results:
Betty Zhou1bc12092018-03-19 14:00:23 -07006469 ad.log.info("Found %s sent successful log message: %s", type,
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006470 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006471 return True
6472 else:
6473 log_results = ad.search_logcat(
6474 "ProcessSentMessageAction: Done sending %s message" % type,
6475 begin_time=begin_time)
6476 if log_results:
6477 for log_result in log_results:
6478 if "status is SUCCEEDED" in log_result["log_message"]:
6479 ad.log.info(
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006480 "Found BugleDataModel %s send succeed log message: %s",
6481 type, log_result["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006482 return True
6483 return False
6484
6485
6486def sms_mms_receive_logcat_check(ad, type, begin_time):
6487 type = type.upper()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006488 smshandle_logs = ad.search_logcat(
Betty Zhou1bc12092018-03-19 14:00:23 -07006489 "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
Betty Zhou6b3593f2018-03-16 20:13:55 -07006490 begin_time=begin_time)
6491 if smshandle_logs:
6492 ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006493 log_results = ad.search_logcat(
Jaineel6cd6d442018-01-08 14:50:44 -08006494 "New %s Received" % type, begin_time=begin_time) or \
6495 ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
Betty Zhou38028b72017-12-20 17:54:12 -08006496 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006497 ad.log.info("Found SL4A %s received log message: %s", type,
6498 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006499 return True
6500 else:
6501 log_results = ad.search_logcat(
6502 "Received %s message" % type, begin_time=begin_time)
6503 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006504 ad.log.info("Found %s received log message: %s", type,
6505 log_results[-1]["log_message"])
Betty Zhou10f887e2018-04-10 12:45:00 -07006506 log_results = ad.search_logcat(
6507 "ProcessDownloadedMmsAction", begin_time=begin_time)
6508 for log_result in log_results:
6509 ad.log.info("Found %s", log_result["log_message"])
6510 if "status is SUCCEEDED" in log_result["log_message"]:
6511 ad.log.info("Download succeed with ProcessDownloadedMmsAction")
6512 return True
Betty Zhou38028b72017-12-20 17:54:12 -08006513 return False
6514
6515
Betty Zhoua27e5d42017-01-17 11:33:04 -08006516#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08006517def mms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006518 log,
6519 ad_tx,
6520 ad_rx,
6521 subid_tx,
6522 subid_rx,
6523 array_payload,
6524 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006525 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00006526
Betty Zhou2e08ac32017-01-27 14:21:29 -08006527 Send (several) MMS from droid_tx to droid_rx.
6528 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00006529 Verify received content and sender's number are correct.
6530
6531 Args:
6532 log: Log object.
6533 ad_tx: Sender's Android Device Object..
6534 ad_rx: Receiver's Android Device Object.
6535 subid_tx: Sender's subsciption ID to be used for SMS
6536 subid_rx: Receiver's subsciption ID to be used for SMS
6537 array_message: the array of message to send/receive
6538 """
6539
Betty Zhou3b2de072018-03-15 16:46:26 -07006540 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6541 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Jaineel6f689de2019-08-07 10:20:02 -07006542 toggle_enforce = False
Betty Zhouf715c792018-02-12 17:32:10 -08006543
Betty Zhoue57ab692018-03-09 18:39:30 -08006544 for ad in (ad_tx, ad_rx):
Betty Zhoued13b712018-05-02 19:40:10 -07006545 ad.send_keycode("BACK")
Jaineel72e5d472019-04-01 16:31:27 -07006546 if "Permissive" not in ad.adb.shell("su root getenforce"):
6547 ad.adb.shell("su root setenforce 0")
Jaineel6f689de2019-08-07 10:20:02 -07006548 toggle_enforce = True
Betty Zhou632793c2018-02-09 18:45:39 -08006549 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08006550 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6551 ad.messaging_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08006552 else:
6553 try:
6554 if not ad.messaging_droid.is_live:
6555 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6556 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006557 else:
6558 ad.messaging_ed.clear_all_events()
6559 ad.messaging_droid.logI(
6560 "Start mms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08006561 except Exception:
6562 ad.log.info("Create new sl4a session for messaging")
6563 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6564 ad.messaging_ed.start()
Betty Zhou38028b72017-12-20 17:54:12 -08006565
Ang Li73697b32015-12-03 00:41:53 +00006566 for subject, message, filename in array_payload:
Betty Zhou632793c2018-02-09 18:45:39 -08006567 ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07006568 ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08006569 ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
6570 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhouf715c792018-02-12 17:32:10 -08006571 ad_tx.log.info(
6572 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
6573 phonenumber_tx, phonenumber_rx, subject, message, filename)
Ang Li73697b32015-12-03 00:41:53 +00006574 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006575 ad_tx.messaging_droid.smsSendMultimediaMessage(
Nathan Harold123c9da2015-12-30 16:33:25 -08006576 phonenumber_rx, subject, message, phonenumber_tx, filename)
Betty Zhoua27e5d42017-01-17 11:33:04 -08006577 try:
Betty Zhou4411c202018-03-29 18:27:25 -07006578 events = ad_tx.messaging_ed.pop_events(
6579 "(%s|%s)" % (EventMmsSentSuccess,
6580 EventMmsSentFailure), max_wait_time)
6581 for event in events:
6582 ad_tx.log.info("Got event %s", event["name"])
6583 if event["name"] == EventMmsSentFailure:
6584 if event.get("data") and event["data"].get("Reason"):
6585 ad_tx.log.error("%s with reason: %s",
6586 event["name"],
6587 event["data"]["Reason"])
6588 return False
6589 elif event["name"] == EventMmsSentSuccess:
6590 break
Betty Zhoua27e5d42017-01-17 11:33:04 -08006591 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07006592 ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
6593 EventMmsSentFailure)
Jaineel8e978552020-06-25 19:21:56 -07006594 return False
Betty Zhou2e08ac32017-01-27 14:21:29 -08006595
Jaineel4b9760a2018-12-13 14:42:10 -08006596 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx,
6597 message, max_wait_time):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006598 return False
Betty Zhou632793c2018-02-09 18:45:39 -08006599 except Exception as e:
6600 log.error("Exception error %s", e)
6601 raise
Betty Zhou2e08ac32017-01-27 14:21:29 -08006602 finally:
Jaineel8e978552020-06-25 19:21:56 -07006603 ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
Jaineel72e5d472019-04-01 16:31:27 -07006604 for ad in (ad_tx, ad_rx):
Jaineel6f689de2019-08-07 10:20:02 -07006605 if toggle_enforce:
6606 ad.send_keycode("BACK")
6607 ad.adb.shell("su root setenforce 1")
Betty Zhou2e08ac32017-01-27 14:21:29 -08006608 return True
6609
6610
Betty Zhou632793c2018-02-09 18:45:39 -08006611def mms_receive_verify_after_call_hangup(
Betty Zhou02571f52018-02-16 14:11:16 -08006612 log, ad_tx, ad_rx, array_message,
6613 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006614 """Verify the suspanded MMS during call will send out after call release.
6615
6616 Hangup call from droid_tx to droid_rx.
6617 Verify MMS is sent, delivered and received.
6618 Verify received content and sender's number are correct.
6619
6620 Args:
6621 log: Log object.
6622 ad_tx: Sender's Android Device Object
6623 ad_rx: Receiver's Android Device Object
6624 array_message: the array of message to send/receive
6625 """
6626 return mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006627 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
Betty Zhou632793c2018-02-09 18:45:39 -08006628 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
Betty Zhou2e08ac32017-01-27 14:21:29 -08006629
6630
6631#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
6632def mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006633 log,
6634 ad_tx,
6635 ad_rx,
6636 subid_tx,
6637 subid_rx,
6638 array_payload,
Betty Zhou632793c2018-02-09 18:45:39 -08006639 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006640 """Verify the suspanded MMS during call will send out after call release.
6641
6642 Hangup call from droid_tx to droid_rx.
6643 Verify MMS is sent, delivered and received.
6644 Verify received content and sender's number are correct.
6645
6646 Args:
6647 log: Log object.
6648 ad_tx: Sender's Android Device Object..
6649 ad_rx: Receiver's Android Device Object.
6650 subid_tx: Sender's subsciption ID to be used for SMS
6651 subid_rx: Receiver's subsciption ID to be used for SMS
6652 array_message: the array of message to send/receive
6653 """
6654
Betty Zhou3b2de072018-03-15 16:46:26 -07006655 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6656 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhou08c1a572018-02-13 20:07:55 -08006657 for ad in (ad_tx, ad_rx):
6658 if not getattr(ad, "messaging_droid", None):
6659 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6660 ad.messaging_ed.start()
Betty Zhou2e08ac32017-01-27 14:21:29 -08006661 for subject, message, filename in array_payload:
Betty Zhoua37acd32017-02-23 20:04:24 -08006662 ad_rx.log.info(
6663 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
6664 phonenumber_tx, phonenumber_rx, subject, message, filename)
Betty Zhou632793c2018-02-09 18:45:39 -08006665 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhou2e08ac32017-01-27 14:21:29 -08006666 time.sleep(5)
6667 try:
6668 hangup_call(log, ad_tx)
6669 hangup_call(log, ad_rx)
6670 try:
Betty Zhou3ea56122018-03-14 17:37:24 -07006671 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
6672 max_wait_time)
Betty Zhou1c8c8d42018-03-14 12:43:50 -07006673 ad_tx.log.info("Got event %s", EventMmsSentSuccess)
Betty Zhou2e08ac32017-01-27 14:21:29 -08006674 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006675 log.warning("No sent_success event.")
Betty Zhoued13b712018-05-02 19:40:10 -07006676 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
Ang Li73697b32015-12-03 00:41:53 +00006677 return False
6678 finally:
Markus Liu6b41e092020-08-17 15:55:28 +08006679 ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00006680 return True
6681
Nathan Harold123c9da2015-12-30 16:33:25 -08006682
Preetesh Barretto0b64c8e2019-03-07 08:43:29 -08006683def ensure_preferred_network_type_for_subscription(
6684 ad,
6685 network_preference
6686 ):
6687 sub_id = ad.droid.subscriptionGetDefaultSubId()
6688 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6689 network_preference, sub_id):
6690 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
6691 sub_id, network_preference)
6692 return True
6693
6694
Nathan Harold123c9da2015-12-30 16:33:25 -08006695def ensure_network_rat(log,
6696 ad,
6697 network_preference,
6698 rat_family,
6699 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006700 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006701 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006702 """Ensure ad's current network is in expected rat_family.
6703 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006704 return ensure_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006705 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
6706 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
Ang Li73697b32015-12-03 00:41:53 +00006707
Nathan Harold123c9da2015-12-30 16:33:25 -08006708
Nathan Harold7642fc92016-05-02 18:29:11 -07006709def ensure_network_rat_for_subscription(
6710 log,
6711 ad,
6712 sub_id,
6713 network_preference,
6714 rat_family,
6715 voice_or_data=None,
6716 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
6717 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006718 """Ensure ad's current network is in expected rat_family.
6719 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006720 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6721 network_preference, sub_id):
Betty Zhoua37acd32017-02-23 20:04:24 -08006722 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
6723 sub_id, network_preference)
Yang Liue23e5b12015-12-07 17:17:27 -08006724 return False
6725 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
Nathan Harold123c9da2015-12-30 16:33:25 -08006726 voice_or_data):
Betty Zhoua37acd32017-02-23 20:04:24 -08006727 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
6728 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08006729 return True
6730
6731 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006732 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006733 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006734 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006735
6736 result = wait_for_network_rat_for_subscription(
6737 log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
6738
Nathan Harold123c9da2015-12-30 16:33:25 -08006739 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08006740 "End of ensure_network_rat_for_subscription for %s. "
6741 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
6742 "data: %s(family: %s)", ad.serial, network_preference, rat_family,
6743 voice_or_data,
6744 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6745 rat_family_from_rat(
6746 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6747 sub_id)),
6748 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6749 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006750 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006751 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08006752 return result
6753
Nathan Harold123c9da2015-12-30 16:33:25 -08006754
6755def ensure_network_preference(log,
6756 ad,
6757 network_preference,
6758 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006759 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006760 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006761 """Ensure that current rat is within the device's preferred network rats.
6762 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006763 return ensure_network_preference_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006764 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08006765 voice_or_data, max_wait_time, toggle_apm_after_setting)
6766
Nathan Harold123c9da2015-12-30 16:33:25 -08006767
6768def ensure_network_preference_for_subscription(
6769 log,
6770 ad,
6771 sub_id,
6772 network_preference,
6773 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006774 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006775 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006776 """Ensure ad's network preference is <network_preference> for sub_id.
6777 """
6778 rat_family_list = rat_families_for_network_preference(network_preference)
Nathan Harold123c9da2015-12-30 16:33:25 -08006779 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6780 network_preference, sub_id):
Yang Liue23e5b12015-12-07 17:17:27 -08006781 log.error("Set Preferred Networks failed.")
6782 return False
Nathan Harold123c9da2015-12-30 16:33:25 -08006783 if is_droid_in_rat_family_list_for_subscription(
6784 log, ad, sub_id, rat_family_list, voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08006785 return True
6786
6787 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006788 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006789 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006790 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006791
6792 result = wait_for_preferred_network_for_subscription(
6793 log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
6794
Betty Zhoua37acd32017-02-23 20:04:24 -08006795 ad.log.info(
6796 "End of ensure_network_preference_for_subscription. "
6797 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
6798 "data: %s(family: %s)", network_preference, rat_family_list,
6799 voice_or_data,
6800 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6801 rat_family_from_rat(
6802 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6803 sub_id)),
6804 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6805 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006806 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006807 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08006808 return result
6809
Nathan Harold123c9da2015-12-30 16:33:25 -08006810
6811def ensure_network_generation(log,
6812 ad,
6813 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006814 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006815 voice_or_data=None,
6816 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006817 """Ensure ad's network is <network generation> for default subscription ID.
6818
6819 Set preferred network generation to <generation>.
6820 Toggle ON/OFF airplane mode if necessary.
6821 Wait for ad in expected network type.
6822 """
6823 return ensure_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006824 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
6825 max_wait_time, voice_or_data, toggle_apm_after_setting)
Yang Liue23e5b12015-12-07 17:17:27 -08006826
Nathan Harold123c9da2015-12-30 16:33:25 -08006827
6828def ensure_network_generation_for_subscription(
6829 log,
6830 ad,
6831 sub_id,
6832 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006833 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006834 voice_or_data=None,
6835 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006836 """Ensure ad's network is <network generation> for specified subscription ID.
6837
Richachab7c94eb2021-04-11 17:32:44 +08006838 Set preferred network generation to <generation>.
6839 Toggle ON/OFF airplane mode if necessary.
6840 Wait for ad in expected network type.
6841
6842 Args:
6843 log: log object.
6844 ad: android device object.
6845 sub_id: subscription id.
6846 generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G.
6847 max_wait_time: the time to wait for NW selection.
6848 voice_or_data: check voice network generation or data network generation
6849 This parameter is optional. If voice_or_data is None, then if
6850 either voice or data in expected generation, function will return True.
6851 toggle_apm_after_setting: Cycle airplane mode if True, otherwise do nothing.
6852
6853 Returns:
6854 True if success, False if fail.
Yang Liue23e5b12015-12-07 17:17:27 -08006855 """
Betty Zhoua37acd32017-02-23 20:04:24 -08006856 ad.log.info(
6857 "RAT network type voice: %s, data: %s",
6858 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6859 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
Betty Zhoua37acd32017-02-23 20:04:24 -08006860
Yang Liue23e5b12015-12-07 17:17:27 -08006861 try:
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006862 ad.log.info("Finding the network preference for generation %s for "
6863 "operator %s phone type %s", generation,
Betty Zhou3b2de072018-03-15 16:46:26 -07006864 ad.telephony["subscription"][sub_id]["operator"],
6865 ad.telephony["subscription"][sub_id]["phone_type"])
Jaineelc52d6852017-10-27 15:03:54 -07006866 network_preference = network_preference_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07006867 generation, ad.telephony["subscription"][sub_id]["operator"],
6868 ad.telephony["subscription"][sub_id]["phone_type"])
Jaineel254dd5d2018-12-03 18:46:36 -08006869 if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \
6870 and generation == GEN_4G:
6871 network_preference = NETWORK_MODE_LTE_ONLY
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006872 ad.log.info("Network preference for %s is %s", generation,
6873 network_preference)
6874 rat_family = rat_family_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07006875 generation, ad.telephony["subscription"][sub_id]["operator"],
6876 ad.telephony["subscription"][sub_id]["phone_type"])
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006877 except KeyError as e:
6878 ad.log.error("Failed to find a rat_family entry for generation %s"
Markus Liu9b24f712018-11-12 15:31:14 +08006879 " for subscriber id %s with error %s", generation,
6880 sub_id, e)
Yang Liue23e5b12015-12-07 17:17:27 -08006881 return False
6882
Betty Zhou1eedf722018-04-27 14:27:04 -07006883 if not set_preferred_network_mode_pref(log, ad, sub_id,
6884 network_preference):
6885 return False
Yang Liue23e5b12015-12-07 17:17:27 -08006886
Jaineel15c50562019-03-29 15:45:32 -07006887 if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad):
6888 ad.log.info("MSIM - Non DDS, ignore data RAT")
6889 return True
6890
Markus Liua3fa4f42021-03-16 20:02:14 +08006891 if generation == GEN_5G:
Richachaa4820752021-04-11 16:46:45 +08006892 if is_current_network_5g_nsa_for_subscription(ad, sub_id=sub_id):
Markus Liua3fa4f42021-03-16 20:02:14 +08006893 ad.log.info("Current network type is 5G NSA.")
6894 return True
Richachaa4820752021-04-11 16:46:45 +08006895 else:
6896 ad.log.error("Not in 5G NSA coverage for Sub %s.", sub_id)
6897 return False
Markus Liua3fa4f42021-03-16 20:02:14 +08006898
Nathan Harold4a144a42016-09-19 14:16:24 -07006899 if is_droid_in_network_generation_for_subscription(
6900 log, ad, sub_id, generation, voice_or_data):
6901 return True
6902
Yang Liue23e5b12015-12-07 17:17:27 -08006903 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006904 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006905 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006906 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006907
6908 result = wait_for_network_generation_for_subscription(
6909 log, ad, sub_id, generation, max_wait_time, voice_or_data)
6910
Betty Zhoua37acd32017-02-23 20:04:24 -08006911 ad.log.info(
Betty Zhou0f5efc42017-04-10 18:38:14 -07006912 "Ensure network %s %s %s. With network preference %s, "
Betty Zhoue955be22017-04-12 17:28:05 -07006913 "current: voice: %s(family: %s), data: %s(family: %s)", generation,
6914 voice_or_data, result, network_preference,
Betty Zhoua37acd32017-02-23 20:04:24 -08006915 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6916 rat_generation_from_rat(
6917 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6918 sub_id)),
6919 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6920 rat_generation_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006921 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006922 sub_id)))
Betty Zhou351d1792017-11-10 16:26:30 -08006923 if not result:
Betty Zhoufe726dc2018-04-25 19:31:33 -07006924 get_telephony_signal_strength(ad)
Yang Liue23e5b12015-12-07 17:17:27 -08006925 return result
6926
Yang Liue23e5b12015-12-07 17:17:27 -08006927
Nathan Harold123c9da2015-12-30 16:33:25 -08006928def wait_for_network_rat(log,
6929 ad,
6930 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006931 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006932 voice_or_data=None):
6933 return wait_for_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006934 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
6935 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006936
6937
Nathan Harold7642fc92016-05-02 18:29:11 -07006938def wait_for_network_rat_for_subscription(
6939 log,
6940 ad,
6941 sub_id,
6942 rat_family,
6943 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
6944 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006945 return _wait_for_droid_in_state_for_subscription(
6946 log, ad, sub_id, max_wait_time,
6947 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
6948
Yang Liue23e5b12015-12-07 17:17:27 -08006949
Nathan Harold123c9da2015-12-30 16:33:25 -08006950def wait_for_not_network_rat(log,
6951 ad,
6952 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006953 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006954 voice_or_data=None):
6955 return wait_for_not_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006956 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
6957 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006958
6959
6960def wait_for_not_network_rat_for_subscription(
6961 log,
6962 ad,
6963 sub_id,
6964 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006965 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006966 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006967 return _wait_for_droid_in_state_for_subscription(
6968 log, ad, sub_id, max_wait_time,
Betty Zhouf809c5c2017-03-21 14:55:59 -07006969 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 -08006970 )
Yang Liue23e5b12015-12-07 17:17:27 -08006971
Nathan Harold123c9da2015-12-30 16:33:25 -08006972
6973def wait_for_preferred_network(log,
6974 ad,
6975 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08006976 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006977 voice_or_data=None):
6978 return wait_for_preferred_network_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006979 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08006980 max_wait_time, voice_or_data)
6981
Nathan Harold123c9da2015-12-30 16:33:25 -08006982
6983def wait_for_preferred_network_for_subscription(
6984 log,
6985 ad,
6986 sub_id,
6987 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08006988 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006989 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006990 rat_family_list = rat_families_for_network_preference(network_preference)
6991 return _wait_for_droid_in_state_for_subscription(
6992 log, ad, sub_id, max_wait_time,
6993 is_droid_in_rat_family_list_for_subscription, rat_family_list,
6994 voice_or_data)
6995
Nathan Harold123c9da2015-12-30 16:33:25 -08006996
6997def wait_for_network_generation(log,
6998 ad,
6999 generation,
Yang Liudf164e32016-01-07 16:49:32 -08007000 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08007001 voice_or_data=None):
7002 return wait_for_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08007003 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
7004 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08007005
7006
7007def wait_for_network_generation_for_subscription(
7008 log,
7009 ad,
7010 sub_id,
7011 generation,
Yang Liudf164e32016-01-07 16:49:32 -08007012 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08007013 voice_or_data=None):
7014 return _wait_for_droid_in_state_for_subscription(
7015 log, ad, sub_id, max_wait_time,
7016 is_droid_in_network_generation_for_subscription, generation,
Yang Liue23e5b12015-12-07 17:17:27 -08007017 voice_or_data)
7018
Yang Liue23e5b12015-12-07 17:17:27 -08007019
7020def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None):
Nathan Harold123c9da2015-12-30 16:33:25 -08007021 return is_droid_in_rat_family_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08007022 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
7023 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08007024
Yang Liue23e5b12015-12-07 17:17:27 -08007025
Nathan Harold123c9da2015-12-30 16:33:25 -08007026def is_droid_in_rat_family_for_subscription(log,
7027 ad,
7028 sub_id,
7029 rat_family,
7030 voice_or_data=None):
7031 return is_droid_in_rat_family_list_for_subscription(
7032 log, ad, sub_id, [rat_family], voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08007033
Nathan Harold123c9da2015-12-30 16:33:25 -08007034
7035def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None):
7036 return is_droid_in_rat_family_list_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08007037 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list,
7038 voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08007039
7040
7041def is_droid_in_rat_family_list_for_subscription(log,
7042 ad,
7043 sub_id,
7044 rat_family_list,
7045 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08007046 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
7047 if voice_or_data:
7048 service_list = [voice_or_data]
7049
7050 for service in service_list:
7051 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
7052 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
7053 continue
Yang Liu7a2e7ee2015-12-28 15:32:44 -08007054 if rat_family_from_rat(nw_rat) in rat_family_list:
Yang Liue23e5b12015-12-07 17:17:27 -08007055 return True
7056 return False
7057
Nathan Harold123c9da2015-12-30 16:33:25 -08007058
Yang Liue23e5b12015-12-07 17:17:27 -08007059def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data):
7060 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00007061
7062 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08007063 log: log object.
7064 ad: android device.
7065 nw_gen: expected generation "4g", "3g", "2g".
7066 voice_or_data: check voice network generation or data network generation
7067 This parameter is optional. If voice_or_data is None, then if
7068 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00007069
7070 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08007071 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00007072 """
Yang Liue23e5b12015-12-07 17:17:27 -08007073 return is_droid_in_network_generation_for_subscription(
7074 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data)
Ang Li73697b32015-12-03 00:41:53 +00007075
Nathan Harold123c9da2015-12-30 16:33:25 -08007076
7077def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen,
7078 voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08007079 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00007080
7081 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08007082 log: log object.
7083 ad: android device.
7084 nw_gen: expected generation "4g", "3g", "2g".
7085 voice_or_data: check voice network generation or data network generation
7086 This parameter is optional. If voice_or_data is None, then if
7087 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00007088
7089 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08007090 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00007091 """
Yang Liue23e5b12015-12-07 17:17:27 -08007092 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
Ang Li73697b32015-12-03 00:41:53 +00007093
Yang Liue23e5b12015-12-07 17:17:27 -08007094 if voice_or_data:
7095 service_list = [voice_or_data]
Ang Li73697b32015-12-03 00:41:53 +00007096
Yang Liue23e5b12015-12-07 17:17:27 -08007097 for service in service_list:
7098 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
Betty Zhou89d090b2017-05-23 11:12:19 -07007099 ad.log.info("%s network rat is %s", service, nw_rat)
Yang Liue23e5b12015-12-07 17:17:27 -08007100 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
7101 continue
7102
Yang Liu7a2e7ee2015-12-28 15:32:44 -08007103 if rat_generation_from_rat(nw_rat) == nw_gen:
Betty Zhou89d090b2017-05-23 11:12:19 -07007104 ad.log.info("%s network rat %s is expected %s", service, nw_rat,
7105 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08007106 return True
7107 else:
Betty Zhou89d090b2017-05-23 11:12:19 -07007108 ad.log.info("%s network rat %s is %s, does not meet expected %s",
Betty Zhouee311052017-12-19 13:09:56 -08007109 service, nw_rat, rat_generation_from_rat(nw_rat),
7110 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08007111 return False
7112
7113 return False
Ang Li73697b32015-12-03 00:41:53 +00007114
Nathan Harold123c9da2015-12-30 16:33:25 -08007115
Ang Li73697b32015-12-03 00:41:53 +00007116def get_network_rat(log, ad, voice_or_data):
7117 """Get current network type (Voice network type, or data network type)
7118 for default subscription id
7119
7120 Args:
7121 ad: Android Device Object
7122 voice_or_data: Input parameter indicating to get voice network type or
7123 data network type.
7124
7125 Returns:
7126 Current voice/data network type.
7127 """
7128 return get_network_rat_for_subscription(
7129 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
7130
Nathan Harold123c9da2015-12-30 16:33:25 -08007131
Ang Li73697b32015-12-03 00:41:53 +00007132def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data):
7133 """Get current network type (Voice network type, or data network type)
7134 for specified subscription id
7135
7136 Args:
7137 ad: Android Device Object
7138 sub_id: subscription ID
7139 voice_or_data: Input parameter indicating to get voice network type or
7140 data network type.
7141
7142 Returns:
7143 Current voice/data network type.
7144 """
7145 if voice_or_data == NETWORK_SERVICE_VOICE:
Nathan Harold123c9da2015-12-30 16:33:25 -08007146 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
7147 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007148 elif voice_or_data == NETWORK_SERVICE_DATA:
Nathan Harold123c9da2015-12-30 16:33:25 -08007149 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
7150 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007151 else:
Yang Liuaed3eef2015-12-15 18:40:25 -08007152 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007153
7154 if ret_val is None:
7155 log.error("get_network_rat(): Unexpected null return value")
7156 return RAT_UNKNOWN
7157 else:
7158 return ret_val
7159
Nathan Harold123c9da2015-12-30 16:33:25 -08007160
Ang Li73697b32015-12-03 00:41:53 +00007161def get_network_gen(log, ad, voice_or_data):
7162 """Get current network generation string (Voice network type, or data network type)
7163
7164 Args:
7165 ad: Android Device Object
7166 voice_or_data: Input parameter indicating to get voice network generation
7167 or data network generation.
7168
7169 Returns:
7170 Current voice/data network generation.
7171 """
7172 return get_network_gen_for_subscription(
7173 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
7174
Nathan Harold123c9da2015-12-30 16:33:25 -08007175
Ang Li73697b32015-12-03 00:41:53 +00007176def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data):
7177 """Get current network generation string (Voice network type, or data network type)
7178
7179 Args:
7180 ad: Android Device Object
7181 voice_or_data: Input parameter indicating to get voice network generation
7182 or data network generation.
7183
7184 Returns:
7185 Current voice/data network generation.
7186 """
7187 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07007188 return rat_generation_from_rat(
7189 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data))
Betty Zhoua37acd32017-02-23 20:04:24 -08007190 except KeyError as e:
7191 ad.log.error("KeyError %s", e)
Yang Liue23e5b12015-12-07 17:17:27 -08007192 return GEN_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00007193
Nathan Harold123c9da2015-12-30 16:33:25 -08007194
7195def check_voice_mail_count(log, ad, voice_mail_count_before,
7196 voice_mail_count_after):
Ang Li73697b32015-12-03 00:41:53 +00007197 """function to check if voice mail count is correct after leaving a new voice message.
7198 """
7199 return get_voice_mail_count_check_function(get_operator_name(log, ad))(
7200 voice_mail_count_before, voice_mail_count_after)
7201
Nathan Harold123c9da2015-12-30 16:33:25 -08007202
Ang Li73697b32015-12-03 00:41:53 +00007203def get_voice_mail_number(log, ad):
7204 """function to get the voice mail number
7205 """
Betty Zhou94023182017-06-07 18:02:14 -07007206 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00007207 if voice_mail_number is None:
7208 return get_phone_number(log, ad)
7209 return voice_mail_number
7210
Nathan Harold123c9da2015-12-30 16:33:25 -08007211
Betty Zhouf809c5c2017-03-21 14:55:59 -07007212def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00007213 """Ensure ads idle (not in call).
7214 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07007215 result = True
Ang Li73697b32015-12-03 00:41:53 +00007216 for ad in ads:
Betty Zhouf809c5c2017-03-21 14:55:59 -07007217 if not ensure_phone_idle(log, ad, max_time=max_time):
7218 result = False
7219 return result
Ang Li73697b32015-12-03 00:41:53 +00007220
Nathan Harold123c9da2015-12-30 16:33:25 -08007221
Markus Liu61220b72019-08-01 16:26:22 +08007222def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP, retry=2):
Ang Li73697b32015-12-03 00:41:53 +00007223 """Ensure ad idle (not in call).
7224 """
Markus Liu61220b72019-08-01 16:26:22 +08007225 while ad.droid.telecomIsInCall() and retry > 0:
Betty Zhouf809c5c2017-03-21 14:55:59 -07007226 ad.droid.telecomEndCall()
Markus Liu61220b72019-08-01 16:26:22 +08007227 time.sleep(3)
7228 retry -= 1
Betty Zhouf809c5c2017-03-21 14:55:59 -07007229 if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
Betty Zhou94023182017-06-07 18:02:14 -07007230 ad.log.error("Failed to end call")
Betty Zhouf809c5c2017-03-21 14:55:59 -07007231 return False
7232 return True
Ang Li73697b32015-12-03 00:41:53 +00007233
Nathan Harold123c9da2015-12-30 16:33:25 -08007234
Betty Zhou7f45f552017-03-15 19:12:52 -07007235def ensure_phone_subscription(log, ad):
7236 """Ensure Phone Subscription.
7237 """
7238 #check for sim and service
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007239 duration = 0
7240 while duration < MAX_WAIT_TIME_NW_SELECTION:
7241 subInfo = ad.droid.subscriptionGetAllSubInfoList()
7242 if subInfo and len(subInfo) >= 1:
Betty Zhoue32dd3b2017-11-28 19:05:55 -08007243 ad.log.debug("Find valid subcription %s", subInfo)
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007244 break
7245 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07007246 ad.log.info("Did not find any subscription")
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007247 time.sleep(5)
7248 duration += 5
7249 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07007250 ad.log.error("Unable to find a valid subscription!")
Betty Zhou7f45f552017-03-15 19:12:52 -07007251 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07007252 while duration < MAX_WAIT_TIME_NW_SELECTION:
7253 data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
7254 voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
7255 if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
7256 ad.log.debug("Find valid voice or data sub id")
7257 break
7258 else:
7259 ad.log.info("Did not find valid data or voice sub id")
7260 time.sleep(5)
7261 duration += 5
7262 else:
7263 ad.log.error("Unable to find valid data or voice sub id")
Betty Zhou7f45f552017-03-15 19:12:52 -07007264 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07007265 while duration < MAX_WAIT_TIME_NW_SELECTION:
Markus Liuc97ceab2020-12-16 14:53:37 +08007266 data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
Betty Zhoub14c1012018-04-20 11:27:00 -07007267 if data_sub_id > INVALID_SUB_ID:
7268 data_rat = get_network_rat_for_subscription(
7269 log, ad, data_sub_id, NETWORK_SERVICE_DATA)
7270 else:
7271 data_rat = RAT_UNKNOWN
7272 if voice_sub_id > INVALID_SUB_ID:
7273 voice_rat = get_network_rat_for_subscription(
7274 log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
7275 else:
7276 voice_rat = RAT_UNKNOWN
7277 if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
7278 ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
7279 data_sub_id, data_rat, voice_sub_id, voice_rat)
7280 return True
7281 else:
7282 ad.log.info("Did not attach for data or voice service")
7283 time.sleep(5)
7284 duration += 5
7285 else:
7286 ad.log.error("Did not attach for voice or data service")
Betty Zhou7f45f552017-03-15 19:12:52 -07007287 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07007288
7289
Markus Liu61220b72019-08-01 16:26:22 +08007290def ensure_phone_default_state(log, ad, check_subscription=True, retry=2):
Ang Li73697b32015-12-03 00:41:53 +00007291 """Ensure ad in default state.
7292 Phone not in call.
7293 Phone have no stored WiFi network and WiFi disconnected.
7294 Phone not in airplane mode.
7295 """
7296 result = True
Betty Zhouf25ce442017-03-03 14:28:36 -08007297 if not toggle_airplane_mode(log, ad, False, False):
7298 ad.log.error("Fail to turn off airplane mode")
7299 result = False
Betty Zhou94023182017-06-07 18:02:14 -07007300 try:
Betty Zhou77f2bed2017-10-04 18:39:07 -07007301 set_wifi_to_default(log, ad)
Markus Liu61220b72019-08-01 16:26:22 +08007302 while ad.droid.telecomIsInCall() and retry > 0:
Betty Zhou94023182017-06-07 18:02:14 -07007303 ad.droid.telecomEndCall()
Markus Liu61220b72019-08-01 16:26:22 +08007304 time.sleep(3)
7305 retry -= 1
7306 if not wait_for_droid_not_in_call(log, ad):
7307 ad.log.error("Failed to end call")
Jaineelcb217b62020-11-03 14:33:40 -08007308 #ad.droid.telephonyFactoryReset()
Betty Zhou2cf788e2017-06-27 17:25:53 -07007309 data_roaming = getattr(ad, 'roaming', False)
7310 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
7311 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Jaineel Mehta750c3362020-11-19 00:50:50 +00007312 #remove_mobile_data_usage_limit(ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07007313 if not wait_for_not_network_rat(
7314 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
7315 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
7316 RAT_FAMILY_WLAN)
7317 result = False
7318
7319 if check_subscription and not ensure_phone_subscription(log, ad):
7320 ad.log.error("Unable to find a valid subscription!")
7321 result = False
Betty Zhou94023182017-06-07 18:02:14 -07007322 except Exception as e:
7323 ad.log.error("%s failure, toggle APM instead", e)
Betty Zhou77f2bed2017-10-04 18:39:07 -07007324 toggle_airplane_mode_by_adb(log, ad, True)
7325 toggle_airplane_mode_by_adb(log, ad, False)
7326 ad.send_keycode("ENDCALL")
7327 ad.adb.shell("settings put global wfc_ims_enabled 0")
7328 ad.adb.shell("settings put global mobile_data 1")
Betty Zhouf809c5c2017-03-21 14:55:59 -07007329
Ang Li73697b32015-12-03 00:41:53 +00007330 return result
7331
Nathan Harold123c9da2015-12-30 16:33:25 -08007332
Betty Zhou68fc0d02017-04-26 13:42:54 -07007333def ensure_phones_default_state(log, ads, check_subscription=True):
Ang Li73697b32015-12-03 00:41:53 +00007334 """Ensure ads in default state.
7335 Phone not in call.
7336 Phone have no stored WiFi network and WiFi disconnected.
7337 Phone not in airplane mode.
Nathan Haroldeb60b192016-08-24 14:41:55 -07007338
7339 Returns:
7340 True if all steps of restoring default state succeed.
7341 False if any of the steps to restore default state fails.
Ang Li73697b32015-12-03 00:41:53 +00007342 """
7343 tasks = []
7344 for ad in ads:
Betty Zhou68fc0d02017-04-26 13:42:54 -07007345 tasks.append((ensure_phone_default_state, (log, ad,
7346 check_subscription)))
Ang Li73697b32015-12-03 00:41:53 +00007347 if not multithread_func(log, tasks):
7348 log.error("Ensure_phones_default_state Fail.")
7349 return False
7350 return True
7351
Nathan Harold123c9da2015-12-30 16:33:25 -08007352
Betty Zhoua37acd32017-02-23 20:04:24 -08007353def check_is_wifi_connected(log, ad, wifi_ssid):
7354 """Check if ad is connected to wifi wifi_ssid.
Ang Li73697b32015-12-03 00:41:53 +00007355
7356 Args:
7357 log: Log object.
7358 ad: Android device object.
7359 wifi_ssid: WiFi network SSID.
Ang Li73697b32015-12-03 00:41:53 +00007360
Betty Zhoua37acd32017-02-23 20:04:24 -08007361 Returns:
7362 True if wifi is connected to wifi_ssid
7363 False if wifi is not connected to wifi_ssid
Ang Li73697b32015-12-03 00:41:53 +00007364 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007365 wifi_info = ad.droid.wifiGetConnectionInfo()
Betty Zhouee311052017-12-19 13:09:56 -08007366 if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid:
Betty Zhoua37acd32017-02-23 20:04:24 -08007367 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007368 ad.on_mobile_data = False
Betty Zhouccd171d2017-02-13 15:11:33 -08007369 return True
Betty Zhoua37acd32017-02-23 20:04:24 -08007370 else:
7371 ad.log.info("Wifi is not connected to %s", wifi_ssid)
7372 ad.log.debug("Wifi connection_info=%s", wifi_info)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007373 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007374 return False
7375
7376
Markus Liud1468dc2020-03-05 18:43:17 +08007377def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3, apm=False):
Betty Zhoua37acd32017-02-23 20:04:24 -08007378 """Ensure ad connected to wifi on network wifi_ssid.
7379
7380 Args:
7381 log: Log object.
7382 ad: Android device object.
7383 wifi_ssid: WiFi network SSID.
7384 wifi_pwd: optional secure network password.
7385 retries: the number of retries.
7386
7387 Returns:
7388 True if wifi is connected to wifi_ssid
7389 False if wifi is not connected to wifi_ssid
7390 """
Markus Liud1468dc2020-03-05 18:43:17 +08007391 if not toggle_airplane_mode(log, ad, apm, strict_checking=False):
7392 return False
7393
Betty Zhouf987b8f2017-03-09 16:34:00 -08007394 network = {WIFI_SSID_KEY: wifi_ssid}
Betty Zhouf25ce442017-03-03 14:28:36 -08007395 if wifi_pwd:
Betty Zhouf987b8f2017-03-09 16:34:00 -08007396 network[WIFI_PWD_KEY] = wifi_pwd
Betty Zhouf25ce442017-03-03 14:28:36 -08007397 for i in range(retries):
7398 if not ad.droid.wifiCheckState():
7399 ad.log.info("Wifi state is down. Turn on Wifi")
7400 ad.droid.wifiToggleState(True)
7401 if check_is_wifi_connected(log, ad, wifi_ssid):
7402 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07007403 return verify_internet_connection(log, ad, retries=3)
Betty Zhouf25ce442017-03-03 14:28:36 -08007404 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08007405 ad.log.info("Connecting to wifi %s", wifi_ssid)
Betty Zhou9a27c6a2017-05-22 12:55:50 -07007406 try:
7407 ad.droid.wifiConnectByConfig(network)
7408 except Exception:
Betty Zhou94023182017-06-07 18:02:14 -07007409 ad.log.info("Connecting to wifi by wifiConnect instead")
Betty Zhou9a27c6a2017-05-22 12:55:50 -07007410 ad.droid.wifiConnect(network)
Betty Zhoua37acd32017-02-23 20:04:24 -08007411 time.sleep(20)
7412 if check_is_wifi_connected(log, ad, wifi_ssid):
Betty Zhou68fc0d02017-04-26 13:42:54 -07007413 ad.log.info("Connected to Wifi %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07007414 return verify_internet_connection(log, ad, retries=3)
Betty Zhoua37acd32017-02-23 20:04:24 -08007415 ad.log.info("Fail to connected to wifi %s", wifi_ssid)
Ang Li73697b32015-12-03 00:41:53 +00007416 return False
7417
Nathan Harold123c9da2015-12-30 16:33:25 -08007418
Betty Zhoua37acd32017-02-23 20:04:24 -08007419def forget_all_wifi_networks(log, ad):
7420 """Forget all stored wifi network information
7421
7422 Args:
7423 log: log object
7424 ad: AndroidDevice object
7425
7426 Returns:
7427 boolean success (True) or failure (False)
7428 """
7429 if not ad.droid.wifiGetConfiguredNetworks():
Betty Zhou1b302fd2017-11-17 11:43:09 -08007430 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007431 return True
7432 try:
7433 old_state = ad.droid.wifiCheckState()
Betty Zhouf987b8f2017-03-09 16:34:00 -08007434 wifi_test_utils.reset_wifi(ad)
Betty Zhou7f45f552017-03-15 19:12:52 -07007435 wifi_toggle_state(log, ad, old_state)
Betty Zhoua37acd32017-02-23 20:04:24 -08007436 except Exception as e:
7437 log.error("forget_all_wifi_networks with exception: %s", e)
7438 return False
Betty Zhou1b302fd2017-11-17 11:43:09 -08007439 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007440 return True
7441
7442
Betty Zhouf987b8f2017-03-09 16:34:00 -08007443def wifi_reset(log, ad, disable_wifi=True):
7444 """Forget all stored wifi networks and (optionally) disable WiFi
7445
7446 Args:
7447 log: log object
7448 ad: AndroidDevice object
7449 disable_wifi: boolean to disable wifi, defaults to True
7450 Returns:
7451 boolean success (True) or failure (False)
7452 """
7453 if not forget_all_wifi_networks(log, ad):
7454 ad.log.error("Unable to forget all networks")
7455 return False
7456 if not wifi_toggle_state(log, ad, not disable_wifi):
7457 ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi)
7458 return False
7459 return True
7460
7461
Betty Zhoua37acd32017-02-23 20:04:24 -08007462def set_wifi_to_default(log, ad):
7463 """Set wifi to default state (Wifi disabled and no configured network)
7464
7465 Args:
7466 log: log object
7467 ad: AndroidDevice object
7468
7469 Returns:
7470 boolean success (True) or failure (False)
7471 """
Betty Zhouf25ce442017-03-03 14:28:36 -08007472 ad.droid.wifiFactoryReset()
Betty Zhoua37acd32017-02-23 20:04:24 -08007473 ad.droid.wifiToggleState(False)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007474 ad.on_mobile_data = True
Betty Zhouf987b8f2017-03-09 16:34:00 -08007475
7476
7477def wifi_toggle_state(log, ad, state, retries=3):
7478 """Toggle the WiFi State
7479
7480 Args:
7481 log: log object
7482 ad: AndroidDevice object
7483 state: True, False, or None
7484
7485 Returns:
7486 boolean success (True) or failure (False)
7487 """
7488 for i in range(retries):
7489 if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False):
Betty Zhou1b302fd2017-11-17 11:43:09 -08007490 ad.on_mobile_data = not state
Betty Zhouf987b8f2017-03-09 16:34:00 -08007491 return True
7492 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
7493 return False
7494
7495
7496def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
7497 """Start a Tethering Session
7498
7499 Args:
7500 log: log object
7501 ad: AndroidDevice object
7502 ssid: the name of the WiFi network
7503 password: optional password, used for secure networks.
7504 ap_band=DEPRECATED specification of 2G or 5G tethering
7505 Returns:
7506 boolean success (True) or failure (False)
7507 """
7508 return wifi_test_utils._assert_on_fail_handler(
7509 wifi_test_utils.start_wifi_tethering,
7510 False,
7511 ad,
7512 ssid,
7513 password,
7514 band=ap_band)
7515
7516
7517def stop_wifi_tethering(log, ad):
7518 """Stop a Tethering Session
7519
7520 Args:
7521 log: log object
7522 ad: AndroidDevice object
7523 Returns:
7524 boolean success (True) or failure (False)
7525 """
7526 return wifi_test_utils._assert_on_fail_handler(
7527 wifi_test_utils.stop_wifi_tethering, False, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08007528
7529
Yang Liu98fd9d72016-03-04 12:14:49 -08007530def reset_preferred_network_type_to_allowable_range(log, ad):
7531 """If preferred network type is not in allowable range, reset to GEN_4G
7532 preferred network type.
7533
7534 Args:
7535 log: log object
7536 ad: android device object
7537
7538 Returns:
7539 None
7540 """
Betty Zhou3b2de072018-03-15 16:46:26 -07007541 for sub_id, sub_info in ad.telephony["subscription"].items():
Yang Liu98fd9d72016-03-04 12:14:49 -08007542 current_preference = \
7543 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id)
Betty Zhoubb192482017-03-01 14:38:56 -08007544 ad.log.debug("sub_id network preference is %s", current_preference)
Yang Liu4072cfa2016-04-06 11:25:07 -07007545 try:
Nathan Harold7642fc92016-05-02 18:29:11 -07007546 if current_preference not in get_allowable_network_preference(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07007547 sub_info["operator"], sub_info["phone_type"]):
Jaineelc52d6852017-10-27 15:03:54 -07007548 network_preference = network_preference_for_generation(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07007549 GEN_4G, sub_info["operator"], sub_info["phone_type"])
Yang Liu4072cfa2016-04-06 11:25:07 -07007550 ad.droid.telephonySetPreferredNetworkTypesForSubscription(
7551 network_preference, sub_id)
7552 except KeyError:
7553 pass
Yang Liu98fd9d72016-03-04 12:14:49 -08007554
Nathan Harold7642fc92016-05-02 18:29:11 -07007555
Ang Li73697b32015-12-03 00:41:53 +00007556def task_wrapper(task):
7557 """Task wrapper for multithread_func
7558
7559 Args:
7560 task[0]: function to be wrapped.
7561 task[1]: function args.
7562
7563 Returns:
7564 Return value of wrapped function call.
7565 """
7566 func = task[0]
7567 params = task[1]
7568 return func(*params)
7569
Nathan Harold123c9da2015-12-30 16:33:25 -08007570
Patrick Chiang75b89862017-10-13 17:02:29 -07007571def run_multithread_func_async(log, task):
7572 """Starts a multi-threaded function asynchronously.
7573
7574 Args:
7575 log: log object.
7576 task: a task to be executed in parallel.
7577
7578 Returns:
7579 Future object representing the execution of the task.
7580 """
7581 executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
7582 try:
7583 future_object = executor.submit(task_wrapper, task)
7584 except Exception as e:
7585 log.error("Exception error %s", e)
7586 raise
7587 return future_object
7588
7589
Betty Zhouccd171d2017-02-13 15:11:33 -08007590def run_multithread_func(log, tasks):
7591 """Run multi-thread functions and return results.
7592
7593 Args:
7594 log: log object.
7595 tasks: a list of tasks to be executed in parallel.
7596
7597 Returns:
7598 results for tasks.
7599 """
Betty Zhouee311052017-12-19 13:09:56 -08007600 MAX_NUMBER_OF_WORKERS = 10
Betty Zhouccd171d2017-02-13 15:11:33 -08007601 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
7602 executor = concurrent.futures.ThreadPoolExecutor(
7603 max_workers=number_of_workers)
Betty Zhou8802ec62017-12-18 19:44:29 -08007604 if not log: log = logging
Betty Zhou95ed1862017-07-21 13:29:02 -07007605 try:
7606 results = list(executor.map(task_wrapper, tasks))
7607 except Exception as e:
7608 log.error("Exception error %s", e)
7609 raise
Betty Zhouccd171d2017-02-13 15:11:33 -08007610 executor.shutdown()
Betty Zhou0111ae02017-11-29 20:37:26 -08007611 if log:
7612 log.info("multithread_func %s result: %s",
7613 [task[0].__name__ for task in tasks], results)
Betty Zhouccd171d2017-02-13 15:11:33 -08007614 return results
7615
7616
Ang Li73697b32015-12-03 00:41:53 +00007617def multithread_func(log, tasks):
7618 """Multi-thread function wrapper.
7619
7620 Args:
7621 log: log object.
7622 tasks: tasks to be executed in parallel.
7623
7624 Returns:
7625 True if all tasks return True.
7626 False if any task return False.
7627 """
Betty Zhouccd171d2017-02-13 15:11:33 -08007628 results = run_multithread_func(log, tasks)
Ang Li73697b32015-12-03 00:41:53 +00007629 for r in results:
7630 if not r:
7631 return False
7632 return True
7633
Nathan Harold123c9da2015-12-30 16:33:25 -08007634
Betty Zhouccd171d2017-02-13 15:11:33 -08007635def multithread_func_and_check_results(log, tasks, expected_results):
7636 """Multi-thread function wrapper.
7637
7638 Args:
7639 log: log object.
7640 tasks: tasks to be executed in parallel.
7641 expected_results: check if the results from tasks match expected_results.
7642
7643 Returns:
7644 True if expected_results are met.
7645 False if expected_results are not met.
7646 """
7647 return_value = True
7648 results = run_multithread_func(log, tasks)
7649 log.info("multithread_func result: %s, expecting %s", results,
7650 expected_results)
7651 for task, result, expected_result in zip(tasks, results, expected_results):
7652 if result != expected_result:
7653 logging.info("Result for task %s is %s, expecting %s", task[0],
7654 result, expected_result)
7655 return_value = False
7656 return return_value
7657
7658
Ang Li73697b32015-12-03 00:41:53 +00007659def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME):
7660 """Set phone screen on time.
7661
7662 Args:
7663 log: Log object.
7664 ad: Android device object.
7665 screen_on_time: screen on time.
7666 This is optional, default value is MAX_SCREEN_ON_TIME.
7667 Returns:
7668 True if set successfully.
7669 """
7670 ad.droid.setScreenTimeout(screen_on_time)
7671 return screen_on_time == ad.droid.getScreenTimeout()
7672
Nathan Harold123c9da2015-12-30 16:33:25 -08007673
Ang Li73697b32015-12-03 00:41:53 +00007674def set_phone_silent_mode(log, ad, silent_mode=True):
7675 """Set phone silent mode.
7676
7677 Args:
7678 log: Log object.
7679 ad: Android device object.
7680 silent_mode: set phone silent or not.
7681 This is optional, default value is True (silent mode on).
7682 Returns:
7683 True if set successfully.
7684 """
7685 ad.droid.toggleRingerSilentMode(silent_mode)
Betty Zhoua37acd32017-02-23 20:04:24 -08007686 ad.droid.setMediaVolume(0)
7687 ad.droid.setVoiceCallVolume(0)
7688 ad.droid.setAlarmVolume(0)
Betty Zhoub4f52102018-05-29 14:39:25 -07007689 ad.adb.ensure_root()
Betty Zhoub7663ba2018-05-23 11:56:22 -07007690 ad.adb.shell("setprop ro.audio.silent 1", ignore_status=True)
Jaineelf0c76cf2019-06-20 14:35:06 -07007691 ad.adb.shell("cmd notification set_dnd on", ignore_status=True)
Ang Li73697b32015-12-03 00:41:53 +00007692 return silent_mode == ad.droid.checkRingerSilentMode()
7693
Nathan Harold123c9da2015-12-30 16:33:25 -08007694
Betty Zhou1eedf722018-04-27 14:27:04 -07007695def set_preferred_network_mode_pref(log,
7696 ad,
7697 sub_id,
7698 network_preference,
7699 timeout=WAIT_TIME_ANDROID_STATE_SETTLING):
Jaineelcd748202017-08-10 12:23:42 -07007700 """Set Preferred Network Mode for Sub_id
7701 Args:
7702 log: Log object.
7703 ad: Android device object.
7704 sub_id: Subscription ID.
7705 network_preference: Network Mode Type
7706 """
Betty Zhou1eedf722018-04-27 14:27:04 -07007707 begin_time = get_device_epoch_time(ad)
7708 if ad.droid.telephonyGetPreferredNetworkTypesForSubscription(
7709 sub_id) == network_preference:
7710 ad.log.info("Current ModePref for Sub %s is in %s", sub_id,
7711 network_preference)
7712 return True
Jaineelcd748202017-08-10 12:23:42 -07007713 ad.log.info("Setting ModePref to %s for Sub %s", network_preference,
7714 sub_id)
Betty Zhou1eedf722018-04-27 14:27:04 -07007715 while timeout >= 0:
7716 if ad.droid.telephonySetPreferredNetworkTypesForSubscription(
7717 network_preference, sub_id):
7718 return True
7719 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
7720 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
7721 error_msg = "Failed to set sub_id %s PreferredNetworkType to %s" % (
7722 sub_id, network_preference)
7723 search_results = ad.search_logcat(
7724 "REQUEST_SET_PREFERRED_NETWORK_TYPE error", begin_time=begin_time)
7725 if search_results:
7726 log_message = search_results[-1]["log_message"]
7727 if "DEVICE_IN_USE" in log_message:
7728 error_msg = "%s due to DEVICE_IN_USE" % error_msg
7729 else:
7730 error_msg = "%s due to %s" % (error_msg, log_message)
7731 ad.log.error(error_msg)
7732 return False
Jaineelcd748202017-08-10 12:23:42 -07007733
7734
Jaineel823f7922020-05-14 16:38:10 -07007735def set_preferred_mode_for_5g(ad, sub_id=None, mode=None):
7736 """Set Preferred Network Mode for 5G NSA
7737 Args:
7738 ad: Android device object.
7739 sub_id: Subscription ID.
7740 mode: 5G Network Mode Type
7741 """
7742 if sub_id is None:
7743 sub_id = ad.droid.subscriptionGetDefaultSubId()
7744 if mode is None:
7745 mode = NETWORK_MODE_NR_LTE_GSM_WCDMA
7746 return set_preferred_network_mode_pref(ad.log, ad, sub_id, mode)
7747
7748
Ang Li73697b32015-12-03 00:41:53 +00007749def set_preferred_subid_for_sms(log, ad, sub_id):
7750 """set subscription id for SMS
7751
7752 Args:
7753 log: Log object.
7754 ad: Android device object.
7755 sub_id :Subscription ID.
7756
7757 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007758 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007759 ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
7760 # Wait to make sure settings take effect
7761 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7762 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId()
7763
Nathan Harold123c9da2015-12-30 16:33:25 -08007764
Ang Li73697b32015-12-03 00:41:53 +00007765def set_preferred_subid_for_data(log, ad, sub_id):
7766 """set subscription id for data
7767
7768 Args:
7769 log: Log object.
7770 ad: Android device object.
7771 sub_id :Subscription ID.
7772
7773 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007774 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007775 ad.droid.subscriptionSetDefaultDataSubId(sub_id)
7776 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7777 # Wait to make sure settings take effect
7778 # Data SIM change takes around 1 min
7779 # Check whether data has changed to selected sim
Nathan Harold7642fc92016-05-02 18:29:11 -07007780 if not wait_for_data_connection(log, ad, True,
7781 MAX_WAIT_TIME_DATA_SUB_CHANGE):
Ang Li73697b32015-12-03 00:41:53 +00007782 log.error("Data Connection failed - Not able to switch Data SIM")
7783 return False
7784 return True
7785
Nathan Harold123c9da2015-12-30 16:33:25 -08007786
Ang Li73697b32015-12-03 00:41:53 +00007787def set_preferred_subid_for_voice(log, ad, sub_id):
7788 """set subscription id for voice
7789
7790 Args:
7791 log: Log object.
7792 ad: Android device object.
7793 sub_id :Subscription ID.
7794
7795 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007796 ad.log.info("Setting subscription %s as Voice SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007797 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
7798 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
7799 # Wait to make sure settings take effect
7800 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7801 return True
7802
Nathan Harold123c9da2015-12-30 16:33:25 -08007803
Ang Li73697b32015-12-03 00:41:53 +00007804def set_call_state_listen_level(log, ad, value, sub_id):
7805 """Set call state listen level for subscription id.
7806
7807 Args:
7808 log: Log object.
7809 ad: Android device object.
7810 value: True or False
7811 sub_id :Subscription ID.
7812
7813 Returns:
7814 True or False
7815 """
7816 if sub_id == INVALID_SUB_ID:
7817 log.error("Invalid Subscription ID")
7818 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08007819 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007820 "Foreground", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08007821 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007822 "Ringing", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08007823 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007824 "Background", value, sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007825 return True
7826
Nathan Harold123c9da2015-12-30 16:33:25 -08007827
Ang Li73697b32015-12-03 00:41:53 +00007828def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False):
7829 """set subscription id for voice, sms and data
7830
7831 Args:
7832 log: Log object.
7833 ad: Android device object.
7834 sub_id :Subscription ID.
7835 voice: True if to set subscription as default voice subscription
7836 sms: True if to set subscription as default sms subscription
7837 data: True if to set subscription as default data subscription
7838
7839 """
7840 if sub_id == INVALID_SUB_ID:
7841 log.error("Invalid Subscription ID")
7842 return False
7843 else:
7844 if voice:
7845 if not set_preferred_subid_for_voice(log, ad, sub_id):
7846 return False
7847 if sms:
7848 if not set_preferred_subid_for_sms(log, ad, sub_id):
7849 return False
7850 if data:
Nathan Harold123c9da2015-12-30 16:33:25 -08007851 if not set_preferred_subid_for_data(log, ad, sub_id):
Ang Li73697b32015-12-03 00:41:53 +00007852 return False
7853 return True
7854
Nathan Harold7642fc92016-05-02 18:29:11 -07007855
Yang Liu8e6adff2016-02-05 10:24:04 -08007856def is_event_match(event, field, value):
7857 """Return if <field> in "event" match <value> or not.
Ang Li73697b32015-12-03 00:41:53 +00007858
7859 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08007860 event: event to test. This event need to have <field>.
7861 field: field to match.
7862 value: value to match.
Ang Li73697b32015-12-03 00:41:53 +00007863
7864 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08007865 True if <field> in "event" match <value>.
Ang Li73697b32015-12-03 00:41:53 +00007866 False otherwise.
7867 """
Yang Liu8e6adff2016-02-05 10:24:04 -08007868 return is_event_match_for_list(event, field, [value])
Ang Li73697b32015-12-03 00:41:53 +00007869
Nathan Harold123c9da2015-12-30 16:33:25 -08007870
Yang Liu8e6adff2016-02-05 10:24:04 -08007871def is_event_match_for_list(event, field, value_list):
7872 """Return if <field> in "event" match any one of the value
7873 in "value_list" or not.
Ang Li73697b32015-12-03 00:41:53 +00007874
7875 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08007876 event: event to test. This event need to have <field>.
7877 field: field to match.
7878 value_list: a list of value to match.
Ang Li73697b32015-12-03 00:41:53 +00007879
7880 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08007881 True if <field> in "event" match one of the value in "value_list".
Ang Li73697b32015-12-03 00:41:53 +00007882 False otherwise.
7883 """
7884 try:
Yang Liu8e6adff2016-02-05 10:24:04 -08007885 value_in_event = event['data'][field]
Ang Li73697b32015-12-03 00:41:53 +00007886 except KeyError:
7887 return False
Yang Liu8e6adff2016-02-05 10:24:04 -08007888 for value in value_list:
7889 if value_in_event == value:
Ang Li73697b32015-12-03 00:41:53 +00007890 return True
7891 return False
7892
Nathan Harold123c9da2015-12-30 16:33:25 -08007893
Yang Liu8e6adff2016-02-05 10:24:04 -08007894def is_network_call_back_event_match(event, network_callback_id,
7895 network_callback_event):
Ang Li73697b32015-12-03 00:41:53 +00007896 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07007897 return (
7898 (network_callback_id == event['data'][NetworkCallbackContainer.ID])
Betty Zhouee311052017-12-19 13:09:56 -08007899 and (network_callback_event == event['data']
7900 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT]))
Ang Li73697b32015-12-03 00:41:53 +00007901 except KeyError:
7902 return False
7903
Nathan Harold123c9da2015-12-30 16:33:25 -08007904
Ang Li73697b32015-12-03 00:41:53 +00007905def is_build_id(log, ad, build_id):
7906 """Return if ad's build id is the same as input parameter build_id.
7907
7908 Args:
7909 log: log object.
7910 ad: android device object.
7911 build_id: android build id.
7912
7913 Returns:
7914 True if ad's build id is the same as input parameter build_id.
7915 False otherwise.
7916 """
7917 actual_bid = ad.droid.getBuildID()
7918
Betty Zhoua37acd32017-02-23 20:04:24 -08007919 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay())
Ang Li73697b32015-12-03 00:41:53 +00007920 #In case we want to log more stuff/more granularity...
7921 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID()))
7922 #log.info("{} BUILD FINGERPRINT: {} "
7923 # .format(ad.serial), ad.droid.getBuildFingerprint())
7924 #log.info("{} BUILD TYPE: {} "
7925 # .format(ad.serial), ad.droid.getBuildType())
7926 #log.info("{} BUILD NUMBER: {} "
7927 # .format(ad.serial), ad.droid.getBuildNumber())
7928 if actual_bid.upper() != build_id.upper():
Betty Zhoua37acd32017-02-23 20:04:24 -08007929 ad.log.error("%s: Incorrect Build ID", ad.model)
Ang Li73697b32015-12-03 00:41:53 +00007930 return False
7931 return True
7932
Nathan Harold123c9da2015-12-30 16:33:25 -08007933
Ang Li73697b32015-12-03 00:41:53 +00007934def is_uri_equivalent(uri1, uri2):
7935 """Check whether two input uris match or not.
7936
7937 Compare Uris.
7938 If Uris are tel URI, it will only take the digit part
7939 and compare as phone number.
7940 Else, it will just do string compare.
7941
7942 Args:
7943 uri1: 1st uri to be compared.
7944 uri2: 2nd uri to be compared.
7945
7946 Returns:
7947 True if two uris match. Otherwise False.
7948 """
Nathan Harold23683d22015-12-14 16:19:08 -08007949
7950 #If either is None/empty we return false
7951 if not uri1 or not uri2:
7952 return False
7953
7954 try:
7955 if uri1.startswith('tel:') and uri2.startswith('tel:'):
Yang Liu598b93d2016-03-22 17:07:59 -07007956 uri1_number = get_number_from_tel_uri(uri1)
7957 uri2_number = get_number_from_tel_uri(uri2)
Nathan Harold23683d22015-12-14 16:19:08 -08007958 return check_phone_number_match(uri1_number, uri2_number)
7959 else:
7960 return uri1 == uri2
7961 except AttributeError as e:
7962 return False
Ang Li73697b32015-12-03 00:41:53 +00007963
Nathan Harold123c9da2015-12-30 16:33:25 -08007964
Ang Li73697b32015-12-03 00:41:53 +00007965def get_call_uri(ad, call_id):
7966 """Get call's uri field.
7967
7968 Get Uri for call_id in ad.
7969
7970 Args:
7971 ad: android device object.
7972 call_id: the call id to get Uri from.
7973
7974 Returns:
7975 call's Uri if call is active and have uri field. None otherwise.
7976 """
7977 try:
7978 call_detail = ad.droid.telecomCallGetDetails(call_id)
7979 return call_detail["Handle"]["Uri"]
7980 except:
7981 return None
7982
Nathan Harold7642fc92016-05-02 18:29:11 -07007983
Yang Liu598b93d2016-03-22 17:07:59 -07007984def get_number_from_tel_uri(uri):
7985 """Get Uri number from tel uri
7986
7987 Args:
7988 uri: input uri
7989
7990 Returns:
7991 If input uri is tel uri, return the number part.
7992 else return None.
7993 """
7994 if uri.startswith('tel:'):
Nathan Harold4a144a42016-09-19 14:16:24 -07007995 uri_number = ''.join(
7996 i for i in urllib.parse.unquote(uri) if i.isdigit())
Yang Liu598b93d2016-03-22 17:07:59 -07007997 return uri_number
7998 else:
7999 return None
Betty Zhou5cf94d82017-06-09 19:18:09 -07008000
8001
Betty Zhou9a96fc32018-02-01 16:44:05 -08008002def find_qxdm_log_mask(ad, mask="default.cfg"):
Betty Zhou550fd372017-10-16 17:22:47 -07008003 """Find QXDM logger mask."""
8004 if "/" not in mask:
Betty Zhoua18d0982017-10-18 14:30:43 -07008005 # Call nexuslogger to generate log mask
8006 start_nexuslogger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07008007 # Find the log mask path
Betty Zhou9a96fc32018-02-01 16:44:05 -08008008 for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs",
jasonkmluc0939182021-02-19 18:34:28 +08008009 "/vendor/etc/mdlog/", "/vendor/etc/modem/"):
Betty Zhou02571f52018-02-16 14:11:16 -08008010 out = ad.adb.shell(
8011 "find %s -type f -iname %s" % (path, mask), ignore_status=True)
Betty Zhou9a96fc32018-02-01 16:44:05 -08008012 if out and "No such" not in out and "Permission denied" not in out:
8013 if path.startswith("/vendor/"):
Betty Zhou739d6b72018-04-18 10:38:53 -07008014 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
Betty Zhou9a96fc32018-02-01 16:44:05 -08008015 else:
Betty Zhou739d6b72018-04-18 10:38:53 -07008016 setattr(ad, "qxdm_log_path", path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08008017 return out.split("\n")[0]
jasonkmluc0939182021-02-19 18:34:28 +08008018 for mask_file in ("/vendor/etc/mdlog/", "/vendor/etc/modem/"):
8019 if mask in ad.adb.shell("ls %s" % mask_file, ignore_status=True):
8020 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
8021 return "%s/%s" % (mask_file, mask)
Betty Zhou550fd372017-10-16 17:22:47 -07008022 else:
8023 out = ad.adb.shell("ls %s" % mask, ignore_status=True)
8024 if out and "No such" not in out:
Betty Zhou739d6b72018-04-18 10:38:53 -07008025 qxdm_log_path, cfg_name = os.path.split(mask)
8026 setattr(ad, "qxdm_log_path", qxdm_log_path)
Betty Zhoua18d0982017-10-18 14:30:43 -07008027 return mask
Betty Zhou550fd372017-10-16 17:22:47 -07008028 ad.log.warning("Could NOT find QXDM logger mask path for %s", mask)
8029
8030
8031def set_qxdm_logger_command(ad, mask=None):
8032 """Set QXDM logger always on.
8033
8034 Args:
8035 ad: android device object.
8036
8037 """
8038 ## Neet to check if log mask will be generated without starting nexus logger
Betty Zhou9a96fc32018-02-01 16:44:05 -08008039 masks = []
8040 mask_path = None
Betty Zhou550fd372017-10-16 17:22:47 -07008041 if mask:
Betty Zhou9a96fc32018-02-01 16:44:05 -08008042 masks = [mask]
8043 masks.extend(["QC_Default.cfg", "default.cfg"])
8044 for mask in masks:
8045 mask_path = find_qxdm_log_mask(ad, mask)
8046 if mask_path: break
Betty Zhou550fd372017-10-16 17:22:47 -07008047 if not mask_path:
Betty Zhou9a96fc32018-02-01 16:44:05 -08008048 ad.log.error("Cannot find QXDM mask %s", mask)
Betty Zhou550fd372017-10-16 17:22:47 -07008049 ad.qxdm_logger_command = None
Betty Zhoua18d0982017-10-18 14:30:43 -07008050 return False
Betty Zhou550fd372017-10-16 17:22:47 -07008051 else:
Betty Zhoua18d0982017-10-18 14:30:43 -07008052 ad.log.info("Use QXDM log mask %s", mask_path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08008053 ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path)
8054 output_path = os.path.join(ad.qxdm_log_path, "logs")
Betty Zhou1fdebb02018-05-30 17:02:53 -07008055 ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 90 -c" %
Betty Zhou9a96fc32018-02-01 16:44:05 -08008056 (mask_path, output_path))
Betty Zhoua18d0982017-10-18 14:30:43 -07008057 return True
Betty Zhou550fd372017-10-16 17:22:47 -07008058
Ashutosh Rajmani Singha54c01e2021-02-01 21:56:25 -08008059def configure_sdm_logs(ad):
8060 if not getattr(ad, "sdm_log", True): return
8061 # Disable any modem logging already running
8062 ad.adb.shell("setprop persist.vendor.sys.modem.logging.enable false")
8063 ad.adb.shell('echo "modem_logging_control START -n 10 -s 100 -i 1" > /data/vendor/radio/logs/always-on.conf')
Betty Zhou550fd372017-10-16 17:22:47 -07008064
Pratik Sheth68e4eba2021-03-23 17:10:13 -07008065
Jaineel72d2c242019-07-23 12:00:07 -07008066def start_sdm_logger(ad):
8067 """Start SDM logger."""
8068 if not getattr(ad, "sdm_log", True): return
8069 # Delete existing SDM logs which were created 15 mins prior
8070 ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
8071 file_count = ad.adb.shell(
Jaineel0cdb4a92020-01-31 12:58:20 -08008072 "find %s -type f -iname sbuff_[0-9]*.sdm* | wc -l" % ad.sdm_log_path)
Jaineel72d2c242019-07-23 12:00:07 -07008073 if int(file_count) > 3:
8074 seconds = 15 * 60
8075 # Remove sdm logs modified more than specified seconds ago
8076 ad.adb.shell(
Jaineel0cdb4a92020-01-31 12:58:20 -08008077 "find %s -type f -iname sbuff_[0-9]*.sdm* -not -mtime -%ss -delete" %
Jaineel72d2c242019-07-23 12:00:07 -07008078 (ad.sdm_log_path, seconds))
8079 # start logging
8080 cmd = "setprop vendor.sys.modem.logging.enable true"
8081 ad.log.debug("start sdm logging")
8082 ad.adb.shell(cmd, ignore_status=True)
8083 time.sleep(5)
8084
8085
8086def stop_sdm_logger(ad):
8087 """Stop SDM logger."""
8088 cmd = "setprop vendor.sys.modem.logging.enable false"
8089 ad.log.debug("stop sdm logging")
8090 ad.adb.shell(cmd, ignore_status=True)
8091 time.sleep(5)
8092
8093
Betty Zhou0111ae02017-11-29 20:37:26 -08008094def stop_qxdm_logger(ad):
8095 """Stop QXDM logger."""
8096 for cmd in ("diag_mdlog -k", "killall diag_mdlog"):
8097 output = ad.adb.shell("ps -ef | grep mdlog") or ""
8098 if "diag_mdlog" not in output:
8099 break
8100 ad.log.debug("Kill the existing qxdm process")
8101 ad.adb.shell(cmd, ignore_status=True)
8102 time.sleep(5)
8103
8104
Betty Zhouee311052017-12-19 13:09:56 -08008105def start_qxdm_logger(ad, begin_time=None):
Betty Zhou550fd372017-10-16 17:22:47 -07008106 """Start QXDM logger."""
Betty Zhou3eceae02018-02-09 12:27:51 -08008107 if not getattr(ad, "qxdm_log", True): return
Betty Zhouee311052017-12-19 13:09:56 -08008108 # Delete existing QXDM logs 5 minutes earlier than the begin_time
Betty Zhoua9a354a2018-03-21 15:01:59 -07008109 current_time = get_current_epoch_time()
Betty Zhou9a96fc32018-02-01 16:44:05 -08008110 if getattr(ad, "qxdm_log_path", None):
8111 seconds = None
Betty Zhoua9a354a2018-03-21 15:01:59 -07008112 file_count = ad.adb.shell(
8113 "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path)
8114 if int(file_count) > 50:
8115 if begin_time:
8116 # if begin_time specified, delete old qxdm logs modified
8117 # 10 minutes before begin time
8118 seconds = int((current_time - begin_time) / 1000.0) + 10 * 60
8119 else:
8120 # if begin_time is not specified, delete old qxdm logs modified
8121 # 15 minutes before current time
8122 seconds = 15 * 60
Betty Zhou9a96fc32018-02-01 16:44:05 -08008123 if seconds:
Betty Zhoua9a354a2018-03-21 15:01:59 -07008124 # Remove qxdm logs modified more than specified seconds ago
Betty Zhou9a96fc32018-02-01 16:44:05 -08008125 ad.adb.shell(
Betty Zhou02571f52018-02-16 14:11:16 -08008126 "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" %
8127 (ad.qxdm_log_path, seconds))
Betty Zhoua9a354a2018-03-21 15:01:59 -07008128 ad.adb.shell(
8129 "find %s -type f -iname *.xml -not -mtime -%ss -delete" %
8130 (ad.qxdm_log_path, seconds))
Betty Zhou550fd372017-10-16 17:22:47 -07008131 if getattr(ad, "qxdm_logger_command", None):
8132 output = ad.adb.shell("ps -ef | grep mdlog") or ""
8133 if ad.qxdm_logger_command not in output:
8134 ad.log.debug("QXDM logging command %s is not running",
8135 ad.qxdm_logger_command)
8136 if "diag_mdlog" in output:
Betty Zhoua9a354a2018-03-21 15:01:59 -07008137 # Kill the existing non-matching diag_mdlog process
Betty Zhou550fd372017-10-16 17:22:47 -07008138 # Only one diag_mdlog process can be run
Betty Zhou0111ae02017-11-29 20:37:26 -08008139 stop_qxdm_logger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07008140 ad.log.info("Start QXDM logger")
Betty Zhou88a39392017-12-01 17:33:57 -08008141 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07008142 time.sleep(10)
Betty Zhoua9a354a2018-03-21 15:01:59 -07008143 else:
Betty Zhoua19e4442018-04-19 19:38:42 -07008144 run_time = check_qxdm_logger_run_time(ad)
8145 if run_time < 600:
8146 # the last diag_mdlog started within 10 minutes ago
8147 # no need to restart
8148 return True
Betty Zhoua9a354a2018-03-21 15:01:59 -07008149 if ad.search_logcat(
8150 "Diag_Lib: diag: In delete_log",
Betty Zhoua19e4442018-04-19 19:38:42 -07008151 begin_time=current_time -
8152 run_time) or not ad.get_file_names(
8153 ad.qxdm_log_path,
8154 begin_time=current_time - 600000,
8155 match_string="*.qmdl"):
Betty Zhoua9a354a2018-03-21 15:01:59 -07008156 # diag_mdlog starts deleting files or no qmdl logs were
Betty Zhoua19e4442018-04-19 19:38:42 -07008157 # modified in the past 10 minutes
Betty Zhoua9a354a2018-03-21 15:01:59 -07008158 ad.log.debug("Quit existing diag_mdlog and start a new one")
8159 stop_qxdm_logger(ad)
8160 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07008161 time.sleep(10)
Betty Zhou0111ae02017-11-29 20:37:26 -08008162 return True
Betty Zhou550fd372017-10-16 17:22:47 -07008163
8164
Betty Zhouf0577582018-06-06 11:34:52 -07008165def disable_qxdm_logger(ad):
8166 for prop in ("persist.sys.modem.diag.mdlog",
Betty Zhou4d97af82018-06-07 14:05:52 -07008167 "persist.vendor.sys.modem.diag.mdlog",
8168 "vendor.sys.modem.diag.mdlog_on"):
Betty Zhouf0577582018-06-06 11:34:52 -07008169 if ad.adb.getprop(prop):
8170 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
8171 for apk in ("com.android.nexuslogger", "com.android.pixellogger"):
8172 if ad.is_apk_installed(apk) and ad.is_apk_running(apk):
8173 ad.force_stop_apk(apk)
8174 stop_qxdm_logger(ad)
8175 return True
8176
8177
Betty Zhoua19e4442018-04-19 19:38:42 -07008178def check_qxdm_logger_run_time(ad):
8179 output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog")
8180 result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output)
8181 if result:
8182 return int(result.group(1)) * 60 * 60 + int(
8183 result.group(2)) * 60 + int(result.group(3))
8184 else:
8185 result = re.search(r"(\d+):(\d+) diag_mdlog", output)
8186 if result:
8187 return int(result.group(1)) * 60 + int(result.group(2))
8188 else:
8189 return 0
8190
8191
Betty Zhouee311052017-12-19 13:09:56 -08008192def start_qxdm_loggers(log, ads, begin_time=None):
Betty Zhou02571f52018-02-16 14:11:16 -08008193 tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads
8194 if getattr(ad, "qxdm_log", True)]
Betty Zhou3eceae02018-02-09 12:27:51 -08008195 if tasks: run_multithread_func(log, tasks)
Betty Zhou550fd372017-10-16 17:22:47 -07008196
8197
Betty Zhou0111ae02017-11-29 20:37:26 -08008198def stop_qxdm_loggers(log, ads):
8199 tasks = [(stop_qxdm_logger, [ad]) for ad in ads]
8200 run_multithread_func(log, tasks)
8201
8202
Jaineel72d2c242019-07-23 12:00:07 -07008203def start_sdm_loggers(log, ads):
8204 tasks = [(start_sdm_logger, [ad]) for ad in ads
8205 if getattr(ad, "sdm_log", True)]
8206 if tasks: run_multithread_func(log, tasks)
8207
8208
8209def stop_sdm_loggers(log, ads):
8210 tasks = [(stop_sdm_logger, [ad]) for ad in ads]
8211 run_multithread_func(log, tasks)
8212
8213
Betty Zhou550fd372017-10-16 17:22:47 -07008214def start_nexuslogger(ad):
Betty Zhou807a81f2017-11-27 14:53:48 -08008215 """Start Nexus/Pixel Logger Apk."""
8216 qxdm_logger_apk = None
Betty Zhouee311052017-12-19 13:09:56 -08008217 for apk, activity in (("com.android.nexuslogger", ".MainActivity"),
8218 ("com.android.pixellogger",
8219 ".ui.main.MainActivity")):
Betty Zhou807a81f2017-11-27 14:53:48 -08008220 if ad.is_apk_installed(apk):
8221 qxdm_logger_apk = apk
8222 break
8223 if not qxdm_logger_apk: return
8224 if ad.is_apk_running(qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07008225 if "granted=true" in ad.adb.shell(
Betty Zhou807a81f2017-11-27 14:53:48 -08008226 "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07008227 return True
8228 else:
Betty Zhou807a81f2017-11-27 14:53:48 -08008229 ad.log.info("Kill %s" % qxdm_logger_apk)
8230 ad.force_stop_apk(qxdm_logger_apk)
Betty Zhou32e403a2017-10-25 20:08:12 -07008231 time.sleep(5)
Betty Zhou807a81f2017-11-27 14:53:48 -08008232 for perm in ("READ", "WRITE"):
8233 ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" %
8234 (qxdm_logger_apk, perm))
8235 time.sleep(2)
Jaineel464a18e2017-12-21 14:37:41 -08008236 for i in range(3):
Betty Zhou3814cbc2018-06-11 19:39:36 -07008237 ad.unlock_screen()
Jaineel464a18e2017-12-21 14:37:41 -08008238 ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1))
8239 ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity))
8240 time.sleep(5)
8241 if ad.is_apk_running(qxdm_logger_apk):
8242 ad.send_keycode("HOME")
8243 return True
8244 return False
Betty Zhou5cf94d82017-06-09 19:18:09 -07008245
8246
Betty Zhou8ac04da2017-10-12 15:27:15 -07008247def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"):
Betty Zhou5cf94d82017-06-09 19:18:09 -07008248 """Check if QXDM logger always on is set.
8249
8250 Args:
8251 ad: android device object.
8252
8253 """
Betty Zhou4b0f1712017-10-12 20:20:14 -07008254 output = ad.adb.shell(
8255 "ls /data/vendor/radio/diag_logs/", ignore_status=True)
8256 if not output or "No such" in output:
8257 return True
Betty Zhou5cf94d82017-06-09 19:18:09 -07008258 if mask_file not in ad.adb.shell(
8259 "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True):
8260 return False
8261 return True
Jaineel55ae6f92017-06-29 17:44:19 -07008262
8263
Betty Zhou9d0366a2018-03-26 13:49:57 -07008264def start_tcpdumps(ads,
8265 test_name="",
8266 begin_time=None,
8267 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07008268 mask="all"):
Betty Zhoue123c672018-03-21 19:57:11 -07008269 for ad in ads:
Betty Zhou819cb732018-05-10 18:45:41 -07008270 try:
8271 start_adb_tcpdump(
8272 ad,
8273 test_name=test_name,
8274 begin_time=begin_time,
8275 interface=interface,
8276 mask=mask)
8277 except Exception as e:
8278 ad.log.warning("Fail to start tcpdump due to %s", e)
Betty Zhoue123c672018-03-21 19:57:11 -07008279
8280
Betty Zhou9d0366a2018-03-26 13:49:57 -07008281def start_adb_tcpdump(ad,
8282 test_name="",
8283 begin_time=None,
8284 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07008285 mask="all"):
Jaineel55ae6f92017-06-29 17:44:19 -07008286 """Start tcpdump on any iface
8287
8288 Args:
8289 ad: android device object.
8290 test_name: tcpdump file name will have this
8291
8292 """
Scott Honge54cb0c2020-10-13 15:10:35 +08008293 out = ad.adb.shell("ls -l /data/local/tmp/tcpdump/", ignore_status=True)
Jaineel7d0408e2017-12-22 15:52:59 -08008294 if "No such file" in out or not out:
Jaineel6cd64742018-06-29 15:43:15 -07008295 ad.adb.shell("mkdir /data/local/tmp/tcpdump")
Jaineel7d0408e2017-12-22 15:52:59 -08008296 else:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008297 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008298 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
8299 ignore_status=True)
Jaineel560ad5d2018-08-23 17:14:14 -07008300 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008301 "find /data/local/tmp/tcpdump -type f -size +5G -delete",
8302 ignore_status=True)
Jaineel7d0408e2017-12-22 15:52:59 -08008303
Betty Zhoue123c672018-03-21 19:57:11 -07008304 if not begin_time:
8305 begin_time = get_current_epoch_time()
Jaineel7d0408e2017-12-22 15:52:59 -08008306
Betty Zhou819cb732018-05-10 18:45:41 -07008307 out = ad.adb.shell(
Betty Zhou80c64cf2018-06-08 18:01:18 -07008308 'ifconfig | grep -v -E "r_|-rmnet" | grep -E "lan|data"',
8309 ignore_status=True,
8310 timeout=180)
8311 intfs = re.findall(r"(\S+).*", out)
8312 if interface and interface not in ("any", "all"):
8313 if interface not in intfs: return
Betty Zhou5dd53c02018-03-22 20:08:33 -07008314 intfs = [interface]
8315
8316 out = ad.adb.shell("ps -ef | grep tcpdump")
8317 cmds = []
8318 for intf in intfs:
8319 if intf in out:
8320 ad.log.info("tcpdump on interface %s is already running", intf)
8321 continue
8322 else:
Jaineel6cd64742018-06-29 15:43:15 -07008323 log_file_name = "/data/local/tmp/tcpdump/tcpdump_%s_%s_%s_%s.pcap" \
8324 % (ad.serial, intf, test_name, begin_time)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008325 if mask == "ims":
8326 cmds.append(
8327 "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or "
Betty Zhou9d0366a2018-03-26 13:49:57 -07008328 "udp port 4500 -w %s" % (ad.serial, intf, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07008329 else:
Betty Zhou9d0366a2018-03-26 13:49:57 -07008330 cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" %
8331 (ad.serial, intf, log_file_name))
jasonkmluc0939182021-02-19 18:34:28 +08008332 if not gutils.check_chipset_vendor_by_qualcomm(ad):
8333 log_file_name = ("/data/local/tmp/tcpdump/tcpdump_%s_any_%s_%s.pcap"
8334 % (ad.serial, test_name, begin_time))
8335 cmds.append("adb -s %s shell nohup tcpdump -i any -s0 -w %s" %
8336 (ad.serial, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07008337 for cmd in cmds:
8338 ad.log.info(cmd)
8339 try:
8340 start_standing_subprocess(cmd, 10)
8341 except Exception as e:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07008342 ad.log.error(e)
Betty Zhou80c64cf2018-06-08 18:01:18 -07008343 if cmds:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008344 time.sleep(5)
Jaineel55ae6f92017-06-29 17:44:19 -07008345
8346
Betty Zhoue123c672018-03-21 19:57:11 -07008347def stop_tcpdumps(ads):
8348 for ad in ads:
8349 stop_adb_tcpdump(ad)
8350
8351
Betty Zhou5dd53c02018-03-22 20:08:33 -07008352def stop_adb_tcpdump(ad, interface="any"):
Jaineel55ae6f92017-06-29 17:44:19 -07008353 """Stops tcpdump on any iface
8354 Pulls the tcpdump file in the tcpdump dir
8355
8356 Args:
8357 ad: android device object.
Jaineel55ae6f92017-06-29 17:44:19 -07008358
8359 """
Betty Zhou5dd53c02018-03-22 20:08:33 -07008360 if interface == "any":
8361 try:
Jaineel1ef929e2020-10-24 12:43:44 -07008362 ad.adb.shell("killall -9 tcpdump", ignore_status=True)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008363 except Exception as e:
Betty Zhoua36c4352018-04-05 18:49:32 -07008364 ad.log.error("Killing tcpdump with exception %s", e)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008365 else:
8366 out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface)
8367 if "tcpdump -i" in out:
8368 pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out)
8369 for pid in pids:
8370 ad.adb.shell("kill -9 %s" % pid)
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008371 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008372 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
8373 ignore_status=True)
Betty Zhoue123c672018-03-21 19:57:11 -07008374
8375
8376def get_tcpdump_log(ad, test_name="", begin_time=None):
8377 """Stops tcpdump on any iface
8378 Pulls the tcpdump file in the tcpdump dir
jasonkmlu2565d892019-11-12 15:31:26 +08008379 Zips all tcpdump files
Betty Zhoue123c672018-03-21 19:57:11 -07008380
8381 Args:
8382 ad: android device object.
8383 test_name: test case name
8384 begin_time: test begin time
8385 """
Jaineel6cd64742018-06-29 15:43:15 -07008386 logs = ad.get_file_names("/data/local/tmp/tcpdump", begin_time=begin_time)
Betty Zhoue123c672018-03-21 19:57:11 -07008387 if logs:
8388 ad.log.info("Pulling tcpdumps %s", logs)
jasonkmlu2565d892019-11-12 15:31:26 +08008389 log_path = os.path.join(
8390 ad.device_log_path, "TCPDUMP_%s_%s" % (ad.model, ad.serial))
Mark De Ruyter72f8df92020-02-12 13:44:49 -08008391 os.makedirs(log_path, exist_ok=True)
Betty Zhoue123c672018-03-21 19:57:11 -07008392 ad.pull_files(logs, log_path)
jasonkmlu2565d892019-11-12 15:31:26 +08008393 shutil.make_archive(log_path, "zip", log_path)
8394 shutil.rmtree(log_path)
Jaineel55ae6f92017-06-29 17:44:19 -07008395 return True
Betty Zhou166a51c2017-08-14 17:40:59 -07008396
8397
8398def fastboot_wipe(ad, skip_setup_wizard=True):
8399 """Wipe the device in fastboot mode.
8400
8401 Pull sl4a apk from device. Terminate all sl4a sessions,
8402 Reboot the device to bootloader, wipe the device by fastboot.
8403 Reboot the device. wait for device to complete booting
8404 Re-intall and start an sl4a session.
8405 """
Betty Zhou77f2bed2017-10-04 18:39:07 -07008406 status = True
Betty Zhou166a51c2017-08-14 17:40:59 -07008407 # Pull sl4a apk from device
Betty Zhou92437702018-02-07 19:49:07 -08008408 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
Betty Zhou166a51c2017-08-14 17:40:59 -07008409 result = re.search(r"package:(.*)", out)
8410 if not result:
8411 ad.log.error("Couldn't find sl4a apk")
8412 else:
8413 sl4a_apk = result.group(1)
8414 ad.log.info("Get sl4a apk from %s", sl4a_apk)
8415 ad.pull_files([sl4a_apk], "/tmp/")
8416 ad.stop_services()
Betty Zhou3e983f22018-04-09 20:37:36 -07008417 attemps = 3
8418 for i in range(1, attemps + 1):
Betty Zhou77f2bed2017-10-04 18:39:07 -07008419 try:
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008420 if ad.serial in list_adb_devices():
8421 ad.log.info("Reboot to bootloader")
8422 ad.adb.reboot("bootloader", ignore_status=True)
8423 time.sleep(10)
8424 if ad.serial in list_fastboot_devices():
8425 ad.log.info("Wipe in fastboot")
Betty Zhou6b678c62018-05-21 12:23:04 -07008426 ad.fastboot._w(timeout=300, ignore_status=True)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008427 time.sleep(30)
8428 ad.log.info("Reboot in fastboot")
8429 ad.fastboot.reboot()
Betty Zhou77f2bed2017-10-04 18:39:07 -07008430 ad.wait_for_boot_completion()
Betty Zhou3e983f22018-04-09 20:37:36 -07008431 ad.root_adb()
8432 if ad.skip_sl4a:
8433 break
Betty Zhou02589bb2017-09-06 15:04:25 -07008434 if ad.is_sl4a_installed():
8435 break
Betty Zhou166a51c2017-08-14 17:40:59 -07008436 ad.log.info("Re-install sl4a")
Xianyuan Jia4d4b3a22019-09-27 11:00:14 -07008437 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
Betty Zhou3e983f22018-04-09 20:37:36 -07008438 ad.adb.install("-r /tmp/base.apk")
Betty Zhou166a51c2017-08-14 17:40:59 -07008439 time.sleep(10)
Betty Zhou3e983f22018-04-09 20:37:36 -07008440 break
8441 except Exception as e:
8442 ad.log.warning(e)
8443 if i == attemps:
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008444 abort_all_tests(log, str(e))
8445 time.sleep(5)
Betty Zhou3c2e2542018-02-21 12:23:04 -08008446 try:
8447 ad.start_adb_logcat()
8448 except:
Betty Zhoua36c4352018-04-05 18:49:32 -07008449 ad.log.error("Failed to start adb logcat!")
Betty Zhou3c2e2542018-02-21 12:23:04 -08008450 if skip_setup_wizard:
8451 ad.exit_setup_wizard()
Jaineel1cde17b2019-01-04 14:26:55 -08008452 if getattr(ad, "qxdm_log", True):
8453 set_qxdm_logger_command(ad, mask=getattr(ad, "qxdm_log_mask", None))
8454 start_qxdm_logger(ad)
Betty Zhouf25fdab2018-04-23 19:20:17 -07008455 if ad.skip_sl4a: return status
8456 bring_up_sl4a(ad)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008457 synchronize_device_time(ad)
Betty Zhoub7663ba2018-05-23 11:56:22 -07008458 set_phone_silent_mode(ad.log, ad)
Shaju Sebastian0b847e72019-01-31 16:40:37 -08008459 # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 &
8460 # b/122327716
8461 activate_wfc_on_device(ad.log, ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07008462 return status
Betty Zhou166a51c2017-08-14 17:40:59 -07008463
Pratik Sheth68e4eba2021-03-23 17:10:13 -07008464
Jaineel1cde17b2019-01-04 14:26:55 -08008465def install_carriersettings_apk(ad, carriersettingsapk, skip_setup_wizard=True):
8466 """ Carrier Setting Installation Steps
8467
8468 Pull sl4a apk from device. Terminate all sl4a sessions,
8469 Reboot the device to bootloader, wipe the device by fastboot.
8470 Reboot the device. wait for device to complete booting
8471 """
8472 status = True
8473 if carriersettingsapk is None:
8474 ad.log.warning("CarrierSettingsApk is not provided, aborting")
8475 return False
8476 ad.log.info("Push carriersettings apk to the Android device.")
8477 android_apk_path = "/product/priv-app/CarrierSettings/CarrierSettings.apk"
8478 ad.adb.push("%s %s" % (carriersettingsapk, android_apk_path))
8479 ad.stop_services()
8480
8481 attempts = 3
8482 for i in range(1, attempts + 1):
8483 try:
8484 if ad.serial in list_adb_devices():
8485 ad.log.info("Reboot to bootloader")
8486 ad.adb.reboot("bootloader", ignore_status=True)
8487 time.sleep(30)
8488 if ad.serial in list_fastboot_devices():
8489 ad.log.info("Reboot in fastboot")
8490 ad.fastboot.reboot()
8491 ad.wait_for_boot_completion()
8492 ad.root_adb()
8493 if ad.is_sl4a_installed():
8494 break
8495 time.sleep(10)
8496 break
8497 except Exception as e:
8498 ad.log.warning(e)
8499 if i == attempts:
8500 abort_all_tests(log, str(e))
8501 time.sleep(5)
8502 try:
8503 ad.start_adb_logcat()
8504 except:
8505 ad.log.error("Failed to start adb logcat!")
8506 if skip_setup_wizard:
8507 ad.exit_setup_wizard()
8508 return status
8509
Betty Zhou166a51c2017-08-14 17:40:59 -07008510
Betty Zhou3c2e2542018-02-21 12:23:04 -08008511def bring_up_sl4a(ad, attemps=3):
8512 for i in range(attemps):
8513 try:
8514 droid, ed = ad.get_droid()
8515 ed.start()
Jaineel1cde17b2019-01-04 14:26:55 -08008516 ad.log.info("Brought up new sl4a session")
Betty Zhou3e983f22018-04-09 20:37:36 -07008517 break
Betty Zhou3c2e2542018-02-21 12:23:04 -08008518 except Exception as e:
8519 if i < attemps - 1:
8520 ad.log.info(e)
8521 time.sleep(10)
8522 else:
8523 ad.log.error(e)
8524 raise
8525
8526
Betty Zhou4f1d9eb2018-06-15 11:27:18 -07008527def reboot_device(ad, recover_sim_state=True):
8528 sim_state = is_sim_ready(ad.log, ad)
Betty Zhouae9d6a82018-02-15 20:05:34 -08008529 ad.reboot()
Jaineel43e4b682019-02-15 12:28:19 -08008530 if ad.qxdm_log:
8531 start_qxdm_logger(ad)
Betty Zhou4f1d9eb2018-06-15 11:27:18 -07008532 ad.unlock_screen()
8533 if recover_sim_state:
8534 if not unlock_sim(ad):
8535 ad.log.error("Unable to unlock SIM")
8536 return False
8537 if sim_state and not _wait_for_droid_in_state(
8538 log, ad, MAX_WAIT_TIME_FOR_STATE_CHANGE, is_sim_ready):
8539 ad.log.error("Sim state didn't reach pre-reboot ready state")
8540 return False
8541 return True
Betty Zhouae9d6a82018-02-15 20:05:34 -08008542
8543
Betty Zhou166a51c2017-08-14 17:40:59 -07008544def unlocking_device(ad, device_password=None):
8545 """First unlock device attempt, required after reboot"""
8546 ad.unlock_screen(device_password)
8547 time.sleep(2)
8548 ad.adb.wait_for_device(timeout=180)
8549 if not ad.is_waiting_for_unlock_pin():
8550 return True
8551 else:
8552 ad.unlock_screen(device_password)
8553 time.sleep(2)
8554 ad.adb.wait_for_device(timeout=180)
8555 if ad.wait_for_window_ready():
8556 return True
8557 ad.log.error("Unable to unlock to user window")
8558 return False
8559
8560
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008561def refresh_sl4a_session(ad):
8562 try:
8563 ad.droid.logI("Checking SL4A connection")
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008564 ad.log.debug("Existing sl4a session is active")
8565 return True
8566 except Exception as e:
Betty Zhoufe726dc2018-04-25 19:31:33 -07008567 ad.log.warning("Existing sl4a session is NOT active: %s", e)
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008568 try:
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008569 ad.terminate_all_sessions()
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008570 except Exception as e:
8571 ad.log.info("terminate_all_sessions with error %s", e)
8572 ad.ensure_screen_on()
8573 ad.log.info("Open new sl4a connection")
8574 bring_up_sl4a(ad)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008575
8576
Betty Zhou166a51c2017-08-14 17:40:59 -07008577def reset_device_password(ad, device_password=None):
8578 # Enable or Disable Device Password per test bed config
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008579 unlock_sim(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008580 screen_lock = ad.is_screen_lock_enabled()
8581 if device_password:
Betty Zhoue66efb42018-01-31 19:45:56 -08008582 try:
Betty Zhouf715c792018-02-12 17:32:10 -08008583 refresh_sl4a_session(ad)
Betty Zhoue66efb42018-01-31 19:45:56 -08008584 ad.droid.setDevicePassword(device_password)
8585 except Exception as e:
8586 ad.log.warning("setDevicePassword failed with %s", e)
Betty Zhou3c2e2542018-02-21 12:23:04 -08008587 try:
8588 ad.droid.setDevicePassword(device_password, "1111")
8589 except Exception as e:
8590 ad.log.warning(
8591 "setDevicePassword providing previous password error: %s",
8592 e)
Betty Zhou166a51c2017-08-14 17:40:59 -07008593 time.sleep(2)
8594 if screen_lock:
8595 # existing password changed
8596 return
8597 else:
8598 # enable device password and log in for the first time
8599 ad.log.info("Enable device password")
8600 ad.adb.wait_for_device(timeout=180)
Betty Zhou166a51c2017-08-14 17:40:59 -07008601 else:
8602 if not screen_lock:
8603 # no existing password, do not set password
8604 return
8605 else:
8606 # password is enabled on the device
8607 # need to disable the password and log in on the first time
8608 # with unlocking with a swipe
8609 ad.log.info("Disable device password")
Betty Zhou688c1032017-11-20 20:08:04 -08008610 ad.unlock_screen(password="1111")
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008611 refresh_sl4a_session(ad)
Betty Zhou351d1792017-11-10 16:26:30 -08008612 ad.ensure_screen_on()
Betty Zhoue66efb42018-01-31 19:45:56 -08008613 try:
8614 ad.droid.disableDevicePassword()
8615 except Exception as e:
8616 ad.log.warning("disableDevicePassword failed with %s", e)
Betty Zhouf715c792018-02-12 17:32:10 -08008617 fastboot_wipe(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008618 time.sleep(2)
8619 ad.adb.wait_for_device(timeout=180)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008620 refresh_sl4a_session(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008621 if not ad.is_adb_logcat_on:
8622 ad.start_adb_logcat()
Betty Zhou59ccab62017-08-17 18:17:29 -07008623
8624
Betty Zhoue66efb42018-01-31 19:45:56 -08008625def get_sim_state(ad):
Betty Zhou13e7adf2017-09-06 14:01:10 -07008626 try:
Betty Zhoue66efb42018-01-31 19:45:56 -08008627 state = ad.droid.telephonyGetSimState()
Jaineel3d14c432018-09-20 19:00:20 -07008628 except Exception as e:
8629 ad.log.error(e)
Betty Zhoue66efb42018-01-31 19:45:56 -08008630 state = ad.adb.getprop("gsm.sim.state")
8631 return state
8632
8633
8634def is_sim_locked(ad):
Betty Zhoub554e342018-02-01 19:01:38 -08008635 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED
Betty Zhou59ccab62017-08-17 18:17:29 -07008636
8637
Betty Zhou28e07e12018-04-11 12:12:11 -07008638def is_sim_lock_enabled(ad):
8639 # TODO: add sl4a fascade to check if sim is locked
8640 return getattr(ad, "is_sim_locked", False)
8641
8642
Betty Zhou59ccab62017-08-17 18:17:29 -07008643def unlock_sim(ad):
8644 #The puk and pin can be provided in testbed config file.
8645 #"AndroidDevice": [{"serial": "84B5T15A29018214",
8646 # "adb_logcat_param": "-b all",
8647 # "puk": "12345678",
8648 # "puk_pin": "1234"}]
Betty Zhouc3f1f9c2017-08-18 15:50:41 -07008649 if not is_sim_locked(ad):
8650 return True
Betty Zhoue66efb42018-01-31 19:45:56 -08008651 else:
8652 ad.is_sim_locked = True
Betty Zhou59ccab62017-08-17 18:17:29 -07008653 puk_pin = getattr(ad, "puk_pin", "1111")
8654 try:
8655 if not hasattr(ad, 'puk'):
Betty Zhoub47a4ea2017-09-06 11:18:40 -07008656 ad.log.info("Enter SIM pin code")
Betty Zhoue66efb42018-01-31 19:45:56 -08008657 ad.droid.telephonySupplyPin(puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07008658 else:
8659 ad.log.info("Enter PUK code and pin")
Betty Zhoue66efb42018-01-31 19:45:56 -08008660 ad.droid.telephonySupplyPuk(ad.puk, puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07008661 except:
8662 # if sl4a is not available, use adb command
8663 ad.unlock_screen(puk_pin)
8664 if is_sim_locked(ad):
8665 ad.unlock_screen(puk_pin)
Betty Zhoub47a4ea2017-09-06 11:18:40 -07008666 time.sleep(30)
Betty Zhou59ccab62017-08-17 18:17:29 -07008667 return not is_sim_locked(ad)
Betty Zhouf3c5bc32017-08-28 17:09:19 -07008668
8669
8670def send_dialer_secret_code(ad, secret_code):
8671 """Send dialer secret code.
8672
8673 ad: android device controller
8674 secret_code: the secret code to be sent to dialer. the string between
8675 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#*
8676 """
8677 action = 'android.provider.Telephony.SECRET_CODE'
8678 uri = 'android_secret_code://%s' % secret_code
8679 intent = ad.droid.makeIntent(
8680 action,
8681 uri,
8682 None, # type
8683 None, # extras
8684 None, # categories,
8685 None, # packagename,
8686 None, # classname,
8687 0x01000000) # flags
8688 ad.log.info('Issuing dialer secret dialer code: %s', secret_code)
8689 ad.droid.sendBroadcastIntent(intent)
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008690
8691
Betty Zhouf7da39e2018-04-16 16:28:58 -07008692def enable_radio_log_on(ad):
Betty Zhou8aafcc12018-05-01 20:54:15 -07008693 if ad.adb.getprop("persist.vendor.radio.adb_log_on") != "1":
8694 ad.log.info("Enable radio adb_log_on and reboot")
Betty Zhouf7da39e2018-04-16 16:28:58 -07008695 adb_disable_verity(ad)
8696 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1")
8697 reboot_device(ad)
8698
8699
8700def adb_disable_verity(ad):
8701 if ad.adb.getprop("ro.boot.veritymode") == "enforcing":
8702 ad.adb.disable_verity()
8703 reboot_device(ad)
8704 ad.adb.remount()
8705
8706
Betty Zhou90472382018-05-25 15:58:36 -07008707def recover_build_id(ad):
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008708 build_fingerprint = ad.adb.getprop(
monikerminea601efc2019-11-11 13:14:49 -08008709 "ro.vendor.build.fingerprint") or ad.adb.getprop(
8710 "ro.build.fingerprint")
Betty Zhou90472382018-05-25 15:58:36 -07008711 if not build_fingerprint:
8712 return
8713 build_id = build_fingerprint.split("/")[3]
8714 if ad.adb.getprop("ro.build.id") != build_id:
8715 build_id_override(ad, build_id)
8716
Pratik Sheth68e4eba2021-03-23 17:10:13 -07008717
“Jamesf11d7222020-04-13 14:49:24 -07008718def enable_privacy_usage_diagnostics(ad):
8719 try:
8720 ad.ensure_screen_on()
8721 ad.send_keycode('HOME')
8722 # open the UI page on which we need to enable the setting
8723 cmd = ('am start -n com.google.android.gms/com.google.android.gms.'
8724 'usagereporting.settings.UsageReportingActivity')
8725 ad.adb.shell(cmd)
8726 # perform the toggle
8727 ad.send_keycode('TAB')
“Jamesab922b82020-05-18 16:57:11 -07008728 ad.send_keycode('ENTER')
“Jamesf11d7222020-04-13 14:49:24 -07008729 except Exception:
8730 ad.log.info("Unable to toggle Usage and Diagnostics")
Betty Zhou90472382018-05-25 15:58:36 -07008731
Pratik Sheth68e4eba2021-03-23 17:10:13 -07008732
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008733def build_id_override(ad, new_build_id=None, postfix=None):
8734 build_fingerprint = ad.adb.getprop(
8735 "ro.build.fingerprint") or ad.adb.getprop(
8736 "ro.vendor.build.fingerprint")
8737 if build_fingerprint:
8738 build_id = build_fingerprint.split("/")[3]
8739 else:
8740 build_id = None
Betty Zhou90472382018-05-25 15:58:36 -07008741 existing_build_id = ad.adb.getprop("ro.build.id")
monikerminea601efc2019-11-11 13:14:49 -08008742 if postfix is not None and postfix in build_id:
Jaineelebd278b2019-02-21 10:56:32 -08008743 ad.log.info("Build id already contains %s", postfix)
8744 return
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008745 if not new_build_id:
8746 if postfix and build_id:
8747 new_build_id = "%s.%s" % (build_id, postfix)
8748 if not new_build_id or existing_build_id == new_build_id:
Betty Zhou90472382018-05-25 15:58:36 -07008749 return
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008750 ad.log.info("Override build id %s with %s", existing_build_id,
8751 new_build_id)
“Jamesf11d7222020-04-13 14:49:24 -07008752 enable_privacy_usage_diagnostics(ad)
Betty Zhou90472382018-05-25 15:58:36 -07008753 adb_disable_verity(ad)
8754 ad.adb.remount()
8755 if "backup.prop" not in ad.adb.shell("ls /sdcard/"):
monikerminea601efc2019-11-11 13:14:49 -08008756 ad.adb.shell("cp /system/build.prop /sdcard/backup.prop")
8757 ad.adb.shell("cat /system/build.prop | grep -v ro.build.id > /sdcard/test.prop")
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008758 ad.adb.shell("echo ro.build.id=%s >> /sdcard/test.prop" % new_build_id)
monikerminea601efc2019-11-11 13:14:49 -08008759 ad.adb.shell("cp /sdcard/test.prop /system/build.prop")
Betty Zhou90472382018-05-25 15:58:36 -07008760 reboot_device(ad)
8761 ad.log.info("ro.build.id = %s", ad.adb.getprop("ro.build.id"))
8762
8763
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008764def enable_connectivity_metrics(ad):
8765 cmds = [
8766 "pm enable com.android.connectivity.metrics",
Betty Zhoue204f462018-06-08 18:36:01 -07008767 "am startservice -a com.google.android.gms.usagereporting.OPTIN_UR",
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008768 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
8769 " -e usagestats:connectivity_metrics:enable_data_collection 1",
8770 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
Betty Zhoue204f462018-06-08 18:36:01 -07008771 " -e usagestats:connectivity_metrics:telephony_snapshot_period_millis 180000"
8772 # By default it turn on all modules
8773 #"am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
8774 #" -e usagestats:connectivity_metrics:data_collection_bitmap 62"
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008775 ]
8776 for cmd in cmds:
Jaineelab5a1c82019-03-25 19:14:16 -07008777 ad.adb.shell(cmd, ignore_status=True)
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008778
8779
Betty Zhoue204f462018-06-08 18:36:01 -07008780def force_connectivity_metrics_upload(ad):
8781 cmd = "cmd jobscheduler run --force com.android.connectivity.metrics %s"
8782 for job_id in [2, 3, 5, 4, 1, 6]:
Jaineelab5a1c82019-03-25 19:14:16 -07008783 ad.adb.shell(cmd % job_id, ignore_status=True)
Betty Zhoue204f462018-06-08 18:36:01 -07008784
8785
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008786def system_file_push(ad, src_file_path, dst_file_path):
8787 """Push system file on a device.
8788
8789 Push system file need to change some system setting and remount.
8790 """
Betty Zhoua9a70f62017-11-16 14:53:11 -08008791 cmd = "%s %s" % (src_file_path, dst_file_path)
8792 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
markdr6607bf12018-01-02 14:45:38 -08008793 skip_sl4a = True if "sl4a.apk" in src_file_path else False
Betty Zhoua9a70f62017-11-16 14:53:11 -08008794 if "Read-only file system" in out:
8795 ad.log.info("Change read-only file system")
Betty Zhouf7da39e2018-04-16 16:28:58 -07008796 adb_disable_verity(ad)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008797 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
8798 if "Read-only file system" in out:
Betty Zhou856ae212018-01-18 19:49:35 -08008799 ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008800 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
8801 if "error" in out:
8802 ad.log.error("%s failed with %s", cmd, out)
8803 return False
8804 else:
Betty Zhou856ae212018-01-18 19:49:35 -08008805 ad.log.info("push %s succeed")
8806 if skip_sl4a: ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008807 return True
8808 else:
8809 return True
8810 elif "error" in out:
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008811 return False
Betty Zhoua9a70f62017-11-16 14:53:11 -08008812 else:
8813 return True
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008814
8815
8816def flash_radio(ad, file_path, skip_setup_wizard=True):
8817 """Flash radio image."""
8818 ad.stop_services()
8819 ad.log.info("Reboot to bootloader")
8820 ad.adb.reboot_bootloader(ignore_status=True)
8821 ad.log.info("Flash radio in fastboot")
8822 try:
8823 ad.fastboot.flash("radio %s" % file_path, timeout=300)
8824 except Exception as e:
8825 ad.log.error(e)
Betty Zhoud4b75c52018-04-03 15:20:00 -07008826 ad.fastboot.reboot("bootloader")
8827 time.sleep(5)
8828 output = ad.fastboot.getvar("version-baseband")
8829 result = re.search(r"version-baseband: (\S+)", output)
8830 if not result:
8831 ad.log.error("fastboot getvar version-baseband output = %s", output)
8832 abort_all_tests(ad.log, "Radio version-baseband is not provided")
8833 fastboot_radio_version_output = result.group(1)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008834 for _ in range(2):
8835 try:
8836 ad.log.info("Reboot in fastboot")
8837 ad.fastboot.reboot()
8838 ad.wait_for_boot_completion()
8839 break
8840 except Exception as e:
8841 ad.log.error("Exception error %s", e)
8842 ad.root_adb()
Betty Zhoud4b75c52018-04-03 15:20:00 -07008843 adb_radio_version_output = ad.adb.getprop("gsm.version.baseband")
8844 ad.log.info("adb getprop gsm.version.baseband = %s",
8845 adb_radio_version_output)
8846 if adb_radio_version_output != fastboot_radio_version_output:
8847 msg = ("fastboot radio version output %s does not match with adb"
8848 " radio version output %s" % (fastboot_radio_version_output,
8849 adb_radio_version_output))
8850 abort_all_tests(ad.log, msg)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008851 if not ad.ensure_screen_on():
8852 ad.log.error("User window cannot come up")
Xianyuan Jia8f6a8e62019-01-07 23:32:47 +00008853 ad.start_services(skip_setup_wizard=skip_setup_wizard)
Betty Zhou447080c2018-02-06 10:43:26 -08008854 unlock_sim(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008855
8856
Jaineel13ac2fc2017-10-26 16:25:50 -07008857def set_preferred_apn_by_adb(ad, pref_apn_name):
8858 """Select Pref APN
8859 Set Preferred APN on UI using content query/insert
8860 It needs apn name as arg, and it will match with plmn id
8861 """
8862 try:
8863 plmn_id = get_plmn_by_adb(ad)
8864 out = ad.adb.shell("content query --uri content://telephony/carriers "
8865 "--where \"apn='%s' and numeric='%s'\"" %
8866 (pref_apn_name, plmn_id))
8867 if "No result found" in out:
8868 ad.log.warning("Cannot find APN %s on device", pref_apn_name)
8869 return False
8870 else:
8871 apn_id = re.search(r'_id=(\d+)', out).group(1)
8872 ad.log.info("APN ID is %s", apn_id)
8873 ad.adb.shell("content insert --uri content:"
8874 "//telephony/carriers/preferapn --bind apn_id:i:%s" %
8875 (apn_id))
8876 out = ad.adb.shell("content query --uri "
8877 "content://telephony/carriers/preferapn")
8878 if "No result found" in out:
8879 ad.log.error("Failed to set prefer APN %s", pref_apn_name)
8880 return False
8881 elif apn_id == re.search(r'_id=(\d+)', out).group(1):
8882 ad.log.info("Preferred APN set to %s", pref_apn_name)
8883 return True
8884 except Exception as e:
8885 ad.log.error("Exception while setting pref apn %s", e)
8886 return True
8887
8888
Jaineel13fb98d2017-10-20 12:26:50 -07008889def check_apm_mode_on_by_serial(ad, serial_id):
8890 try:
8891 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id,
8892 "grep -i airplanemodeon", "cut -f2 -d ' '"))
8893 output = exe_cmd(apm_check_cmd)
8894 if output.decode("utf-8").split("\n")[0] == "true":
8895 return True
8896 else:
8897 return False
8898 except Exception as e:
8899 ad.log.warning("Exception during check apm mode on %s", e)
Jaineel5576d432017-10-19 15:36:42 -07008900 return True
Jaineel5576d432017-10-19 15:36:42 -07008901
8902
Jaineel13fb98d2017-10-20 12:26:50 -07008903def set_apm_mode_on_by_serial(ad, serial_id):
8904 try:
8905 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id
8906 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id
8907 exe_cmd(cmd1)
8908 exe_cmd(cmd2)
8909 except Exception as e:
8910 ad.log.warning("Exception during set apm mode on %s", e)
8911 return True
Jaineel5576d432017-10-19 15:36:42 -07008912
8913
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008914def print_radio_info(ad, extra_msg=""):
8915 for prop in ("gsm.version.baseband", "persist.radio.ver_info",
Betty Zhou447080c2018-02-06 10:43:26 -08008916 "persist.radio.cnv.ver_info"):
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008917 output = ad.adb.getprop(prop)
Betty Zhou447080c2018-02-06 10:43:26 -08008918 ad.log.info("%s%s = %s", extra_msg, prop, output)
Betty Zhou32e403a2017-10-25 20:08:12 -07008919
8920
8921def wait_for_state(state_check_func,
8922 state,
Betty Zhouddc76402018-01-23 16:29:25 -08008923 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE,
markdr6607bf12018-01-02 14:45:38 -08008924 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK,
Betty Zhou32e403a2017-10-25 20:08:12 -07008925 *args,
8926 **kwargs):
8927 while max_wait_time >= 0:
8928 if state_check_func(*args, **kwargs) == state:
8929 return True
8930 time.sleep(checking_interval)
8931 max_wait_time -= checking_interval
8932 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008933
8934
Betty Zhou6dd0ac62018-04-27 18:59:12 -07008935def power_off_sim(ad, sim_slot_id=None,
8936 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008937 try:
8938 if sim_slot_id is None:
8939 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN)
8940 verify_func = ad.droid.telephonyGetSimState
8941 verify_args = []
8942 else:
markdr6607bf12018-01-02 14:45:38 -08008943 ad.droid.telephonySetSimStateForSlotId(sim_slot_id,
8944 CARD_POWER_DOWN)
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008945 verify_func = ad.droid.telephonyGetSimStateForSlotId
8946 verify_args = [sim_slot_id]
8947 except Exception as e:
8948 ad.log.error(e)
8949 return False
Betty Zhou6dd0ac62018-04-27 18:59:12 -07008950 while timeout > 0:
8951 sim_state = verify_func(*verify_args)
8952 if sim_state in (SIM_STATE_UNKNOWN, SIM_STATE_ABSENT):
8953 ad.log.info("SIM slot is powered off, SIM state is %s", sim_state)
8954 return True
8955 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
8956 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
8957 ad.log.warning("Fail to power off SIM slot, sim_state=%s",
8958 verify_func(*verify_args))
8959 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008960
8961
8962def power_on_sim(ad, sim_slot_id=None):
8963 try:
8964 if sim_slot_id is None:
8965 ad.droid.telephonySetSimPowerState(CARD_POWER_UP)
8966 verify_func = ad.droid.telephonyGetSimState
8967 verify_args = []
8968 else:
8969 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP)
8970 verify_func = ad.droid.telephonyGetSimStateForSlotId
8971 verify_args = [sim_slot_id]
8972 except Exception as e:
8973 ad.log.error(e)
8974 return False
Betty Zhouddc76402018-01-23 16:29:25 -08008975 if wait_for_state(verify_func, SIM_STATE_READY,
8976 MAX_WAIT_TIME_FOR_STATE_CHANGE,
8977 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args):
Betty Zhoua0469792018-01-22 18:48:02 -08008978 ad.log.info("SIM slot is powered on, SIM state is READY")
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008979 return True
8980 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED:
Betty Zhoue66efb42018-01-31 19:45:56 -08008981 ad.log.info("SIM is pin locked")
8982 return True
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008983 else:
8984 ad.log.error("Fail to power on SIM slot")
markdr6607bf12018-01-02 14:45:38 -08008985 return False
Betty Zhou6357f452018-02-05 18:09:07 -08008986
8987
Betty Zhou3db27a32018-04-23 14:31:25 -07008988def extract_test_log(log, src_file, dst_file, test_tag):
Mark De Ruyter72f8df92020-02-12 13:44:49 -08008989 os.makedirs(os.path.dirname(dst_file), exist_ok=True)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008990 cmd = "grep -n '%s' %s" % (test_tag, src_file)
Betty Zhou3db27a32018-04-23 14:31:25 -07008991 result = job.run(cmd, ignore_status=True)
8992 if not result.stdout or result.exit_status == 1:
Betty Zhoue26fe892018-04-23 15:29:53 -07008993 log.warning("Command %s returns %s", cmd, result)
Betty Zhou3db27a32018-04-23 14:31:25 -07008994 return
8995 line_nums = re.findall(r"(\d+).*", result.stdout)
8996 if line_nums:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008997 begin_line = int(line_nums[0])
8998 end_line = int(line_nums[-1])
8999 if end_line - begin_line <= 5:
9000 result = job.run("wc -l < %s" % src_file)
9001 if result.stdout:
9002 end_line = int(result.stdout)
Betty Zhou3db27a32018-04-23 14:31:25 -07009003 log.info("Extract %s from line %s to line %s to %s", src_file,
9004 begin_line, end_line, dst_file)
9005 job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line,
9006 src_file, dst_file))
9007
9008
Betty Zhou0ca65c52018-04-26 15:47:38 -07009009def get_device_epoch_time(ad):
9010 return int(1000 * float(ad.adb.shell("date +%s.%N")))
9011
9012
9013def synchronize_device_time(ad):
Betty Zhouff2a3fa2018-05-02 16:58:27 -07009014 ad.adb.shell("put global auto_time 0", ignore_status=True)
9015 try:
Betty Zhouff2a3fa2018-05-02 16:58:27 -07009016 ad.adb.droid.setTime(get_current_epoch_time())
Betty Zhou819cb732018-05-10 18:45:41 -07009017 except Exception:
9018 try:
9019 ad.adb.shell("date `date +%m%d%H%M%G.%S`")
9020 except Exception:
9021 pass
9022 try:
9023 ad.adb.shell(
9024 "am broadcast -a android.intent.action.TIME_SET",
9025 ignore_status=True)
9026 except Exception:
9027 pass
Betty Zhou0ca65c52018-04-26 15:47:38 -07009028
9029
Betty Zhou8aafcc12018-05-01 20:54:15 -07009030def revert_default_telephony_setting(ad):
9031 toggle_airplane_mode_by_adb(ad.log, ad, True)
9032 default_data_roaming = int(
9033 ad.adb.getprop("ro.com.android.dataroaming") == 'true')
9034 default_network_preference = int(
9035 ad.adb.getprop("ro.telephony.default_network"))
9036 ad.log.info("Default data roaming %s, network preference %s",
9037 default_data_roaming, default_network_preference)
9038 new_data_roaming = abs(default_data_roaming - 1)
9039 new_network_preference = abs(default_network_preference - 1)
9040 ad.log.info(
9041 "Set data roaming = %s, mobile data = 0, network preference = %s",
9042 new_data_roaming, new_network_preference)
9043 ad.adb.shell("settings put global mobile_data 0")
9044 ad.adb.shell("settings put global data_roaming %s" % new_data_roaming)
9045 ad.adb.shell("settings put global preferred_network_mode %s" %
9046 new_network_preference)
9047
9048
9049def verify_default_telephony_setting(ad):
9050 ad.log.info("carrier_config: %s", dumpsys_carrier_config(ad))
9051 default_data_roaming = int(
9052 ad.adb.getprop("ro.com.android.dataroaming") == 'true')
9053 default_network_preference = int(
9054 ad.adb.getprop("ro.telephony.default_network"))
9055 ad.log.info("Default data roaming %s, network preference %s",
9056 default_data_roaming, default_network_preference)
9057 data_roaming = int(ad.adb.shell("settings get global data_roaming"))
9058 mobile_data = int(ad.adb.shell("settings get global mobile_data"))
9059 network_preference = int(
9060 ad.adb.shell("settings get global preferred_network_mode"))
9061 airplane_mode = int(ad.adb.shell("settings get global airplane_mode_on"))
9062 result = True
Betty Zhouff2a3fa2018-05-02 16:58:27 -07009063 ad.log.info("data_roaming = %s, mobile_data = %s, "
9064 "network_perference = %s, airplane_mode = %s", data_roaming,
9065 mobile_data, network_preference, airplane_mode)
Betty Zhou8aafcc12018-05-01 20:54:15 -07009066 if airplane_mode:
9067 ad.log.error("Airplane mode is on")
9068 result = False
9069 if data_roaming != default_data_roaming:
9070 ad.log.error("Data roaming is %s, expecting %s", data_roaming,
9071 default_data_roaming)
9072 result = False
9073 if not mobile_data:
9074 ad.log.error("Mobile data is off")
9075 result = False
9076 if network_preference != default_network_preference:
9077 ad.log.error("preferred_network_mode is %s, expecting %s",
9078 network_preference, default_network_preference)
9079 result = False
9080 return result
9081
9082
Betty Zhou74cf9922018-04-18 20:18:12 -07009083def log_messaging_screen_shot(ad, test_name=""):
Betty Zhou2186ebc2018-05-09 16:50:26 -07009084 ad.ensure_screen_on()
Betty Zhou1ffbc832018-05-08 19:02:56 -07009085 ad.send_keycode("HOME")
Betty Zhou2186ebc2018-05-09 16:50:26 -07009086 ad.adb.shell("am start -n com.google.android.apps.messaging/.ui."
9087 "ConversationListActivity")
Richacha5a65ffa2021-01-12 20:06:13 +08009088 time.sleep(3)
Betty Zhou74cf9922018-04-18 20:18:12 -07009089 log_screen_shot(ad, test_name)
Betty Zhou2186ebc2018-05-09 16:50:26 -07009090 ad.adb.shell("am start -n com.google.android.apps.messaging/com.google."
Richacha5a65ffa2021-01-12 20:06:13 +08009091 "android.apps.messaging.ui.conversation."
9092 "LaunchConversationShimActivity -e conversation_id 1")
9093 time.sleep(3)
Betty Zhou74cf9922018-04-18 20:18:12 -07009094 log_screen_shot(ad, test_name)
9095 ad.send_keycode("HOME")
9096
9097
Betty Zhoua36c4352018-04-05 18:49:32 -07009098def log_screen_shot(ad, test_name=""):
Betty Zhou74cf9922018-04-18 20:18:12 -07009099 file_name = "/sdcard/Pictures/screencap"
9100 if test_name:
9101 file_name = "%s_%s" % (file_name, test_name)
9102 file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
Betty Zhoue57ab692018-03-09 18:39:30 -08009103 try:
9104 ad.adb.shell("screencap -p %s" % file_name)
Betty Zhoue57ab692018-03-09 18:39:30 -08009105 except:
Betty Zhoue123c672018-03-21 19:57:11 -07009106 ad.log.error("Fail to log screen shot to %s", file_name)
9107
9108
9109def get_screen_shot_log(ad, test_name="", begin_time=None):
9110 logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time)
9111 if logs:
9112 ad.log.info("Pulling %s", logs)
Xianyuan Jiad6b2a632019-05-24 17:40:45 +00009113 log_path = os.path.join(ad.device_log_path, "Screenshot_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08009114 os.makedirs(log_path, exist_ok=True)
Betty Zhoua36c4352018-04-05 18:49:32 -07009115 ad.pull_files(logs, log_path)
Betty Zhoue123c672018-03-21 19:57:11 -07009116 ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True)
9117
9118
9119def get_screen_shot_logs(ads, test_name="", begin_time=None):
9120 for ad in ads:
9121 get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time)
Betty Zhouc8213812018-04-02 14:06:50 -07009122
9123
Jaineela03017f2019-03-07 17:30:17 -08009124def get_carrier_id_version(ad):
9125 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | " \
9126 "grep -i carrier_list_version")
9127 if out and ":" in out:
9128 version = out.split(':')[1].lstrip()
9129 else:
9130 version = "0"
9131 ad.log.debug("Carrier Config Version is %s", version)
9132 return version
9133
9134
Jaineel1cde17b2019-01-04 14:26:55 -08009135def get_carrier_config_version(ad):
9136 out = ad.adb.shell("dumpsys carrier_config | grep version_string")
9137 if out and "-" in out:
9138 version = out.split('-')[1]
9139 else:
9140 version = "0"
9141 ad.log.debug("Carrier Config Version is %s", version)
9142 return version
9143
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009144
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009145def get_er_db_id_version(ad):
9146 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \
9147 grep -i \"Database Version\"")
9148 if out and ":" in out:
Ashutosh Rajmani Singh4d1c9bf2020-04-16 14:40:02 -07009149 version = out.split(':', 2)[2].lstrip()
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009150 else:
9151 version = "0"
9152 ad.log.debug("Emergency database Version is %s", version)
9153 return version
9154
Ashutosh Rajmani Singh8a8ee3e2020-04-20 19:47:44 -07009155def get_database_content(ad):
9156 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \
9157 egrep -i \EmergencyNumber:Number-54321")
9158 if out:
9159 return True
9160 result = ad.adb.shell(r"dumpsys activity service TelephonyDebugService | \
9161 egrep -i \updateOtaEmergencyNumberListDatabaseAndNotify")
9162 ad.log.error("Emergency Number is incorrect. %s ", result)
9163 return False
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009164
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009165
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009166def add_whitelisted_account(ad, user_account,user_password, retries=3):
9167 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9168 ad.log.error("GoogleAccountUtil is not installed")
9169 return False
9170 for _ in range(retries):
9171 ad.ensure_screen_on()
9172 output = ad.adb.shell(
9173 'am instrument -w -e account "%s@gmail.com" -e password '
9174 '"%s" -e sync true -e wait-for-checkin false '
9175 'com.google.android.tradefed.account/.AddAccount' %
9176 (user_account, user_password))
9177 if "result=SUCCESS" in output:
9178 ad.log.info("Google account is added successfully")
9179 return True
9180 ad.log.error("Failed to add google account - %s", output)
9181 return False
9182
Jaineel1cde17b2019-01-04 14:26:55 -08009183
Jaineelc50c2e62019-02-15 16:46:36 -08009184def install_googleaccountutil_apk(ad, account_util):
9185 ad.log.info("Install account_util %s", account_util)
9186 ad.ensure_screen_on()
9187 ad.adb.install("-r %s" % account_util, timeout=300, ignore_status=True)
9188 time.sleep(3)
9189 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9190 ad.log.info("com.google.android.tradefed.account is not installed")
9191 return False
9192 return True
9193
9194
Jaineel5865cac2019-02-20 16:30:42 -08009195def install_googlefi_apk(ad, fi_util):
9196 ad.log.info("Install fi_util %s", fi_util)
9197 ad.ensure_screen_on()
9198 ad.adb.install("-r -g --user 0 %s" % fi_util,
9199 timeout=300, ignore_status=True)
9200 time.sleep(3)
Jaineel39e72882019-03-21 13:20:49 -07009201 if not check_fi_apk_installed(ad):
9202 return False
9203 return True
9204
9205
9206def check_fi_apk_installed(ad):
Jaineel5865cac2019-02-20 16:30:42 -08009207 if not ad.is_apk_installed("com.google.android.apps.tycho"):
Jaineel39e72882019-03-21 13:20:49 -07009208 ad.log.warning("com.google.android.apps.tycho is not installed")
Jaineel5865cac2019-02-20 16:30:42 -08009209 return False
9210 return True
9211
9212
Jaineelc50c2e62019-02-15 16:46:36 -08009213def add_google_account(ad, retries=3):
9214 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9215 ad.log.error("GoogleAccountUtil is not installed")
9216 return False
9217 for _ in range(retries):
9218 ad.ensure_screen_on()
9219 output = ad.adb.shell(
9220 'am instrument -w -e account "%s@gmail.com" -e password '
9221 '"%s" -e sync true -e wait-for-checkin false '
9222 'com.google.android.tradefed.account/.AddAccount' %
9223 (ad.user_account, ad.user_password))
9224 if "result=SUCCESS" in output:
9225 ad.log.info("Google account is added successfully")
9226 return True
9227 ad.log.error("Failed to add google account - %s", output)
9228 return False
9229
9230
9231def remove_google_account(ad, retries=3):
9232 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9233 ad.log.error("GoogleAccountUtil is not installed")
9234 return False
9235 for _ in range(retries):
9236 ad.ensure_screen_on()
9237 output = ad.adb.shell(
9238 'am instrument -w '
9239 'com.google.android.tradefed.account/.RemoveAccounts')
9240 if "result=SUCCESS" in output:
9241 ad.log.info("google account is removed successfully")
9242 return True
9243 ad.log.error("Fail to remove google account due to %s", output)
9244 return False
9245
9246
Jaineele74193b2019-02-19 17:52:50 -08009247def my_current_screen_content(ad, content):
9248 ad.adb.shell("uiautomator dump --window=WINDOW")
9249 out = ad.adb.shell("cat /sdcard/window_dump.xml | grep -E '%s'" % content)
9250 if not out:
Jaineel39e72882019-03-21 13:20:49 -07009251 ad.log.warning("NOT FOUND - %s", content)
Jaineele74193b2019-02-19 17:52:50 -08009252 return False
9253 return True
9254
9255
Jaineelea47b1e2019-09-18 11:11:03 -07009256def activate_esim_using_suw(ad):
9257 _START_SUW = ('am start -a android.intent.action.MAIN -n '
9258 'com.google.android.setupwizard/.SetupWizardTestActivity')
9259 _STOP_SUW = ('am start -a com.android.setupwizard.EXIT')
9260
9261 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
9262 ad.adb.shell("settings put system screen_off_timeout 1800000")
9263 ad.ensure_screen_on()
9264 ad.send_keycode("MENU")
9265 ad.send_keycode("HOME")
9266 for _ in range(3):
9267 ad.log.info("Attempt %d - activating eSIM", (_ + 1))
9268 ad.adb.shell(_START_SUW)
9269 time.sleep(10)
9270 log_screen_shot(ad, "start_suw")
9271 for _ in range(4):
9272 ad.send_keycode("TAB")
9273 time.sleep(0.5)
9274 ad.send_keycode("ENTER")
9275 time.sleep(15)
9276 log_screen_shot(ad, "activate_esim")
9277 get_screen_shot_log(ad)
9278 ad.adb.shell(_STOP_SUW)
9279 time.sleep(5)
9280 current_sim = get_sim_state(ad)
9281 ad.log.info("Current SIM status is %s", current_sim)
9282 if current_sim not in (SIM_STATE_ABSENT, SIM_STATE_UNKNOWN):
9283 break
9284 return True
9285
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009286
Jaineele1b182a2019-04-12 15:47:48 -07009287def activate_google_fi_account(ad, retries=10):
Jaineele74193b2019-02-19 17:52:50 -08009288 _FI_APK = "com.google.android.apps.tycho"
9289 _FI_ACTIVATE_CMD = ('am start -c android.intent.category.DEFAULT -n '
Jaineelfc742862019-05-16 14:57:56 -07009290 'com.google.android.apps.tycho/.AccountDetailsActivity --ez '
Jaineele74193b2019-02-19 17:52:50 -08009291 'in_setup_wizard false --ez force_show_account_chooser '
9292 'false')
Jaineel39e72882019-03-21 13:20:49 -07009293 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
Jaineele74193b2019-02-19 17:52:50 -08009294 ad.adb.shell("settings put system screen_off_timeout 1800000")
9295 page_match_dict = {
Jaineelfc742862019-05-16 14:57:56 -07009296 "SelectAccount" : "Choose an account to use",
Jaineele74193b2019-02-19 17:52:50 -08009297 "Setup" : "Activate Google Fi to use your device for calls",
9298 "Switch" : "Switch to the Google Fi mobile network",
Jaineelfc742862019-05-16 14:57:56 -07009299 "WiFi" : "Fi to download your SIM",
Jaineel39e72882019-03-21 13:20:49 -07009300 "Connect" : "Connect to the Google Fi mobile network",
9301 "Move" : "Move number",
Jaineele1b182a2019-04-12 15:47:48 -07009302 "Data" : "first turn on mobile data",
Jaineele74193b2019-02-19 17:52:50 -08009303 "Activate" : "This takes a minute or two, sometimes longer",
9304 "Welcome" : "Welcome to Google Fi",
Jaineel39e72882019-03-21 13:20:49 -07009305 "Account" : "Your current cycle ends in"
Jaineele74193b2019-02-19 17:52:50 -08009306 }
Jaineelfc742862019-05-16 14:57:56 -07009307 page_list = ["Account", "Setup", "WiFi", "Switch", "Connect",
Jaineele1b182a2019-04-12 15:47:48 -07009308 "Activate", "Move", "Welcome", "Data"]
Jaineele74193b2019-02-19 17:52:50 -08009309 for _ in range(retries):
9310 ad.force_stop_apk(_FI_APK)
9311 ad.ensure_screen_on()
Jaineel687a67c2019-04-08 13:08:37 -07009312 ad.send_keycode("MENU")
Jaineele74193b2019-02-19 17:52:50 -08009313 ad.send_keycode("HOME")
9314 ad.adb.shell(_FI_ACTIVATE_CMD)
9315 time.sleep(15)
Jaineel39e72882019-03-21 13:20:49 -07009316 for page in page_list:
Jaineele74193b2019-02-19 17:52:50 -08009317 if my_current_screen_content(ad, page_match_dict[page]):
9318 ad.log.info("Ready for Step %s", page)
9319 log_screen_shot(ad, "fi_activation_step_%s" % page)
Jaineelfc742862019-05-16 14:57:56 -07009320 if page in ("Setup", "Switch", "Connect", "WiFi"):
Jaineele74193b2019-02-19 17:52:50 -08009321 ad.send_keycode("TAB")
9322 ad.send_keycode("TAB")
9323 ad.send_keycode("ENTER")
9324 time.sleep(30)
Jaineelfc742862019-05-16 14:57:56 -07009325 elif page == "Move" or page == "SelectAccount":
Jaineel39e72882019-03-21 13:20:49 -07009326 ad.send_keycode("TAB")
9327 ad.send_keycode("ENTER")
9328 time.sleep(5)
Jaineele74193b2019-02-19 17:52:50 -08009329 elif page == "Welcome":
9330 ad.send_keycode("TAB")
9331 ad.send_keycode("TAB")
9332 ad.send_keycode("TAB")
9333 ad.send_keycode("ENTER")
9334 ad.log.info("Activation SUCCESS using Fi App")
9335 time.sleep(5)
9336 ad.send_keycode("TAB")
9337 ad.send_keycode("TAB")
9338 ad.send_keycode("ENTER")
9339 return True
9340 elif page == "Activate":
9341 time.sleep(60)
9342 if my_current_screen_content(ad, page_match_dict[page]):
9343 time.sleep(60)
Jaineel39e72882019-03-21 13:20:49 -07009344 elif page == "Account":
9345 return True
Jaineele1b182a2019-04-12 15:47:48 -07009346 elif page == "Data":
9347 ad.log.error("Mobile Data is turned OFF by default")
9348 ad.send_keycode("TAB")
9349 ad.send_keycode("TAB")
9350 ad.send_keycode("ENTER")
Jaineele74193b2019-02-19 17:52:50 -08009351 else:
Jaineel39e72882019-03-21 13:20:49 -07009352 ad.log.info("NOT FOUND - Page %s", page)
Jaineele74193b2019-02-19 17:52:50 -08009353 log_screen_shot(ad, "fi_activation_step_%s_failure" % page)
Jaineelfc742862019-05-16 14:57:56 -07009354 get_screen_shot_log(ad)
Jaineele74193b2019-02-19 17:52:50 -08009355 return False
9356
9357
9358def check_google_fi_activated(ad, retries=20):
Jaineel39e72882019-03-21 13:20:49 -07009359 if check_fi_apk_installed(ad):
9360 _FI_APK = "com.google.android.apps.tycho"
9361 _FI_LAUNCH_CMD = ("am start -n %s/%s.AccountDetailsActivity" \
9362 % (_FI_APK, _FI_APK))
9363 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
9364 ad.adb.shell("settings put system screen_off_timeout 1800000")
9365 ad.force_stop_apk(_FI_APK)
9366 ad.ensure_screen_on()
9367 ad.send_keycode("HOME")
9368 ad.adb.shell(_FI_LAUNCH_CMD)
9369 time.sleep(10)
9370 if not my_current_screen_content(ad, "Your current cycle ends in"):
9371 ad.log.warning("Fi is not activated")
9372 return False
9373 ad.send_keycode("HOME")
9374 return True
9375 else:
9376 ad.log.info("Fi Apk is not yet installed")
9377 return False
Jaineele74193b2019-02-19 17:52:50 -08009378
9379
Jaineela03017f2019-03-07 17:30:17 -08009380def cleanup_configupdater(ad):
9381 cmds = ('rm -rf /data/data/com.google.android.configupdater/shared_prefs',
9382 'rm /data/misc/carrierid/carrier_list.pb',
9383 'setprop persist.telephony.test.carrierid.ota true',
9384 'rm /data/user_de/0/com.android.providers.telephony/shared_prefs'
9385 '/CarrierIdProvider.xml')
9386 for cmd in cmds:
9387 ad.log.info("Cleanup ConfigUpdater - %s", cmd)
9388 ad.adb.shell(cmd, ignore_status=True)
9389
9390
9391def pull_carrier_id_files(ad, carrier_id_path):
Mark De Ruyter72f8df92020-02-12 13:44:49 -08009392 os.makedirs(carrier_id_path, exist_ok=True)
Jaineela03017f2019-03-07 17:30:17 -08009393 ad.log.info("Pull CarrierId Files")
Jaineel3fc8ad02019-03-14 09:53:20 -07009394 cmds = ('/data/data/com.google.android.configupdater/shared_prefs/',
9395 '/data/misc/carrierid/',
9396 '/data/user_de/0/com.android.providers.telephony/shared_prefs/',
9397 '/data/data/com.android.providers.downloads/databases/downloads.db')
Jaineela03017f2019-03-07 17:30:17 -08009398 for cmd in cmds:
Jaineel3fc8ad02019-03-14 09:53:20 -07009399 cmd = cmd + " %s" % carrier_id_path
Jaineela03017f2019-03-07 17:30:17 -08009400 ad.adb.pull(cmd, timeout=30, ignore_status=True)
9401
9402
Betty Zhouc8213812018-04-02 14:06:50 -07009403def bring_up_connectivity_monitor(ad):
9404 monitor_apk = None
9405 for apk in ("com.google.telephonymonitor",
9406 "com.google.android.connectivitymonitor"):
9407 if ad.is_apk_installed(apk):
9408 ad.log.info("apk %s is installed", apk)
9409 monitor_apk = apk
9410 break
9411 if not monitor_apk:
9412 ad.log.info("ConnectivityMonitor|TelephonyMonitor is not installed")
9413 return False
9414 toggle_connectivity_monitor_setting(ad, True)
9415
9416 if not ad.is_apk_running(monitor_apk):
9417 ad.log.info("%s is not running", monitor_apk)
9418 # Reboot
9419 ad.log.info("reboot to bring up %s", monitor_apk)
9420 reboot_device(ad)
9421 for i in range(30):
Betty Zhoue21f4922018-04-02 18:41:44 -07009422 if ad.is_apk_running(monitor_apk):
9423 ad.log.info("%s is running after reboot", monitor_apk)
Betty Zhouc8213812018-04-02 14:06:50 -07009424 return True
9425 else:
Betty Zhoue21f4922018-04-02 18:41:44 -07009426 ad.log.info(
Betty Zhouc8213812018-04-02 14:06:50 -07009427 "%s is not running after reboot. Wait and check again",
9428 monitor_apk)
9429 time.sleep(30)
9430 ad.log.error("%s is not running after reboot", monitor_apk)
9431 return False
9432 else:
9433 ad.log.info("%s is running", monitor_apk)
9434 return True
9435
9436
monikermine709efcd2019-10-04 14:06:26 -07009437def get_host_ip_address(ad):
9438 cmd = "|".join(("ifconfig", "grep eno1 -A1", "grep inet", "awk '{$1=$1};1'", "cut -d ' ' -f 2"))
9439 destination_ip = exe_cmd(cmd)
9440 destination_ip = (destination_ip.decode("utf-8")).split("\n")[0]
9441 ad.log.info("Host IP is %s", destination_ip)
9442 return destination_ip
9443
9444
Mars Linc6e99602019-12-02 12:00:06 +08009445def load_scone_cat_simulate_data(ad, simulate_data, sub_id=None):
9446 """ Load radio simulate data
9447 ad: android device controller
9448 simulate_data: JSON object of simulate data
9449 sub_id: RIL sub id, should be 0 or 1
9450 """
9451 ad.log.info("load_scone_cat_simulate_data")
9452
9453 #Check RIL sub id
9454 if sub_id is None or sub_id > 1:
9455 ad.log.error("The value of RIL sub_id should be 0 or 1")
9456 return False
9457
9458 action = "com.google.android.apps.scone.cat.action.SetSimulateData"
9459
9460 #add sub id
9461 simulate_data["SubId"] = sub_id
9462 try:
9463 #dump json
9464 extra = json.dumps(simulate_data)
9465 ad.log.info("send simulate_data=[%s]" % extra)
9466 #send data
9467 ad.adb.shell("am broadcast -a " + action + " --es simulate_data '" + extra + "'")
9468 except Exception as e:
9469 ad.log.error("Exception error to send CAT: %s", e)
9470 return False
9471
9472 return True
9473
9474
9475def load_scone_cat_data_from_file(ad, simulate_file_path, sub_id=None):
9476 """ Load radio simulate data
9477 ad: android device controller
9478 simulate_file_path: JSON file of simulate data
9479 sub_id: RIL sub id, should be 0 or 1
9480 """
9481 ad.log.info("load_radio_simulate_data_from_file from %s" % simulate_file_path)
9482 radio_simulate_data = {}
9483
9484 #Check RIL sub id
9485 if sub_id is None or sub_id > 1:
9486 ad.log.error("The value of RIL sub_id should be 0 or 1")
9487 raise ValueError
9488
9489 with open(simulate_file_path, 'r') as f:
9490 try:
9491 radio_simulate_data = json.load(f)
9492 except Exception as e:
Richachaecd93c12021-04-25 22:23:47 +08009493 ad.log.error("Exception error to load %s: %s", f, e)
Mars Linc6e99602019-12-02 12:00:06 +08009494 return False
9495
9496 for item in radio_simulate_data:
9497 result = load_scone_cat_simulate_data(ad, item, sub_id)
9498 if result == False:
9499 ad.log.error("Load CAT command fail")
9500 return False
9501 time.sleep(0.1)
9502
9503 return True
9504
9505
Betty Zhouc8213812018-04-02 14:06:50 -07009506def toggle_connectivity_monitor_setting(ad, state=True):
9507 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon")
9508 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting)
9509 current_state = True if monitor_setting == "user_enabled" else False
9510 if current_state == state:
9511 return True
9512 elif state is None:
9513 state = not current_state
9514 expected_monitor_setting = "user_enabled" if state else "disabled"
9515 cmd = "setprop persist.radio.enable_tel_mon %s" % expected_monitor_setting
9516 ad.log.info("Toggle connectivity monitor by %s", cmd)
9517 ad.adb.shell(
9518 "am start -n com.android.settings/.DevelopmentSettings",
9519 ignore_status=True)
9520 ad.adb.shell(cmd)
9521 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon")
9522 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting)
9523 return monitor_setting == expected_monitor_setting
Markus Liu1cca96e2019-11-26 15:05:25 +08009524
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009525
Markus Liu1cca96e2019-11-26 15:05:25 +08009526def get_call_forwarding_by_adb(log, ad, call_forwarding_type="unconditional"):
9527 """ Get call forwarding status by adb shell command
9528 'dumpsys telephony.registry'.
9529
9530 Args:
9531 log: log object
9532 ad: android object
9533 call_forwarding_type:
9534 - "unconditional"
9535 - "busy" (todo)
9536 - "not_answered" (todo)
9537 - "not_reachable" (todo)
9538 Returns:
9539 - "true": if call forwarding unconditional is enabled.
9540 - "false": if call forwarding unconditional is disabled.
9541 - "unknown": if the type is other than 'unconditional'.
9542 - False: any case other than above 3 cases.
9543 """
9544 if call_forwarding_type != "unconditional":
9545 return "unknown"
9546
9547 slot_index_of_default_voice_subid = get_slot_index_from_subid(log, ad,
9548 get_incoming_voice_sub_id(ad))
9549 output = ad.adb.shell("dumpsys telephony.registry | grep mCallForwarding")
9550 if "mCallForwarding" in output:
9551 result_list = re.findall(r"mCallForwarding=(true|false)", output)
9552 if result_list:
9553 result = result_list[slot_index_of_default_voice_subid]
9554 ad.log.info("mCallForwarding is %s", result)
9555
9556 if re.search("false", result, re.I):
9557 return "false"
9558 elif re.search("true", result, re.I):
9559 return "true"
9560 else:
9561 return False
9562 else:
9563 return False
9564 else:
9565 ad.log.error("'mCallForwarding' cannot be found in dumpsys.")
9566 return False
9567
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009568
Markus Liu1cca96e2019-11-26 15:05:25 +08009569def erase_call_forwarding_by_mmi(
9570 log,
9571 ad,
9572 retry=2,
9573 call_forwarding_type="unconditional"):
9574 """ Erase setting of call forwarding (erase the number and disable call
9575 forwarding) by MMI code.
9576
9577 Args:
9578 log: log object
9579 ad: android object
9580 retry: times of retry if the erasure failed.
9581 call_forwarding_type:
9582 - "unconditional"
9583 - "busy"
9584 - "not_answered"
9585 - "not_reachable"
9586 Returns:
9587 True by successful erasure. Otherwise False.
9588 """
Markus Liu8dd3efa2021-04-01 19:31:27 +08009589 operator_name = get_operator_name(log, ad)
9590
9591 run_get_call_forwarding_by_adb = 1
9592 if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
9593 run_get_call_forwarding_by_adb = 0
9594
9595 if run_get_call_forwarding_by_adb:
9596 res = get_call_forwarding_by_adb(log, ad,
9597 call_forwarding_type=call_forwarding_type)
9598 if res == "false":
9599 return True
Markus Liu1cca96e2019-11-26 15:05:25 +08009600
9601 user_config_profile = get_user_config_profile(ad)
9602 is_airplane_mode = user_config_profile["Airplane Mode"]
9603 is_wfc_enabled = user_config_profile["WFC Enabled"]
9604 wfc_mode = user_config_profile["WFC Mode"]
9605 is_wifi_on = user_config_profile["WiFi State"]
9606
9607 if is_airplane_mode:
9608 if not toggle_airplane_mode(log, ad, False):
9609 ad.log.error("Failed to disable airplane mode.")
9610 return False
9611
Markus Liu1cca96e2019-11-26 15:05:25 +08009612 code_dict = {
9613 "Verizon": {
9614 "unconditional": "73",
9615 "busy": "73",
9616 "not_answered": "73",
9617 "not_reachable": "73",
9618 "mmi": "*%s"
9619 },
9620 "Sprint": {
9621 "unconditional": "720",
9622 "busy": "740",
9623 "not_answered": "730",
9624 "not_reachable": "720",
9625 "mmi": "*%s"
9626 },
Markus Liu8dd3efa2021-04-01 19:31:27 +08009627 "Far EasTone": {
9628 "unconditional": "142",
9629 "busy": "143",
9630 "not_answered": "144",
9631 "not_reachable": "144",
9632 "mmi": "*%s*2"
9633 },
Markus Liu1cca96e2019-11-26 15:05:25 +08009634 'Generic': {
9635 "unconditional": "21",
9636 "busy": "67",
9637 "not_answered": "61",
9638 "not_reachable": "62",
9639 "mmi": "##%s#"
9640 }
9641 }
9642
9643 if operator_name in code_dict:
9644 code = code_dict[operator_name][call_forwarding_type]
9645 mmi = code_dict[operator_name]["mmi"]
9646 else:
9647 code = code_dict['Generic'][call_forwarding_type]
9648 mmi = code_dict['Generic']["mmi"]
9649
9650 result = False
9651 while retry >= 0:
Markus Liu8dd3efa2021-04-01 19:31:27 +08009652 if run_get_call_forwarding_by_adb:
9653 res = get_call_forwarding_by_adb(
9654 log, ad, call_forwarding_type=call_forwarding_type)
9655 if res == "false":
9656 ad.log.info("Call forwarding is already disabled.")
9657 result = True
9658 break
Markus Liu1cca96e2019-11-26 15:05:25 +08009659
9660 ad.log.info("Erasing and deactivating call forwarding %s..." %
9661 call_forwarding_type)
9662
9663 ad.droid.telecomDialNumber(mmi % code)
9664
9665 time.sleep(3)
9666 ad.send_keycode("ENTER")
9667 time.sleep(15)
9668
9669 # To dismiss the pop-out dialog
9670 ad.send_keycode("BACK")
9671 time.sleep(5)
9672 ad.send_keycode("BACK")
9673
Markus Liu8dd3efa2021-04-01 19:31:27 +08009674 if run_get_call_forwarding_by_adb:
9675 res = get_call_forwarding_by_adb(
9676 log, ad, call_forwarding_type=call_forwarding_type)
9677 if res == "false" or res == "unknown":
9678 result = True
9679 break
9680 else:
9681 ad.log.error("Failed to erase and deactivate call forwarding by "
9682 "MMI code ##%s#." % code)
9683 retry = retry - 1
9684 time.sleep(30)
9685 else:
Markus Liu1cca96e2019-11-26 15:05:25 +08009686 result = True
9687 break
Markus Liu1cca96e2019-11-26 15:05:25 +08009688
9689 if is_airplane_mode:
9690 if not toggle_airplane_mode(log, ad, True):
9691 ad.log.error("Failed to enable airplane mode again.")
9692 else:
9693 if is_wifi_on:
9694 ad.droid.wifiToggleState(True)
9695 if is_wfc_enabled:
9696 if not wait_for_wfc_enabled(
9697 log, ad,max_time=MAX_WAIT_TIME_WFC_ENABLED):
9698 ad.log.error("WFC is not enabled")
9699
9700 return result
9701
9702def set_call_forwarding_by_mmi(
9703 log,
9704 ad,
9705 ad_forwarded,
9706 call_forwarding_type="unconditional",
9707 retry=2):
9708 """ Set up the forwarded number and enable call forwarding by MMI code.
9709
9710 Args:
9711 log: log object
9712 ad: android object of the device forwarding the call (primary device)
9713 ad_forwarded: android object of the device receiving forwarded call.
9714 retry: times of retry if the erasure failed.
9715 call_forwarding_type:
9716 - "unconditional"
9717 - "busy"
9718 - "not_answered"
9719 - "not_reachable"
9720 Returns:
9721 True by successful erasure. Otherwise False.
9722 """
9723
9724 res = get_call_forwarding_by_adb(log, ad,
9725 call_forwarding_type=call_forwarding_type)
9726 if res == "true":
9727 return True
9728
9729 if ad.droid.connectivityCheckAirplaneMode():
9730 ad.log.warning("%s is now in airplane mode.", ad.serial)
9731 return False
9732
9733 operator_name = get_operator_name(log, ad)
9734
9735 code_dict = {
9736 "Verizon": {
9737 "unconditional": "72",
9738 "busy": "71",
9739 "not_answered": "71",
9740 "not_reachable": "72",
9741 "mmi": "*%s%s"
9742 },
9743 "Sprint": {
9744 "unconditional": "72",
9745 "busy": "74",
9746 "not_answered": "73",
9747 "not_reachable": "72",
9748 "mmi": "*%s%s"
9749 },
Markus Liu8dd3efa2021-04-01 19:31:27 +08009750 "Far EasTone": {
9751 "unconditional": "142",
9752 "busy": "143",
9753 "not_answered": "144",
9754 "not_reachable": "144",
9755 "mmi": "*%s*%s"
9756 },
Markus Liu1cca96e2019-11-26 15:05:25 +08009757 'Generic': {
9758 "unconditional": "21",
9759 "busy": "67",
9760 "not_answered": "61",
9761 "not_reachable": "62",
9762 "mmi": "*%s*%s#",
9763 "mmi_for_plus_sign": "*%s*"
9764 }
9765 }
9766
9767 if operator_name in code_dict:
9768 code = code_dict[operator_name][call_forwarding_type]
9769 mmi = code_dict[operator_name]["mmi"]
Markus Liu8dd3efa2021-04-01 19:31:27 +08009770 if "mmi_for_plus_sign" in code_dict[operator_name]:
9771 mmi_for_plus_sign = code_dict[operator_name]["mmi_for_plus_sign"]
Markus Liu1cca96e2019-11-26 15:05:25 +08009772 else:
9773 code = code_dict['Generic'][call_forwarding_type]
9774 mmi = code_dict['Generic']["mmi"]
9775 mmi_for_plus_sign = code_dict['Generic']["mmi_for_plus_sign"]
9776
9777 while retry >= 0:
9778 if not erase_call_forwarding_by_mmi(
9779 log, ad, call_forwarding_type=call_forwarding_type):
9780 retry = retry - 1
9781 continue
9782
9783 forwarded_number = ad_forwarded.telephony['subscription'][
9784 ad_forwarded.droid.subscriptionGetDefaultVoiceSubId()][
9785 'phone_num']
9786 ad.log.info("Registering and activating call forwarding %s to %s..." %
9787 (call_forwarding_type, forwarded_number))
9788
9789 (forwarded_number_no_prefix, _) = _phone_number_remove_prefix(
9790 forwarded_number)
9791
Markus Liu8dd3efa2021-04-01 19:31:27 +08009792 if operator_name == "Far EasTone":
9793 forwarded_number_no_prefix = "0" + forwarded_number_no_prefix
9794
9795 run_get_call_forwarding_by_adb = 1
9796 if operator_name in NOT_CHECK_MCALLFORWARDING_OPERATOR_LIST:
9797 run_get_call_forwarding_by_adb = 0
9798
Markus Liu1cca96e2019-11-26 15:05:25 +08009799 _found_plus_sign = 0
9800 if re.search("^\+", forwarded_number):
9801 _found_plus_sign = 1
9802 forwarded_number.replace("+", "")
9803
9804 if operator_name in code_dict:
9805 ad.droid.telecomDialNumber(mmi % (code, forwarded_number_no_prefix))
9806 else:
9807 if _found_plus_sign == 0:
9808 ad.droid.telecomDialNumber(mmi % (code, forwarded_number))
9809 else:
9810 ad.droid.telecomDialNumber(mmi_for_plus_sign % code)
9811 ad.send_keycode("PLUS")
Markus Liu8dd3efa2021-04-01 19:31:27 +08009812
9813 if "#" in mmi:
9814 dial_phone_number(ad, forwarded_number + "#")
9815 else:
9816 dial_phone_number(ad, forwarded_number)
Markus Liu1cca96e2019-11-26 15:05:25 +08009817
9818 time.sleep(3)
9819 ad.send_keycode("ENTER")
9820 time.sleep(15)
9821
9822 # To dismiss the pop-out dialog
9823 ad.send_keycode("BACK")
9824 time.sleep(5)
9825 ad.send_keycode("BACK")
9826
Markus Liu8dd3efa2021-04-01 19:31:27 +08009827 if not run_get_call_forwarding_by_adb:
9828 return True
9829
Markus Liu1cca96e2019-11-26 15:05:25 +08009830 result = get_call_forwarding_by_adb(
9831 log, ad, call_forwarding_type=call_forwarding_type)
9832 if result == "false":
9833 retry = retry - 1
9834 elif result == "true":
9835 return True
9836 elif result == "unknown":
9837 return True
9838 else:
9839 retry = retry - 1
9840
9841 if retry >= 0:
9842 ad.log.warning("Failed to register or activate call forwarding %s "
9843 "to %s. Retry after 15 seconds." % (call_forwarding_type,
9844 forwarded_number))
9845 time.sleep(15)
9846
9847 ad.log.error("Failed to register or activate call forwarding %s to %s." %
9848 (call_forwarding_type, forwarded_number))
Jaineel51bf49b2020-01-15 11:02:13 -08009849 return False
Ignacio Guarna9c63ef52020-02-06 17:08:09 -03009850
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009851
Markus Liude6e5db2019-12-18 15:31:54 +08009852def get_call_waiting_status(log, ad):
9853 """ (Todo) Get call waiting status (activated or deactivated) when there is
9854 any proper method available.
9855 """
9856 return True
9857
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009858
Markus Liude6e5db2019-12-18 15:31:54 +08009859def set_call_waiting(log, ad, enable=1, retry=1):
9860 """ Activate/deactivate call waiting by dialing MMI code.
9861
9862 Args:
9863 log: log object.
9864 ad: android object.
9865 enable: 1 for activation and 0 fir deactivation
9866 retry: times of retry if activation/deactivation fails
9867
9868 Returns:
9869 True by successful activation/deactivation; otherwise False.
9870 """
9871 operator_name = get_operator_name(log, ad)
9872
9873 if operator_name in ["Verizon", "Sprint"]:
9874 return True
9875
9876 while retry >= 0:
9877 if enable:
9878 ad.log.info("Activating call waiting...")
9879 ad.droid.telecomDialNumber("*43#")
9880 else:
9881 ad.log.info("Deactivating call waiting...")
9882 ad.droid.telecomDialNumber("#43#")
9883
9884 time.sleep(3)
9885 ad.send_keycode("ENTER")
9886 time.sleep(15)
9887
9888 ad.send_keycode("BACK")
9889 time.sleep(5)
9890 ad.send_keycode("BACK")
9891
9892 if get_call_waiting_status(log, ad):
9893 return True
9894 else:
9895 retry = retry + 1
9896
9897 return False
Ignacio Guarna9c63ef52020-02-06 17:08:09 -03009898
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009899
Ignacio Guarna9c63ef52020-02-06 17:08:09 -03009900def get_rx_tx_power_levels(log, ad):
9901 """ Obtains Rx and Tx power levels from the MDS application.
9902
9903 The method requires the MDS app to be installed in the DUT.
9904
9905 Args:
9906 log: logger object
9907 ad: an android device
9908
9909 Return:
9910 A tuple where the first element is an array array with the RSRP value
9911 in Rx chain, and the second element is the transmitted power in dBm.
9912 Values for invalid Rx / Tx chains are set to None.
9913 """
9914 cmd = ('am instrument -w -e request "80 00 e8 03 00 08 00 00 00" -e '
9915 'response wait "com.google.mdstest/com.google.mdstest.instrument.'
9916 'ModemCommandInstrumentation"')
9917 output = ad.adb.shell(cmd)
9918
9919 if 'result=SUCCESS' not in output:
9920 raise RuntimeError('Could not obtain Tx/Rx power levels from MDS. Is '
9921 'the MDS app installed?')
9922
9923 response = re.search(r"(?<=response=).+", output)
9924
9925 if not response:
9926 raise RuntimeError('Invalid response from the MDS app:\n' + output)
9927
9928 # Obtain a list of bytes in hex format from the response string
9929 response_hex = response.group(0).split(' ')
9930
9931 def get_bool(pos):
9932 """ Obtain a boolean variable from the byte array. """
9933 return response_hex[pos] == '01'
9934
9935 def get_int32(pos):
9936 """ Obtain an int from the byte array. Bytes are printed in
9937 little endian format."""
9938 return struct.unpack(
9939 '<i', bytearray.fromhex(''.join(response_hex[pos:pos + 4])))[0]
9940
9941 rx_power = []
9942 RX_CHAINS = 4
9943
9944 for i in range(RX_CHAINS):
9945 # Calculate starting position for the Rx chain data structure
9946 start = 12 + i * 22
9947
9948 # The first byte in the data structure indicates if the rx chain is
9949 # valid.
9950 if get_bool(start):
9951 rx_power.append(get_int32(start + 2) / 10)
9952 else:
9953 rx_power.append(None)
9954
9955 # Calculate the position for the tx chain data structure
9956 tx_pos = 12 + RX_CHAINS * 22
9957
9958 tx_valid = get_bool(tx_pos)
9959 if tx_valid:
9960 tx_power = get_int32(tx_pos + 2) / -10
9961 else:
9962 tx_power = None
9963
9964 return rx_power, tx_power
Markus Liud7850222020-04-14 17:11:12 +08009965
Pratik Sheth68e4eba2021-03-23 17:10:13 -07009966
Markus Liud7850222020-04-14 17:11:12 +08009967def sms_in_collision_send_receive_verify(
9968 log,
9969 ad_rx,
9970 ad_rx2,
9971 ad_tx,
9972 ad_tx2,
9973 array_message,
9974 array_message2,
9975 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
9976 """Send 2 SMS', receive both SMS', and verify content and sender's number of
9977 each SMS.
9978
9979 Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
9980 When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
9981 be tested.
9982 Verify both SMS' are sent, delivered and received.
9983 Verify received content and sender's number of each SMS is correct.
9984
9985 Args:
9986 log: Log object.
9987 ad_tx: Sender's Android Device Object..
9988 ad_rx: Receiver's Android Device Object.
9989 ad_tx2: 2nd sender's Android Device Object..
9990 ad_rx2: 2nd receiver's Android Device Object.
9991 array_message: the array of message to send/receive from ad_tx to ad_rx
9992 array_message2: the array of message to send/receive from ad_tx2 to
9993 ad_rx2
9994 max_wait_time: Max time to wait for reception of SMS
9995 """
9996
9997 rx_sub_id = get_outgoing_message_sub_id(ad_rx)
9998 rx2_sub_id = get_outgoing_message_sub_id(ad_rx2)
9999
10000 _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
10001 [ad_rx, ad_tx, ad_tx2],
10002 host_sub_id=rx_sub_id)
10003 set_subid_for_message(ad_tx, tx_sub_id)
10004
10005 _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
10006 [ad_rx2, ad_tx, ad_tx2],
10007 host_sub_id=rx2_sub_id)
10008 set_subid_for_message(ad_tx2, tx2_sub_id)
10009
10010 if not sms_in_collision_send_receive_verify_for_subscription(
10011 log,
10012 ad_tx,
10013 ad_tx2,
10014 ad_rx,
10015 ad_rx2,
10016 tx_sub_id,
10017 tx2_sub_id,
10018 rx_sub_id,
10019 rx_sub_id,
10020 array_message,
10021 array_message2,
10022 max_wait_time):
10023 log_messaging_screen_shot(
10024 ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
10025 log_messaging_screen_shot(
10026 ad_rx2, test_name="sms rx2 subid: %s" % rx2_sub_id)
10027 log_messaging_screen_shot(
10028 ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
10029 log_messaging_screen_shot(
10030 ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
10031 return False
10032 return True
10033
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010034
Markus Liud7850222020-04-14 17:11:12 +080010035def sms_in_collision_send_receive_verify_for_subscription(
10036 log,
10037 ad_tx,
10038 ad_tx2,
10039 ad_rx,
10040 ad_rx2,
10041 subid_tx,
10042 subid_tx2,
10043 subid_rx,
10044 subid_rx2,
10045 array_message,
10046 array_message2,
10047 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10048 """Send 2 SMS', receive both SMS', and verify content and sender's number of
10049 each SMS.
10050
10051 Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
10052 When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
10053 be tested.
10054 Verify both SMS' are sent, delivered and received.
10055 Verify received content and sender's number of each SMS is correct.
10056
10057 Args:
10058 log: Log object.
10059 ad_tx: Sender's Android Device Object..
10060 ad_rx: Receiver's Android Device Object.
10061 ad_tx2: 2nd sender's Android Device Object..
10062 ad_rx2: 2nd receiver's Android Device Object.
10063 subid_tx: Sub ID of ad_tx as default Sub ID for outgoing SMS
10064 subid_tx2: Sub ID of ad_tx2 as default Sub ID for outgoing SMS
10065 subid_rx: Sub ID of ad_rx as default Sub ID for incoming SMS
10066 subid_rx2: Sub ID of ad_rx2 as default Sub ID for incoming SMS
10067 array_message: the array of message to send/receive from ad_tx to ad_rx
10068 array_message2: the array of message to send/receive from ad_tx2 to
10069 ad_rx2
10070 max_wait_time: Max time to wait for reception of SMS
10071 """
10072
10073 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
10074 phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
10075 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
10076 phonenumber_rx2 = ad_rx2.telephony['subscription'][subid_rx2]['phone_num']
10077
10078 for ad in (ad_tx, ad_tx2, ad_rx, ad_rx2):
10079 ad.send_keycode("BACK")
10080 if not getattr(ad, "messaging_droid", None):
10081 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10082 ad.messaging_ed.start()
10083 else:
10084 try:
10085 if not ad.messaging_droid.is_live:
10086 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10087 ad.messaging_ed.start()
10088 else:
10089 ad.messaging_ed.clear_all_events()
10090 ad.messaging_droid.logI(
10091 "Start sms_send_receive_verify_for_subscription test")
10092 except Exception:
10093 ad.log.info("Create new sl4a session for messaging")
10094 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10095 ad.messaging_ed.start()
10096
10097 for text, text2 in zip(array_message, array_message2):
10098 length = len(text)
10099 length2 = len(text2)
10100 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10101 phonenumber_tx, phonenumber_rx, length, text)
10102 ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10103 phonenumber_tx2, phonenumber_rx2, length2, text2)
10104
10105 try:
10106 ad_rx.messaging_ed.clear_events(EventSmsReceived)
10107 ad_rx2.messaging_ed.clear_events(EventSmsReceived)
10108 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
10109 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
10110 ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
10111 ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
10112 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
10113 if ad_rx2 != ad_rx:
10114 ad_rx2.messaging_droid.smsStartTrackingIncomingSmsMessage()
10115 time.sleep(1)
10116 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
10117 ad_tx2.messaging_droid.logI("Sending SMS of length %s" % length2)
10118 ad_rx.messaging_droid.logI(
10119 "Expecting SMS of length %s from %s" % (length, ad_tx.serial))
10120 ad_rx2.messaging_droid.logI(
10121 "Expecting SMS of length %s from %s" % (length2, ad_tx2.serial))
10122
10123 tasks = [
10124 (ad_tx.messaging_droid.smsSendTextMessage,
10125 (phonenumber_rx, text, True)),
10126 (ad_tx2.messaging_droid.smsSendTextMessage,
10127 (phonenumber_rx2, text2, True))]
10128 multithread_func(log, tasks)
10129 try:
10130 tasks = [
10131 (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10132 EventSmsSentSuccess,
10133 EventSmsSentFailure,
10134 EventSmsDeliverSuccess,
10135 EventSmsDeliverFailure), max_wait_time)),
10136 (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10137 EventSmsSentSuccess,
10138 EventSmsSentFailure,
10139 EventSmsDeliverSuccess,
10140 EventSmsDeliverFailure), max_wait_time))
10141 ]
10142 results = run_multithread_func(log, tasks)
10143 res = True
10144 _ad = ad_tx
10145 for ad, events in [(ad_tx, results[0]),(ad_tx2, results[1])]:
10146 _ad = ad
10147 for event in events:
10148 ad.log.info("Got event %s", event["name"])
10149 if event["name"] == EventSmsSentFailure or \
10150 event["name"] == EventSmsDeliverFailure:
10151 if event.get("data") and event["data"].get("Reason"):
10152 ad.log.error("%s with reason: %s",
10153 event["name"],
10154 event["data"]["Reason"])
10155 res = False
10156 elif event["name"] == EventSmsSentSuccess or \
10157 event["name"] == EventSmsDeliverSuccess:
10158 break
10159 if not res:
10160 return False
10161 except Empty:
10162 _ad.log.error("No %s or %s event for SMS of length %s.",
10163 EventSmsSentSuccess, EventSmsSentFailure,
10164 length)
10165 return False
10166 if ad_rx == ad_rx2:
10167 if not wait_for_matching_mt_sms_in_collision(
10168 log,
10169 ad_rx,
10170 phonenumber_tx,
10171 phonenumber_tx2,
10172 text,
10173 text2,
10174 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10175
10176 ad_rx.log.error(
10177 "No matching received SMS of length %s from %s.",
10178 length,
10179 ad_rx.serial)
10180 return False
10181 else:
10182 if not wait_for_matching_mt_sms_in_collision_with_mo_sms(
10183 log,
10184 ad_rx,
10185 ad_rx2,
10186 phonenumber_tx,
10187 phonenumber_tx2,
10188 text,
10189 text2,
10190 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10191 return False
10192 except Exception as e:
10193 log.error("Exception error %s", e)
10194 raise
10195 finally:
10196 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
10197 ad_rx2.messaging_droid.smsStopTrackingIncomingSmsMessage()
10198 return True
10199
10200
10201def sms_rx_power_off_multiple_send_receive_verify(
10202 log,
10203 ad_rx,
10204 ad_tx,
10205 ad_tx2,
10206 array_message_length,
10207 array_message2_length,
10208 num_array_message,
10209 num_array_message2,
10210 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10211
10212 rx_sub_id = get_outgoing_message_sub_id(ad_rx)
10213
10214 _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
10215 [ad_rx, ad_tx, ad_tx2],
10216 host_sub_id=rx_sub_id)
10217 set_subid_for_message(ad_tx, tx_sub_id)
10218
10219 _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
10220 [ad_rx, ad_tx, ad_tx2],
10221 host_sub_id=rx_sub_id)
10222 set_subid_for_message(ad_tx2, tx2_sub_id)
10223
10224 if not sms_rx_power_off_multiple_send_receive_verify_for_subscription(
10225 log,
10226 ad_tx,
10227 ad_tx2,
10228 ad_rx,
10229 tx_sub_id,
10230 tx2_sub_id,
10231 rx_sub_id,
10232 rx_sub_id,
10233 array_message_length,
10234 array_message2_length,
10235 num_array_message,
10236 num_array_message2):
10237 log_messaging_screen_shot(
10238 ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
10239 log_messaging_screen_shot(
10240 ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
10241 log_messaging_screen_shot(
10242 ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
10243 return False
10244 return True
10245
10246
10247def sms_rx_power_off_multiple_send_receive_verify_for_subscription(
10248 log,
10249 ad_tx,
10250 ad_tx2,
10251 ad_rx,
10252 subid_tx,
10253 subid_tx2,
10254 subid_rx,
10255 subid_rx2,
10256 array_message_length,
10257 array_message2_length,
10258 num_array_message,
10259 num_array_message2,
10260 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10261
10262 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
10263 phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
10264 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
10265 phonenumber_rx2 = ad_rx.telephony['subscription'][subid_rx2]['phone_num']
10266
10267 if not toggle_airplane_mode(log, ad_rx, True):
10268 ad_rx.log.error("Failed to enable Airplane Mode")
10269 return False
10270 ad_rx.stop_services()
10271 ad_rx.log.info("Rebooting......")
10272 ad_rx.adb.reboot()
10273
10274 message_dict = {phonenumber_tx: [], phonenumber_tx2: []}
10275 for index in range(max(num_array_message, num_array_message2)):
10276 array_message = [rand_ascii_str(array_message_length)]
10277 array_message2 = [rand_ascii_str(array_message2_length)]
10278 for text, text2 in zip(array_message, array_message2):
10279 message_dict[phonenumber_tx].append(text)
10280 message_dict[phonenumber_tx2].append(text2)
10281 length = len(text)
10282 length2 = len(text2)
10283
10284 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10285 phonenumber_tx, phonenumber_rx, length, text)
10286 ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10287 phonenumber_tx2, phonenumber_rx2, length2, text2)
10288
10289 try:
10290 for ad in (ad_tx, ad_tx2):
10291 ad.send_keycode("BACK")
10292 if not getattr(ad, "messaging_droid", None):
10293 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10294 ad.messaging_ed.start()
10295 else:
10296 try:
10297 if not ad.messaging_droid.is_live:
10298 ad.messaging_droid, ad.messaging_ed = \
10299 ad.get_droid()
10300 ad.messaging_ed.start()
10301 else:
10302 ad.messaging_ed.clear_all_events()
10303 ad.messaging_droid.logI(
10304 "Start sms_send_receive_verify_for_subscription"
10305 " test")
10306 except Exception:
10307 ad.log.info("Create new sl4a session for messaging")
10308 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10309 ad.messaging_ed.start()
10310
10311 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
10312 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
10313 ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
10314 ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
10315
10316 if index < num_array_message and index < num_array_message2:
10317 ad_tx.messaging_droid.logI(
10318 "Sending SMS of length %s" % length)
10319 ad_tx2.messaging_droid.logI(
10320 "Sending SMS of length %s" % length2)
10321 tasks = [
10322 (ad_tx.messaging_droid.smsSendTextMessage,
10323 (phonenumber_rx, text, True)),
10324 (ad_tx2.messaging_droid.smsSendTextMessage,
10325 (phonenumber_rx2, text2, True))]
10326 multithread_func(log, tasks)
10327 else:
10328 if index < num_array_message:
10329 ad_tx.messaging_droid.logI(
10330 "Sending SMS of length %s" % length)
10331 ad_tx.messaging_droid.smsSendTextMessage(
10332 phonenumber_rx, text, True)
10333 if index < num_array_message2:
10334 ad_tx2.messaging_droid.logI(
10335 "Sending SMS of length %s" % length2)
10336 ad_tx2.messaging_droid.smsSendTextMessage(
10337 phonenumber_rx2, text2, True)
10338
10339 try:
10340 if index < num_array_message and index < num_array_message2:
10341 tasks = [
10342 (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10343 EventSmsSentSuccess,
10344 EventSmsSentFailure,
10345 EventSmsDeliverSuccess,
10346 EventSmsDeliverFailure),
10347 max_wait_time)),
10348 (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10349 EventSmsSentSuccess,
10350 EventSmsSentFailure,
10351 EventSmsDeliverSuccess,
10352 EventSmsDeliverFailure),
10353 max_wait_time))
10354 ]
10355 results = run_multithread_func(log, tasks)
10356 res = True
10357 _ad = ad_tx
10358 for ad, events in [
10359 (ad_tx, results[0]), (ad_tx2, results[1])]:
10360 _ad = ad
10361 for event in events:
10362 ad.log.info("Got event %s", event["name"])
10363 if event["name"] == EventSmsSentFailure or \
10364 event["name"] == EventSmsDeliverFailure:
10365 if event.get("data") and \
10366 event["data"].get("Reason"):
10367 ad.log.error("%s with reason: %s",
10368 event["name"],
10369 event["data"]["Reason"])
10370 res = False
10371 elif event["name"] == EventSmsSentSuccess or \
10372 event["name"] == EventSmsDeliverSuccess:
10373 break
10374 if not res:
10375 return False
10376 else:
10377 if index < num_array_message:
10378 result = ad_tx.messaging_ed.pop_events(
10379 "(%s|%s|%s|%s)" % (
10380 EventSmsSentSuccess,
10381 EventSmsSentFailure,
10382 EventSmsDeliverSuccess,
10383 EventSmsDeliverFailure),
10384 max_wait_time)
10385 res = True
10386 _ad = ad_tx
10387 for ad, events in [(ad_tx, result)]:
10388 _ad = ad
10389 for event in events:
10390 ad.log.info("Got event %s", event["name"])
10391 if event["name"] == EventSmsSentFailure or \
10392 event["name"] == EventSmsDeliverFailure:
10393 if event.get("data") and \
10394 event["data"].get("Reason"):
10395 ad.log.error(
10396 "%s with reason: %s",
10397 event["name"],
10398 event["data"]["Reason"])
10399 res = False
10400 elif event["name"] == EventSmsSentSuccess \
10401 or event["name"] == EventSmsDeliverSuccess:
10402 break
10403 if not res:
10404 return False
10405 if index < num_array_message2:
10406 result = ad_tx2.messaging_ed.pop_events(
10407 "(%s|%s|%s|%s)" % (
10408 EventSmsSentSuccess,
10409 EventSmsSentFailure,
10410 EventSmsDeliverSuccess,
10411 EventSmsDeliverFailure),
10412 max_wait_time)
10413 res = True
10414 _ad = ad_tx2
10415 for ad, events in [(ad_tx2, result)]:
10416 _ad = ad
10417 for event in events:
10418 ad.log.info("Got event %s", event["name"])
10419 if event["name"] == EventSmsSentFailure or \
10420 event["name"] == EventSmsDeliverFailure:
10421 if event.get("data") and \
10422 event["data"].get("Reason"):
10423 ad.log.error(
10424 "%s with reason: %s",
10425 event["name"],
10426 event["data"]["Reason"])
10427 res = False
10428 elif event["name"] == EventSmsSentSuccess \
10429 or event["name"] == EventSmsDeliverSuccess:
10430 break
10431 if not res:
10432 return False
10433
10434
10435 except Empty:
10436 _ad.log.error("No %s or %s event for SMS of length %s.",
10437 EventSmsSentSuccess, EventSmsSentFailure,
10438 length)
10439 return False
10440
10441 except Exception as e:
10442 log.error("Exception error %s", e)
10443 raise
10444
10445 ad_rx.wait_for_boot_completion()
10446 ad_rx.root_adb()
10447 ad_rx.start_services(skip_setup_wizard=False)
10448
10449 output = ad_rx.adb.logcat("-t 1")
10450 match = re.search(r"\d+-\d+\s\d+:\d+:\d+.\d+", output)
10451 if match:
10452 ad_rx.test_log_begin_time = match.group(0)
10453
10454 ad_rx.messaging_droid, ad_rx.messaging_ed = ad_rx.get_droid()
10455 ad_rx.messaging_ed.start()
10456 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
10457 time.sleep(1) #sleep 100ms after starting event tracking
10458
10459 if not toggle_airplane_mode(log, ad_rx, False):
10460 ad_rx.log.error("Failed to disable Airplane Mode")
10461 return False
10462
10463 res = True
10464 try:
10465 if not wait_for_matching_multiple_sms(log,
10466 ad_rx,
10467 phonenumber_tx,
10468 phonenumber_tx2,
10469 messages=message_dict,
10470 max_wait_time=max_wait_time):
10471 res = False
10472 except Exception as e:
10473 log.error("Exception error %s", e)
10474 raise
10475 finally:
10476 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
10477
10478 return res
10479
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010480
Markus Liud7850222020-04-14 17:11:12 +080010481def wait_for_matching_mt_sms_in_collision(log,
10482 ad_rx,
10483 phonenumber_tx,
10484 phonenumber_tx2,
10485 text,
10486 text2,
10487 allow_multi_part_long_sms=True,
10488 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10489
10490 if not allow_multi_part_long_sms:
10491 try:
10492 ad_rx.messaging_ed.wait_for_event(
10493 EventSmsReceived,
10494 is_sms_in_collision_match,
10495 max_wait_time,
10496 phonenumber_tx,
10497 phonenumber_tx2,
10498 text,
10499 text2)
10500 ad_rx.log.info("Got event %s", EventSmsReceived)
10501 return True
10502 except Empty:
10503 ad_rx.log.error("No matched SMS received event.")
10504 return False
10505 else:
10506 try:
10507 received_sms = ''
10508 received_sms2 = ''
10509 remaining_text = text
10510 remaining_text2 = text2
10511 while (remaining_text != '' or remaining_text2 != ''):
10512 event = ad_rx.messaging_ed.wait_for_event(
10513 EventSmsReceived,
10514 is_sms_in_collision_partial_match,
10515 max_wait_time,
10516 phonenumber_tx,
10517 phonenumber_tx2,
10518 remaining_text,
10519 remaining_text2)
10520 event_text = event['data']['Text'].split(")")[-1].strip()
10521 event_text_length = len(event_text)
10522
10523 if event_text in remaining_text:
10524 ad_rx.log.info("Got event %s of text length %s from %s",
10525 EventSmsReceived, event_text_length,
10526 phonenumber_tx)
10527 remaining_text = remaining_text[event_text_length:]
10528 received_sms += event_text
10529 elif event_text in remaining_text2:
10530 ad_rx.log.info("Got event %s of text length %s from %s",
10531 EventSmsReceived, event_text_length,
10532 phonenumber_tx2)
10533 remaining_text2 = remaining_text2[event_text_length:]
10534 received_sms2 += event_text
10535
10536 ad_rx.log.info("Received SMS of length %s", len(received_sms))
10537 ad_rx.log.info("Received SMS of length %s", len(received_sms2))
10538 return True
10539 except Empty:
10540 ad_rx.log.error(
10541 "Missing SMS received event.")
10542 if received_sms != '':
10543 ad_rx.log.error(
10544 "Only received partial matched SMS of length %s from %s",
10545 len(received_sms), phonenumber_tx)
10546 if received_sms2 != '':
10547 ad_rx.log.error(
10548 "Only received partial matched SMS of length %s from %s",
10549 len(received_sms2), phonenumber_tx2)
10550 return False
10551
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010552
Markus Liud7850222020-04-14 17:11:12 +080010553def wait_for_matching_mt_sms_in_collision_with_mo_sms(log,
10554 ad_rx,
10555 ad_rx2,
10556 phonenumber_tx,
10557 phonenumber_tx2,
10558 text,
10559 text2,
10560 allow_multi_part_long_sms=True,
10561 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10562
10563 if not allow_multi_part_long_sms:
10564 result = True
10565 try:
10566 ad_rx.messaging_ed.wait_for_call_offhook_event(
10567 EventSmsReceived,
10568 is_sms_match,
10569 max_wait_time,
10570 phonenumber_tx,
10571 text)
10572 ad_rx.log.info("Got event %s", EventSmsReceived)
10573 except Empty:
10574 ad_rx.log.error("No matched SMS received event.")
10575 result = False
10576
10577 try:
10578 ad_rx2.messaging_ed.wait_for_call_offhook_event(
10579 EventSmsReceived,
10580 is_sms_match,
10581 max_wait_time,
10582 phonenumber_tx2,
10583 text2)
10584 ad_rx2.log.info("Got event %s", EventSmsReceived)
10585 except Empty:
10586 ad_rx2.log.error("No matched SMS received event.")
10587 result = False
10588
10589 return result
10590 else:
10591 result = True
10592 try:
10593 received_sms = ''
10594 remaining_text = text
10595 while remaining_text != '':
10596 event = ad_rx.messaging_ed.wait_for_event(
10597 EventSmsReceived, is_sms_partial_match, max_wait_time,
10598 phonenumber_tx, remaining_text)
10599 event_text = event['data']['Text'].split(")")[-1].strip()
10600 event_text_length = len(event_text)
10601
10602 if event_text in remaining_text:
10603 ad_rx.log.info("Got event %s of text length %s from %s",
10604 EventSmsReceived, event_text_length,
10605 phonenumber_tx)
10606 remaining_text = remaining_text[event_text_length:]
10607 received_sms += event_text
10608
10609 ad_rx.log.info("Received SMS of length %s", len(received_sms))
10610 except Empty:
10611 ad_rx.log.error(
10612 "Missing SMS received event.")
10613 if received_sms != '':
10614 ad_rx.log.error(
10615 "Only received partial matched SMS of length %s from %s",
10616 len(received_sms), phonenumber_tx)
10617 result = False
10618
10619 try:
10620 received_sms2 = ''
10621 remaining_text2 = text2
10622 while remaining_text2 != '':
10623 event2 = ad_rx2.messaging_ed.wait_for_event(
10624 EventSmsReceived, is_sms_partial_match, max_wait_time,
10625 phonenumber_tx2, remaining_text2)
10626 event_text2 = event2['data']['Text'].split(")")[-1].strip()
10627 event_text_length2 = len(event_text2)
10628
10629 if event_text2 in remaining_text2:
10630 ad_rx2.log.info("Got event %s of text length %s from %s",
10631 EventSmsReceived, event_text_length2,
10632 phonenumber_tx2)
10633 remaining_text2 = remaining_text2[event_text_length2:]
10634 received_sms2 += event_text2
10635
10636 ad_rx2.log.info("Received SMS of length %s", len(received_sms2))
10637 except Empty:
10638 ad_rx2.log.error(
10639 "Missing SMS received event.")
10640 if received_sms2 != '':
10641 ad_rx2.log.error(
10642 "Only received partial matched SMS of length %s from %s",
10643 len(received_sms2), phonenumber_tx2)
10644 result = False
10645
10646 return result
10647
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010648
Markus Liud7850222020-04-14 17:11:12 +080010649def wait_for_matching_multiple_sms(log,
10650 ad_rx,
10651 phonenumber_tx,
10652 phonenumber_tx2,
10653 messages={},
10654 allow_multi_part_long_sms=True,
10655 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
10656
10657 if not allow_multi_part_long_sms:
10658 try:
10659 ad_rx.messaging_ed.wait_for_event(
10660 EventSmsReceived,
10661 is_sms_match_among_multiple_sms,
10662 max_wait_time,
10663 phonenumber_tx,
10664 phonenumber_tx2,
10665 messages[phonenumber_tx],
10666 messages[phonenumber_tx2])
10667 ad_rx.log.info("Got event %s", EventSmsReceived)
10668 return True
10669 except Empty:
10670 ad_rx.log.error("No matched SMS received event.")
10671 return False
10672 else:
10673 all_msgs = []
10674 for tx, msgs in messages.items():
10675 for msg in msgs:
10676 all_msgs.append([tx, msg, msg, ''])
10677
10678 all_msgs_copy = all_msgs.copy()
10679
10680 try:
10681 while (all_msgs != []):
10682 event = ad_rx.messaging_ed.wait_for_event(
10683 EventSmsReceived,
10684 is_sms_partial_match_among_multiple_sms,
10685 max_wait_time,
10686 phonenumber_tx,
10687 phonenumber_tx2,
10688 messages[phonenumber_tx],
10689 messages[phonenumber_tx2])
10690 event_text = event['data']['Text'].split(")")[-1].strip()
10691 event_text_length = len(event_text)
10692
10693 for msg in all_msgs_copy:
10694 if event_text in msg[2]:
10695 ad_rx.log.info("Got event %s of text length %s from %s",
10696 EventSmsReceived, event_text_length,
10697 msg[0])
10698 msg[2] = msg[2][event_text_length:]
10699 msg[3] += event_text
10700
10701 if msg[2] == "":
10702 all_msgs.remove(msg)
10703
10704 ad_rx.log.info("Received all SMS' sent when power-off.")
10705 except Empty:
10706 ad_rx.log.error(
10707 "Missing SMS received event.")
10708
10709 for msg in all_msgs_copy:
10710 if msg[3] != '':
10711 ad_rx.log.error(
10712 "Only received partial matched SMS of length %s from %s",
10713 len(msg[3]), msg[0])
10714 return False
10715
10716 return True
10717
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010718
Markus Liu6b41e092020-08-17 15:55:28 +080010719def is_sms_in_collision_match(
10720 event, phonenumber_tx, phonenumber_tx2, text, text2):
Markus Liud7850222020-04-14 17:11:12 +080010721 event_text = event['data']['Text'].strip()
10722 if event_text.startswith("("):
10723 event_text = event_text.split(")")[-1]
10724
10725 for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
Markus Liu6b41e092020-08-17 15:55:28 +080010726 if check_phone_number_match(
10727 event['data']['Sender'], phonenumber) and txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010728 return True
10729 return False
10730
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010731
Markus Liu6b41e092020-08-17 15:55:28 +080010732def is_sms_in_collision_partial_match(
10733 event, phonenumber_tx, phonenumber_tx2, text, text2):
Markus Liud7850222020-04-14 17:11:12 +080010734 for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
Markus Liu6b41e092020-08-17 15:55:28 +080010735 if check_phone_number_match(
10736 event['data']['Sender'], phonenumber) and \
10737 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010738 return True
10739 return False
10740
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010741
Markus Liu6b41e092020-08-17 15:55:28 +080010742def is_sms_match_among_multiple_sms(
10743 event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
Markus Liud7850222020-04-14 17:11:12 +080010744 for txt in texts:
Markus Liu6b41e092020-08-17 15:55:28 +080010745 if check_phone_number_match(
10746 event['data']['Sender'], phonenumber_tx) and \
10747 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010748 return True
10749
10750 for txt in texts2:
Markus Liu6b41e092020-08-17 15:55:28 +080010751 if check_phone_number_match(
10752 event['data']['Sender'], phonenumber_tx2) and \
10753 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010754 return True
10755
10756 return False
10757
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010758
Markus Liu6b41e092020-08-17 15:55:28 +080010759def is_sms_partial_match_among_multiple_sms(
10760 event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
Markus Liud7850222020-04-14 17:11:12 +080010761 event_text = event['data']['Text'].strip()
10762 if event_text.startswith("("):
10763 event_text = event_text.split(")")[-1]
10764
10765 for txt in texts:
Markus Liu6b41e092020-08-17 15:55:28 +080010766 if check_phone_number_match(
10767 event['data']['Sender'], phonenumber_tx) and \
10768 txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010769 return True
10770
10771 for txt in texts2:
Markus Liu6b41e092020-08-17 15:55:28 +080010772 if check_phone_number_match(
10773 event['data']['Sender'], phonenumber_tx2) and \
10774 txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010775 return True
10776
Jaineel08466192020-07-13 17:09:03 -070010777 return False
davinkao439e38e2020-07-29 11:34:43 +080010778
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010779
davinkao439e38e2020-07-29 11:34:43 +080010780def set_time_sync_from_network(ad, action):
10781 if (action == 'enable'):
10782 ad.log.info('Enabling sync time from network.')
10783 ad.adb.shell('settings put global auto_time 1')
10784
10785 elif (action == 'disable'):
10786 ad.log.info('Disabling sync time from network.')
10787 ad.adb.shell('settings put global auto_time 0')
10788
10789 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK)
10790
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010791
davinkao439e38e2020-07-29 11:34:43 +080010792def datetime_handle(ad, action, set_datetime_value='', get_year=False):
10793 get_value = ''
10794 if (action == 'get'):
10795 if (get_year):
10796 datetime_string = ad.adb.shell('date')
10797 datetime_list = datetime_string.split()
10798 try:
10799 get_value = datetime_list[5]
10800 except Exception as e:
Richachaecd93c12021-04-25 22:23:47 +080010801 ad.log.error("Fail to get year from datetime: %s. " \
davinkao439e38e2020-07-29 11:34:43 +080010802 "Exception error: %s", datetime_list
10803 , str(e))
10804 raise signals.TestSkip("Fail to get year from datetime" \
10805 ", the format is changed. Skip the test.")
10806 else:
10807 get_value = ad.adb.shell('date')
10808
10809 elif (action == 'set'):
10810 ad.adb.shell('date %s' % set_datetime_value)
10811 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK)
10812 ad.adb.shell('am broadcast -a android.intent.action.TIME_SET')
10813
10814 return get_value
Markus Liu6b41e092020-08-17 15:55:28 +080010815
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010816
Markus Liucb900da2020-08-17 16:12:31 +080010817def wait_for_sending_sms(ad_tx, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
10818 try:
10819 events = ad_tx.messaging_ed.pop_events(
10820 "(%s|%s|%s|%s)" %
10821 (EventSmsSentSuccess, EventSmsSentFailure,
10822 EventSmsDeliverSuccess,
10823 EventSmsDeliverFailure), max_wait_time)
10824 for event in events:
10825 ad_tx.log.info("Got event %s", event["name"])
10826 if event["name"] == EventSmsSentFailure or \
10827 event["name"] == EventSmsDeliverFailure:
10828 if event.get("data") and event["data"].get("Reason"):
10829 ad_tx.log.error("%s with reason: %s",
10830 event["name"],
10831 event["data"]["Reason"])
10832 return False
10833 elif event["name"] == EventSmsSentSuccess or \
10834 event["name"] == EventSmsDeliverSuccess:
10835 return True
10836 except Empty:
10837 ad_tx.log.error("No %s or %s event for SMS.",
10838 EventSmsSentSuccess, EventSmsSentFailure)
10839 return False
10840
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010841
Markus Liucb900da2020-08-17 16:12:31 +080010842def wait_for_call_end(
10843 log,
10844 ad_caller,
10845 ad_callee,
10846 ad_hangup,
10847 verify_caller_func,
10848 verify_callee_func,
10849 check_interval=5,
10850 tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')),
10851 wait_time_in_call=WAIT_TIME_IN_CALL):
10852 elapsed_time = 0
10853 while (elapsed_time < wait_time_in_call):
10854 check_interval = min(check_interval, wait_time_in_call - elapsed_time)
10855 time.sleep(check_interval)
10856 elapsed_time += check_interval
10857 time_message = "at <%s>/<%s> second." % (elapsed_time, wait_time_in_call)
10858 for ad, call_func in [(ad_caller, verify_caller_func),
10859 (ad_callee, verify_callee_func)]:
10860 if not call_func(log, ad):
10861 ad.log.error(
10862 "NOT in correct %s state at %s, voice in RAT %s",
10863 call_func.__name__,
10864 time_message,
10865 ad.droid.telephonyGetCurrentVoiceNetworkType())
10866 tel_result_wrapper.result_value = CallResult(
10867 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
10868 else:
10869 ad.log.info("In correct %s state at %s",
10870 call_func.__name__, time_message)
10871 if not ad.droid.telecomCallGetAudioState():
10872 ad.log.error("Audio is not in call state at %s", time_message)
10873 tel_result_wrapper.result_value = CallResult(
10874 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
10875 if not tel_result_wrapper:
10876 return tel_result_wrapper
10877
10878 if ad_hangup:
10879 if not hangup_call(log, ad_hangup):
10880 ad_hangup.log.info("Failed to hang up the call")
10881 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
10882
10883 if not tel_result_wrapper:
10884 for ad in (ad_caller, ad_callee):
10885 last_call_drop_reason(ad, begin_time)
10886 try:
10887 if ad.droid.telecomIsInCall():
10888 ad.log.info("In call. End now.")
10889 ad.droid.telecomEndCall()
10890 except Exception as e:
10891 log.error(str(e))
10892 if ad_hangup or not tel_result_wrapper:
10893 for ad in (ad_caller, ad_callee):
10894 if not wait_for_call_id_clearing(ad, getattr(ad, "caller_ids", [])):
10895 tel_result_wrapper.result_value = CallResult(
10896 'CALL_ID_CLEANUP_FAIL')
10897
10898 return tel_result_wrapper
10899
Pratik Sheth68e4eba2021-03-23 17:10:13 -070010900
Markus Liucb900da2020-08-17 16:12:31 +080010901def voice_call_in_collision_with_mt_sms_msim(
10902 log,
10903 ad_primary,
10904 ad_sms,
10905 ad_voice,
10906 sms_subid_ad_primary,
10907 sms_subid_ad_sms,
10908 voice_subid_ad_primary,
10909 voice_subid_ad_voice,
10910 array_message,
10911 ad_hangup=None,
10912 verify_caller_func=None,
10913 verify_callee_func=None,
10914 call_direction="mo",
10915 wait_time_in_call=WAIT_TIME_IN_CALL,
10916 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
10917 dialing_number_length=None,
10918 video_state=None):
10919
10920 ad_tx = ad_sms
10921 ad_rx = ad_primary
10922 subid_tx = sms_subid_ad_sms
10923 subid_rx = sms_subid_ad_primary
10924
10925 if call_direction == "mo":
10926 ad_caller = ad_primary
10927 ad_callee = ad_voice
10928 subid_caller = voice_subid_ad_primary
10929 subid_callee = voice_subid_ad_voice
10930 elif call_direction == "mt":
10931 ad_callee = ad_primary
10932 ad_caller = ad_voice
10933 subid_callee = voice_subid_ad_primary
10934 subid_caller = voice_subid_ad_voice
10935
10936
10937 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
10938 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
10939
10940 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
10941
10942 for ad in (ad_tx, ad_rx):
10943 ad.send_keycode("BACK")
10944 if not getattr(ad, "messaging_droid", None):
10945 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10946 ad.messaging_ed.start()
10947 else:
10948 try:
10949 if not ad.messaging_droid.is_live:
10950 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10951 ad.messaging_ed.start()
10952 else:
10953 ad.messaging_ed.clear_all_events()
10954 except Exception:
10955 ad.log.info("Create new sl4a session for messaging")
10956 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10957 ad.messaging_ed.start()
10958
10959 begin_time = get_current_epoch_time()
10960 if not verify_caller_func:
10961 verify_caller_func = is_phone_in_call
10962 if not verify_callee_func:
10963 verify_callee_func = is_phone_in_call
10964
10965 caller_number = ad_caller.telephony['subscription'][subid_caller][
10966 'phone_num']
10967 callee_number = ad_callee.telephony['subscription'][subid_callee][
10968 'phone_num']
10969 if dialing_number_length:
10970 skip_test = False
10971 trunc_position = 0 - int(dialing_number_length)
10972 try:
10973 caller_area_code = caller_number[:trunc_position]
10974 callee_area_code = callee_number[:trunc_position]
10975 callee_dial_number = callee_number[trunc_position:]
10976 except:
10977 skip_test = True
10978 if caller_area_code != callee_area_code:
10979 skip_test = True
10980 if skip_test:
10981 msg = "Cannot make call from %s to %s by %s digits" % (
10982 caller_number, callee_number, dialing_number_length)
10983 ad_caller.log.info(msg)
10984 raise signals.TestSkip(msg)
10985 else:
10986 callee_number = callee_dial_number
10987
10988 msg = "Call from %s to %s" % (caller_number, callee_number)
10989 if video_state:
10990 msg = "Video %s" % msg
10991 video = True
10992 else:
10993 video = False
10994 if ad_hangup:
10995 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
10996 ad_caller.log.info(msg)
10997
10998 for ad in (ad_caller, ad_callee):
10999 call_ids = ad.droid.telecomCallGetCallIds()
11000 setattr(ad, "call_ids", call_ids)
11001 if call_ids:
11002 ad.log.info("Pre-exist CallId %s before making call", call_ids)
11003
11004 ad_caller.ed.clear_events(EventCallStateChanged)
11005 begin_time = get_device_epoch_time(ad)
11006 ad_caller.droid.telephonyStartTrackingCallStateForSubscription(subid_caller)
11007
11008 for text in array_message:
11009 length = len(text)
11010 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
11011 phonenumber_tx, phonenumber_rx, length, text)
11012 try:
11013 ad_rx.messaging_ed.clear_events(EventSmsReceived)
11014 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
11015 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
11016 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
11017 time.sleep(1) #sleep 100ms after starting event tracking
11018 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
11019 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
11020 ad_caller.log.info("Make a phone call to %s", callee_number)
11021
11022 tasks = [
11023 (ad_tx.messaging_droid.smsSendTextMessage,
11024 (phonenumber_rx, text, True)),
11025 (ad_caller.droid.telecomCallNumber,
11026 (callee_number, video))]
11027
11028 run_multithread_func(log, tasks)
11029
11030 try:
11031 # Verify OFFHOOK state
11032 if not wait_for_call_offhook_for_subscription(
11033 log,
11034 ad_caller,
11035 subid_caller,
11036 event_tracking_started=True):
11037 ad_caller.log.info(
11038 "sub_id %s not in call offhook state", subid_caller)
11039 last_call_drop_reason(ad_caller, begin_time=begin_time)
11040
11041 ad_caller.log.error("Initiate call failed.")
11042 tel_result_wrapper.result_value = CallResult(
11043 'INITIATE_FAILED')
11044 return tel_result_wrapper
11045 else:
11046 ad_caller.log.info("Caller initate call successfully")
11047 finally:
11048 ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription(
11049 subid_caller)
11050 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
11051 ad_caller.droid.telecomShowInCallScreen()
11052 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
11053 ad_caller.droid.showHomeScreen()
11054
11055 if not wait_and_answer_call_for_subscription(
11056 log,
11057 ad_callee,
11058 subid_callee,
11059 incoming_number=caller_number,
11060 caller=ad_caller,
11061 incall_ui_display=incall_ui_display,
11062 video_state=video_state):
11063 ad_callee.log.error("Answer call fail.")
11064 tel_result_wrapper.result_value = CallResult(
11065 'NO_RING_EVENT_OR_ANSWER_FAILED')
11066 return tel_result_wrapper
11067 else:
11068 ad_callee.log.info("Callee answered the call successfully")
11069
11070 for ad, call_func in zip([ad_caller, ad_callee],
11071 [verify_caller_func, verify_callee_func]):
11072 call_ids = ad.droid.telecomCallGetCallIds()
11073 new_call_ids = set(call_ids) - set(ad.call_ids)
11074 if not new_call_ids:
11075 ad.log.error(
11076 "No new call ids are found after call establishment")
11077 ad.log.error("telecomCallGetCallIds returns %s",
11078 ad.droid.telecomCallGetCallIds())
11079 tel_result_wrapper.result_value = CallResult(
11080 'NO_CALL_ID_FOUND')
11081 for new_call_id in new_call_ids:
11082 if not wait_for_in_call_active(ad, call_id=new_call_id):
11083 tel_result_wrapper.result_value = CallResult(
11084 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
11085 else:
11086 ad.log.info(
11087 "callProperties = %s",
11088 ad.droid.telecomCallGetProperties(new_call_id))
11089
11090 if not ad.droid.telecomCallGetAudioState():
11091 ad.log.error("Audio is not in call state")
11092 tel_result_wrapper.result_value = CallResult(
11093 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
11094
11095 if call_func(log, ad):
11096 ad.log.info("Call is in %s state", call_func.__name__)
11097 else:
11098 ad.log.error("Call is not in %s state, voice in RAT %s",
11099 call_func.__name__,
11100 ad.droid.telephonyGetCurrentVoiceNetworkType())
11101 tel_result_wrapper.result_value = CallResult(
11102 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
11103 if not tel_result_wrapper:
11104 return tel_result_wrapper
11105
11106 if not wait_for_sending_sms(
11107 ad_tx,
11108 max_wait_time=MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION):
11109 return False
11110
11111 tasks = [
11112 (wait_for_matching_sms,
11113 (log, ad_rx, phonenumber_tx, text,
11114 MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION, True)),
11115 (wait_for_call_end,
11116 (log, ad_caller, ad_callee, ad_hangup, verify_caller_func,
11117 verify_callee_func, 5, tel_result_wrapper,
11118 WAIT_TIME_IN_CALL))]
11119
11120 results = run_multithread_func(log, tasks)
11121
11122 if not results[0]:
11123 ad_rx.log.error("No matching received SMS of length %s.",
11124 length)
11125 return False
11126
11127 tel_result_wrapper = results[1]
11128
11129 except Exception as e:
11130 log.error("Exception error %s", e)
11131 raise
11132 finally:
11133 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
11134
11135 return tel_result_wrapper
11136
Pratik Sheth68e4eba2021-03-23 17:10:13 -070011137
Markus Liu8a65ea02021-03-18 16:33:41 +080011138def change_voice_subid_temporarily(ad, sub_id, state_check_func, params=None):
Markus Liu6b41e092020-08-17 15:55:28 +080011139 result = False
11140 voice_sub_id_changed = False
11141 current_sub_id = get_incoming_voice_sub_id(ad)
11142 if current_sub_id != sub_id:
11143 set_incoming_voice_sub_id(ad, sub_id)
11144 voice_sub_id_changed = True
11145
Markus Liu8a65ea02021-03-18 16:33:41 +080011146 if not params:
11147 if state_check_func():
11148 result = True
11149 else:
11150 if state_check_func(*params):
11151 result = True
Markus Liu6b41e092020-08-17 15:55:28 +080011152
11153 if voice_sub_id_changed:
11154 set_incoming_voice_sub_id(ad, current_sub_id)
11155
Jaineelcb217b62020-11-03 14:33:40 -080011156 return result
Markus Liu569f1b92020-12-29 16:23:24 +080011157
Pratik Sheth68e4eba2021-03-23 17:10:13 -070011158
Markus Liu569f1b92020-12-29 16:23:24 +080011159def wait_for_network_service(
11160 log,
11161 ad,
11162 wifi_connected=False,
11163 wifi_ssid=None,
11164 ims_reg=True,
11165 recover=False,
11166 retry=3):
11167 """ Wait for multiple network services in sequence, including:
11168 - service state
11169 - network connection
11170 - wifi connection
11171 - cellular data
11172 - internet connection
11173 - IMS registration
11174
11175 The mechanism (cycling airplane mode) to recover network services is
11176 also provided if any service is not available.
11177
11178 Args:
11179 log: log object
11180 ad: android device
11181 wifi_connected: True if wifi should be connected. Otherwise False.
11182 ims_reg: True if IMS should be registered. Otherwise False.
11183 recover: True if the mechanism (cycling airplane mode) to recover
11184 network services should be enabled (by default False).
11185 retry: times of retry.
11186 """
11187 times = 1
11188 while times <= retry:
11189 while True:
11190 if not wait_for_state(
11191 get_service_state_by_adb,
11192 "IN_SERVICE",
11193 MAX_WAIT_TIME_FOR_STATE_CHANGE,
11194 WAIT_TIME_BETWEEN_STATE_CHECK,
11195 log,
11196 ad):
11197 ad.log.error("Current service state is not 'IN_SERVICE'.")
11198 break
11199
11200 if not wait_for_state(
11201 ad.droid.connectivityNetworkIsConnected,
11202 True,
11203 MAX_WAIT_TIME_FOR_STATE_CHANGE,
11204 WAIT_TIME_BETWEEN_STATE_CHECK):
11205 ad.log.error("Network is NOT connected!")
11206 break
11207
11208 if wifi_connected and wifi_ssid:
11209 if not wait_for_state(
11210 check_is_wifi_connected,
11211 True,
11212 MAX_WAIT_TIME_FOR_STATE_CHANGE,
11213 WAIT_TIME_BETWEEN_STATE_CHECK,
11214 log,
11215 ad,
11216 wifi_ssid):
11217 ad.log.error("Failed to connect Wi-Fi SSID '%s'.", wifi_ssid)
11218 break
11219 else:
11220 if not wait_for_cell_data_connection(log, ad, True):
11221 ad.log.error("Failed to enable data connection.")
11222 break
11223
11224 if not wait_for_state(
11225 verify_internet_connection,
11226 True,
11227 MAX_WAIT_TIME_FOR_STATE_CHANGE,
11228 WAIT_TIME_BETWEEN_STATE_CHECK,
11229 log,
11230 ad):
11231 ad.log.error("Data not available on cell.")
11232 break
11233
11234 if ims_reg:
11235 if not wait_for_ims_registered(log, ad):
11236 ad.log.error("IMS is not registered.")
11237 break
11238 ad.log.info("IMS is registered.")
11239 return True
11240
11241 if recover:
11242 ad.log.warning("Trying to recover by cycling airplane mode...")
11243 if not toggle_airplane_mode(log, ad, True):
11244 ad.log.error("Failed to enable airplane mode")
11245 break
11246
11247 time.sleep(5)
11248
11249 if not toggle_airplane_mode(log, ad, False):
11250 ad.log.error("Failed to disable airplane mode")
11251 break
11252
11253 times = times + 1
11254
11255 else:
11256 return False
Ashutosh Rajmani Singh370096b2021-01-29 16:25:56 -080011257 return False
Markus Liu2bd82302021-02-01 12:03:44 +080011258
Pratik Sheth68e4eba2021-03-23 17:10:13 -070011259
11260def check_voice_network_type(ads, voice_init=True):
11261 """
11262 Args:
11263 ad: Android device object
11264 voice_init: check voice network type before initiate call
11265 Return:
11266 voice_network_list: Network Type for all android devices
11267 """
11268 voice_network_list = []
11269 for ad in ads:
11270 voice_network_list.append(ad.droid.telephonyGetCurrentVoiceNetworkType())
11271 if voice_init:
11272 ad.log.debug("Voice Network Type Before Call is %s",
11273 ad.droid.telephonyGetCurrentVoiceNetworkType())
11274 else:
11275 ad.log.debug("Voice Network Type During Call is %s",
11276 ad.droid.telephonyGetCurrentVoiceNetworkType())
11277 return voice_network_list
11278
11279
11280def check_call_status(ad, voice_type_init=None, voice_type_in_call=None):
11281 """"
11282 Args:
11283 ad: Android device object
11284 voice_type_init: Voice network type before initiate call
11285 voice_type_in_call: Voice network type in call state
11286
11287 Return:
11288 voice_call_type_dict: Voice call status
11289 """
11290 dut = str(ad.serial)
11291 network_type = voice_type_init + "_" + voice_type_in_call
11292 if network_type == "NR_NR":
11293 voice_call_type_dict = update_voice_call_type_dict(dut, "VoNR")
11294 elif network_type == "NR_LTE":
11295 voice_call_type_dict = update_voice_call_type_dict(dut, "EPSFB")
11296 elif network_type == "LTE_LTE":
11297 voice_call_type_dict = update_voice_call_type_dict(dut, "VoLTE")
11298 elif network_type == "LTE_WCDMA":
11299 voice_call_type_dict = update_voice_call_type_dict(dut, "CSFB")
11300 else:
11301 voice_call_type_dict = update_voice_call_type_dict(dut, "UNKNOWN")
11302 return voice_call_type_dict
11303
11304
11305def update_voice_call_type_dict(dut, key):
11306 """
11307 Args:
11308 dut: Serial Number of android device object
11309 key: Network subscription parameter (VoNR or EPSFB or VoLTE or CSFB or UNKNOWN)
11310 Return:
11311 voice_call_type: Voice call status
11312 """
11313 if dut in voice_call_type.keys():
11314 voice_call_type[dut][key] += 1
11315 else:
11316 voice_call_type[dut] = {key:0}
11317 voice_call_type[dut][key] += 1
11318 return voice_call_type
11319
11320
Markus Liu2bd82302021-02-01 12:03:44 +080011321def wait_for_log(ad, pattern, begin_time=None, end_time=None, max_wait_time=120):
11322 """Wait for logcat logs matching given pattern. This function searches in
11323 logcat for strings matching given pattern by using search_logcat per second
11324 until max_wait_time reaches.
11325
11326 Args:
11327 ad: android device object
11328 pattern: pattern to be searched in grep format
11329 begin_time: only the lines in logcat with time stamps later than
11330 begin_time will be searched.
11331 end_time: only the lines in logcat with time stamps earlier than
11332 end_time will be searched.
11333 max_wait_time: timeout of this function
11334
11335 Returns:
11336 All matched lines will be returned. If no line matches the given pattern
11337 None will be returned.
11338 """
11339 start_time = datetime.now()
11340 while True:
11341 ad.log.info(
11342 '====== Searching logcat for "%s" ====== ', pattern)
11343 res = ad.search_logcat(
11344 pattern, begin_time=begin_time, end_time=end_time)
11345 if res:
11346 return res
11347 time.sleep(1)
11348 stop_time = datetime.now()
11349 passed_time = (stop_time - start_time).total_seconds()
11350 if passed_time > max_wait_time:
Pratik Sheth232f7952021-04-08 12:17:30 -070011351 return