blob: 846a2f9469440282882a15b12a398a216a689afd [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
Ang Li73697b32015-12-03 00:41:53 +00002#
Alexander Dorokhine7abf60e2016-02-10 10:56:09 -08003# Copyright 2016 - Google
Ang Li73697b32015-12-03 00:41:53 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Alexander Dorokhine642e63f2016-02-11 13:32:37 -080017from future import standard_library
18standard_library.install_aliases()
19
Ang Li73697b32015-12-03 00:41:53 +000020import concurrent.futures
Betty Zhou2e01bc82017-03-17 10:55:57 -070021import json
Ang Li5bd83f32016-05-23 14:39:38 -070022import logging
Betty Zhou17dcabb2017-05-25 19:14:58 -070023import re
Betty Zhouccd171d2017-02-13 15:11:33 -080024import os
Ang Li73697b32015-12-03 00:41:53 +000025import urllib.parse
26import time
monikermine61898b92019-10-31 17:21:16 -070027import acts.controllers.iperf_server as ipf
jasonkmlu2565d892019-11-12 15:31:26 +080028import shutil
Ignacio Guarna9c63ef52020-02-06 17:08:09 -030029import struct
Ang Li73697b32015-12-03 00:41:53 +000030
Betty Zhou3b2de072018-03-15 16:46:26 -070031from acts import signals
Betty Zhoue62b1f12018-01-24 17:05:20 -080032from acts import utils
Ang Li73697b32015-12-03 00:41:53 +000033from queue import Empty
Betty Zhou5534e672017-03-07 13:47:10 -080034from acts.asserts import abort_all
Ashutosh Rajmani Singh69a5f5e2018-11-13 12:38:29 -080035from acts.asserts import fail
David Goldfarb78a3b672020-03-31 12:44:01 -070036from acts.controllers.adb_lib.error import AdbError
Betty Zhoub25ba2d2018-05-03 15:52:54 -070037from acts.controllers.android_device import list_adb_devices
38from acts.controllers.android_device import list_fastboot_devices
Betty Zhou9a96fc32018-02-01 16:44:05 -080039from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
Jaineel72d2c242019-07-23 12:00:07 -070040from acts.controllers.android_device import DEFAULT_SDM_LOG_PATH
Betty Zhou92437702018-02-07 19:49:07 -080041from acts.controllers.android_device import SL4A_APK_NAME
Betty Zhou3db27a32018-04-23 14:31:25 -070042from acts.libs.proc import job
Xianyuan Jia24299b72020-10-21 13:52:47 -070043from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
44from acts_contrib.test_utils.tel.tel_defines import CarrierConfigs, CARRIER_NTT_DOCOMO, CARRIER_KDDI, CARRIER_RAKUTEN, \
ju8230cef2020-07-29 09:48:02 -070045 CARRIER_SBM
Xianyuan Jia24299b72020-10-21 13:52:47 -070046from acts_contrib.test_utils.tel.tel_defines import AOSP_PREFIX
47from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_DOWN
48from acts_contrib.test_utils.tel.tel_defines import CARD_POWER_UP
49from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_CONFERENCE
50from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
51from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_PROVISIONING
52from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING
53from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL
54from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VT
55from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
56from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC_MODE_CHANGE
57from acts_contrib.test_utils.tel.tel_defines import CARRIER_UNKNOWN
58from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
59from acts_contrib.test_utils.tel.tel_defines import COUNTRY_CODE_LIST
60from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_CONNECTED
61from acts_contrib.test_utils.tel.tel_defines import DATA_STATE_DISCONNECTED
62from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_ENABLE
63from acts_contrib.test_utils.tel.tel_defines import DATA_ROAMING_DISABLE
64from acts_contrib.test_utils.tel.tel_defines import GEN_4G
65from acts_contrib.test_utils.tel.tel_defines import GEN_UNKNOWN
66from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
67from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
68from acts_contrib.test_utils.tel.tel_defines import INVALID_SIM_SLOT_INDEX
69from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
70from acts_contrib.test_utils.tel.tel_defines import MAX_SAVED_VOICE_MAIL
71from acts_contrib.test_utils.tel.tel_defines import MAX_SCREEN_ON_TIME
72from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT
73from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_AIRPLANEMODE_EVENT
74from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
75from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION
76from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING
77from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
78from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_DATA_SUB_CHANGE
79from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_IDLE_EVENT
80from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
81from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
82from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION
83from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS
84from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION
85from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING
86from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOICE_MAIL_COUNT
87from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
88from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_DISABLED
89from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
90from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL
91from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_NW_VALID_FAIL
92from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_FOR_DATA_STALL_RECOVERY
93from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
94from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_CELL
95from acts_contrib.test_utils.tel.tel_defines import NETWORK_CONNECTION_TYPE_WIFI
96from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
97from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
98from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_7_DIGIT
99from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_10_DIGIT
100from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_11_DIGIT
101from acts_contrib.test_utils.tel.tel_defines import PHONE_NUMBER_STRING_FORMAT_12_DIGIT
102from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
103from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
104from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
105from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
106from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
107from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
108from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_EMERGENCY_ONLY
109from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_IN_SERVICE
110from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_MAPPING
111from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_OUT_OF_SERVICE
112from acts_contrib.test_utils.tel.tel_defines import SERVICE_STATE_POWER_OFF
113from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_ABSENT
114from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_LOADED
115from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_NOT_READY
116from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_PIN_REQUIRED
117from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_READY
118from acts_contrib.test_utils.tel.tel_defines import SIM_STATE_UNKNOWN
119from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
120from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK
121from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING
122from acts_contrib.test_utils.tel.tel_defines import VOICEMAIL_DELETE_DIGIT
123from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
124from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
125from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK
126from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE
127from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID
128from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
129from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL
130from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL
131from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK
132from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE
133from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
134from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
135from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
136from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
137from acts_contrib.test_utils.tel.tel_defines import TYPE_MOBILE
138from acts_contrib.test_utils.tel.tel_defines import TYPE_WIFI
139from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
140from acts_contrib.test_utils.tel.tel_defines import EventActiveDataSubIdChanged
141from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged
142from acts_contrib.test_utils.tel.tel_defines import EventConnectivityChanged
143from acts_contrib.test_utils.tel.tel_defines import EventDataConnectionStateChanged
144from acts_contrib.test_utils.tel.tel_defines import EventDataSmsReceived
145from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
146from acts_contrib.test_utils.tel.tel_defines import EventServiceStateChanged
147from acts_contrib.test_utils.tel.tel_defines import EventMmsSentFailure
148from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
149from acts_contrib.test_utils.tel.tel_defines import EventMmsDownloaded
150from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
151from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverFailure
152from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
153from acts_contrib.test_utils.tel.tel_defines import EventSmsSentFailure
154from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
155from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
156from acts_contrib.test_utils.tel.tel_defines import DataConnectionStateContainer
157from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
158from acts_contrib.test_utils.tel.tel_defines import NetworkCallbackContainer
159from acts_contrib.test_utils.tel.tel_defines import ServiceStateContainer
160from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer
161from acts_contrib.test_utils.tel.tel_defines import OverrideNetworkContainer
162from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_NR_LTE_GSM_WCDMA
163from acts_contrib.test_utils.tel.tel_defines import CARRIER_VZW, CARRIER_ATT, \
Shaju Sebastian0b847e72019-01-31 16:40:37 -0800164 CARRIER_BELL, CARRIER_ROGERS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_TELUS
Xianyuan Jia24299b72020-10-21 13:52:47 -0700165from acts_contrib.test_utils.tel.tel_lookup_tables import connection_type_from_type_string
166from acts_contrib.test_utils.tel.tel_lookup_tables import is_valid_rat
167from acts_contrib.test_utils.tel.tel_lookup_tables import get_allowable_network_preference
168from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_count_check_function
169from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_check_number
170from acts_contrib.test_utils.tel.tel_lookup_tables import get_voice_mail_delete_digit
171from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
172from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_network_name
173from acts_contrib.test_utils.tel.tel_lookup_tables import operator_name_from_plmn_id
174from acts_contrib.test_utils.tel.tel_lookup_tables import rat_families_for_network_preference
175from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_for_generation
176from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat
177from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
178from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id, get_subid_from_slot_index
179from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
180from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
181from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
182from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_message_sub_id
183from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
184from acts_contrib.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id
185from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
186from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad
187from acts_contrib.test_utils.wifi import wifi_test_utils
188from acts_contrib.test_utils.wifi import wifi_constants
Betty Zhou8e11e442017-03-30 20:00:34 -0700189from acts.utils import adb_shell_ping
Yang Liu46ed7222015-12-28 14:08:52 -0800190from acts.utils import load_config
Jaineel55ae6f92017-06-29 17:44:19 -0700191from acts.utils import start_standing_subprocess
192from acts.utils import stop_standing_subprocess
Jaineelc9e7bfa2017-08-07 14:11:30 -0700193from acts.logger import epoch_to_log_line_timestamp
194from acts.logger import normalize_log_line_timestamp
195from acts.utils import get_current_epoch_time
Jaineel5576d432017-10-19 15:36:42 -0700196from acts.utils import exe_cmd
Markus Liud7850222020-04-14 17:11:12 +0800197from acts.utils import rand_ascii_str
Ang Li5bd83f32016-05-23 14:39:38 -0700198
Jaineel1cde17b2019-01-04 14:26:55 -0800199
Betty Zhouf987b8f2017-03-09 16:34:00 -0800200WIFI_SSID_KEY = wifi_test_utils.WifiEnums.SSID_KEY
201WIFI_PWD_KEY = wifi_test_utils.WifiEnums.PWD_KEY
Jaineel08466192020-07-13 17:09:03 -0700202WIFI_CONFIG_APBAND_2G = 1
203WIFI_CONFIG_APBAND_5G = 2
Bindu Mahadevfb8fbe02018-04-06 16:23:40 -0700204WIFI_CONFIG_APBAND_AUTO = wifi_test_utils.WifiEnums.WIFI_CONFIG_APBAND_AUTO
Ang Li5bd83f32016-05-23 14:39:38 -0700205log = logging
Betty Zhoudd781f82017-08-08 14:46:23 -0700206STORY_LINE = "+19523521350"
Kris Rambishdfe4a3a2019-03-26 21:53:43 -0700207CallResult = TelephonyVoiceTestResult.CallResult.Value
Ang Li73697b32015-12-03 00:41:53 +0000208
Nathan Harold123c9da2015-12-30 16:33:25 -0800209
Ang Li73697b32015-12-03 00:41:53 +0000210class TelTestUtilsError(Exception):
211 pass
212
Nathan Harold123c9da2015-12-30 16:33:25 -0800213
Kris Rambishdfe4a3a2019-03-26 21:53:43 -0700214class TelResultWrapper(object):
215 """Test results wrapper for Telephony test utils.
216
217 In order to enable metrics reporting without refactoring
218 all of the test utils this class is used to keep the
219 current return boolean scheme in tact.
220 """
221
222 def __init__(self, result_value):
223 self._result_value = result_value
224
225 @property
226 def result_value(self):
227 return self._result_value
228
229 @result_value.setter
230 def result_value(self, result_value):
231 self._result_value = result_value
232
233 def __bool__(self):
234 return self._result_value == CallResult('SUCCESS')
235
236
Betty Zhou5534e672017-03-07 13:47:10 -0800237def abort_all_tests(log, msg):
238 log.error("Aborting all ongoing tests due to: %s.", msg)
239 abort_all(msg)
240
241
Betty Zhou5b069a02016-12-06 19:23:44 -0800242def get_phone_number_by_adb(ad):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700243 return phone_number_formatter(
244 ad.adb.shell("service call iphonesubinfo 13"))
Betty Zhou5b069a02016-12-06 19:23:44 -0800245
246
247def get_iccid_by_adb(ad):
248 return ad.adb.shell("service call iphonesubinfo 11")
249
250
251def get_operator_by_adb(ad):
Jaineel28aec0e2019-01-10 14:16:36 -0800252 operator = ad.adb.getprop("gsm.sim.operator.alpha")
253 if "," in operator:
254 operator = operator.strip()[0]
255 return operator
Betty Zhou5b069a02016-12-06 19:23:44 -0800256
257
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700258def get_plmn_by_adb(ad):
Jaineel28aec0e2019-01-10 14:16:36 -0800259 plmn_id = ad.adb.getprop("gsm.sim.operator.numeric")
260 if "," in plmn_id:
261 plmn_id = plmn_id.strip()[0]
262 return plmn_id
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700263
264
Betty Zhou5b069a02016-12-06 19:23:44 -0800265def get_sub_id_by_adb(ad):
266 return ad.adb.shell("service call iphonesubinfo 5")
267
268
269def setup_droid_properties_by_adb(log, ad, sim_filename=None):
Ang Li73697b32015-12-03 00:41:53 +0000270
Betty Zhou5b069a02016-12-06 19:23:44 -0800271 sim_data = None
272 if sim_filename:
273 try:
274 sim_data = load_config(sim_filename)
275 except Exception:
Betty Zhouccd171d2017-02-13 15:11:33 -0800276 log.warning("Failed to load %s!", sim_filename)
Betty Zhou5b069a02016-12-06 19:23:44 -0800277
Betty Zhou76a83f72016-12-20 14:21:11 -0800278 sub_id = get_sub_id_by_adb(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700279 iccid = get_iccid_by_adb(ad)
280 ad.log.info("iccid = %s", iccid)
281 if sim_data.get(iccid) and sim_data[iccid].get("phone_num"):
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700282 phone_number = phone_number_formatter(sim_data[iccid]["phone_num"])
283 else:
284 phone_number = get_phone_number_by_adb(ad)
Betty Zhouddb361d2017-09-07 17:07:20 -0700285 if not phone_number and hasattr(ad, phone_number):
286 phone_number = ad.phone_number
Betty Zhou5b069a02016-12-06 19:23:44 -0800287 if not phone_number:
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700288 ad.log.error("Failed to find valid phone number for %s", iccid)
Betty Zhoud4b75c52018-04-03 15:20:00 -0700289 abort_all_tests(ad.log, "Failed to find valid phone number for %s")
Betty Zhou3b2de072018-03-15 16:46:26 -0700290 sub_record = {
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700291 'phone_num': phone_number,
Betty Zhoua27e5d42017-01-17 11:33:04 -0800292 'iccid': get_iccid_by_adb(ad),
Betty Zhou8ecd1da2017-10-05 15:44:24 -0700293 'sim_operator_name': get_operator_by_adb(ad),
294 'operator': operator_name_from_plmn_id(get_plmn_by_adb(ad))
Betty Zhoua27e5d42017-01-17 11:33:04 -0800295 }
Betty Zhou3b2de072018-03-15 16:46:26 -0700296 device_props = {'subscription': {sub_id: sub_record}}
297 ad.log.info("subId %s SIM record: %s", sub_id, sub_record)
298 setattr(ad, 'telephony', device_props)
Betty Zhou5b069a02016-12-06 19:23:44 -0800299
300
Jaineelc9ea2f32019-08-21 13:48:16 -0700301def setup_droid_properties(log, ad, sim_filename=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800302
Betty Zhou5b069a02016-12-06 19:23:44 -0800303 if ad.skip_sl4a:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800304 return setup_droid_properties_by_adb(
305 log, ad, sim_filename=sim_filename)
Jaineelc9ea2f32019-08-21 13:48:16 -0700306 refresh_droid_config(log, ad)
Ang Li73697b32015-12-03 00:41:53 +0000307 device_props = {}
308 device_props['subscription'] = {}
309
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700310 sim_data = {}
311 if sim_filename:
312 try:
313 sim_data = load_config(sim_filename)
314 except Exception:
315 log.warning("Failed to load %s!", sim_filename)
Betty Zhou3b2de072018-03-15 16:46:26 -0700316 if not ad.telephony["subscription"]:
Betty Zhou28e07e12018-04-11 12:12:11 -0700317 abort_all_tests(ad.log, "No valid subscription")
Jaineel28aec0e2019-01-10 14:16:36 -0800318 ad.log.debug("Subscription DB %s", ad.telephony["subscription"])
Betty Zhoude88d172017-10-27 18:20:29 -0700319 result = True
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800320 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhou3b2de072018-03-15 16:46:26 -0700321 for sub_id, sub_info in ad.telephony["subscription"].items():
Jaineel28aec0e2019-01-10 14:16:36 -0800322 ad.log.debug("Loop for Subid %s", sub_id)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700323 sub_info["operator"] = get_operator_name(log, ad, sub_id)
324 iccid = sub_info["iccid"]
325 if not iccid:
Betty Zhou3b2de072018-03-15 16:46:26 -0700326 ad.log.warning("Unable to find ICC-ID for subscriber %s", sub_id)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700327 continue
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800328 if sub_info.get("phone_num"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700329 if iccid in sim_data and sim_data[iccid].get("phone_num"):
330 if not check_phone_number_match(sim_data[iccid]["phone_num"],
331 sub_info["phone_num"]):
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800332 ad.log.warning(
333 "phone_num %s in sim card data file for iccid %s"
Betty Zhou3b2de072018-03-15 16:46:26 -0700334 " do not match phone_num %s from subscription",
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800335 sim_data[iccid]["phone_num"], iccid,
336 sub_info["phone_num"])
Betty Zhou3b2de072018-03-15 16:46:26 -0700337 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
338 else:
339 if iccid in sim_data and sim_data[iccid].get("phone_num"):
340 sub_info["phone_num"] = sim_data[iccid]["phone_num"]
341 elif sub_id == active_sub_id:
342 phone_number = get_phone_number_by_secret_code(
343 ad, sub_info["sim_operator_name"])
344 if phone_number:
345 sub_info["phone_num"] = phone_number
346 elif getattr(ad, "phone_num", None):
347 sub_info["phone_num"] = ad.phone_number
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800348 if (not sub_info.get("phone_num")) and sub_id == active_sub_id:
349 ad.log.info("sub_id %s sub_info = %s", sub_id, sub_info)
350 ad.log.error(
351 "Unable to retrieve phone number for sub %s with iccid"
352 " %s from device or testbed config or sim card file %s",
353 sub_id, iccid, sim_filename)
354 result = False
Betty Zhouee311052017-12-19 13:09:56 -0800355 if not hasattr(
356 ad, 'roaming'
Betty Zhou3b2de072018-03-15 16:46:26 -0700357 ) and sub_info["sim_plmn"] != sub_info["network_plmn"] and sub_info["sim_operator_name"].strip(
358 ) not in sub_info["network_operator_name"].strip():
Betty Zhou2cf788e2017-06-27 17:25:53 -0700359 ad.log.info("roaming is not enabled, enable it")
Betty Zhoubbbc1cf2017-03-29 16:08:36 -0700360 setattr(ad, 'roaming', True)
Betty Zhou70cc4332017-09-20 15:06:13 -0700361 ad.log.info("SubId %s info: %s", sub_id, sorted(sub_info.items()))
Betty Zhou8aafcc12018-05-01 20:54:15 -0700362 get_phone_capability(ad)
Betty Zhou2cf788e2017-06-27 17:25:53 -0700363 data_roaming = getattr(ad, 'roaming', False)
364 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
365 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Betty Zhou739d6b72018-04-18 10:38:53 -0700366 # Setup VoWiFi MDN for Verizon. b/33187374
Betty Zhouddb361d2017-09-07 17:07:20 -0700367 if not result:
368 abort_all_tests(ad.log, "Failed to find valid phone number")
Ang Li73697b32015-12-03 00:41:53 +0000369
Betty Zhou3b2de072018-03-15 16:46:26 -0700370 ad.log.debug("telephony = %s", ad.telephony)
Ang Li73697b32015-12-03 00:41:53 +0000371
Nathan Harold7642fc92016-05-02 18:29:11 -0700372
Jaineelc9ea2f32019-08-21 13:48:16 -0700373def refresh_droid_config(log, ad):
Betty Zhou3b2de072018-03-15 16:46:26 -0700374 """ Update Android Device telephony records for each sub_id.
Yang Liuad9c63d2016-02-25 13:59:23 -0800375
376 Args:
377 log: log object
378 ad: android device object
Yang Liuad9c63d2016-02-25 13:59:23 -0800379
380 Returns:
Yang Liu6c70e022016-03-07 16:19:42 -0800381 None
Yang Liuad9c63d2016-02-25 13:59:23 -0800382 """
Betty Zhou3b2de072018-03-15 16:46:26 -0700383 if not getattr(ad, 'telephony', {}):
384 setattr(ad, 'telephony', {"subscription": {}})
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700385 droid = ad.droid
386 sub_info_list = droid.subscriptionGetAllSubInfoList()
Jaineel28aec0e2019-01-10 14:16:36 -0800387 ad.log.info("SubInfoList is %s", sub_info_list)
Betty Zhou3b2de072018-03-15 16:46:26 -0700388 active_sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700389 for sub_info in sub_info_list:
390 sub_id = sub_info["subscriptionId"]
391 sim_slot = sub_info["simSlotIndex"]
Jaineel50c2de12019-08-27 16:33:28 -0700392 if sub_info.get("carrierId"):
393 carrier_id = sub_info["carrierId"]
394 else:
395 carrier_id = -1
Jaineel24052672020-04-16 20:37:36 -0700396 if sub_info.get("isOpportunistic"):
397 isopportunistic = sub_info["isOpportunistic"]
398 else:
399 isopportunistic = -1
Jaineel28aec0e2019-01-10 14:16:36 -0800400
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700401 if sim_slot != INVALID_SIM_SLOT_INDEX:
Betty Zhou3b2de072018-03-15 16:46:26 -0700402 if sub_id not in ad.telephony["subscription"]:
403 ad.telephony["subscription"][sub_id] = {}
404 sub_record = ad.telephony["subscription"][sub_id]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800405 if sub_info.get("iccId"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700406 sub_record["iccid"] = sub_info["iccId"]
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800407 else:
Betty Zhou3b2de072018-03-15 16:46:26 -0700408 sub_record[
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800409 "iccid"] = droid.telephonyGetSimSerialNumberForSubscription(
410 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700411 sub_record["sim_slot"] = sim_slot
412 if sub_info.get("mcc"):
413 sub_record["mcc"] = sub_info["mcc"]
414 if sub_info.get("mnc"):
415 sub_record["mnc"] = sub_info["mnc"]
416 if sub_info.get("displayName"):
417 sub_record["display_name"] = sub_info["displayName"]
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700418 try:
Betty Zhou3b2de072018-03-15 16:46:26 -0700419 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700420 "phone_type"] = droid.telephonyGetPhoneTypeForSubscription(
421 sub_id)
422 except:
Betty Zhou3b2de072018-03-15 16:46:26 -0700423 if not sub_record.get("phone_type"):
424 sub_record["phone_type"] = droid.telephonyGetPhoneType()
425 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700426 "sim_plmn"] = droid.telephonyGetSimOperatorForSubscription(
427 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700428 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700429 "sim_operator_name"] = droid.telephonyGetSimOperatorNameForSubscription(
430 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700431 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700432 "network_plmn"] = droid.telephonyGetNetworkOperatorForSubscription(
433 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700434 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700435 "network_operator_name"] = droid.telephonyGetNetworkOperatorNameForSubscription(
436 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700437 sub_record[
Betty Zhoud2da7ba2017-03-24 12:54:34 -0700438 "sim_country"] = droid.telephonyGetSimCountryIsoForSubscription(
439 sub_id)
Betty Zhou3b2de072018-03-15 16:46:26 -0700440 if active_sub_id == sub_id:
441 try:
442 sub_record[
443 "carrier_id"] = ad.droid.telephonyGetSimCarrierId()
444 sub_record[
445 "carrier_id_name"] = ad.droid.telephonyGetSimCarrierIdName(
446 )
447 except:
448 ad.log.info("Carrier ID is not supported")
Jaineelc9ea2f32019-08-21 13:48:16 -0700449 if carrier_id == 2340:
450 ad.log.info("SubId %s info: %s", sub_id, sorted(
451 sub_record.items()))
Jaineel9fe43112019-12-12 13:18:59 -0800452 continue
Jaineel24052672020-04-16 20:37:36 -0700453 if carrier_id == 1989 and isopportunistic == "true":
454 ad.log.info("SubId %s info: %s", sub_id, sorted(
455 sub_record.items()))
456 continue
Betty Zhou3b2de072018-03-15 16:46:26 -0700457 if not sub_info.get("number"):
458 sub_info[
459 "number"] = droid.telephonyGetLine1NumberForSubscription(
460 sub_id)
Betty Zhoue32dd3b2017-11-28 19:05:55 -0800461 if sub_info.get("number"):
Betty Zhou3b2de072018-03-15 16:46:26 -0700462 if sub_record.get("phone_num"):
463 # Use the phone number provided in sim info file by default
464 # as the sub_info["number"] may not be formatted in a
465 # dialable number
466 if not check_phone_number_match(sub_info["number"],
467 sub_record["phone_num"]):
468 ad.log.info(
469 "Subscriber phone number changed from %s to %s",
470 sub_record["phone_num"], sub_info["number"])
471 sub_record["phone_num"] = sub_info["number"]
472 else:
473 sub_record["phone_num"] = phone_number_formatter(
474 sub_info["number"])
475 #ad.telephony['subscription'][sub_id] = sub_record
476 ad.log.info("SubId %s info: %s", sub_id, sorted(
477 sub_record.items()))
Nathan Harold7642fc92016-05-02 18:29:11 -0700478
Nathan Harold123c9da2015-12-30 16:33:25 -0800479
Betty Zhouddb361d2017-09-07 17:07:20 -0700480def get_phone_number_by_secret_code(ad, operator):
481 if "T-Mobile" in operator:
482 ad.droid.telecomDialNumber("#686#")
483 ad.send_keycode("ENTER")
Betty Zhoub4062372017-09-08 11:29:38 -0700484 for _ in range(12):
485 output = ad.search_logcat("mobile number")
486 if output:
487 result = re.findall(r"mobile number is (\S+)",
488 output[-1]["log_message"])
Betty Zhou70cc4332017-09-20 15:06:13 -0700489 ad.send_keycode("BACK")
Betty Zhoub4062372017-09-08 11:29:38 -0700490 return result[0]
491 else:
492 time.sleep(5)
493 return ""
Betty Zhouddb361d2017-09-07 17:07:20 -0700494
495
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700496def get_user_config_profile(ad):
497 return {
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700498 "Airplane Mode":
499 ad.droid.connectivityCheckAirplaneMode(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700500 "IMS Registered":
501 ad.droid.telephonyIsImsRegistered(),
Betty Zhoued13b712018-05-02 19:40:10 -0700502 "Preferred Network Type":
503 ad.droid.telephonyGetPreferredNetworkTypes(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700504 "VoLTE Platform Enabled":
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700505 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(),
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700506 "VoLTE Enabled":
Betty Zhou8aafcc12018-05-01 20:54:15 -0700507 ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser(),
508 "VoLTE Available":
509 ad.droid.telephonyIsVolteAvailable(),
510 "VT Available":
511 ad.droid.telephonyIsVideoCallingAvailable(),
512 "VT Enabled":
513 ad.droid.imsIsVtEnabledByUser(),
514 "VT Platform Enabled":
515 ad.droid.imsIsVtEnabledByPlatform(),
Markus Liu1cca96e2019-11-26 15:05:25 +0800516 "WiFi State":
517 ad.droid.wifiCheckState(),
Betty Zhou8aafcc12018-05-01 20:54:15 -0700518 "WFC Available":
519 ad.droid.telephonyIsWifiCallingAvailable(),
520 "WFC Enabled":
521 ad.droid.imsIsWfcEnabledByUser(),
522 "WFC Platform Enabled":
523 ad.droid.imsIsWfcEnabledByPlatform(),
524 "WFC Mode":
525 ad.droid.imsGetWfcMode()
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700526 }
527
528
Yang Liu7ce19982016-03-09 12:20:41 -0800529def get_slot_index_from_subid(log, ad, sub_id):
530 try:
531 info = ad.droid.subscriptionGetSubInfoForSubscriber(sub_id)
532 return info['simSlotIndex']
tturney10eda2e2016-03-30 19:55:57 -0700533 except KeyError:
Yang Liu7ce19982016-03-09 12:20:41 -0800534 return INVALID_SIM_SLOT_INDEX
535
Nathan Harold123c9da2015-12-30 16:33:25 -0800536
Ang Li73697b32015-12-03 00:41:53 +0000537def get_num_active_sims(log, ad):
538 """ Get the number of active SIM cards by counting slots
539
540 Args:
541 ad: android_device object.
542
543 Returns:
544 result: The number of loaded (physical) SIM cards
545 """
546 # using a dictionary as a cheap way to prevent double counting
547 # in the situation where multiple subscriptions are on the same SIM.
548 # yes, this is a corner corner case.
549 valid_sims = {}
550 subInfo = ad.droid.subscriptionGetAllSubInfoList()
551 for info in subInfo:
552 ssidx = info['simSlotIndex']
553 if ssidx == INVALID_SIM_SLOT_INDEX:
554 continue
555 valid_sims[ssidx] = True
556 return len(valid_sims.keys())
557
Nathan Harold123c9da2015-12-30 16:33:25 -0800558
Betty Zhoua37acd32017-02-23 20:04:24 -0800559def toggle_airplane_mode_by_adb(log, ad, new_state=None):
Betty Zhou5b069a02016-12-06 19:23:44 -0800560 """ Toggle the state of airplane mode.
561
562 Args:
563 log: log handler.
564 ad: android_device object.
565 new_state: Airplane mode state to set to.
566 If None, opposite of the current state.
567 strict_checking: Whether to turn on strict checking that checks all features.
568
569 Returns:
570 result: True if operation succeed. False if error happens.
571 """
572 cur_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
573 if new_state == cur_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800574 ad.log.info("Airplane mode already in %s", new_state)
Betty Zhou5b069a02016-12-06 19:23:44 -0800575 return True
576 elif new_state is None:
577 new_state = not cur_state
Betty Zhou8aafcc12018-05-01 20:54:15 -0700578 ad.log.info("Change airplane mode from %s to %s", cur_state, new_state)
monikermine3eb66302019-10-29 13:46:56 -0700579 try:
580 ad.adb.shell("settings put global airplane_mode_on %s" % int(new_state))
581 ad.adb.shell("am broadcast -a android.intent.action.AIRPLANE_MODE")
582 except Exception as e:
583 ad.log.error(e)
584 return False
585 changed_state = bool(int(ad.adb.shell("settings get global airplane_mode_on")))
586 return changed_state == new_state
Betty Zhou5b069a02016-12-06 19:23:44 -0800587
588
Betty Zhou28732962016-11-28 15:00:58 -0800589def toggle_airplane_mode(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000590 """ Toggle the state of airplane mode.
591
592 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800593 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000594 ad: android_device object.
595 new_state: Airplane mode state to set to.
596 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800597 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000598
599 Returns:
600 result: True if operation succeed. False if error happens.
601 """
Betty Zhou5b069a02016-12-06 19:23:44 -0800602 if ad.skip_sl4a:
603 return toggle_airplane_mode_by_adb(log, ad, new_state)
604 else:
Betty Zhoua27e5d42017-01-17 11:33:04 -0800605 return toggle_airplane_mode_msim(
606 log, ad, new_state, strict_checking=strict_checking)
Ang Li73697b32015-12-03 00:41:53 +0000607
Nathan Harold123c9da2015-12-30 16:33:25 -0800608
Betty Zhou17dcabb2017-05-25 19:14:58 -0700609def get_telephony_signal_strength(ad):
Betty Zhou17dcabb2017-05-25 19:14:58 -0700610 #{'evdoEcio': -1, 'asuLevel': 28, 'lteSignalStrength': 14, 'gsmLevel': 0,
611 # 'cdmaAsuLevel': 99, 'evdoDbm': -120, 'gsmDbm': -1, 'cdmaEcio': -160,
612 # 'level': 2, 'lteLevel': 2, 'cdmaDbm': -120, 'dbm': -112, 'cdmaLevel': 0,
613 # 'lteAsuLevel': 28, 'gsmAsuLevel': 99, 'gsmBitErrorRate': 0,
614 # 'lteDbm': -112, 'gsmSignalStrength': 99}
Betty Zhouf7da39e2018-04-16 16:28:58 -0700615 try:
616 signal_strength = ad.droid.telephonyGetSignalStrength()
617 if not signal_strength:
618 signal_strength = {}
619 except Exception as e:
620 ad.log.error(e)
621 signal_strength = {}
Betty Zhou17dcabb2017-05-25 19:14:58 -0700622 return signal_strength
623
624
Jaineele64be822017-11-30 16:36:36 -0800625def get_wifi_signal_strength(ad):
626 signal_strength = ad.droid.wifiGetConnectionInfo()['rssi']
627 ad.log.info("WiFi Signal Strength is %s" % signal_strength)
628 return signal_strength
629
630
Jaineel2947eaf2019-04-03 11:18:53 -0700631def get_lte_rsrp(ad):
632 try:
633 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
634 out = ad.adb.shell(
635 "dumpsys telephony.registry | grep -i signalstrength")
636 if out:
637 lte_rsrp = out.split()[9]
638 if lte_rsrp:
639 ad.log.info("lte_rsrp: %s ", lte_rsrp)
640 return lte_rsrp
641 else:
642 out = ad.adb.shell(
643 "dumpsys telephony.registry |grep -i primary=CellSignalStrengthLte")
644 if out:
645 lte_cell_info = out.split('mLte=')[1]
646 lte_rsrp = re.match(r'.*rsrp=(\S+).*', lte_cell_info).group(1)
647 if lte_rsrp:
648 ad.log.info("lte_rsrp: %s ", lte_rsrp)
649 return lte_rsrp
650 except Exception as e:
651 ad.log.error(e)
652 return None
653
654
Jaineel22508f22019-01-31 18:30:21 -0800655def check_data_stall_detection(ad, wait_time=WAIT_TIME_FOR_DATA_STALL):
656 data_stall_detected = False
657 time_var = 1
658 try:
659 while (time_var < wait_time):
660 out = ad.adb.shell("dumpsys network_stack " \
661 "| grep \"Suspecting data stall\"",
662 ignore_status=True)
663 ad.log.debug("Output is %s", out)
664 if out:
665 ad.log.info("NetworkMonitor detected - %s", out)
Jaineel22508f22019-01-31 18:30:21 -0800666 data_stall_detected = True
667 break
668 time.sleep(30)
669 time_var += 30
670 except Exception as e:
671 ad.log.error(e)
672 return data_stall_detected
673
674
675def check_network_validation_fail(ad, begin_time=None,
676 wait_time=WAIT_TIME_FOR_NW_VALID_FAIL):
677 network_validation_fail = False
678 time_var = 1
679 try:
680 while (time_var < wait_time):
681 time_var += 30
682 nw_valid = ad.search_logcat("validation failed",
683 begin_time)
684 if nw_valid:
685 ad.log.info("Validation Failed received here - %s",
686 nw_valid[0]["log_message"])
687 network_validation_fail = True
688 break
689 time.sleep(30)
690 except Exception as e:
691 ad.log.error(e)
692 return network_validation_fail
693
694
695def check_data_stall_recovery(ad, begin_time=None,
696 wait_time=WAIT_TIME_FOR_DATA_STALL_RECOVERY):
697 data_stall_recovery = False
698 time_var = 1
699 try:
700 while (time_var < wait_time):
701 time_var += 30
702 recovery = ad.search_logcat("doRecovery() cleanup all connections",
703 begin_time)
704 if recovery:
705 ad.log.info("Recovery Performed here - %s",
706 recovery[-1]["log_message"])
707 data_stall_recovery = True
708 break
709 time.sleep(30)
710 except Exception as e:
711 ad.log.error(e)
712 return data_stall_recovery
713
714
715def break_internet_except_sl4a_port(ad, sl4a_port):
716 ad.log.info("Breaking internet using iptables rules")
717 ad.adb.shell("iptables -I INPUT 1 -p tcp --dport %s -j ACCEPT" % sl4a_port,
718 ignore_status=True)
719 ad.adb.shell("iptables -I INPUT 2 -p tcp --sport %s -j ACCEPT" % sl4a_port,
720 ignore_status=True)
721 ad.adb.shell("iptables -I INPUT 3 -j DROP", ignore_status=True)
722 ad.adb.shell("ip6tables -I INPUT -j DROP", ignore_status=True)
723 return True
724
725
726def resume_internet_with_sl4a_port(ad, sl4a_port):
727 ad.log.info("Bring internet back using iptables rules")
728 ad.adb.shell("iptables -D INPUT -p tcp --dport %s -j ACCEPT" % sl4a_port,
729 ignore_status=True)
730 ad.adb.shell("iptables -D INPUT -p tcp --sport %s -j ACCEPT" % sl4a_port,
731 ignore_status=True)
732 ad.adb.shell("iptables -D INPUT -j DROP", ignore_status=True)
733 ad.adb.shell("ip6tables -D INPUT -j DROP", ignore_status=True)
734 return True
735
736
737def test_data_browsing_success_using_sl4a(log, ad):
738 result = True
739 web_page_list = ['https://www.google.com', 'https://www.yahoo.com',
740 'https://www.amazon.com', 'https://www.nike.com',
741 'https://www.facebook.com']
742 for website in web_page_list:
743 if not verify_http_connection(log, ad, website, retry=0):
744 ad.log.error("Failed to browse %s successfully!", website)
745 result = False
746 return result
747
748
749def test_data_browsing_failure_using_sl4a(log, ad):
750 result = True
751 web_page_list = ['https://www.youtube.com', 'https://www.cnn.com',
752 'https://www.att.com', 'https://www.nbc.com',
753 'https://www.verizonwireless.com']
754 for website in web_page_list:
755 if not verify_http_connection(log, ad, website, retry=0,
756 expected_state=False):
757 ad.log.error("Browsing to %s worked!", website)
758 result = False
759 return result
760
761
Ang Li73697b32015-12-03 00:41:53 +0000762def is_expected_event(event_to_check, events_list):
763 """ check whether event is present in the event list
764
765 Args:
766 event_to_check: event to be checked.
767 events_list: list of events
768 Returns:
769 result: True if event present in the list. False if not.
770 """
771 for event in events_list:
772 if event in event_to_check['name']:
773 return True
774 return False
775
Nathan Harold123c9da2015-12-30 16:33:25 -0800776
Ang Li73697b32015-12-03 00:41:53 +0000777def is_sim_ready(log, ad, sim_slot_id=None):
778 """ check whether SIM is ready.
779
780 Args:
781 ad: android_device object.
782 sim_slot_id: check the SIM status for sim_slot_id
783 This is optional. If this is None, check default SIM.
784
785 Returns:
786 result: True if all SIMs are ready. False if not.
787 """
788 if sim_slot_id is None:
Yang Liuaed3eef2015-12-15 18:40:25 -0800789 status = ad.droid.telephonyGetSimState()
Ang Li73697b32015-12-03 00:41:53 +0000790 else:
Yang Liuaed3eef2015-12-15 18:40:25 -0800791 status = ad.droid.telephonyGetSimStateForSlotId(sim_slot_id)
Ang Li73697b32015-12-03 00:41:53 +0000792 if status != SIM_STATE_READY:
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700793 ad.log.info("Sim state is %s, not ready", status)
Nathan Harold123c9da2015-12-30 16:33:25 -0800794 return False
Ang Li73697b32015-12-03 00:41:53 +0000795 return True
796
Nathan Harold123c9da2015-12-30 16:33:25 -0800797
Betty Zhou688c1032017-11-20 20:08:04 -0800798def is_sim_ready_by_adb(log, ad):
Betty Zhoue66efb42018-01-31 19:45:56 -0800799 state = ad.adb.getprop("gsm.sim.state")
Betty Zhou28e07e12018-04-11 12:12:11 -0700800 ad.log.info("gsm.sim.state = %s", state)
Betty Zhoue66efb42018-01-31 19:45:56 -0800801 return state == SIM_STATE_READY or state == SIM_STATE_LOADED
Betty Zhou688c1032017-11-20 20:08:04 -0800802
803
804def wait_for_sim_ready_by_adb(log, ad, wait_time=90):
805 return _wait_for_droid_in_state(log, ad, wait_time, is_sim_ready_by_adb)
806
807
Visweswara Kumar541c0c72018-09-05 12:53:31 -0700808def is_sims_ready_by_adb(log, ad):
809 states = list(ad.adb.getprop("gsm.sim.state").split(","))
810 ad.log.info("gsm.sim.state = %s", states)
811 for state in states:
812 if state != SIM_STATE_READY and state != SIM_STATE_LOADED:
813 return False
814 return True
815
816
817def wait_for_sims_ready_by_adb(log, ad, wait_time=90):
818 return _wait_for_droid_in_state(log, ad, wait_time, is_sims_ready_by_adb)
819
820
Betty Zhou688c1032017-11-20 20:08:04 -0800821def get_service_state_by_adb(log, ad):
822 output = ad.adb.shell("dumpsys telephony.registry | grep mServiceState")
823 if "mVoiceRegState" in output:
824 result = re.search(r"mVoiceRegState=(\S+)\((\S+)\)", output)
825 if result:
Betty Zhouee311052017-12-19 13:09:56 -0800826 ad.log.info("mVoiceRegState is %s %s", result.group(1),
827 result.group(2))
Betty Zhou688c1032017-11-20 20:08:04 -0800828 return result.group(2)
monikermine9880a712019-11-07 12:24:55 -0800829 else:
830 if getattr(ad, "sdm_log", False):
831 #look for all occurrence in string
832 result2 = re.findall(r"mVoiceRegState=(\S+)\((\S+)\)", output)
833 for voice_state in result2:
834 if voice_state[0] == 0:
835 ad.log.info("mVoiceRegState is 0 %s", voice_state[1])
836 return voice_state[1]
837 return result2[1][1]
Betty Zhou688c1032017-11-20 20:08:04 -0800838 else:
839 result = re.search(r"mServiceState=(\S+)", output)
840 if result:
Betty Zhouee311052017-12-19 13:09:56 -0800841 ad.log.info("mServiceState=%s %s", result.group(1),
Betty Zhou688c1032017-11-20 20:08:04 -0800842 SERVICE_STATE_MAPPING[result.group(1)])
843 return SERVICE_STATE_MAPPING[result.group(1)]
844
845
Ang Li73697b32015-12-03 00:41:53 +0000846def _is_expecting_event(event_recv_list):
847 """ check for more event is expected in event list
848
849 Args:
850 event_recv_list: list of events
851 Returns:
852 result: True if more events are expected. False if not.
853 """
854 for state in event_recv_list:
855 if state is False:
Nathan Harold123c9da2015-12-30 16:33:25 -0800856 return True
Ang Li73697b32015-12-03 00:41:53 +0000857 return False
858
Nathan Harold123c9da2015-12-30 16:33:25 -0800859
860def _set_event_list(event_recv_list, sub_id_list, sub_id, value):
Ang Li73697b32015-12-03 00:41:53 +0000861 """ set received event in expected event list
862
863 Args:
864 event_recv_list: list of received events
865 sub_id_list: subscription ID list
866 sub_id: subscription id of current event
867 value: True or False
868 Returns:
869 None.
870 """
871 for i in range(len(sub_id_list)):
872 if sub_id_list[i] == sub_id:
873 event_recv_list[i] = value
874
Nathan Harold123c9da2015-12-30 16:33:25 -0800875
Nathan Harold54129bb2016-09-29 19:40:52 -0700876def _wait_for_bluetooth_in_state(log, ad, state, max_wait):
877 # FIXME: These event names should be defined in a common location
878 _BLUETOOTH_STATE_ON_EVENT = 'BluetoothStateChangedOn'
879 _BLUETOOTH_STATE_OFF_EVENT = 'BluetoothStateChangedOff'
Nathan Harold9b1b2f12016-10-14 12:42:57 -0700880 ad.ed.clear_events(_BLUETOOTH_STATE_ON_EVENT)
881 ad.ed.clear_events(_BLUETOOTH_STATE_OFF_EVENT)
882
Nathan Harold54129bb2016-09-29 19:40:52 -0700883 ad.droid.bluetoothStartListeningForAdapterStateChange()
884 try:
885 bt_state = ad.droid.bluetoothCheckState()
886 if bt_state == state:
887 return True
888 if max_wait <= 0:
Betty Zhoua37acd32017-02-23 20:04:24 -0800889 ad.log.error("Time out: bluetooth state still %s, expecting %s",
890 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700891 return False
892
Betty Zhoua27e5d42017-01-17 11:33:04 -0800893 event = {
894 False: _BLUETOOTH_STATE_OFF_EVENT,
895 True: _BLUETOOTH_STATE_ON_EVENT
896 }[state]
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700897 event = ad.ed.pop_event(event, max_wait)
898 ad.log.info("Got event %s", event['name'])
Nathan Harold54129bb2016-09-29 19:40:52 -0700899 return True
900 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -0800901 ad.log.error("Time out: bluetooth state still in %s, expecting %s",
902 bt_state, state)
Nathan Harold54129bb2016-09-29 19:40:52 -0700903 return False
904 finally:
905 ad.droid.bluetoothStopListeningForAdapterStateChange()
906
907
908# TODO: replace this with an event-based function
909def _wait_for_wifi_in_state(log, ad, state, max_wait):
910 return _wait_for_droid_in_state(log, ad, max_wait,
911 lambda log, ad, state: \
912 (True if ad.droid.wifiCheckState() == state else False),
913 state)
914
915
Betty Zhou28732962016-11-28 15:00:58 -0800916def toggle_airplane_mode_msim(log, ad, new_state=None, strict_checking=True):
Ang Li73697b32015-12-03 00:41:53 +0000917 """ Toggle the state of airplane mode.
918
919 Args:
Betty Zhou28732962016-11-28 15:00:58 -0800920 log: log handler.
Ang Li73697b32015-12-03 00:41:53 +0000921 ad: android_device object.
922 new_state: Airplane mode state to set to.
923 If None, opposite of the current state.
Betty Zhou28732962016-11-28 15:00:58 -0800924 strict_checking: Whether to turn on strict checking that checks all features.
Ang Li73697b32015-12-03 00:41:53 +0000925
926 Returns:
927 result: True if operation succeed. False if error happens.
928 """
Ang Li73697b32015-12-03 00:41:53 +0000929
Ang Li73697b32015-12-03 00:41:53 +0000930 cur_state = ad.droid.connectivityCheckAirplaneMode()
931 if cur_state == new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -0800932 ad.log.info("Airplane mode already in %s", new_state)
Ang Li73697b32015-12-03 00:41:53 +0000933 return True
934 elif new_state is None:
Ang Li73697b32015-12-03 00:41:53 +0000935 new_state = not cur_state
Betty Zhoub66d48f2018-04-09 12:00:53 -0700936 ad.log.info("Toggle APM mode, from current tate %s to %s", cur_state,
937 new_state)
Betty Zhoue123c672018-03-21 19:57:11 -0700938 sub_id_list = []
939 active_sub_info = ad.droid.subscriptionGetAllSubInfoList()
codycaldwell555da912020-01-27 15:08:46 -0800940 if active_sub_info:
941 for info in active_sub_info:
942 sub_id_list.append(info['subscriptionId'])
Betty Zhoue123c672018-03-21 19:57:11 -0700943
944 ad.ed.clear_all_events()
945 time.sleep(0.1)
Yang Liu8e6adff2016-02-05 10:24:04 -0800946 service_state_list = []
Ang Li73697b32015-12-03 00:41:53 +0000947 if new_state:
Yang Liu8e6adff2016-02-05 10:24:04 -0800948 service_state_list.append(SERVICE_STATE_POWER_OFF)
Betty Zhoua37acd32017-02-23 20:04:24 -0800949 ad.log.info("Turn on airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000950
951 else:
952 # If either one of these 3 events show up, it should be OK.
953 # Normal SIM, phone in service
Yang Liu8e6adff2016-02-05 10:24:04 -0800954 service_state_list.append(SERVICE_STATE_IN_SERVICE)
Ang Li73697b32015-12-03 00:41:53 +0000955 # NO SIM, or Dead SIM, or no Roaming coverage.
Yang Liu8e6adff2016-02-05 10:24:04 -0800956 service_state_list.append(SERVICE_STATE_OUT_OF_SERVICE)
957 service_state_list.append(SERVICE_STATE_EMERGENCY_ONLY)
Betty Zhoua37acd32017-02-23 20:04:24 -0800958 ad.log.info("Turn off airplane mode")
Ang Li73697b32015-12-03 00:41:53 +0000959
960 for sub_id in sub_id_list:
Nathan Harold123c9da2015-12-30 16:33:25 -0800961 ad.droid.telephonyStartTrackingServiceStateChangeForSubscription(
962 sub_id)
Nathan Harold54129bb2016-09-29 19:40:52 -0700963
964 timeout_time = time.time() + MAX_WAIT_TIME_AIRPLANEMODE_EVENT
Ang Li73697b32015-12-03 00:41:53 +0000965 ad.droid.connectivityToggleAirplaneMode(new_state)
966
Ang Li73697b32015-12-03 00:41:53 +0000967 try:
968 try:
Nathan Harold7642fc92016-05-02 18:29:11 -0700969 event = ad.ed.wait_for_event(
970 EventServiceStateChanged,
971 is_event_match_for_list,
972 timeout=MAX_WAIT_TIME_AIRPLANEMODE_EVENT,
973 field=ServiceStateContainer.SERVICE_STATE,
974 value_list=service_state_list)
Betty Zhou5c7dbd12018-03-13 18:27:44 -0700975 ad.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +0000976 except Empty:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -0700977 ad.log.warning("Did not get expected service state change to %s",
978 service_state_list)
Betty Zhoua36c4352018-04-05 18:49:32 -0700979 finally:
980 for sub_id in sub_id_list:
981 ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
982 sub_id)
983 except Exception as e:
984 ad.log.error(e)
Ang Li73697b32015-12-03 00:41:53 +0000985
Nathan Harold54129bb2016-09-29 19:40:52 -0700986 # APM on (new_state=True) will turn off bluetooth but may not turn it on
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800987 try:
988 if new_state and not _wait_for_bluetooth_in_state(
Betty Zhoua27e5d42017-01-17 11:33:04 -0800989 log, ad, False, timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -0800990 ad.log.error(
991 "Failed waiting for bluetooth during airplane mode toggle")
Betty Zhou28732962016-11-28 15:00:58 -0800992 if strict_checking: return False
Betty Zhoue1cf85f2016-11-18 19:18:17 -0800993 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -0800994 ad.log.error("Failed to check bluetooth state due to %s", e)
Betty Zhou28732962016-11-28 15:00:58 -0800995 if strict_checking:
996 raise
Nathan Harold54129bb2016-09-29 19:40:52 -0700997
998 # APM on (new_state=True) will turn off wifi but may not turn it on
Nathan Harold450a7682016-10-12 12:57:17 -0700999 if new_state and not _wait_for_wifi_in_state(log, ad, False,
1000 timeout_time - time.time()):
Betty Zhoua37acd32017-02-23 20:04:24 -08001001 ad.log.error("Failed waiting for wifi during airplane mode toggle on")
1002 if strict_checking: return False
Nathan Harold54129bb2016-09-29 19:40:52 -07001003
1004 if ad.droid.connectivityCheckAirplaneMode() != new_state:
Betty Zhoua37acd32017-02-23 20:04:24 -08001005 ad.log.error("Set airplane mode to %s failed", new_state)
Nathan Harold54129bb2016-09-29 19:40:52 -07001006 return False
Ang Li73697b32015-12-03 00:41:53 +00001007 return True
1008
Nathan Harold123c9da2015-12-30 16:33:25 -08001009
1010def wait_and_answer_call(log,
1011 ad,
1012 incoming_number=None,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001013 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07001014 caller=None,
1015 video_state=None):
Ang Li73697b32015-12-03 00:41:53 +00001016 """Wait for an incoming call on default voice subscription and
1017 accepts the call.
1018
1019 Args:
1020 ad: android device object.
1021 incoming_number: Expected incoming number.
1022 Optional. Default is None
Ang Li73697b32015-12-03 00:41:53 +00001023 incall_ui_display: after answer the call, bring in-call UI to foreground or
1024 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1025 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1026 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1027 else, do nothing.
1028
1029 Returns:
1030 True: if incoming call is received and answered successfully.
1031 False: for errors
1032 """
1033 return wait_and_answer_call_for_subscription(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001034 log,
1035 ad,
1036 get_incoming_voice_sub_id(ad),
1037 incoming_number,
1038 incall_ui_display=incall_ui_display,
Betty Zhou48557582018-05-14 13:19:23 -07001039 caller=caller,
1040 video_state=video_state)
Nathan Harold123c9da2015-12-30 16:33:25 -08001041
Ang Li73697b32015-12-03 00:41:53 +00001042
Nathan Harold54c7c742016-08-04 19:40:44 -07001043def _wait_for_ringing_event(log, ad, wait_time):
Ang Li73697b32015-12-03 00:41:53 +00001044 """Wait for ringing event.
1045
1046 Args:
1047 log: log object.
1048 ad: android device object.
1049 wait_time: max time to wait for ringing event.
1050
1051 Returns:
1052 event_ringing if received ringing event.
1053 otherwise return None.
1054 """
Ang Li73697b32015-12-03 00:41:53 +00001055 event_ringing = None
1056
Nathan Harold0111e202016-09-27 17:03:00 -07001057 try:
1058 event_ringing = ad.ed.wait_for_event(
1059 EventCallStateChanged,
1060 is_event_match,
1061 timeout=wait_time,
1062 field=CallStateContainer.CALL_STATE,
1063 value=TELEPHONY_STATE_RINGING)
Betty Zhoua37acd32017-02-23 20:04:24 -08001064 ad.log.info("Receive ringing event")
Nathan Harold0111e202016-09-27 17:03:00 -07001065 except Empty:
Betty Zhoua37acd32017-02-23 20:04:24 -08001066 ad.log.info("No Ringing Event")
Nathan Harold0111e202016-09-27 17:03:00 -07001067 finally:
1068 return event_ringing
Ang Li73697b32015-12-03 00:41:53 +00001069
Nathan Harold123c9da2015-12-30 16:33:25 -08001070
Nathan Harold54c7c742016-08-04 19:40:44 -07001071def wait_for_ringing_call(log, ad, incoming_number=None):
1072 """Wait for an incoming call on default voice subscription and
Ang Li73697b32015-12-03 00:41:53 +00001073 accepts the call.
1074
1075 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001076 log: log object.
1077 ad: android device object.
1078 incoming_number: Expected incoming number.
1079 Optional. Default is None
1080
1081 Returns:
1082 True: if incoming call is received and answered successfully.
1083 False: for errors
1084 """
1085 return wait_for_ringing_call_for_subscription(
1086 log, ad, get_incoming_voice_sub_id(ad), incoming_number)
1087
1088
Betty Zhoua37acd32017-02-23 20:04:24 -08001089def wait_for_ringing_call_for_subscription(
1090 log,
1091 ad,
1092 sub_id,
1093 incoming_number=None,
Betty Zhou7f45f552017-03-15 19:12:52 -07001094 caller=None,
Betty Zhoua37acd32017-02-23 20:04:24 -08001095 event_tracking_started=False,
Betty Zhoubcffe442017-07-05 17:27:55 -07001096 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
Betty Zhou17548912018-05-31 16:09:07 -07001097 interval=WAIT_TIME_BETWEEN_STATE_CHECK):
Nathan Harold54c7c742016-08-04 19:40:44 -07001098 """Wait for an incoming call on specified subscription.
1099
1100 Args:
1101 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001102 ad: android device object.
1103 sub_id: subscription ID
Betty Zhoua37acd32017-02-23 20:04:24 -08001104 incoming_number: Expected incoming number. Default is None
1105 event_tracking_started: True if event tracking already state outside
1106 timeout: time to wait for ring
Betty Zhou17548912018-05-31 16:09:07 -07001107 interval: checking interval
Ang Li73697b32015-12-03 00:41:53 +00001108
1109 Returns:
1110 True: if incoming call is received and answered successfully.
1111 False: for errors
1112 """
Betty Zhou17548912018-05-31 16:09:07 -07001113 if not event_tracking_started:
1114 ad.ed.clear_events(EventCallStateChanged)
1115 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Betty Zhou03bd3f92018-06-06 17:37:56 -07001116 ring_event_received = False
Betty Zhou17548912018-05-31 16:09:07 -07001117 end_time = time.time() + timeout
1118 try:
1119 while time.time() < end_time:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001120 if not ring_event_received:
Betty Zhou17548912018-05-31 16:09:07 -07001121 event_ringing = _wait_for_ringing_event(log, ad, interval)
1122 if event_ringing:
Betty Zhou17548912018-05-31 16:09:07 -07001123 if incoming_number and not check_phone_number_match(
1124 event_ringing['data']
1125 [CallStateContainer.INCOMING_NUMBER], incoming_number):
1126 ad.log.error(
1127 "Incoming Number not match. Expected number:%s, actual number:%s",
1128 incoming_number, event_ringing['data'][
1129 CallStateContainer.INCOMING_NUMBER])
1130 return False
Betty Zhou03bd3f92018-06-06 17:37:56 -07001131 ring_event_received = True
1132 telephony_state = ad.droid.telephonyGetCallStateForSubscription(
1133 sub_id)
1134 telecom_state = ad.droid.telecomGetCallState()
1135 if telephony_state == TELEPHONY_STATE_RINGING and (
1136 telecom_state == TELEPHONY_STATE_RINGING):
1137 ad.log.info("callee is in telephony and telecom RINGING state")
Betty Zhou17548912018-05-31 16:09:07 -07001138 if caller:
1139 if caller.droid.telecomIsInCall():
1140 caller.log.info("Caller telecom is in call state")
1141 return True
1142 else:
1143 caller.log.info("Caller telecom is NOT in call state")
1144 else:
1145 return True
1146 else:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001147 ad.log.info(
1148 "telephony in %s, telecom in %s, expecting RINGING state",
1149 telephony_state, telecom_state)
Betty Zhou17548912018-05-31 16:09:07 -07001150 time.sleep(interval)
1151 finally:
Betty Zhou9a0840d2018-05-24 18:01:00 -07001152 if not event_tracking_started:
1153 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1154 sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -08001155
1156
Betty Zhou03bd3f92018-06-06 17:37:56 -07001157def wait_for_call_offhook_for_subscription(
1158 log,
1159 ad,
1160 sub_id,
1161 event_tracking_started=False,
1162 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
1163 interval=WAIT_TIME_BETWEEN_STATE_CHECK):
1164 """Wait for an incoming call on specified subscription.
1165
1166 Args:
1167 log: log object.
1168 ad: android device object.
1169 sub_id: subscription ID
1170 timeout: time to wait for ring
1171 interval: checking interval
1172
1173 Returns:
1174 True: if incoming call is received and answered successfully.
1175 False: for errors
1176 """
1177 if not event_tracking_started:
1178 ad.ed.clear_events(EventCallStateChanged)
1179 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
1180 offhook_event_received = False
1181 end_time = time.time() + timeout
1182 try:
1183 while time.time() < end_time:
1184 if not offhook_event_received:
1185 if wait_for_call_offhook_event(log, ad, sub_id, True,
1186 interval):
1187 offhook_event_received = True
1188 telephony_state = ad.droid.telephonyGetCallStateForSubscription(
1189 sub_id)
1190 telecom_state = ad.droid.telecomGetCallState()
1191 if telephony_state == TELEPHONY_STATE_OFFHOOK and (
1192 telecom_state == TELEPHONY_STATE_OFFHOOK):
1193 ad.log.info("telephony and telecom are in OFFHOOK state")
1194 return True
1195 else:
1196 ad.log.info(
1197 "telephony in %s, telecom in %s, expecting OFFHOOK state",
1198 telephony_state, telecom_state)
1199 if offhook_event_received:
1200 time.sleep(interval)
1201 finally:
1202 if not event_tracking_started:
1203 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1204 sub_id)
1205
1206
Betty Zhoua37acd32017-02-23 20:04:24 -08001207def wait_for_call_offhook_event(
1208 log,
1209 ad,
Betty Zhoubb192482017-03-01 14:38:56 -08001210 sub_id,
Betty Zhoua37acd32017-02-23 20:04:24 -08001211 event_tracking_started=False,
1212 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT):
1213 """Wait for an incoming call on specified subscription.
1214
1215 Args:
1216 log: log object.
1217 ad: android device object.
1218 event_tracking_started: True if event tracking already state outside
1219 timeout: time to wait for event
1220
1221 Returns:
1222 True: if call offhook event is received.
1223 False: if call offhook event is not received.
1224 """
1225 if not event_tracking_started:
Betty Zhou287f9df2018-01-23 10:57:55 -08001226 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoua37acd32017-02-23 20:04:24 -08001227 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
1228 try:
1229 ad.ed.wait_for_event(
1230 EventCallStateChanged,
1231 is_event_match,
1232 timeout=timeout,
1233 field=CallStateContainer.CALL_STATE,
1234 value=TELEPHONY_STATE_OFFHOOK)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07001235 ad.log.info("Got event %s", TELEPHONY_STATE_OFFHOOK)
Betty Zhoua37acd32017-02-23 20:04:24 -08001236 except Empty:
Betty Zhoubb192482017-03-01 14:38:56 -08001237 ad.log.info("No event for call state change to OFFHOOK")
Betty Zhoua37acd32017-02-23 20:04:24 -08001238 return False
1239 finally:
1240 if not event_tracking_started:
1241 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(
1242 sub_id)
Nathan Harold54c7c742016-08-04 19:40:44 -07001243 return True
1244
1245
1246def wait_and_answer_call_for_subscription(
1247 log,
1248 ad,
1249 sub_id,
1250 incoming_number=None,
Betty Zhoua37acd32017-02-23 20:04:24 -08001251 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001252 timeout=MAX_WAIT_TIME_CALLEE_RINGING,
Betty Zhou48557582018-05-14 13:19:23 -07001253 caller=None,
1254 video_state=None):
Nathan Harold54c7c742016-08-04 19:40:44 -07001255 """Wait for an incoming call on specified subscription and
1256 accepts the call.
1257
1258 Args:
1259 log: log object.
1260 ad: android device object.
1261 sub_id: subscription ID
1262 incoming_number: Expected incoming number.
1263 Optional. Default is None
1264 incall_ui_display: after answer the call, bring in-call UI to foreground or
1265 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
1266 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
1267 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
1268 else, do nothing.
1269
1270 Returns:
1271 True: if incoming call is received and answered successfully.
1272 False: for errors
1273 """
Betty Zhou287f9df2018-01-23 10:57:55 -08001274 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001275 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001276 try:
Betty Zhou17548912018-05-31 16:09:07 -07001277 if not wait_for_ringing_call_for_subscription(
Betty Zhouf25ce442017-03-03 14:28:36 -08001278 log,
1279 ad,
Betty Zhouf25ce442017-03-03 14:28:36 -08001280 sub_id,
Betty Zhou17548912018-05-31 16:09:07 -07001281 incoming_number=incoming_number,
Betty Zhou7f45f552017-03-15 19:12:52 -07001282 caller=caller,
Betty Zhoue5c0b232017-03-14 18:55:40 -07001283 event_tracking_started=True,
Betty Zhou17548912018-05-31 16:09:07 -07001284 timeout=timeout):
1285 ad.log.info("Incoming call ringing check failed.")
Betty Zhoua37acd32017-02-23 20:04:24 -08001286 return False
Betty Zhoubb192482017-03-01 14:38:56 -08001287 ad.log.info("Accept the ring call")
Betty Zhou48557582018-05-14 13:19:23 -07001288 ad.droid.telecomAcceptRingingCall(video_state)
Betty Zhouf25ce442017-03-03 14:28:36 -08001289
Betty Zhou03bd3f92018-06-06 17:37:56 -07001290 if wait_for_call_offhook_for_subscription(
1291 log, ad, sub_id, event_tracking_started=True):
Betty Zhoua37acd32017-02-23 20:04:24 -08001292 return True
1293 else:
1294 ad.log.error("Could not answer the call.")
Ang Li73697b32015-12-03 00:41:53 +00001295 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07001296 except Exception as e:
1297 log.error(e)
1298 return False
Ang Li73697b32015-12-03 00:41:53 +00001299 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001300 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhoua37acd32017-02-23 20:04:24 -08001301 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
1302 ad.droid.telecomShowInCallScreen()
1303 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
1304 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +00001305
Nathan Harold123c9da2015-12-30 16:33:25 -08001306
1307def wait_and_reject_call(log,
1308 ad,
1309 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001310 delay_reject=WAIT_TIME_REJECT_CALL,
1311 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001312 """Wait for an incoming call on default voice subscription and
1313 reject the call.
1314
1315 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001316 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001317 ad: android device object.
1318 incoming_number: Expected incoming number.
1319 Optional. Default is None
1320 delay_reject: time to wait before rejecting the call
1321 Optional. Default is WAIT_TIME_REJECT_CALL
1322
1323 Returns:
1324 True: if incoming call is received and reject successfully.
1325 False: for errors
1326 """
Betty Zhouee311052017-12-19 13:09:56 -08001327 return wait_and_reject_call_for_subscription(log, ad,
1328 get_incoming_voice_sub_id(ad),
1329 incoming_number, delay_reject,
1330 reject)
Ang Li73697b32015-12-03 00:41:53 +00001331
Nathan Harold123c9da2015-12-30 16:33:25 -08001332
1333def wait_and_reject_call_for_subscription(log,
1334 ad,
1335 sub_id,
1336 incoming_number=None,
Yang Liu598b93d2016-03-22 17:07:59 -07001337 delay_reject=WAIT_TIME_REJECT_CALL,
1338 reject=True):
Ang Li73697b32015-12-03 00:41:53 +00001339 """Wait for an incoming call on specific subscription and
1340 reject the call.
1341
1342 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07001343 log: log object.
Ang Li73697b32015-12-03 00:41:53 +00001344 ad: android device object.
1345 sub_id: subscription ID
1346 incoming_number: Expected incoming number.
1347 Optional. Default is None
1348 delay_reject: time to wait before rejecting the call
1349 Optional. Default is WAIT_TIME_REJECT_CALL
1350
1351 Returns:
1352 True: if incoming call is received and reject successfully.
1353 False: for errors
1354 """
Ang Li73697b32015-12-03 00:41:53 +00001355
Nathan Harold54c7c742016-08-04 19:40:44 -07001356 if not wait_for_ringing_call_for_subscription(log, ad, sub_id,
1357 incoming_number):
Betty Zhou17548912018-05-31 16:09:07 -07001358 ad.log.error(
1359 "Could not reject a call: incoming call in ringing check failed.")
Nathan Harold54c7c742016-08-04 19:40:44 -07001360 return False
Ang Li73697b32015-12-03 00:41:53 +00001361
Betty Zhou287f9df2018-01-23 10:57:55 -08001362 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001363 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Yang Liu598b93d2016-03-22 17:07:59 -07001364 if reject is True:
1365 # Delay between ringing and reject.
1366 time.sleep(delay_reject)
Yang Liu598b93d2016-03-22 17:07:59 -07001367 is_find = False
1368 # Loop the call list and find the matched one to disconnect.
1369 for call in ad.droid.telecomCallGetCallIds():
1370 if check_phone_number_match(
1371 get_number_from_tel_uri(get_call_uri(ad, call)),
1372 incoming_number):
1373 ad.droid.telecomCallDisconnect(call)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001374 ad.log.info("Callee reject the call")
Yang Liu598b93d2016-03-22 17:07:59 -07001375 is_find = True
1376 if is_find is False:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001377 ad.log.error("Callee did not find matching call to reject.")
Yang Liu598b93d2016-03-22 17:07:59 -07001378 return False
1379 else:
1380 # don't reject on callee. Just ignore the incoming call.
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001381 ad.log.info("Callee received incoming call. Ignore it.")
Ang Li73697b32015-12-03 00:41:53 +00001382 try:
Yang Liu598b93d2016-03-22 17:07:59 -07001383 ad.ed.wait_for_event(
1384 EventCallStateChanged,
1385 is_event_match_for_list,
1386 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1387 field=CallStateContainer.CALL_STATE,
1388 value_list=[TELEPHONY_STATE_IDLE, TELEPHONY_STATE_OFFHOOK])
Ang Li73697b32015-12-03 00:41:53 +00001389 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07001390 ad.log.error("No onCallStateChangedIdle event received.")
Ang Li73697b32015-12-03 00:41:53 +00001391 return False
1392 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001393 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001394 return True
1395
Nathan Harold123c9da2015-12-30 16:33:25 -08001396
Jaineel720448a2019-05-22 18:21:54 -07001397def hangup_call(log, ad, is_emergency=False):
Ang Li73697b32015-12-03 00:41:53 +00001398 """Hang up ongoing active call.
Nathan Harold54c7c742016-08-04 19:40:44 -07001399
1400 Args:
1401 log: log object.
1402 ad: android device object.
1403
1404 Returns:
Nathan Haroldd2d30092016-10-12 12:45:55 -07001405 True: if all calls are cleared
Nathan Harold54c7c742016-08-04 19:40:44 -07001406 False: for errors
Ang Li73697b32015-12-03 00:41:53 +00001407 """
Nathan Haroldd2d30092016-10-12 12:45:55 -07001408 # short circuit in case no calls are active
1409 if not ad.droid.telecomIsInCall():
1410 return True
Betty Zhou287f9df2018-01-23 10:57:55 -08001411 ad.ed.clear_events(EventCallStateChanged)
Yang Liuaed3eef2015-12-15 18:40:25 -08001412 ad.droid.telephonyStartTrackingCallState()
Betty Zhouf27f5482017-07-24 18:56:17 -07001413 ad.log.info("Hangup call.")
Jaineel720448a2019-05-22 18:21:54 -07001414 if is_emergency:
1415 for call in ad.droid.telecomCallGetCallIds():
1416 ad.droid.telecomCallDisconnect(call)
1417 else:
1418 ad.droid.telecomEndCall()
Ang Li73697b32015-12-03 00:41:53 +00001419
1420 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07001421 ad.ed.wait_for_event(
1422 EventCallStateChanged,
1423 is_event_match,
1424 timeout=MAX_WAIT_TIME_CALL_IDLE_EVENT,
1425 field=CallStateContainer.CALL_STATE,
1426 value=TELEPHONY_STATE_IDLE)
Ang Li73697b32015-12-03 00:41:53 +00001427 except Empty:
Betty Zhou03bd3f92018-06-06 17:37:56 -07001428 ad.log.warning("Call state IDLE event is not received after hang up.")
Ang Li73697b32015-12-03 00:41:53 +00001429 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08001430 ad.droid.telephonyStopTrackingCallStateChange()
Betty Zhoufe726dc2018-04-25 19:31:33 -07001431 if not wait_for_state(ad.droid.telecomIsInCall, False, 15, 1):
1432 ad.log.error("Telecom is in call, hangup call failed.")
1433 return False
1434 return True
Ang Li73697b32015-12-03 00:41:53 +00001435
Nathan Harold123c9da2015-12-30 16:33:25 -08001436
Jaineel15879c92019-06-03 17:08:13 -07001437def wait_for_cbrs_data_active_sub_change_event(
1438 ad,
1439 event_tracking_started=False,
1440 timeout=120):
1441 """Wait for an data change event on specified subscription.
1442
1443 Args:
1444 ad: android device object.
1445 event_tracking_started: True if event tracking already state outside
1446 timeout: time to wait for event
1447
1448 Returns:
1449 True: if data change event is received.
1450 False: if data change event is not received.
1451 """
1452 if not event_tracking_started:
1453 ad.ed.clear_events(EventActiveDataSubIdChanged)
1454 ad.droid.telephonyStartTrackingActiveDataChange()
1455 try:
1456 ad.ed.wait_for_event(
1457 EventActiveDataSubIdChanged,
1458 is_event_match,
1459 timeout=timeout)
1460 ad.log.info("Got event activedatasubidchanged")
1461 except Empty:
1462 ad.log.info("No event for data subid change")
1463 return False
1464 finally:
1465 if not event_tracking_started:
1466 ad.droid.telephonyStopTrackingActiveDataChange()
1467 return True
1468
1469
1470def is_current_data_on_cbrs(ad, cbrs_subid):
1471 """Verifies if current data sub is on CBRS
1472
1473 Args:
1474 ad: android device object.
1475 cbrs_subid: sub_id against which we need to check
1476
1477 Returns:
1478 True: if data is on cbrs
1479 False: if data is not on cbrs
1480 """
1481 if cbrs_subid is None:
1482 return False
Jaineel07447192019-07-01 17:06:05 -07001483 current_data = ad.droid.subscriptionGetActiveDataSubscriptionId()
Jaineel15879c92019-06-03 17:08:13 -07001484 ad.log.info("Current Data subid %s cbrs_subid %s", current_data, cbrs_subid)
Jaineel5dfd44a2019-06-10 10:48:23 -07001485 if current_data == cbrs_subid:
Jaineel15879c92019-06-03 17:08:13 -07001486 return True
1487 else:
1488 return False
1489
1490
Jaineel305b2ac2020-04-20 12:06:44 -07001491def get_current_override_network_type(ad, timeout=30):
1492 """Returns current override network type
1493
1494 Args:
1495 ad: android device object.
1496 timeout: max time to wait for event
1497
1498 Returns:
1499 value: current override type
1500 -1: if no event received
1501 """
1502 override_value_list = [OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA,
1503 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NONE,
1504 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE,
1505 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_CA,
1506 OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO]
1507 ad.ed.clear_events(EventDisplayInfoChanged)
1508 ad.droid.telephonyStartTrackingDisplayInfoChange()
1509 try:
1510 event = ad.ed.wait_for_event(
1511 EventDisplayInfoChanged,
1512 is_event_match_for_list,
1513 timeout=timeout,
1514 field=DisplayInfoContainer.OVERRIDE,
1515 value_list=override_value_list)
1516 override_type = event['data']['override']
1517 ad.log.info("Current Override Type is %s", override_type)
1518 return override_type
1519 except Empty:
1520 ad.log.info("No event for display info change")
1521 return -1
1522 finally:
1523 ad.droid.telephonyStopTrackingDisplayInfoChange()
1524 return -1
1525
1526
1527def is_current_network_5g_nsa(ad, timeout=30):
1528 """Verifies 5G NSA override network type
1529
1530 Args:
1531 ad: android device object.
1532 timeout: max time to wait for event
1533
1534 Returns:
1535 True: if data is on 5g NSA
1536 False: if data is not on 5g NSA
1537 """
1538 ad.ed.clear_events(EventDisplayInfoChanged)
1539 ad.droid.telephonyStartTrackingDisplayInfoChange()
1540 try:
1541 event = ad.ed.wait_for_event(
1542 EventDisplayInfoChanged,
1543 is_event_match,
1544 timeout=timeout,
1545 field=DisplayInfoContainer.OVERRIDE,
1546 value=OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA)
1547 ad.log.info("Got expected event %s", event)
1548 return True
1549 except Empty:
1550 ad.log.info("No event for display info change")
1551 return False
1552 finally:
1553 ad.droid.telephonyStopTrackingDisplayInfoChange()
1554 return None
1555
1556
Ang Li73697b32015-12-03 00:41:53 +00001557def disconnect_call_by_id(log, ad, call_id):
1558 """Disconnect call by call id.
1559 """
1560 ad.droid.telecomCallDisconnect(call_id)
1561 return True
1562
Nathan Harold54c7c742016-08-04 19:40:44 -07001563
Yang Liu3197de22016-04-11 13:59:41 -07001564def _phone_number_remove_prefix(number):
1565 """Remove the country code and other prefix from the input phone number.
1566 Currently only handle phone number with the following formats:
1567 (US phone number format)
1568 +1abcxxxyyyy
1569 1abcxxxyyyy
1570 abcxxxyyyy
1571 abc xxx yyyy
1572 abc.xxx.yyyy
1573 abc-xxx-yyyy
1574 (EEUK phone number format)
1575 +44abcxxxyyyy
1576 0abcxxxyyyy
1577
1578 Args:
1579 number: input phone number
1580
1581 Returns:
1582 Phone number without country code or prefix
1583 """
Yang Liu8fcffd52016-05-31 18:38:35 -07001584 if number is None:
1585 return None, None
Betty Zhou9e54fc22017-01-19 12:15:53 -08001586 for country_code in COUNTRY_CODE_LIST:
Yang Liu3197de22016-04-11 13:59:41 -07001587 if number.startswith(country_code):
1588 return number[len(country_code):], country_code
1589 if number[0] == "1" or number[0] == "0":
1590 return number[1:], None
Yang Liu8fcffd52016-05-31 18:38:35 -07001591 return number, None
Yang Liu3197de22016-04-11 13:59:41 -07001592
Nathan Harold123c9da2015-12-30 16:33:25 -08001593
Ang Li73697b32015-12-03 00:41:53 +00001594def check_phone_number_match(number1, number2):
1595 """Check whether two input phone numbers match or not.
1596
1597 Compare the two input phone numbers.
1598 If they match, return True; otherwise, return False.
1599 Currently only handle phone number with the following formats:
1600 (US phone number format)
1601 +1abcxxxyyyy
1602 1abcxxxyyyy
1603 abcxxxyyyy
1604 abc xxx yyyy
1605 abc.xxx.yyyy
1606 abc-xxx-yyyy
Yang Liu3197de22016-04-11 13:59:41 -07001607 (EEUK phone number format)
1608 +44abcxxxyyyy
1609 0abcxxxyyyy
1610
1611 There are some scenarios we can not verify, one example is:
1612 number1 = +15555555555, number2 = 5555555555
1613 (number2 have no country code)
Ang Li73697b32015-12-03 00:41:53 +00001614
1615 Args:
1616 number1: 1st phone number to be compared.
1617 number2: 2nd phone number to be compared.
1618
1619 Returns:
1620 True if two phone numbers match. Otherwise False.
1621 """
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001622 number1 = phone_number_formatter(number1)
1623 number2 = phone_number_formatter(number2)
Betty Zhou9e54fc22017-01-19 12:15:53 -08001624 # Handle extra country code attachment when matching phone number
Betty Zhoue32dd3b2017-11-28 19:05:55 -08001625 if number1[-7:] in number2 or number2[-7:] in number1:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001626 return True
Betty Zhoud2da7ba2017-03-24 12:54:34 -07001627 else:
Betty Zhou9e54fc22017-01-19 12:15:53 -08001628 logging.info("phone number1 %s and number2 %s does not match" %
1629 (number1, number2))
1630 return False
Ang Li73697b32015-12-03 00:41:53 +00001631
1632
Betty Zhoubb192482017-03-01 14:38:56 -08001633def initiate_call(log,
1634 ad,
1635 callee_number,
1636 emergency=False,
1637 timeout=MAX_WAIT_TIME_CALL_INITIATION,
Betty Zhou1ffbc832018-05-08 19:02:56 -07001638 checking_interval=5,
Betty Zhou48557582018-05-14 13:19:23 -07001639 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
1640 video=False):
Ang Li73697b32015-12-03 00:41:53 +00001641 """Make phone call from caller to callee.
1642
1643 Args:
1644 ad_caller: Caller android device object.
1645 callee_number: Callee phone number.
1646 emergency : specify the call is emergency.
1647 Optional. Default value is False.
Betty Zhou1ffbc832018-05-08 19:02:56 -07001648 incall_ui_display: show the dialer UI foreground or backgroud
Betty Zhou48557582018-05-14 13:19:23 -07001649 video: whether to initiate as video call
Ang Li73697b32015-12-03 00:41:53 +00001650
1651 Returns:
1652 result: if phone call is placed successfully.
1653 """
Betty Zhou287f9df2018-01-23 10:57:55 -08001654 ad.ed.clear_events(EventCallStateChanged)
Betty Zhoubb192482017-03-01 14:38:56 -08001655 sub_id = get_outgoing_voice_sub_id(ad)
Betty Zhou16e8e662018-05-08 18:26:18 -07001656 begin_time = get_device_epoch_time(ad)
Betty Zhoubb192482017-03-01 14:38:56 -08001657 ad.droid.telephonyStartTrackingCallStateForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00001658 try:
1659 # Make a Call
Betty Zhoubb192482017-03-01 14:38:56 -08001660 ad.log.info("Make a phone call to %s", callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001661 if emergency:
Betty Zhoubb192482017-03-01 14:38:56 -08001662 ad.droid.telecomCallEmergencyNumber(callee_number)
Ang Li73697b32015-12-03 00:41:53 +00001663 else:
Betty Zhou48557582018-05-14 13:19:23 -07001664 ad.droid.telecomCallNumber(callee_number, video)
Ang Li73697b32015-12-03 00:41:53 +00001665
Betty Zhou03bd3f92018-06-06 17:37:56 -07001666 # Verify OFFHOOK state
1667 if not wait_for_call_offhook_for_subscription(
1668 log, ad, sub_id, event_tracking_started=True):
1669 ad.log.info("sub_id %s not in call offhook state", sub_id)
1670 last_call_drop_reason(ad, begin_time=begin_time)
1671 return False
1672 else:
1673 return True
Ang Li73697b32015-12-03 00:41:53 +00001674 finally:
Sarah Boechat2be72ce2019-09-27 12:21:27 -07001675 if hasattr(ad, "sdm_log") and getattr(ad, "sdm_log"):
1676 ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
1677 ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
Betty Zhoubb192482017-03-01 14:38:56 -08001678 ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
Betty Zhou1ffbc832018-05-08 19:02:56 -07001679 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
1680 ad.droid.telecomShowInCallScreen()
1681 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
1682 ad.droid.showHomeScreen()
Ang Li73697b32015-12-03 00:41:53 +00001683
Nathan Harold123c9da2015-12-30 16:33:25 -08001684
Betty Zhou8da03782017-07-28 18:02:24 -07001685def dial_phone_number(ad, callee_number):
1686 for number in str(callee_number):
1687 if number == "#":
1688 ad.send_keycode("POUND")
1689 elif number == "*":
1690 ad.send_keycode("STAR")
1691 elif number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]:
1692 ad.send_keycode("%s" % number)
1693
1694
1695def get_call_state_by_adb(ad):
Markus Liuf3410172019-08-06 19:40:32 +08001696 slot_index_of_default_voice_subid = get_slot_index_from_subid(ad.log, ad,
1697 get_incoming_voice_sub_id(ad))
1698 output = ad.adb.shell("dumpsys telephony.registry | grep mCallState")
1699 if "mCallState" in output:
1700 call_state_list = re.findall("mCallState=(\d)", output)
1701 if call_state_list:
1702 return call_state_list[slot_index_of_default_voice_subid]
Betty Zhou8da03782017-07-28 18:02:24 -07001703
1704
1705def check_call_state_connected_by_adb(ad):
1706 return "2" in get_call_state_by_adb(ad)
1707
1708
1709def check_call_state_idle_by_adb(ad):
1710 return "0" in get_call_state_by_adb(ad)
1711
1712
1713def check_call_state_ring_by_adb(ad):
1714 return "1" in get_call_state_by_adb(ad)
1715
1716
1717def get_incoming_call_number_by_adb(ad):
1718 output = ad.adb.shell(
1719 "dumpsys telephony.registry | grep mCallIncomingNumber")
1720 return re.search(r"mCallIncomingNumber=(.*)", output).group(1)
1721
1722
1723def emergency_dialer_call_by_keyevent(ad, callee_number):
1724 for i in range(3):
1725 if "EmergencyDialer" in ad.get_my_current_focus_window():
1726 ad.log.info("EmergencyDialer is the current focus window")
1727 break
1728 elif i <= 2:
1729 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
1730 time.sleep(1)
1731 else:
1732 ad.log.error("Unable to bring up EmergencyDialer")
1733 return False
1734 ad.log.info("Make a phone call to %s", callee_number)
1735 dial_phone_number(ad, callee_number)
1736 ad.send_keycode("CALL")
1737
1738
1739def initiate_emergency_dialer_call_by_adb(
1740 log,
1741 ad,
1742 callee_number,
1743 timeout=MAX_WAIT_TIME_CALL_INITIATION,
1744 checking_interval=5):
1745 """Make emergency call by EmergencyDialer.
1746
1747 Args:
1748 ad: Caller android device object.
1749 callee_number: Callee phone number.
1750 emergency : specify the call is emergency.
1751 Optional. Default value is False.
1752
1753 Returns:
1754 result: if phone call is placed successfully.
1755 """
1756 try:
1757 # Make a Call
1758 ad.wakeup_screen()
Betty Zhou3c2e2542018-02-21 12:23:04 -08001759 ad.send_keycode("MENU")
Betty Zhou8da03782017-07-28 18:02:24 -07001760 ad.log.info("Call %s", callee_number)
Betty Zhou4617cba2017-08-10 11:58:39 -07001761 ad.adb.shell("am start -a com.android.phone.EmergencyDialer.DIAL")
Betty Zhou8da03782017-07-28 18:02:24 -07001762 ad.adb.shell(
1763 "am start -a android.intent.action.CALL_EMERGENCY -d tel:%s" %
1764 callee_number)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001765 if not timeout: return True
Betty Zhou8da03782017-07-28 18:02:24 -07001766 ad.log.info("Check call state")
1767 # Verify Call State
1768 elapsed_time = 0
1769 while elapsed_time < timeout:
1770 time.sleep(checking_interval)
1771 elapsed_time += checking_interval
1772 if check_call_state_connected_by_adb(ad):
1773 ad.log.info("Call to %s is connected", callee_number)
1774 return True
Betty Zhou13e7adf2017-09-06 14:01:10 -07001775 if check_call_state_idle_by_adb(ad):
1776 ad.log.info("Call to %s failed", callee_number)
1777 return False
Betty Zhou8da03782017-07-28 18:02:24 -07001778 ad.log.info("Make call to %s failed", callee_number)
1779 return False
1780 except Exception as e:
1781 ad.log.error("initiate emergency call failed with error %s", e)
1782
1783
Betty Zhoucbda4122018-01-16 19:15:42 -08001784def hangup_call_by_adb(ad):
Betty Zhou8da03782017-07-28 18:02:24 -07001785 """Make emergency call by EmergencyDialer.
1786
1787 Args:
1788 ad: Caller android device object.
1789 callee_number: Callee phone number.
1790 """
1791 ad.log.info("End call by adb")
1792 ad.send_keycode("ENDCALL")
1793
1794
Betty Zhouf7da39e2018-04-16 16:28:58 -07001795def dumpsys_all_call_info(ad):
Betty Zhoudd781f82017-08-08 14:46:23 -07001796 """ Get call information by dumpsys telecom. """
Betty Zhou8da03782017-07-28 18:02:24 -07001797 output = ad.adb.shell("dumpsys telecom")
1798 calls = re.findall("Call TC@\d+: {(.*?)}", output, re.DOTALL)
1799 calls_info = []
1800 for call in calls:
1801 call_info = {}
Betty Zhoudd781f82017-08-08 14:46:23 -07001802 for attr in ("startTime", "endTime", "direction", "isInterrupted",
Betty Zhou8da03782017-07-28 18:02:24 -07001803 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001804 "connectionService", "isVideoCall", "callProperties"):
Betty Zhou8da03782017-07-28 18:02:24 -07001805 match = re.search(r"%s: (.*)" % attr, call)
1806 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001807 if attr in ("startTime", "endTime"):
1808 call_info[attr] = epoch_to_log_line_timestamp(
1809 int(match.group(1)))
1810 else:
1811 call_info[attr] = match.group(1)
Betty Zhou8da03782017-07-28 18:02:24 -07001812 call_info["inCallServices"] = re.findall(r"name: (.*)", call)
1813 calls_info.append(call_info)
1814 ad.log.debug("calls_info = %s", calls_info)
1815 return calls_info
1816
1817
Betty Zhouf7da39e2018-04-16 16:28:58 -07001818def dumpsys_last_call_info(ad):
1819 """ Get call information by dumpsys telecom. """
1820 num = dumpsys_last_call_number(ad)
1821 output = ad.adb.shell("dumpsys telecom")
1822 result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL)
Betty Zhou739d6b72018-04-18 10:38:53 -07001823 call_info = {"TC": num}
Betty Zhouf7da39e2018-04-16 16:28:58 -07001824 if result:
1825 result = result.group(1)
1826 for attr in ("startTime", "endTime", "direction", "isInterrupted",
1827 "callTechnologies", "callTerminationsReason",
Betty Zhou739d6b72018-04-18 10:38:53 -07001828 "isVideoCall", "callProperties"):
Betty Zhouf7da39e2018-04-16 16:28:58 -07001829 match = re.search(r"%s: (.*)" % attr, result)
1830 if match:
Betty Zhou739d6b72018-04-18 10:38:53 -07001831 if attr in ("startTime", "endTime"):
1832 call_info[attr] = epoch_to_log_line_timestamp(
1833 int(match.group(1)))
1834 else:
1835 call_info[attr] = match.group(1)
Betty Zhouf7da39e2018-04-16 16:28:58 -07001836 ad.log.debug("call_info = %s", call_info)
1837 return call_info
1838
1839
1840def dumpsys_last_call_number(ad):
1841 output = ad.adb.shell("dumpsys telecom")
1842 call_nums = re.findall("Call TC@(\d+):", output)
1843 if not call_nums:
1844 return 0
1845 else:
1846 return int(call_nums[-1])
1847
1848
Betty Zhoufe726dc2018-04-25 19:31:33 -07001849def dumpsys_new_call_info(ad, last_tc_number, retries=3, interval=5):
1850 for i in range(retries):
1851 if dumpsys_last_call_number(ad) > last_tc_number:
1852 call_info = dumpsys_last_call_info(ad)
1853 ad.log.info("New call info = %s", sorted(call_info.items()))
1854 return call_info
1855 else:
1856 time.sleep(interval)
1857 ad.log.error("New call is not in sysdump telecom")
1858 return {}
1859
1860
Betty Zhou8aafcc12018-05-01 20:54:15 -07001861def dumpsys_carrier_config(ad):
Markus Liuf3410172019-08-06 19:40:32 +08001862 output = ad.adb.shell("dumpsys carrier_config").split("\n")
1863 output_phone_id_0 = []
1864 output_phone_id_1 = []
1865 current_output = []
1866 for line in output:
1867 if "Phone Id = 0" in line:
1868 current_output = output_phone_id_0
1869 elif "Phone Id = 1" in line:
1870 current_output = output_phone_id_1
1871 current_output.append(line.strip())
1872
Betty Zhou8aafcc12018-05-01 20:54:15 -07001873 configs = {}
Jaineel64b4ce92019-08-20 14:17:43 -07001874 if ad.adb.getprop("ro.build.version.release")[0] in ("9", "P"):
1875 phone_count = 1
1876 if "," in ad.adb.getprop("gsm.network.type"):
1877 phone_count = 2
1878 else:
1879 phone_count = ad.droid.telephonyGetPhoneCount()
1880
Markus Liuf3410172019-08-06 19:40:32 +08001881 slot_0_subid = get_subid_from_slot_index(ad.log, ad, 0)
1882 if slot_0_subid != INVALID_SUB_ID:
1883 configs[slot_0_subid] = {}
1884
1885 if phone_count == 2:
1886 slot_1_subid = get_subid_from_slot_index(ad.log, ad, 1)
1887 if slot_1_subid != INVALID_SUB_ID:
1888 configs[slot_1_subid] = {}
1889
Betty Zhou8aafcc12018-05-01 20:54:15 -07001890 attrs = [attr for attr in dir(CarrierConfigs) if not attr.startswith("__")]
1891 for attr in attrs:
1892 attr_string = getattr(CarrierConfigs, attr)
Markus Liuf3410172019-08-06 19:40:32 +08001893 values = re.findall(
1894 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_0))
1895
1896 if slot_0_subid != INVALID_SUB_ID:
1897 if values:
1898 value = values[-1]
1899 if value == "true":
1900 configs[slot_0_subid][attr_string] = True
1901 elif value == "false":
1902 configs[slot_0_subid][attr_string] = False
1903 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT:
1904 if value == "0":
1905 configs[slot_0_subid][attr_string] = WFC_MODE_WIFI_ONLY
1906 elif value == "1":
1907 configs[slot_0_subid][attr_string] = \
1908 WFC_MODE_CELLULAR_PREFERRED
1909 elif value == "2":
1910 configs[slot_0_subid][attr_string] = \
1911 WFC_MODE_WIFI_PREFERRED
1912 else:
1913 try:
1914 configs[slot_0_subid][attr_string] = int(value)
1915 except Exception:
1916 configs[slot_0_subid][attr_string] = value
Betty Zhou8aafcc12018-05-01 20:54:15 -07001917 else:
Markus Liuf3410172019-08-06 19:40:32 +08001918 configs[slot_0_subid][attr_string] = None
1919
1920 if phone_count == 2:
1921 if slot_1_subid != INVALID_SUB_ID:
1922 values = re.findall(
1923 r"%s = (\S+)" % attr_string, "\n".join(output_phone_id_1))
1924 if values:
1925 value = values[-1]
1926 if value == "true":
1927 configs[slot_1_subid][attr_string] = True
1928 elif value == "false":
1929 configs[slot_1_subid][attr_string] = False
1930 elif attr_string == CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT:
1931 if value == "0":
1932 configs[slot_1_subid][attr_string] = \
1933 WFC_MODE_WIFI_ONLY
1934 elif value == "1":
1935 configs[slot_1_subid][attr_string] = \
1936 WFC_MODE_CELLULAR_PREFERRED
1937 elif value == "2":
1938 configs[slot_1_subid][attr_string] = \
1939 WFC_MODE_WIFI_PREFERRED
1940 else:
1941 try:
1942 configs[slot_1_subid][attr_string] = int(value)
1943 except Exception:
1944 configs[slot_1_subid][attr_string] = value
1945 else:
1946 configs[slot_1_subid][attr_string] = None
Betty Zhou8aafcc12018-05-01 20:54:15 -07001947 return configs
1948
1949
1950def get_phone_capability(ad):
Betty Zhou8aafcc12018-05-01 20:54:15 -07001951 carrier_configs = dumpsys_carrier_config(ad)
Markus Liuf3410172019-08-06 19:40:32 +08001952 for sub_id in carrier_configs:
1953 capabilities = []
1954 if carrier_configs[sub_id][CarrierConfigs.VOLTE_AVAILABLE_BOOL]:
1955 capabilities.append(CAPABILITY_VOLTE)
1956 if carrier_configs[sub_id][CarrierConfigs.WFC_IMS_AVAILABLE_BOOL]:
1957 capabilities.append(CAPABILITY_WFC)
1958 if carrier_configs[sub_id][CarrierConfigs.EDITABLE_WFC_MODE_BOOL]:
1959 capabilities.append(CAPABILITY_WFC_MODE_CHANGE)
1960 if carrier_configs[sub_id][CarrierConfigs.SUPPORT_CONFERENCE_CALL_BOOL]:
1961 capabilities.append(CAPABILITY_CONFERENCE)
1962 if carrier_configs[sub_id][CarrierConfigs.VT_AVAILABLE_BOOL]:
1963 capabilities.append(CAPABILITY_VT)
1964 if carrier_configs[sub_id][CarrierConfigs.VOLTE_PROVISIONED_BOOL]:
1965 capabilities.append(CAPABILITY_VOLTE_PROVISIONING)
1966 if carrier_configs[sub_id][CarrierConfigs.VOLTE_OVERRIDE_WFC_BOOL]:
1967 capabilities.append(CAPABILITY_VOLTE_OVERRIDE_WFC_PROVISIONING)
Markus Liu2cf8d0b2019-10-04 11:13:17 +08001968 if carrier_configs[sub_id][CarrierConfigs.HIDE_ENHANCED_4G_LTE_BOOL]:
1969 capabilities.append(CAPABILITY_HIDE_ENHANCED_4G_LTE_BOOL)
1970
Markus Liuf3410172019-08-06 19:40:32 +08001971 ad.log.info("Capabilities of sub ID %s: %s", sub_id, capabilities)
1972 if not getattr(ad, 'telephony', {}):
1973 ad.telephony["subscription"] = {}
1974 ad.telephony["subscription"][sub_id] = {}
1975 setattr(
1976 ad.telephony["subscription"][sub_id],
1977 'capabilities', capabilities)
1978
Betty Zhou4418a332018-05-15 13:11:18 -07001979 else:
Markus Liuf3410172019-08-06 19:40:32 +08001980 ad.telephony["subscription"][sub_id]["capabilities"] = capabilities
1981 if CAPABILITY_WFC not in capabilities:
1982 wfc_modes = []
1983 else:
1984 if carrier_configs[sub_id].get(
1985 CarrierConfigs.EDITABLE_WFC_MODE_BOOL, False):
1986 wfc_modes = [
1987 WFC_MODE_CELLULAR_PREFERRED,
1988 WFC_MODE_WIFI_PREFERRED]
1989 else:
1990 wfc_modes = [
1991 carrier_configs[sub_id].get(
1992 CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT,
1993 WFC_MODE_CELLULAR_PREFERRED)
1994 ]
1995 if carrier_configs[sub_id].get(
1996 CarrierConfigs.WFC_SUPPORTS_WIFI_ONLY_BOOL,
1997 False) and WFC_MODE_WIFI_ONLY not in wfc_modes:
1998 wfc_modes.append(WFC_MODE_WIFI_ONLY)
1999 ad.telephony["subscription"][sub_id]["wfc_modes"] = wfc_modes
2000 if wfc_modes:
2001 ad.log.info("Supported WFC modes for sub ID %s: %s", sub_id,
2002 wfc_modes)
2003
2004
2005def get_capability_for_subscription(ad, capability, subid):
2006 if capability in ad.telephony["subscription"][subid].get(
2007 "capabilities", []):
2008 ad.log.info('Capability "%s" is available for sub ID %s.',
2009 capability, subid)
2010 return True
2011 else:
2012 ad.log.info('Capability "%s" is NOT available for sub ID %s.',
2013 capability, subid)
2014 return False
Betty Zhou8aafcc12018-05-01 20:54:15 -07002015
2016
Yang Liu598b93d2016-03-22 17:07:59 -07002017def call_reject(log, ad_caller, ad_callee, reject=True):
2018 """Caller call Callee, then reject on callee.
2019
2020
2021 """
2022 subid_caller = ad_caller.droid.subscriptionGetDefaultVoiceSubId()
2023 subid_callee = ad_callee.incoming_voice_sub_id
Betty Zhoua37acd32017-02-23 20:04:24 -08002024 ad_caller.log.info("Sub-ID Caller %s, Sub-ID Callee %s", subid_caller,
2025 subid_callee)
Yang Liu598b93d2016-03-22 17:07:59 -07002026 return call_reject_for_subscription(log, ad_caller, ad_callee,
2027 subid_caller, subid_callee, reject)
2028
2029
2030def call_reject_for_subscription(log,
2031 ad_caller,
2032 ad_callee,
2033 subid_caller,
2034 subid_callee,
2035 reject=True):
2036 """
2037 """
2038
Betty Zhou3b2de072018-03-15 16:46:26 -07002039 caller_number = ad_caller.telephony['subscription'][subid_caller][
2040 'phone_num']
2041 callee_number = ad_callee.telephony['subscription'][subid_callee][
2042 'phone_num']
Yang Liu598b93d2016-03-22 17:07:59 -07002043
Betty Zhoua37acd32017-02-23 20:04:24 -08002044 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Betty Zhou48557582018-05-14 13:19:23 -07002045 if not initiate_call(log, ad_caller, callee_number):
2046 ad_caller.log.error("Initiate call failed")
Yang Liu598b93d2016-03-22 17:07:59 -07002047 return False
Betty Zhou48557582018-05-14 13:19:23 -07002048
2049 if not wait_and_reject_call_for_subscription(
2050 log, ad_callee, subid_callee, caller_number, WAIT_TIME_REJECT_CALL,
2051 reject):
2052 ad_callee.log.error("Reject call fail.")
2053 return False
2054 # Check if incoming call is cleared on callee or not.
2055 if ad_callee.droid.telephonyGetCallStateForSubscription(
2056 subid_callee) == TELEPHONY_STATE_RINGING:
2057 ad_callee.log.error("Incoming call is not cleared")
2058 return False
2059 # Hangup on caller
2060 hangup_call(log, ad_caller)
Yang Liu598b93d2016-03-22 17:07:59 -07002061 return True
2062
2063
Nathan Harold123c9da2015-12-30 16:33:25 -08002064def call_reject_leave_message(log,
2065 ad_caller,
2066 ad_callee,
2067 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08002068 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00002069 """On default voice subscription, Call from caller to callee,
2070 reject on callee, caller leave a voice mail.
2071
2072 1. Caller call Callee.
2073 2. Callee reject incoming call.
2074 3. Caller leave a voice mail.
2075 4. Verify callee received the voice mail notification.
2076
2077 Args:
2078 ad_caller: caller android device object.
2079 ad_callee: callee android device object.
2080 verify_caller_func: function to verify caller is in correct state while in-call.
2081 This is optional, default is None.
2082 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08002083 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00002084
2085 Returns:
2086 True: if voice message is received on callee successfully.
2087 False: for errors
2088 """
Yang Liu963c93c2016-04-05 10:52:00 -07002089 subid_caller = get_outgoing_voice_sub_id(ad_caller)
2090 subid_callee = get_incoming_voice_sub_id(ad_callee)
Nathan Harold123c9da2015-12-30 16:33:25 -08002091 return call_reject_leave_message_for_subscription(
2092 log, ad_caller, ad_callee, subid_caller, subid_callee,
2093 verify_caller_func, wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00002094
Nathan Harold123c9da2015-12-30 16:33:25 -08002095
ju8230cef2020-07-29 09:48:02 -07002096def check_reject_needed_for_voice_mail(log, ad_callee):
2097 """Check if the carrier requires reject call to receive voice mail or just keep ringing
2098 Requested in b//155935290
2099 Four Japan carriers do not need to reject
2100 SBM, KDDI, Ntt Docomo, Rakuten
2101 Args:
2102 log: log object
2103 ad_callee: android device object
2104 Returns:
2105 True if callee's carrier is not one of the four Japan carriers
2106 False if callee's carrier is one of the four Japan carriers
2107 """
2108
2109 operators_no_reject = [CARRIER_NTT_DOCOMO,
2110 CARRIER_KDDI,
2111 CARRIER_RAKUTEN,
2112 CARRIER_SBM]
2113 operator_name = get_operator_name(log, ad_callee)
2114
2115 return operator_name not in operators_no_reject
2116
2117
Nathan Harold123c9da2015-12-30 16:33:25 -08002118def call_reject_leave_message_for_subscription(
2119 log,
2120 ad_caller,
2121 ad_callee,
2122 subid_caller,
2123 subid_callee,
2124 verify_caller_func=None,
Yang Liudf164e32016-01-07 16:49:32 -08002125 wait_time_in_call=WAIT_TIME_LEAVE_VOICE_MAIL):
Ang Li73697b32015-12-03 00:41:53 +00002126 """On specific voice subscription, Call from caller to callee,
2127 reject on callee, caller leave a voice mail.
2128
2129 1. Caller call Callee.
2130 2. Callee reject incoming call.
2131 3. Caller leave a voice mail.
2132 4. Verify callee received the voice mail notification.
2133
2134 Args:
2135 ad_caller: caller android device object.
2136 ad_callee: callee android device object.
2137 subid_caller: caller's subscription id.
2138 subid_callee: callee's subscription id.
2139 verify_caller_func: function to verify caller is in correct state while in-call.
2140 This is optional, default is None.
2141 wait_time_in_call: time to wait when leaving a voice mail.
Yang Liudf164e32016-01-07 16:49:32 -08002142 This is optional, default is WAIT_TIME_LEAVE_VOICE_MAIL
Ang Li73697b32015-12-03 00:41:53 +00002143
2144 Returns:
2145 True: if voice message is received on callee successfully.
2146 False: for errors
2147 """
Nathan Harold123c9da2015-12-30 16:33:25 -08002148
Ang Li73697b32015-12-03 00:41:53 +00002149 # Currently this test utility only works for TMO and ATT and SPT.
2150 # It does not work for VZW (see b/21559800)
2151 # "with VVM TelephonyManager APIs won't work for vm"
2152
Betty Zhou3b2de072018-03-15 16:46:26 -07002153 caller_number = ad_caller.telephony['subscription'][subid_caller][
2154 'phone_num']
2155 callee_number = ad_callee.telephony['subscription'][subid_callee][
2156 'phone_num']
Ang Li73697b32015-12-03 00:41:53 +00002157
Betty Zhoua37acd32017-02-23 20:04:24 -08002158 ad_caller.log.info("Call from %s to %s", caller_number, callee_number)
Ang Li73697b32015-12-03 00:41:53 +00002159
2160 try:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002161 voice_mail_count_before = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
2162 subid_callee)
2163 ad_callee.log.info("voice mail count is %s", voice_mail_count_before)
2164 # -1 means there are unread voice mail, but the count is unknown
2165 # 0 means either this API not working (VZW) or no unread voice mail.
2166 if voice_mail_count_before != 0:
2167 log.warning("--Pending new Voice Mail, please clear on phone.--")
Ang Li73697b32015-12-03 00:41:53 +00002168
2169 if not initiate_call(log, ad_caller, callee_number):
Betty Zhou48557582018-05-14 13:19:23 -07002170 ad_caller.log.error("Initiate call failed.")
2171 return False
ju8230cef2020-07-29 09:48:02 -07002172 if check_reject_needed_for_voice_mail(log, ad_callee):
2173 carrier_specific_delay_reject = 30
2174 else:
2175 carrier_specific_delay_reject = 2
2176 carrier_reject_call = not check_reject_needed_for_voice_mail(log, ad_callee)
Ang Li73697b32015-12-03 00:41:53 +00002177
2178 if not wait_and_reject_call_for_subscription(
ju8230cef2020-07-29 09:48:02 -07002179 log, ad_callee, subid_callee, incoming_number=caller_number, delay_reject=carrier_specific_delay_reject,
2180 reject=carrier_reject_call):
Betty Zhou48557582018-05-14 13:19:23 -07002181 ad_callee.log.error("Reject call fail.")
2182 return False
Ang Li73697b32015-12-03 00:41:53 +00002183
Yang Liuaed3eef2015-12-15 18:40:25 -08002184 ad_callee.droid.telephonyStartTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002185 subid_callee)
Ang Li73697b32015-12-03 00:41:53 +00002186
2187 # ensure that all internal states are updated in telecom
2188 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Markus Liu35df2bc2018-11-09 11:14:01 +08002189 ad_callee.ed.clear_events(EventCallStateChanged)
Ang Li73697b32015-12-03 00:41:53 +00002190
2191 if verify_caller_func and not verify_caller_func(log, ad_caller):
Betty Zhou48557582018-05-14 13:19:23 -07002192 ad_caller.log.error("Caller not in correct state!")
2193 return False
Ang Li73697b32015-12-03 00:41:53 +00002194
Yang Liu7a2e7ee2015-12-28 15:32:44 -08002195 # TODO: b/26293512 Need to play some sound to leave message.
2196 # Otherwise carrier voice mail server may drop this voice mail.
Ang Li73697b32015-12-03 00:41:53 +00002197 time.sleep(wait_time_in_call)
2198
2199 if not verify_caller_func:
2200 caller_state_result = ad_caller.droid.telecomIsInCall()
2201 else:
2202 caller_state_result = verify_caller_func(log, ad_caller)
2203 if not caller_state_result:
Betty Zhou48557582018-05-14 13:19:23 -07002204 ad_caller.log.error("Caller not in correct state after %s seconds",
2205 wait_time_in_call)
Ang Li73697b32015-12-03 00:41:53 +00002206
2207 if not hangup_call(log, ad_caller):
Betty Zhou48557582018-05-14 13:19:23 -07002208 ad_caller.log.error("Error in Hanging-Up Call")
2209 return False
Ang Li73697b32015-12-03 00:41:53 +00002210
Betty Zhou48557582018-05-14 13:19:23 -07002211 ad_callee.log.info("Wait for voice mail indicator on callee.")
Ang Li73697b32015-12-03 00:41:53 +00002212 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08002213 event = ad_callee.ed.wait_for_event(
2214 EventMessageWaitingIndicatorChanged,
2215 _is_on_message_waiting_event_true)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07002216 ad_callee.log.info("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00002217 except Empty:
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002218 ad_callee.log.warning("No expected event %s",
2219 EventMessageWaitingIndicatorChanged)
Betty Zhou48557582018-05-14 13:19:23 -07002220 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08002221 voice_mail_count_after = ad_callee.droid.telephonyGetVoiceMailCountForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002222 subid_callee)
Betty Zhoua37acd32017-02-23 20:04:24 -08002223 ad_callee.log.info(
2224 "telephonyGetVoiceMailCount output - before: %s, after: %s",
2225 voice_mail_count_before, voice_mail_count_after)
Ang Li73697b32015-12-03 00:41:53 +00002226
2227 # voice_mail_count_after should:
2228 # either equals to (voice_mail_count_before + 1) [For ATT and SPT]
2229 # or equals to -1 [For TMO]
2230 # -1 means there are unread voice mail, but the count is unknown
Nathan Harold123c9da2015-12-30 16:33:25 -08002231 if not check_voice_mail_count(log, ad_callee, voice_mail_count_before,
Ang Li73697b32015-12-03 00:41:53 +00002232 voice_mail_count_after):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002233 log.error("before and after voice mail count is not incorrect.")
Ang Li73697b32015-12-03 00:41:53 +00002234 return False
Ang Li73697b32015-12-03 00:41:53 +00002235 finally:
Yang Liuaed3eef2015-12-15 18:40:25 -08002236 ad_callee.droid.telephonyStopTrackingVoiceMailStateChangeForSubscription(
Ang Li73697b32015-12-03 00:41:53 +00002237 subid_callee)
2238 return True
2239
Nathan Harold123c9da2015-12-30 16:33:25 -08002240
Ang Li73697b32015-12-03 00:41:53 +00002241def call_voicemail_erase_all_pending_voicemail(log, ad):
2242 """Script for phone to erase all pending voice mail.
2243 This script only works for TMO and ATT and SPT currently.
2244 This script only works if phone have already set up voice mail options,
2245 and phone should disable password protection for voice mail.
2246
2247 1. If phone don't have pending voice message, return True.
2248 2. Dial voice mail number.
2249 For TMO, the number is '123'
2250 For ATT, the number is phone's number
2251 For SPT, the number is phone's number
2252 3. Wait for voice mail connection setup.
2253 4. Wait for voice mail play pending voice message.
2254 5. Send DTMF to delete one message.
2255 The digit is '7'.
2256 6. Repeat steps 4 and 5 until voice mail server drop this call.
2257 (No pending message)
Yang Liuaed3eef2015-12-15 18:40:25 -08002258 6. Check telephonyGetVoiceMailCount result. it should be 0.
Ang Li73697b32015-12-03 00:41:53 +00002259
2260 Args:
2261 log: log object
2262 ad: android device object
2263 Returns:
2264 False if error happens. True is succeed.
2265 """
2266 log.info("Erase all pending voice mail.")
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002267 count = ad.droid.telephonyGetVoiceMailCount()
2268 if count == 0:
2269 ad.log.info("No Pending voice mail.")
Ang Li73697b32015-12-03 00:41:53 +00002270 return True
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002271 if count == -1:
2272 ad.log.info("There is pending voice mail, but the count is unknown")
2273 count = MAX_SAVED_VOICE_MAIL
2274 else:
2275 ad.log.info("There are %s voicemails", count)
Ang Li73697b32015-12-03 00:41:53 +00002276
2277 voice_mail_number = get_voice_mail_number(log, ad)
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002278 delete_digit = get_voice_mail_delete_digit(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00002279 if not initiate_call(log, ad, voice_mail_number):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002280 log.error("Initiate call to voice mail failed.")
Ang Li73697b32015-12-03 00:41:53 +00002281 return False
Yang Liudf164e32016-01-07 16:49:32 -08002282 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00002283 callId = ad.droid.telecomCallGetCallIds()[0]
Yang Liudf164e32016-01-07 16:49:32 -08002284 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Nathan Harold123c9da2015-12-30 16:33:25 -08002285 while (is_phone_in_call(log, ad) and (count > 0)):
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002286 ad.log.info("Press %s to delete voice mail.", delete_digit)
2287 ad.droid.telecomCallPlayDtmfTone(callId, delete_digit)
Ang Li73697b32015-12-03 00:41:53 +00002288 ad.droid.telecomCallStopDtmfTone(callId)
Yang Liudf164e32016-01-07 16:49:32 -08002289 time.sleep(WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE)
Ang Li73697b32015-12-03 00:41:53 +00002290 count -= 1
Betty Zhoua6c82eb2017-04-13 18:09:03 -07002291 if is_phone_in_call(log, ad):
2292 hangup_call(log, ad)
2293
Yang Liuaed3eef2015-12-15 18:40:25 -08002294 # wait for telephonyGetVoiceMailCount to update correct result
Yang Liudf164e32016-01-07 16:49:32 -08002295 remaining_time = MAX_WAIT_TIME_VOICE_MAIL_COUNT
Betty Zhouee311052017-12-19 13:09:56 -08002296 while ((remaining_time > 0)
2297 and (ad.droid.telephonyGetVoiceMailCount() != 0)):
Ang Li73697b32015-12-03 00:41:53 +00002298 time.sleep(1)
2299 remaining_time -= 1
Yang Liuaed3eef2015-12-15 18:40:25 -08002300 current_voice_mail_count = ad.droid.telephonyGetVoiceMailCount()
Betty Zhoua37acd32017-02-23 20:04:24 -08002301 ad.log.info("telephonyGetVoiceMailCount: %s", current_voice_mail_count)
Ang Li73697b32015-12-03 00:41:53 +00002302 return (current_voice_mail_count == 0)
2303
Nathan Harold123c9da2015-12-30 16:33:25 -08002304
Ang Li73697b32015-12-03 00:41:53 +00002305def _is_on_message_waiting_event_true(event):
2306 """Private function to return if the received EventMessageWaitingIndicatorChanged
Yang Liudc8564b2016-01-27 14:15:37 -08002307 event MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING field is True.
Ang Li73697b32015-12-03 00:41:53 +00002308 """
Yang Liudc8564b2016-01-27 14:15:37 -08002309 return event['data'][MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING]
Ang Li73697b32015-12-03 00:41:53 +00002310
Nathan Harold123c9da2015-12-30 16:33:25 -08002311
2312def call_setup_teardown(log,
2313 ad_caller,
2314 ad_callee,
2315 ad_hangup=None,
2316 verify_caller_func=None,
2317 verify_callee_func=None,
2318 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07002319 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07002320 dialing_number_length=None,
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002321 video_state=None,
2322 slot_id_callee=None):
Ang Li73697b32015-12-03 00:41:53 +00002323 """ Call process, including make a phone call from caller,
2324 accept from callee, and hang up. The call is on default voice subscription
2325
2326 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08002327 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00002328
2329 Args:
2330 ad_caller: Caller Android Device Object.
2331 ad_callee: Callee Android Device Object.
2332 ad_hangup: Android Device Object end the phone call.
2333 Optional. Default value is None, and phone call will continue.
2334 verify_call_mode_caller: func_ptr to verify caller in correct mode
2335 Optional. Default is None
2336 verify_call_mode_caller: func_ptr to verify caller in correct mode
2337 Optional. Default is None
2338 incall_ui_display: after answer the call, bring in-call UI to foreground or
2339 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2340 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2341 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2342 else, do nothing.
Betty Zhoued13b712018-05-02 19:40:10 -07002343 dialing_number_length: the number of digits used for dialing
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002344 slot_id_callee : the slot if of the callee to call to
Ang Li73697b32015-12-03 00:41:53 +00002345
2346 Returns:
2347 True if call process without any error.
2348 False if error happened.
2349
2350 """
Yang Liu963c93c2016-04-05 10:52:00 -07002351 subid_caller = get_outgoing_voice_sub_id(ad_caller)
Visweswara Kumar541c0c72018-09-05 12:53:31 -07002352 if slot_id_callee is None:
2353 subid_callee = get_incoming_voice_sub_id(ad_callee)
2354 else:
2355 subid_callee = get_subid_from_slot_index(log, ad_callee, slot_id_callee)
2356
Nathan Harold123c9da2015-12-30 16:33:25 -08002357 return call_setup_teardown_for_subscription(
2358 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
2359 verify_caller_func, verify_callee_func, wait_time_in_call,
Betty Zhou48557582018-05-14 13:19:23 -07002360 incall_ui_display, dialing_number_length, video_state)
Ang Li73697b32015-12-03 00:41:53 +00002361
2362
Nathan Harold123c9da2015-12-30 16:33:25 -08002363def call_setup_teardown_for_subscription(
2364 log,
2365 ad_caller,
2366 ad_callee,
2367 subid_caller,
2368 subid_callee,
2369 ad_hangup=None,
2370 verify_caller_func=None,
2371 verify_callee_func=None,
2372 wait_time_in_call=WAIT_TIME_IN_CALL,
Jaineelf08d6a22017-09-11 14:17:48 -07002373 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
Betty Zhou48557582018-05-14 13:19:23 -07002374 dialing_number_length=None,
2375 video_state=None):
Ang Li73697b32015-12-03 00:41:53 +00002376 """ Call process, including make a phone call from caller,
2377 accept from callee, and hang up. The call is on specified subscription
2378
2379 In call process, call from <droid_caller> to <droid_callee>,
Yang Liu855d5f82016-01-27 15:35:48 -08002380 accept the call, (optional)then hang up from <droid_hangup>.
Ang Li73697b32015-12-03 00:41:53 +00002381
2382 Args:
2383 ad_caller: Caller Android Device Object.
2384 ad_callee: Callee Android Device Object.
2385 subid_caller: Caller subscription ID
2386 subid_callee: Callee subscription ID
2387 ad_hangup: Android Device Object end the phone call.
2388 Optional. Default value is None, and phone call will continue.
2389 verify_call_mode_caller: func_ptr to verify caller in correct mode
2390 Optional. Default is None
2391 verify_call_mode_caller: func_ptr to verify caller in correct mode
2392 Optional. Default is None
2393 incall_ui_display: after answer the call, bring in-call UI to foreground or
2394 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2395 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2396 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2397 else, do nothing.
2398
2399 Returns:
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002400 TelResultWrapper which will evaluate as False if error.
Ang Li73697b32015-12-03 00:41:53 +00002401
2402 """
Betty Zhouf27f5482017-07-24 18:56:17 -07002403 CHECK_INTERVAL = 5
Betty Zhoua301c202018-02-13 15:11:47 -08002404 begin_time = get_current_epoch_time()
Betty Zhou74481722018-04-13 16:19:25 -07002405 if not verify_caller_func:
2406 verify_caller_func = is_phone_in_call
2407 if not verify_callee_func:
2408 verify_callee_func = is_phone_in_call
Nathan Harold123c9da2015-12-30 16:33:25 -08002409
Betty Zhou3b2de072018-03-15 16:46:26 -07002410 caller_number = ad_caller.telephony['subscription'][subid_caller][
2411 'phone_num']
2412 callee_number = ad_callee.telephony['subscription'][subid_callee][
2413 'phone_num']
2414 if dialing_number_length:
2415 skip_test = False
2416 trunc_position = 0 - int(dialing_number_length)
2417 try:
2418 caller_area_code = caller_number[:trunc_position]
2419 callee_area_code = callee_number[:trunc_position]
2420 callee_dial_number = callee_number[trunc_position:]
2421 except:
2422 skip_test = True
2423 if caller_area_code != callee_area_code:
2424 skip_test = True
2425 if skip_test:
2426 msg = "Cannot make call from %s to %s by %s digits" % (
2427 caller_number, callee_number, dialing_number_length)
2428 ad_caller.log.info(msg)
2429 raise signals.TestSkip(msg)
2430 else:
2431 callee_number = callee_dial_number
Ang Li73697b32015-12-03 00:41:53 +00002432
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002433 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
Betty Zhou628b98e2018-01-08 15:45:25 -08002434 msg = "Call from %s to %s" % (caller_number, callee_number)
Betty Zhou48557582018-05-14 13:19:23 -07002435 if video_state:
2436 msg = "Video %s" % msg
2437 video = True
2438 else:
2439 video = False
Betty Zhou628b98e2018-01-08 15:45:25 -08002440 if ad_hangup:
2441 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
2442 ad_caller.log.info(msg)
Ang Li73697b32015-12-03 00:41:53 +00002443
Betty Zhou0d774582018-03-01 17:46:44 -08002444 for ad in (ad_caller, ad_callee):
2445 call_ids = ad.droid.telecomCallGetCallIds()
2446 setattr(ad, "call_ids", call_ids)
Betty Zhou774ea542018-05-16 12:45:36 -07002447 if call_ids:
2448 ad.log.info("Pre-exist CallId %s before making call", call_ids)
Ang Li73697b32015-12-03 00:41:53 +00002449 try:
Betty Zhou2186ebc2018-05-09 16:50:26 -07002450 if not initiate_call(
Betty Zhou48557582018-05-14 13:19:23 -07002451 log,
2452 ad_caller,
2453 callee_number,
2454 incall_ui_display=incall_ui_display,
2455 video=video):
Betty Zhouf27f5482017-07-24 18:56:17 -07002456 ad_caller.log.error("Initiate call failed.")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002457 tel_result_wrapper.result_value = CallResult('INITIATE_FAILED')
2458 return tel_result_wrapper
Betty Zhou94023182017-06-07 18:02:14 -07002459 else:
2460 ad_caller.log.info("Caller initate call successfully")
Ang Li73697b32015-12-03 00:41:53 +00002461 if not wait_and_answer_call_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08002462 log,
2463 ad_callee,
2464 subid_callee,
2465 incoming_number=caller_number,
Betty Zhou2e01bc82017-03-17 10:55:57 -07002466 caller=ad_caller,
Betty Zhou48557582018-05-14 13:19:23 -07002467 incall_ui_display=incall_ui_display,
2468 video_state=video_state):
Betty Zhouf27f5482017-07-24 18:56:17 -07002469 ad_callee.log.error("Answer call fail.")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002470 tel_result_wrapper.result_value = CallResult(
2471 'NO_RING_EVENT_OR_ANSWER_FAILED')
2472 return tel_result_wrapper
Betty Zhou94023182017-06-07 18:02:14 -07002473 else:
2474 ad_callee.log.info("Callee answered the call successfully")
Ang Li73697b32015-12-03 00:41:53 +00002475
Betty Zhou74481722018-04-13 16:19:25 -07002476 for ad, call_func in zip([ad_caller, ad_callee],
2477 [verify_caller_func, verify_callee_func]):
Betty Zhou0d774582018-03-01 17:46:44 -08002478 call_ids = ad.droid.telecomCallGetCallIds()
Betty Zhou5dd53c02018-03-22 20:08:33 -07002479 new_call_ids = set(call_ids) - set(ad.call_ids)
2480 if not new_call_ids:
2481 ad.log.error(
2482 "No new call ids are found after call establishment")
Betty Zhouf25fdab2018-04-23 19:20:17 -07002483 ad.log.error("telecomCallGetCallIds returns %s",
2484 ad.droid.telecomCallGetCallIds())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002485 tel_result_wrapper.result_value = CallResult('NO_CALL_ID_FOUND')
Betty Zhou5dd53c02018-03-22 20:08:33 -07002486 for new_call_id in new_call_ids:
2487 if not wait_for_in_call_active(ad, call_id=new_call_id):
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002488 tel_result_wrapper.result_value = CallResult(
2489 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
Betty Zhou8aafcc12018-05-01 20:54:15 -07002490 else:
2491 ad.log.info("callProperties = %s",
2492 ad.droid.telecomCallGetProperties(new_call_id))
Betty Zhouc4dfad12018-04-11 18:36:49 -07002493
Betty Zhouf31dffe2018-02-23 19:29:28 -08002494 if not ad.droid.telecomCallGetAudioState():
2495 ad.log.error("Audio is not in call state")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002496 tel_result_wrapper.result_value = CallResult(
2497 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
Betty Zhoucf048542018-02-22 17:14:08 -08002498
Betty Zhou74481722018-04-13 16:19:25 -07002499 if call_func(log, ad):
2500 ad.log.info("Call is in %s state", call_func.__name__)
2501 else:
Betty Zhou16e8e662018-05-08 18:26:18 -07002502 ad.log.error("Call is not in %s state, voice in RAT %s",
2503 call_func.__name__,
2504 ad.droid.telephonyGetCurrentVoiceNetworkType())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002505 tel_result_wrapper.result_value = CallResult(
2506 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
2507 if not tel_result_wrapper:
2508 return tel_result_wrapper
Yang Liu13406292016-02-23 14:58:25 -08002509 elapsed_time = 0
Nathan Harold7642fc92016-05-02 18:29:11 -07002510 while (elapsed_time < wait_time_in_call):
2511 CHECK_INTERVAL = min(CHECK_INTERVAL,
2512 wait_time_in_call - elapsed_time)
Yang Liu13406292016-02-23 14:58:25 -08002513 time.sleep(CHECK_INTERVAL)
2514 elapsed_time += CHECK_INTERVAL
Betty Zhou94023182017-06-07 18:02:14 -07002515 time_message = "at <%s>/<%s> second." % (elapsed_time,
2516 wait_time_in_call)
Betty Zhouc2801992018-01-30 16:40:28 -08002517 for ad, call_func in [(ad_caller, verify_caller_func),
2518 (ad_callee, verify_callee_func)]:
2519 if not call_func(log, ad):
Betty Zhou16e8e662018-05-08 18:26:18 -07002520 ad.log.error(
2521 "NOT in correct %s state at %s, voice in RAT %s",
2522 call_func.__name__, time_message,
2523 ad.droid.telephonyGetCurrentVoiceNetworkType())
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002524 tel_result_wrapper.result_value = CallResult(
2525 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
Betty Zhouc2801992018-01-30 16:40:28 -08002526 else:
2527 ad.log.info("In correct %s state at %s",
2528 call_func.__name__, time_message)
2529 if not ad.droid.telecomCallGetAudioState():
2530 ad.log.error("Audio is not in call state at %s",
2531 time_message)
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002532 tel_result_wrapper.result_value = CallResult(
2533 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
2534 if not tel_result_wrapper:
2535 return tel_result_wrapper
Betty Zhoub707ef22018-05-14 16:47:05 -07002536
Betty Zhoufe726dc2018-04-25 19:31:33 -07002537 if ad_hangup:
Betty Zhoufe726dc2018-04-25 19:31:33 -07002538 if not hangup_call(log, ad_hangup):
2539 ad_hangup.log.info("Failed to hang up the call")
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002540 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
2541 return tel_result_wrapper
Betty Zhoufd1e0da2018-02-20 14:39:35 -08002542 finally:
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002543 if not tel_result_wrapper:
Betty Zhou16e8e662018-05-08 18:26:18 -07002544 for ad in (ad_caller, ad_callee):
2545 last_call_drop_reason(ad, begin_time)
Ang Li73697b32015-12-03 00:41:53 +00002546 try:
2547 if ad.droid.telecomIsInCall():
Betty Zhoufe726dc2018-04-25 19:31:33 -07002548 ad.log.info("In call. End now.")
Ang Li73697b32015-12-03 00:41:53 +00002549 ad.droid.telecomEndCall()
2550 except Exception as e:
2551 log.error(str(e))
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002552 if ad_hangup or not tel_result_wrapper:
Betty Zhou16e8e662018-05-08 18:26:18 -07002553 for ad in (ad_caller, ad_callee):
2554 if not wait_for_call_id_clearing(
2555 ad, getattr(ad, "caller_ids", [])):
Kris Rambishdfe4a3a2019-03-26 21:53:43 -07002556 tel_result_wrapper.result_value = CallResult(
2557 'CALL_ID_CLEANUP_FAIL')
2558 return tel_result_wrapper
Ang Li73697b32015-12-03 00:41:53 +00002559
Markus Liu1cca96e2019-11-26 15:05:25 +08002560def call_setup_teardown_for_call_forwarding(
2561 log,
2562 ad_caller,
2563 ad_callee,
2564 forwarded_callee,
2565 ad_hangup=None,
2566 verify_callee_func=None,
2567 verify_after_cf_disabled=None,
2568 wait_time_in_call=WAIT_TIME_IN_CALL,
2569 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
2570 dialing_number_length=None,
2571 video_state=None,
2572 call_forwarding_type="unconditional"):
2573 """ Call process for call forwarding, including make a phone call from
2574 caller, forward from callee, accept from the forwarded callee and hang up.
2575 The call is on default voice subscription
2576
2577 In call process, call from <ad_caller> to <ad_callee>, forwarded to
2578 <forwarded_callee>, accept the call, (optional) and then hang up from
2579 <ad_hangup>.
2580
2581 Args:
2582 ad_caller: Caller Android Device Object.
2583 ad_callee: Callee Android Device Object which forwards the call.
2584 forwarded_callee: Callee Android Device Object which answers the call.
2585 ad_hangup: Android Device Object end the phone call.
2586 Optional. Default value is None, and phone call will continue.
2587 verify_callee_func: func_ptr to verify callee in correct mode
2588 Optional. Default is None
2589 verify_after_cf_disabled: If True the test of disabling call forwarding
2590 will be appended.
2591 wait_time_in_call: the call duration of a connected call
2592 incall_ui_display: after answer the call, bring in-call UI to foreground
2593 or background.
2594 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2595 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2596 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2597 else, do nothing.
2598 dialing_number_length: the number of digits used for dialing
2599 video_state: video call or voice call. Default is voice call.
2600 call_forwarding_type: type of call forwarding listed below:
2601 - unconditional
2602 - busy
2603 - not_answered
2604 - not_reachable
2605
2606 Returns:
2607 True if call process without any error.
2608 False if error happened.
2609
2610 """
2611 subid_caller = get_outgoing_voice_sub_id(ad_caller)
2612 subid_callee = get_incoming_voice_sub_id(ad_callee)
2613 subid_forwarded_callee = get_incoming_voice_sub_id(forwarded_callee)
2614 return call_setup_teardown_for_call_forwarding_for_subscription(
2615 log,
2616 ad_caller,
2617 ad_callee,
2618 forwarded_callee,
2619 subid_caller,
2620 subid_callee,
2621 subid_forwarded_callee,
2622 ad_hangup,
2623 verify_callee_func,
2624 wait_time_in_call,
2625 incall_ui_display,
2626 dialing_number_length,
2627 video_state,
2628 call_forwarding_type,
2629 verify_after_cf_disabled)
2630
2631def call_setup_teardown_for_call_forwarding_for_subscription(
2632 log,
2633 ad_caller,
2634 ad_callee,
2635 forwarded_callee,
2636 subid_caller,
2637 subid_callee,
2638 subid_forwarded_callee,
2639 ad_hangup=None,
2640 verify_callee_func=None,
2641 wait_time_in_call=WAIT_TIME_IN_CALL,
2642 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
2643 dialing_number_length=None,
2644 video_state=None,
2645 call_forwarding_type="unconditional",
2646 verify_after_cf_disabled=None):
2647 """ Call process for call forwarding, including make a phone call from caller,
2648 forward from callee, accept from the forwarded callee and hang up.
2649 The call is on specified subscription
2650
2651 In call process, call from <ad_caller> to <ad_callee>, forwarded to
2652 <forwarded_callee>, accept the call, (optional) and then hang up from
2653 <ad_hangup>.
2654
2655 Args:
2656 ad_caller: Caller Android Device Object.
2657 ad_callee: Callee Android Device Object which forwards the call.
2658 forwarded_callee: Callee Android Device Object which answers the call.
2659 subid_caller: Caller subscription ID
2660 subid_callee: Callee subscription ID
2661 subid_forwarded_callee: Forwarded callee subscription ID
2662 ad_hangup: Android Device Object end the phone call.
2663 Optional. Default value is None, and phone call will continue.
2664 verify_callee_func: func_ptr to verify callee in correct mode
2665 Optional. Default is None
2666 wait_time_in_call: the call duration of a connected call
2667 incall_ui_display: after answer the call, bring in-call UI to foreground
2668 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
2669 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
2670 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
2671 else, do nothing.
2672 dialing_number_length: the number of digits used for dialing
2673 video_state: video call or voice call. Default is voice call.
2674 call_forwarding_type: type of call forwarding listed below:
2675 - unconditional
2676 - busy
2677 - not_answered
2678 - not_reachable
2679 verify_after_cf_disabled: If True the call forwarding will not be
2680 enabled. This argument is used to verify if the call can be received
2681 successfully after call forwarding was disabled.
2682
2683 Returns:
2684 True if call process without any error.
2685 False if error happened.
2686
2687 """
2688 CHECK_INTERVAL = 5
2689 begin_time = get_current_epoch_time()
2690 verify_caller_func = is_phone_in_call
2691 if not verify_callee_func:
2692 verify_callee_func = is_phone_in_call
2693 verify_forwarded_callee_func = is_phone_in_call
2694
2695 caller_number = ad_caller.telephony['subscription'][subid_caller][
2696 'phone_num']
2697 callee_number = ad_callee.telephony['subscription'][subid_callee][
2698 'phone_num']
2699 forwarded_callee_number = forwarded_callee.telephony['subscription'][
2700 subid_forwarded_callee]['phone_num']
2701
2702 if dialing_number_length:
2703 skip_test = False
2704 trunc_position = 0 - int(dialing_number_length)
2705 try:
2706 caller_area_code = caller_number[:trunc_position]
2707 callee_area_code = callee_number[:trunc_position]
2708 callee_dial_number = callee_number[trunc_position:]
2709 except:
2710 skip_test = True
2711 if caller_area_code != callee_area_code:
2712 skip_test = True
2713 if skip_test:
2714 msg = "Cannot make call from %s to %s by %s digits" % (
2715 caller_number, callee_number, dialing_number_length)
2716 ad_caller.log.info(msg)
2717 raise signals.TestSkip(msg)
2718 else:
2719 callee_number = callee_dial_number
2720
2721 result = True
2722 msg = "Call from %s to %s (forwarded to %s)" % (
2723 caller_number, callee_number, forwarded_callee_number)
2724 if video_state:
2725 msg = "Video %s" % msg
2726 video = True
2727 else:
2728 video = False
2729 if ad_hangup:
2730 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
2731 ad_caller.log.info(msg)
2732
2733 for ad in (ad_caller, forwarded_callee):
2734 call_ids = ad.droid.telecomCallGetCallIds()
2735 setattr(ad, "call_ids", call_ids)
2736 if call_ids:
2737 ad.log.info("Pre-exist CallId %s before making call", call_ids)
2738
2739 if not verify_after_cf_disabled:
2740 if not set_call_forwarding_by_mmi(
2741 log,
2742 ad_callee,
2743 forwarded_callee,
2744 call_forwarding_type=call_forwarding_type):
2745 raise signals.TestFailure(
2746 "Failed to register or activate call forwarding.",
2747 extras={"fail_reason": "Failed to register or activate call"
2748 " forwarding."})
2749
2750 if call_forwarding_type == "not_reachable":
2751 if not toggle_airplane_mode_msim(
2752 log,
2753 ad_callee,
2754 new_state=True,
2755 strict_checking=True):
2756 return False
2757
2758 if call_forwarding_type == "busy":
2759 ad_callee.log.info("Callee is making a phone call to 0000000000 to make"
2760 " itself busy.")
2761 ad_callee.droid.telecomCallNumber("0000000000", False)
2762 time.sleep(2)
2763
2764 if check_call_state_idle_by_adb(ad_callee):
2765 ad_callee.log.error("Call state of the callee is idle.")
2766 if not verify_after_cf_disabled:
2767 erase_call_forwarding_by_mmi(
2768 log,
2769 ad_callee,
2770 call_forwarding_type=call_forwarding_type)
2771 return False
2772
2773 try:
2774 if not initiate_call(
2775 log,
2776 ad_caller,
2777 callee_number,
2778 incall_ui_display=incall_ui_display,
2779 video=video):
2780
2781 ad_caller.log.error("Caller failed to initiate the call.")
2782 result = False
2783
2784 if call_forwarding_type == "not_reachable":
2785 if toggle_airplane_mode_msim(
2786 log,
2787 ad_callee,
2788 new_state=False,
2789 strict_checking=True):
2790 time.sleep(10)
2791 elif call_forwarding_type == "busy":
2792 hangup_call(log, ad_callee)
2793
2794 if not verify_after_cf_disabled:
2795 erase_call_forwarding_by_mmi(
2796 log,
2797 ad_callee,
2798 call_forwarding_type=call_forwarding_type)
2799 return False
2800 else:
2801 ad_caller.log.info("Caller initated the call successfully.")
2802
2803 if call_forwarding_type == "not_answered":
2804 if not wait_for_ringing_call_for_subscription(
2805 log,
2806 ad_callee,
2807 subid_callee,
2808 incoming_number=caller_number,
2809 caller=ad_caller,
2810 event_tracking_started=True):
2811 ad.log.info("Incoming call ringing check failed.")
2812 return False
2813
2814 _timeout = 30
2815 while check_call_state_ring_by_adb(ad_callee) == 1 and _timeout >= 0:
2816 time.sleep(1)
2817 _timeout = _timeout - 1
2818
2819 if not wait_and_answer_call_for_subscription(
2820 log,
2821 forwarded_callee,
2822 subid_forwarded_callee,
2823 incoming_number=caller_number,
2824 caller=ad_caller,
2825 incall_ui_display=incall_ui_display,
2826 video_state=video_state):
2827
2828 if not verify_after_cf_disabled:
2829 forwarded_callee.log.error("Forwarded callee failed to receive"
2830 "or answer the call.")
2831 result = False
2832 else:
2833 forwarded_callee.log.info("Forwarded callee did not receive or"
2834 " answer the call.")
2835
2836 if call_forwarding_type == "not_reachable":
2837 if toggle_airplane_mode_msim(
2838 log,
2839 ad_callee,
2840 new_state=False,
2841 strict_checking=True):
2842 time.sleep(10)
2843 elif call_forwarding_type == "busy":
2844 hangup_call(log, ad_callee)
2845
2846 if not verify_after_cf_disabled:
2847 erase_call_forwarding_by_mmi(
2848 log,
2849 ad_callee,
2850 call_forwarding_type=call_forwarding_type)
2851 return False
2852
2853 else:
2854 if not verify_after_cf_disabled:
2855 forwarded_callee.log.info("Forwarded callee answered the call"
2856 " successfully.")
2857 else:
2858 forwarded_callee.log.error("Forwarded callee should not be able"
2859 " to answer the call.")
2860 hangup_call(log, ad_caller)
2861 result = False
2862
2863 for ad, subid, call_func in zip(
2864 [ad_caller, forwarded_callee],
2865 [subid_caller, subid_forwarded_callee],
2866 [verify_caller_func, verify_forwarded_callee_func]):
2867 call_ids = ad.droid.telecomCallGetCallIds()
2868 new_call_ids = set(call_ids) - set(ad.call_ids)
2869 if not new_call_ids:
2870 if not verify_after_cf_disabled:
2871 ad.log.error(
2872 "No new call ids are found after call establishment")
2873 ad.log.error("telecomCallGetCallIds returns %s",
2874 ad.droid.telecomCallGetCallIds())
2875 result = False
2876 for new_call_id in new_call_ids:
2877 if not verify_after_cf_disabled:
2878 if not wait_for_in_call_active(ad, call_id=new_call_id):
2879 result = False
2880 else:
2881 ad.log.info("callProperties = %s",
2882 ad.droid.telecomCallGetProperties(new_call_id))
2883 else:
2884 ad.log.error("No new call id should be found.")
2885
2886 if not ad.droid.telecomCallGetAudioState():
2887 if not verify_after_cf_disabled:
2888 ad.log.error("Audio is not in call state")
2889 result = False
2890
2891 if call_func(log, ad):
2892 if not verify_after_cf_disabled:
2893 ad.log.info("Call is in %s state", call_func.__name__)
2894 else:
2895 ad.log.error("Call is in %s state", call_func.__name__)
2896 else:
2897 if not verify_after_cf_disabled:
2898 ad.log.error(
2899 "Call is not in %s state, voice in RAT %s",
2900 call_func.__name__,
2901 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
2902 result = False
2903
2904 if not result:
2905 if call_forwarding_type == "not_reachable":
2906 if toggle_airplane_mode_msim(
2907 log,
2908 ad_callee,
2909 new_state=False,
2910 strict_checking=True):
2911 time.sleep(10)
2912 elif call_forwarding_type == "busy":
2913 hangup_call(log, ad_callee)
2914
2915 if not verify_after_cf_disabled:
2916 erase_call_forwarding_by_mmi(
2917 log,
2918 ad_callee,
2919 call_forwarding_type=call_forwarding_type)
2920 return False
2921
2922 elapsed_time = 0
2923 while (elapsed_time < wait_time_in_call):
2924 CHECK_INTERVAL = min(CHECK_INTERVAL,
2925 wait_time_in_call - elapsed_time)
2926 time.sleep(CHECK_INTERVAL)
2927 elapsed_time += CHECK_INTERVAL
2928 time_message = "at <%s>/<%s> second." % (elapsed_time,
2929 wait_time_in_call)
2930 for ad, subid, call_func in [
2931 (ad_caller, subid_caller, verify_caller_func),
2932 (forwarded_callee, subid_forwarded_callee,
2933 verify_forwarded_callee_func)]:
2934 if not call_func(log, ad):
2935 if not verify_after_cf_disabled:
2936 ad.log.error(
2937 "NOT in correct %s state at %s, voice in RAT %s",
2938 call_func.__name__, time_message,
2939 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
2940 result = False
2941 else:
2942 if not verify_after_cf_disabled:
2943 ad.log.info("In correct %s state at %s",
2944 call_func.__name__, time_message)
2945 else:
2946 ad.log.error("In correct %s state at %s",
2947 call_func.__name__, time_message)
2948
2949 if not ad.droid.telecomCallGetAudioState():
2950 if not verify_after_cf_disabled:
2951 ad.log.error("Audio is not in call state at %s",
2952 time_message)
2953 result = False
2954
2955 if not result:
2956 if call_forwarding_type == "not_reachable":
2957 if toggle_airplane_mode_msim(
2958 log,
2959 ad_callee,
2960 new_state=False,
2961 strict_checking=True):
2962 time.sleep(10)
2963 elif call_forwarding_type == "busy":
2964 hangup_call(log, ad_callee)
2965
2966 if not verify_after_cf_disabled:
2967 erase_call_forwarding_by_mmi(
2968 log,
2969 ad_callee,
2970 call_forwarding_type=call_forwarding_type)
2971 return False
2972
2973 if ad_hangup:
2974 if not hangup_call(log, ad_hangup):
2975 ad_hangup.log.info("Failed to hang up the call")
2976 result = False
2977 if call_forwarding_type == "not_reachable":
2978 if toggle_airplane_mode_msim(
2979 log,
2980 ad_callee,
2981 new_state=False,
2982 strict_checking=True):
2983 time.sleep(10)
2984 elif call_forwarding_type == "busy":
2985 hangup_call(log, ad_callee)
2986
2987 if not verify_after_cf_disabled:
2988 erase_call_forwarding_by_mmi(
2989 log,
2990 ad_callee,
2991 call_forwarding_type=call_forwarding_type)
2992 return False
2993 finally:
2994 if not result:
2995 if verify_after_cf_disabled:
2996 result = True
2997 else:
2998 for ad in (ad_caller, forwarded_callee):
2999 last_call_drop_reason(ad, begin_time)
3000 try:
3001 if ad.droid.telecomIsInCall():
3002 ad.log.info("In call. End now.")
3003 ad.droid.telecomEndCall()
3004 except Exception as e:
3005 log.error(str(e))
3006
3007 if ad_hangup or not result:
3008 for ad in (ad_caller, forwarded_callee):
3009 if not wait_for_call_id_clearing(
3010 ad, getattr(ad, "caller_ids", [])):
3011 result = False
3012
3013 if call_forwarding_type == "not_reachable":
3014 if toggle_airplane_mode_msim(
3015 log,
3016 ad_callee,
3017 new_state=False,
3018 strict_checking=True):
3019 time.sleep(10)
3020 elif call_forwarding_type == "busy":
3021 hangup_call(log, ad_callee)
3022
3023 if not verify_after_cf_disabled:
3024 erase_call_forwarding_by_mmi(
3025 log,
3026 ad_callee,
3027 call_forwarding_type=call_forwarding_type)
3028
3029 if not result:
3030 return result
3031
3032 ad_caller.log.info(
3033 "Make a normal call to callee to ensure the call can be connected after"
3034 " call forwarding was disabled")
3035 return call_setup_teardown_for_subscription(
3036 log, ad_caller, ad_callee, subid_caller, subid_callee, ad_caller,
3037 verify_caller_func, verify_callee_func, wait_time_in_call,
3038 incall_ui_display, dialing_number_length, video_state)
Nathan Harold123c9da2015-12-30 16:33:25 -08003039
Markus Liude6e5db2019-12-18 15:31:54 +08003040def call_setup_teardown_for_call_waiting(log,
3041 ad_caller,
3042 ad_callee,
3043 ad_caller2,
3044 ad_hangup=None,
3045 ad_hangup2=None,
3046 verify_callee_func=None,
3047 end_first_call_before_answering_second_call=True,
3048 wait_time_in_call=WAIT_TIME_IN_CALL,
3049 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
3050 dialing_number_length=None,
3051 video_state=None,
3052 call_waiting=True):
3053 """ Call process for call waiting, including make the 1st phone call from
3054 caller, answer the call by the callee, and receive the 2nd call from the
3055 caller2. The call is on default voice subscription
3056
3057 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
3058 <ad_caller2> to <ad_callee>, hang up the existing call or reject the
3059 incoming call according to the test scenario.
3060
3061 Args:
3062 ad_caller: Caller Android Device Object.
3063 ad_callee: Callee Android Device Object.
3064 ad_caller2: Caller2 Android Device Object.
3065 ad_hangup: Android Device Object end the 1st phone call.
3066 Optional. Default value is None, and phone call will continue.
3067 ad_hangup2: Android Device Object end the 2nd phone call.
3068 Optional. Default value is None, and phone call will continue.
3069 verify_callee_func: func_ptr to verify callee in correct mode
3070 Optional. Default is None
3071 end_first_call_before_answering_second_call: If True the 2nd call will
3072 be rejected on the ringing stage.
3073 wait_time_in_call: the call duration of a connected call
3074 incall_ui_display: after answer the call, bring in-call UI to foreground
3075 or background.
3076 Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
3077 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
3078 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
3079 else, do nothing.
3080 dialing_number_length: the number of digits used for dialing
3081 video_state: video call or voice call. Default is voice call.
3082 call_waiting: True to enable call waiting and False to disable.
3083
3084 Returns:
3085 True if call process without any error.
3086 False if error happened.
3087
3088 """
3089 subid_caller = get_outgoing_voice_sub_id(ad_caller)
3090 subid_callee = get_incoming_voice_sub_id(ad_callee)
3091 subid_caller2 = get_incoming_voice_sub_id(ad_caller2)
3092 return call_setup_teardown_for_call_waiting_for_subscription(
3093 log,
3094 ad_caller,
3095 ad_callee,
3096 ad_caller2,
3097 subid_caller,
3098 subid_callee,
3099 subid_caller2,
3100 ad_hangup, ad_hangup2,
3101 verify_callee_func,
3102 end_first_call_before_answering_second_call,
3103 wait_time_in_call,
3104 incall_ui_display,
3105 dialing_number_length,
3106 video_state,
3107 call_waiting)
3108
3109def call_setup_teardown_for_call_waiting_for_subscription(
3110 log,
3111 ad_caller,
3112 ad_callee,
3113 ad_caller2,
3114 subid_caller,
3115 subid_callee,
3116 subid_caller2,
3117 ad_hangup=None,
3118 ad_hangup2=None,
3119 verify_callee_func=None,
3120 end_first_call_before_answering_second_call=True,
3121 wait_time_in_call=WAIT_TIME_IN_CALL,
3122 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
3123 dialing_number_length=None,
3124 video_state=None,
3125 call_waiting=True):
3126 """ Call process for call waiting, including make the 1st phone call from
3127 caller, answer the call by the callee, and receive the 2nd call from the
3128 caller2. The call is on specified subscription.
3129
3130 In call process, 1st call from <ad_caller> to <ad_callee>, 2nd call from
3131 <ad_caller2> to <ad_callee>, hang up the existing call or reject the
3132 incoming call according to the test scenario.
3133
3134 Args:
3135 ad_caller: Caller Android Device Object.
3136 ad_callee: Callee Android Device Object.
3137 ad_caller2: Caller2 Android Device Object.
3138 subid_caller: Caller subscription ID.
3139 subid_callee: Callee subscription ID.
3140 subid_caller2: Caller2 subscription ID.
3141 ad_hangup: Android Device Object end the 1st phone call.
3142 Optional. Default value is None, and phone call will continue.
3143 ad_hangup2: Android Device Object end the 2nd phone call.
3144 Optional. Default value is None, and phone call will continue.
3145 verify_callee_func: func_ptr to verify callee in correct mode
3146 Optional. Default is None
3147 end_first_call_before_answering_second_call: If True the 2nd call will
3148 be rejected on the ringing stage.
3149 wait_time_in_call: the call duration of a connected call
3150 incall_ui_display: after answer the call, bring in-call UI to foreground
3151 or background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
3152 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
3153 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
3154 else, do nothing.
3155 dialing_number_length: the number of digits used for dialing
3156 video_state: video call or voice call. Default is voice call.
3157 call_waiting: True to enable call waiting and False to disable.
3158
3159 Returns:
3160 True if call process without any error.
3161 False if error happened.
3162
3163 """
3164
3165 CHECK_INTERVAL = 5
3166 begin_time = get_current_epoch_time()
3167 verify_caller_func = is_phone_in_call
3168 if not verify_callee_func:
3169 verify_callee_func = is_phone_in_call
3170 verify_caller2_func = is_phone_in_call
3171
3172 caller_number = ad_caller.telephony['subscription'][subid_caller][
3173 'phone_num']
3174 callee_number = ad_callee.telephony['subscription'][subid_callee][
3175 'phone_num']
3176 caller2_number = ad_caller2.telephony['subscription'][subid_caller2][
3177 'phone_num']
3178 if dialing_number_length:
3179 skip_test = False
3180 trunc_position = 0 - int(dialing_number_length)
3181 try:
3182 caller_area_code = caller_number[:trunc_position]
3183 callee_area_code = callee_number[:trunc_position]
3184 callee_dial_number = callee_number[trunc_position:]
3185 except:
3186 skip_test = True
3187 if caller_area_code != callee_area_code:
3188 skip_test = True
3189 if skip_test:
3190 msg = "Cannot make call from %s to %s by %s digits" % (
3191 caller_number, callee_number, dialing_number_length)
3192 ad_caller.log.info(msg)
3193 raise signals.TestSkip(msg)
3194 else:
3195 callee_number = callee_dial_number
3196
3197 result = True
3198 msg = "Call from %s to %s" % (caller_number, callee_number)
3199 if video_state:
3200 msg = "Video %s" % msg
3201 video = True
3202 else:
3203 video = False
3204 if ad_hangup:
3205 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
3206 ad_caller.log.info(msg)
3207
3208 for ad in (ad_caller, ad_callee, ad_caller2):
3209 call_ids = ad.droid.telecomCallGetCallIds()
3210 setattr(ad, "call_ids", call_ids)
3211 if call_ids:
3212 ad.log.info("Pre-exist CallId %s before making call", call_ids)
3213
3214 if not call_waiting:
3215 set_call_waiting(log, ad_callee, enable=0)
3216 else:
3217 set_call_waiting(log, ad_callee, enable=1)
3218
3219 first_call_ids = []
3220 try:
3221 if not initiate_call(
3222 log,
3223 ad_caller,
3224 callee_number,
3225 incall_ui_display=incall_ui_display,
3226 video=video):
3227 ad_caller.log.error("Initiate call failed.")
3228 if not call_waiting:
3229 set_call_waiting(log, ad_callee, enable=1)
3230 result = False
3231 return False
3232 else:
3233 ad_caller.log.info("Caller initate call successfully")
3234 if not wait_and_answer_call_for_subscription(
3235 log,
3236 ad_callee,
3237 subid_callee,
3238 incoming_number=caller_number,
3239 caller=ad_caller,
3240 incall_ui_display=incall_ui_display,
3241 video_state=video_state):
3242 ad_callee.log.error("Answer call fail.")
3243 if not call_waiting:
3244 set_call_waiting(log, ad_callee, enable=1)
3245 result = False
3246 return False
3247 else:
3248 ad_callee.log.info("Callee answered the call successfully")
3249
3250 for ad, subid, call_func in zip(
3251 [ad_caller, ad_callee],
3252 [subid_caller, subid_callee],
3253 [verify_caller_func, verify_callee_func]):
3254 call_ids = ad.droid.telecomCallGetCallIds()
3255 new_call_ids = set(call_ids) - set(ad.call_ids)
3256 if not new_call_ids:
3257 ad.log.error(
3258 "No new call ids are found after call establishment")
3259 ad.log.error("telecomCallGetCallIds returns %s",
3260 ad.droid.telecomCallGetCallIds())
3261 result = False
3262 for new_call_id in new_call_ids:
3263 first_call_ids.append(new_call_id)
3264 if not wait_for_in_call_active(ad, call_id=new_call_id):
3265 result = False
3266 else:
3267 ad.log.info("callProperties = %s",
3268 ad.droid.telecomCallGetProperties(new_call_id))
3269
3270 if not ad.droid.telecomCallGetAudioState():
3271 ad.log.error("Audio is not in call state")
3272 result = False
3273
3274 if call_func(log, ad):
3275 ad.log.info("Call is in %s state", call_func.__name__)
3276 else:
3277 ad.log.error("Call is not in %s state, voice in RAT %s",
3278 call_func.__name__,
3279 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3280 result = False
3281 if not result:
3282 if not call_waiting:
3283 set_call_waiting(log, ad_callee, enable=1)
3284 return False
3285
3286 time.sleep(3)
3287 if not call_waiting:
3288 if not initiate_call(
3289 log,
3290 ad_caller2,
3291 callee_number,
3292 incall_ui_display=incall_ui_display,
3293 video=video):
3294 ad_caller2.log.info("Initiate call failed.")
3295 if not call_waiting:
3296 set_call_waiting(log, ad_callee, enable=1)
3297 result = False
3298 return False
3299 else:
3300 ad_caller2.log.info("Caller 2 initate 2nd call successfully")
3301
3302 if not wait_and_answer_call_for_subscription(
3303 log,
3304 ad_callee,
3305 subid_callee,
3306 incoming_number=caller2_number,
3307 caller=ad_caller2,
3308 incall_ui_display=incall_ui_display,
3309 video_state=video_state):
3310 ad_callee.log.info(
3311 "Answering 2nd call fail due to call waiting deactivate.")
3312 else:
3313 ad_callee.log.error("Callee should not be able to answer the"
3314 " 2nd call due to call waiting deactivated.")
3315 if not call_waiting:
3316 set_call_waiting(log, ad_callee, enable=1)
3317 result = False
3318 return False
3319
3320 time.sleep(3)
3321 if not hangup_call(log, ad_caller2):
3322 ad_caller2.log.info("Failed to hang up the 2nd call")
3323 if not call_waiting:
3324 set_call_waiting(log, ad_callee, enable=1)
3325 result = False
3326 return False
3327
3328 else:
3329
3330 for ad in (ad_callee, ad_caller2):
3331 call_ids = ad.droid.telecomCallGetCallIds()
3332 setattr(ad, "call_ids", call_ids)
3333 if call_ids:
3334 ad.log.info("Current existing CallId %s before making the"
3335 " second call.", call_ids)
3336
3337 if not initiate_call(
3338 log,
3339 ad_caller2,
3340 callee_number,
3341 incall_ui_display=incall_ui_display,
3342 video=video):
3343 ad_caller2.log.info("Initiate 2nd call failed.")
3344 if not call_waiting:
3345 set_call_waiting(log, ad_callee, enable=1)
3346 result = False
3347 return False
3348 else:
3349 ad_caller2.log.info("Caller 2 initate 2nd call successfully")
3350
3351 if end_first_call_before_answering_second_call:
3352 try:
3353 if not wait_for_ringing_call_for_subscription(
3354 log,
3355 ad_callee,
3356 subid_callee,
3357 incoming_number=caller2_number,
3358 caller=ad_caller2,
3359 event_tracking_started=True):
3360 ad_callee.log.info(
3361 "2nd incoming call ringing check failed.")
3362 if not call_waiting:
3363 set_call_waiting(log, ad_callee, enable=1)
3364 return False
3365
3366 time.sleep(3)
3367
3368 ad_hangup.log.info("Disconnecting first call...")
3369 for call_id in first_call_ids:
3370 disconnect_call_by_id(log, ad_hangup, call_id)
3371 time.sleep(3)
3372
3373 ad_callee.log.info("Answering the 2nd ring call...")
3374 ad_callee.droid.telecomAcceptRingingCall(video_state)
3375
3376 if wait_for_call_offhook_for_subscription(
3377 log,
3378 ad_callee,
3379 subid_callee,
3380 event_tracking_started=True):
3381 ad_callee.log.info(
3382 "Callee answered the 2nd call successfully.")
3383 else:
3384 ad_callee.log.error("Could not answer the 2nd call.")
3385 if not call_waiting:
3386 set_call_waiting(log, ad_callee, enable=1)
3387 return False
3388 except Exception as e:
3389 log.error(e)
3390 if not call_waiting:
3391 set_call_waiting(log, ad_callee, enable=1)
3392 return False
3393
3394 else:
3395 if not wait_and_answer_call_for_subscription(
3396 log,
3397 ad_callee,
3398 subid_callee,
3399 incoming_number=caller2_number,
3400 caller=ad_caller2,
3401 incall_ui_display=incall_ui_display,
3402 video_state=video_state):
3403 ad_callee.log.error("Failed to answer 2nd call.")
3404 if not call_waiting:
3405 set_call_waiting(log, ad_callee, enable=1)
3406 result = False
3407 return False
3408 else:
3409 ad_callee.log.info(
3410 "Callee answered the 2nd call successfully.")
3411
3412 for ad, subid, call_func in zip(
3413 [ad_callee, ad_caller2],
3414 [subid_callee, subid_caller2],
3415 [verify_callee_func, verify_caller2_func]):
3416 call_ids = ad.droid.telecomCallGetCallIds()
3417 new_call_ids = set(call_ids) - set(ad.call_ids)
3418 if not new_call_ids:
3419 ad.log.error(
3420 "No new call ids are found after 2nd call establishment")
3421 ad.log.error("telecomCallGetCallIds returns %s",
3422 ad.droid.telecomCallGetCallIds())
3423 result = False
3424 for new_call_id in new_call_ids:
3425 if not wait_for_in_call_active(ad, call_id=new_call_id):
3426 result = False
3427 else:
3428 ad.log.info("callProperties = %s",
3429 ad.droid.telecomCallGetProperties(new_call_id))
3430
3431 if not ad.droid.telecomCallGetAudioState():
3432 ad.log.error("Audio is not in 2nd call state")
3433 result = False
3434
3435 if call_func(log, ad):
3436 ad.log.info("2nd call is in %s state", call_func.__name__)
3437 else:
3438 ad.log.error("2nd call is not in %s state, voice in RAT %s",
3439 call_func.__name__,
3440 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3441 result = False
3442 if not result:
3443 if not call_waiting:
3444 set_call_waiting(log, ad_callee, enable=1)
3445 return False
3446
3447 elapsed_time = 0
3448 while (elapsed_time < wait_time_in_call):
3449 CHECK_INTERVAL = min(CHECK_INTERVAL,
3450 wait_time_in_call - elapsed_time)
3451 time.sleep(CHECK_INTERVAL)
3452 elapsed_time += CHECK_INTERVAL
3453 time_message = "at <%s>/<%s> second." % (elapsed_time,
3454 wait_time_in_call)
3455
3456 if not end_first_call_before_answering_second_call or \
3457 not call_waiting:
3458 for ad, subid, call_func in [
3459 (ad_caller, subid_caller, verify_caller_func),
3460 (ad_callee, subid_callee, verify_callee_func)]:
3461 if not call_func(log, ad):
3462 ad.log.error(
3463 "The first call NOT in correct %s state at %s,"
3464 " voice in RAT %s",
3465 call_func.__name__, time_message,
3466 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3467 result = False
3468 else:
3469 ad.log.info("The first call in correct %s state at %s",
3470 call_func.__name__, time_message)
3471 if not ad.droid.telecomCallGetAudioState():
3472 ad.log.error(
3473 "The first call audio is not in call state at %s",
3474 time_message)
3475 result = False
3476 if not result:
3477 if not call_waiting:
3478 set_call_waiting(log, ad_callee, enable=1)
3479 return False
3480
3481 if call_waiting:
3482 for ad, call_func in [(ad_caller2, verify_caller2_func),
3483 (ad_callee, verify_callee_func)]:
3484 if not call_func(log, ad):
3485 ad.log.error(
3486 "The 2nd call NOT in correct %s state at %s,"
3487 " voice in RAT %s",
3488 call_func.__name__, time_message,
3489 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(subid))
3490 result = False
3491 else:
3492 ad.log.info("The 2nd call in correct %s state at %s",
3493 call_func.__name__, time_message)
3494 if not ad.droid.telecomCallGetAudioState():
3495 ad.log.error(
3496 "The 2nd call audio is not in call state at %s",
3497 time_message)
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 if not end_first_call_before_answering_second_call or not call_waiting:
3505 ad_hangup.log.info("Hanging up the first call...")
3506 for call_id in first_call_ids:
3507 disconnect_call_by_id(log, ad_hangup, call_id)
3508 time.sleep(5)
3509
3510 if ad_hangup2 and call_waiting:
3511 if not hangup_call(log, ad_hangup2):
3512 ad_hangup2.log.info("Failed to hang up the 2nd call")
3513 if not call_waiting:
3514 set_call_waiting(log, ad_callee, enable=1)
3515 result = False
3516 return False
3517 finally:
3518 if not result:
3519 for ad in (ad_caller, ad_callee, ad_caller2):
3520 last_call_drop_reason(ad, begin_time)
3521 try:
3522 if ad.droid.telecomIsInCall():
3523 ad.log.info("In call. End now.")
3524 ad.droid.telecomEndCall()
3525 except Exception as e:
3526 log.error(str(e))
3527
3528 if ad_hangup or not result:
3529 for ad in (ad_caller, ad_callee):
3530 if not wait_for_call_id_clearing(
3531 ad, getattr(ad, "caller_ids", [])):
3532 result = False
3533
3534 if call_waiting:
3535 if ad_hangup2 or not result:
3536 for ad in (ad_caller2, ad_callee):
3537 if not wait_for_call_id_clearing(
3538 ad, getattr(ad, "caller_ids", [])):
3539 result = False
3540 if not call_waiting:
3541 set_call_waiting(log, ad_callee, enable=1)
3542 return result
3543
Betty Zhoue7cc3672018-04-26 16:58:56 -07003544def wait_for_call_id_clearing(ad,
3545 previous_ids,
3546 timeout=MAX_WAIT_TIME_CALL_DROP):
Betty Zhoufe726dc2018-04-25 19:31:33 -07003547 while timeout > 0:
3548 new_call_ids = ad.droid.telecomCallGetCallIds()
Betty Zhou16e8e662018-05-08 18:26:18 -07003549 if len(new_call_ids) <= len(previous_ids):
Betty Zhoufe726dc2018-04-25 19:31:33 -07003550 return True
3551 time.sleep(5)
3552 timeout = timeout - 5
Betty Zhou16e8e662018-05-08 18:26:18 -07003553 ad.log.error("Call id clearing failed. Before: %s; After: %s",
3554 previous_ids, new_call_ids)
Betty Zhoufe726dc2018-04-25 19:31:33 -07003555 return False
3556
3557
Betty Zhou16e8e662018-05-08 18:26:18 -07003558def last_call_drop_reason(ad, begin_time=None):
3559 reasons = ad.search_logcat(
3560 "qcril_qmi_voice_map_qmi_to_ril_last_call_failure_cause", begin_time)
Betty Zhou1113ed92018-06-07 16:40:59 -07003561 reason_string = ""
Betty Zhou16e8e662018-05-08 18:26:18 -07003562 if reasons:
3563 log_msg = "Logcat call drop reasons:"
Betty Zhou1113ed92018-06-07 16:40:59 -07003564 for reason in reasons:
3565 log_msg = "%s\n\t%s" % (log_msg, reason["log_message"])
3566 if "ril reason str" in reason["log_message"]:
3567 reason_string = reason["log_message"].split(":")[-1].strip()
Betty Zhou16e8e662018-05-08 18:26:18 -07003568 ad.log.info(log_msg)
3569 reasons = ad.search_logcat("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION",
3570 begin_time)
3571 if reasons:
3572 ad.log.warning("ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION is seen")
3573 ad.log.info("last call dumpsys: %s",
3574 sorted(dumpsys_last_call_info(ad).items()))
Betty Zhou1113ed92018-06-07 16:40:59 -07003575 return reason_string
Betty Zhou16e8e662018-05-08 18:26:18 -07003576
3577
Betty Zhoua37acd32017-02-23 20:04:24 -08003578def phone_number_formatter(input_string, formatter=None):
Ang Li73697b32015-12-03 00:41:53 +00003579 """Get expected format of input phone number string.
3580
3581 Args:
3582 input_string: (string) input phone number.
3583 The input could be 10/11/12 digital, with or without " "/"-"/"."
Betty Zhoua37acd32017-02-23 20:04:24 -08003584 formatter: (int) expected format, this could be 7/10/11/12
3585 if formatter is 7: output string would be 7 digital number.
3586 if formatter is 10: output string would be 10 digital (standard) number.
3587 if formatter is 11: output string would be "1" + 10 digital number.
3588 if formatter is 12: output string would be "+1" + 10 digital number.
Ang Li73697b32015-12-03 00:41:53 +00003589
3590 Returns:
3591 If no error happen, return phone number in expected format.
3592 Else, return None.
3593 """
Betty Zhouddb361d2017-09-07 17:07:20 -07003594 if not input_string:
3595 return ""
Ang Li73697b32015-12-03 00:41:53 +00003596 # make sure input_string is 10 digital
3597 # Remove white spaces, dashes, dots
Betty Zhoue955be22017-04-12 17:28:05 -07003598 input_string = input_string.replace(" ", "").replace("-", "").replace(
Betty Zhou77aa5f52017-05-08 20:23:35 -07003599 ".", "").lstrip("0")
Betty Zhoua37acd32017-02-23 20:04:24 -08003600 if not formatter:
Nathan Haroldae6a0da2016-03-16 20:56:47 +00003601 return input_string
Ashutosh Rajmani Singha3259692019-07-15 16:24:02 -07003602 # Remove +81 and add 0 for Japan Carriers only.
3603 if (len(input_string) == 13 and input_string[0:3] == "+81"):
3604 input_string = "0" + input_string[3:]
Mark De Ruyter60b759e2019-07-17 16:04:16 -07003605 return input_string
Ang Li73697b32015-12-03 00:41:53 +00003606 # Remove "1" or "+1"from front
Betty Zhouee311052017-12-19 13:09:56 -08003607 if (len(input_string) == PHONE_NUMBER_STRING_FORMAT_11_DIGIT
3608 and input_string[0] == "1"):
Ang Li73697b32015-12-03 00:41:53 +00003609 input_string = input_string[1:]
Betty Zhouee311052017-12-19 13:09:56 -08003610 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_12_DIGIT
3611 and input_string[0:2] == "+1"):
Ang Li73697b32015-12-03 00:41:53 +00003612 input_string = input_string[2:]
Betty Zhouee311052017-12-19 13:09:56 -08003613 elif (len(input_string) == PHONE_NUMBER_STRING_FORMAT_7_DIGIT
3614 and formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT):
Ang Li73697b32015-12-03 00:41:53 +00003615 return input_string
3616 elif len(input_string) != PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
3617 return None
3618 # change input_string according to format
Betty Zhoua37acd32017-02-23 20:04:24 -08003619 if formatter == PHONE_NUMBER_STRING_FORMAT_12_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08003620 input_string = "+1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003621 elif formatter == PHONE_NUMBER_STRING_FORMAT_11_DIGIT:
Nathan Harold123c9da2015-12-30 16:33:25 -08003622 input_string = "1" + input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003623 elif formatter == PHONE_NUMBER_STRING_FORMAT_10_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00003624 input_string = input_string
Betty Zhoua37acd32017-02-23 20:04:24 -08003625 elif formatter == PHONE_NUMBER_STRING_FORMAT_7_DIGIT:
Ang Li73697b32015-12-03 00:41:53 +00003626 input_string = input_string[3:]
3627 else:
3628 return None
3629 return input_string
3630
Nathan Harold123c9da2015-12-30 16:33:25 -08003631
Ang Li73697b32015-12-03 00:41:53 +00003632def get_internet_connection_type(log, ad):
3633 """Get current active connection type name.
3634
3635 Args:
3636 log: Log object.
3637 ad: Android Device Object.
3638 Returns:
3639 current active connection type name.
3640 """
3641 if not ad.droid.connectivityNetworkIsConnected():
3642 return 'none'
3643 return connection_type_from_type_string(
3644 ad.droid.connectivityNetworkGetActiveConnectionTypeName())
3645
Nathan Harold123c9da2015-12-30 16:33:25 -08003646
3647def verify_http_connection(log,
3648 ad,
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003649 url="https://www.google.com",
Betty Zhouf809c5c2017-03-21 14:55:59 -07003650 retry=5,
Betty Zhou32e403a2017-10-25 20:08:12 -07003651 retry_interval=15,
3652 expected_state=True):
Ang Li73697b32015-12-03 00:41:53 +00003653 """Make ping request and return status.
3654
3655 Args:
Nathan Harold54c7c742016-08-04 19:40:44 -07003656 log: log object
Ang Li73697b32015-12-03 00:41:53 +00003657 ad: Android Device Object.
3658 url: Optional. The ping request will be made to this URL.
3659 Default Value is "http://www.google.com/".
3660
3661 """
Betty Zhou03bd3f92018-06-06 17:37:56 -07003662 if not getattr(ad, "data_droid", None):
3663 ad.data_droid, ad.data_ed = ad.get_droid()
3664 ad.data_ed.start()
3665 else:
3666 try:
3667 if not ad.data_droid.is_live:
3668 ad.data_droid, ad.data_ed = ad.get_droid()
3669 ad.data_ed.start()
3670 except Exception:
3671 ad.log.info("Start new sl4a session for file download")
3672 ad.data_droid, ad.data_ed = ad.get_droid()
3673 ad.data_ed.start()
Nathan Harold123c9da2015-12-30 16:33:25 -08003674 for i in range(0, retry + 1):
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003675 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07003676 http_response = ad.data_droid.httpPing(url)
Betty Zhou3814cbc2018-06-11 19:39:36 -07003677 except Exception as e:
3678 ad.log.info("httpPing with %s", e)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003679 http_response = None
3680 if (expected_state and http_response) or (not expected_state
3681 and not http_response):
Betty Zhou8a53f0f2018-06-06 14:35:50 -07003682 ad.log.info("Http ping response for %s meet expected %s", url,
3683 expected_state)
Ang Li73697b32015-12-03 00:41:53 +00003684 return True
Betty Zhou32e403a2017-10-25 20:08:12 -07003685 if i < retry:
Betty Zhou32e403a2017-10-25 20:08:12 -07003686 time.sleep(retry_interval)
Betty Zhoue7cc3672018-04-26 16:58:56 -07003687 ad.log.error("Http ping to %s is %s after %s second, expecting %s", url,
3688 http_response, i * retry_interval, expected_state)
Ang Li73697b32015-12-03 00:41:53 +00003689 return False
3690
3691
Betty Zhoucea4b432017-07-20 18:29:24 -07003692def _generate_file_directory_and_file_name(url, out_path):
Betty Zhouccd171d2017-02-13 15:11:33 -08003693 file_name = url.split("/")[-1]
3694 if not out_path:
Betty Zhoucea4b432017-07-20 18:29:24 -07003695 file_directory = "/sdcard/Download/"
3696 elif not out_path.endswith("/"):
3697 file_directory, file_name = os.path.split(out_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003698 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003699 file_directory = out_path
3700 return file_directory, file_name
Betty Zhouccd171d2017-02-13 15:11:33 -08003701
3702
Betty Zhoucea4b432017-07-20 18:29:24 -07003703def _check_file_existance(ad, file_path, expected_file_size=None):
3704 """Check file existance by file_path. If expected_file_size
Betty Zhouccd171d2017-02-13 15:11:33 -08003705 is provided, then also check if the file meet the file size requirement.
3706 """
Girish Moturu2c21eb32017-05-25 14:37:55 +05303707 out = None
3708 try:
3709 out = ad.adb.shell('stat -c "%%s" %s' % file_path)
3710 except AdbError:
3711 pass
Betty Zhouccd171d2017-02-13 15:11:33 -08003712 # Handle some old version adb returns error message "No such" into std_out
Betty Zhouf17f0692017-06-28 13:10:31 -07003713 if out and "No such" not in out:
Betty Zhouccd171d2017-02-13 15:11:33 -08003714 if expected_file_size:
Betty Zhouf17f0692017-06-28 13:10:31 -07003715 file_size = int(out)
Betty Zhouccd171d2017-02-13 15:11:33 -08003716 if file_size >= expected_file_size:
Betty Zhoucea4b432017-07-20 18:29:24 -07003717 ad.log.info("File %s of size %s exists", file_path, file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08003718 return True
3719 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003720 ad.log.info("File %s is of size %s, does not meet expected %s",
3721 file_path, file_size, expected_file_size)
Betty Zhouccd171d2017-02-13 15:11:33 -08003722 return False
3723 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003724 ad.log.info("File %s exists", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003725 return True
3726 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07003727 ad.log.info("File %s does not exist.", file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08003728 return False
3729
3730
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003731def check_curl_availability(ad):
Betty Zhouf3b7d252017-07-19 17:51:06 -07003732 if not hasattr(ad, "curl_capable"):
3733 try:
Jaineel3ee37012017-08-21 15:21:57 -07003734 out = ad.adb.shell("/data/curl --version")
Betty Zhouf3b7d252017-07-19 17:51:06 -07003735 if not out or "not found" in out:
3736 setattr(ad, "curl_capable", False)
3737 ad.log.info("curl is unavailable, use chrome to download file")
3738 else:
3739 setattr(ad, "curl_capable", True)
3740 except Exception:
3741 setattr(ad, "curl_capable", False)
3742 ad.log.info("curl is unavailable, use chrome to download file")
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003743 return ad.curl_capable
Betty Zhouf3b7d252017-07-19 17:51:06 -07003744
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003745
Betty Zhou71a97672018-06-19 12:54:08 -07003746def start_youtube_video(ad, url="https://www.youtube.com/watch?v=pSJoP0LR8CQ"):
Betty Zhouf50cab32018-03-05 19:18:15 -08003747 ad.log.info("Open an youtube video")
Markus Liu035648e2019-09-19 18:32:53 +08003748 for _ in range(3):
3749 ad.ensure_screen_on()
Betty Zhou71a97672018-06-19 12:54:08 -07003750 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
3751 if wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
3752 ad.log.info("Started a video in youtube, audio is in MUSIC state")
3753 return True
Markus Liu035648e2019-09-19 18:32:53 +08003754 ad.log.info("Audio is not in MUSIC state. Quit Youtube.")
3755 for _ in range(3):
3756 ad.send_keycode("BACK")
3757 time.sleep(1)
3758 time.sleep(3)
3759 return False
Betty Zhouf50cab32018-03-05 19:18:15 -08003760
3761
Betty Zhou3b2de072018-03-15 16:46:26 -07003762def active_file_download_task(log, ad, file_name="5MB", method="curl"):
Betty Zhou86671922017-05-10 15:32:10 -07003763 # files available for download on the same website:
3764 # 1GB.zip, 512MB.zip, 200MB.zip, 50MB.zip, 20MB.zip, 10MB.zip, 5MB.zip
3765 # download file by adb command, as phone call will use sl4a
Betty Zhou5ee8e042018-06-05 20:34:12 -07003766 file_size_map = {
Jaineeld5f43e02020-02-27 11:35:19 -08003767 '1MB': 1000000,
Betty Zhou86671922017-05-10 15:32:10 -07003768 '5MB': 5000000,
3769 '10MB': 10000000,
3770 '20MB': 20000000,
3771 '50MB': 50000000,
Betty Zhou461f3102017-08-04 17:04:44 -07003772 '100MB': 100000000,
Betty Zhou86671922017-05-10 15:32:10 -07003773 '200MB': 200000000,
Betty Zhou461f3102017-08-04 17:04:44 -07003774 '512MB': 512000000
Betty Zhou86671922017-05-10 15:32:10 -07003775 }
Betty Zhou5ee8e042018-06-05 20:34:12 -07003776 url_map = {
Jaineeld5f43e02020-02-27 11:35:19 -08003777 "1MB": [
Jaineel33a11932020-07-31 17:37:03 -07003778 "http://146.148.91.8/download/1MB.zip",
Jaineeld5f43e02020-02-27 11:35:19 -08003779 "http://ipv4.download.thinkbroadband.com/1MB.zip"
3780 ],
Betty Zhou5ee8e042018-06-05 20:34:12 -07003781 "5MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003782 "http://146.148.91.8/download/5MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003783 "http://212.183.159.230/5MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003784 "http://ipv4.download.thinkbroadband.com/5MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003785 ],
3786 "10MB": [
Betty Zhou5ee8e042018-06-05 20:34:12 -07003787 "http://146.148.91.8/download/10MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003788 "http://212.183.159.230/10MB.zip",
3789 "http://ipv4.download.thinkbroadband.com/10MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003790 "http://lax.futurehosting.com/test.zip",
3791 "http://ovh.net/files/10Mio.dat"
3792 ],
3793 "20MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003794 "http://146.148.91.8/download/20MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003795 "http://212.183.159.230/20MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003796 "http://ipv4.download.thinkbroadband.com/20MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003797 ],
3798 "50MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003799 "http://146.148.91.8/download/50MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003800 "http://212.183.159.230/50MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003801 "http://ipv4.download.thinkbroadband.com/50MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003802 ],
3803 "100MB": [
Betty Zhou5ee8e042018-06-05 20:34:12 -07003804 "http://146.148.91.8/download/100MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003805 "http://212.183.159.230/100MB.zip",
3806 "http://ipv4.download.thinkbroadband.com/100MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003807 "http://speedtest-ca.turnkeyinternet.net/100mb.bin",
3808 "http://ovh.net/files/100Mio.dat",
3809 "http://lax.futurehosting.com/test100.zip"
3810 ],
3811 "200MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003812 "http://146.148.91.8/download/200MB.zip",
Betty Zhou5ee8e042018-06-05 20:34:12 -07003813 "http://212.183.159.230/200MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003814 "http://ipv4.download.thinkbroadband.com/200MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003815 ],
3816 "512MB": [
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003817 "http://146.148.91.8/download/512MB.zip",
Betty Zhouf0577582018-06-06 11:34:52 -07003818 "http://212.183.159.230/512MB.zip",
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07003819 "http://ipv4.download.thinkbroadband.com/512MB.zip"
Betty Zhou5ee8e042018-06-05 20:34:12 -07003820 ]
3821 }
3822
3823 file_size = file_size_map.get(file_name)
3824 file_urls = url_map.get(file_name)
3825 file_url = None
3826 for url in file_urls:
3827 url_splits = url.split("/")
3828 if verify_http_connection(log, ad, url=url, retry=1):
3829 output_path = "/sdcard/Download/%s" % url_splits[-1]
3830 file_url = url
3831 break
3832 if not file_url:
Betty Zhou4d97af82018-06-07 14:05:52 -07003833 ad.log.error("No url is available to download %s", file_name)
Betty Zhou86671922017-05-10 15:32:10 -07003834 return False
Jaineel5719eb52017-09-12 12:57:07 -07003835 timeout = min(max(file_size / 100000, 600), 3600)
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003836 if method == "sl4a":
Betty Zhou5ee8e042018-06-05 20:34:12 -07003837 return (http_file_download_by_sl4a, (ad, file_url, output_path,
3838 file_size, True, timeout))
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003839 if method == "curl" and check_curl_availability(ad):
Betty Zhou5ee8e042018-06-05 20:34:12 -07003840 return (http_file_download_by_curl, (ad, file_url, output_path,
3841 file_size, True, timeout))
Betty Zhou65666862018-06-05 13:51:48 -07003842 elif method == "sl4a" or method == "curl":
Betty Zhou5ee8e042018-06-05 20:34:12 -07003843 return (http_file_download_by_sl4a, (ad, file_url, output_path,
3844 file_size, True, timeout))
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003845 else:
Betty Zhou5ee8e042018-06-05 20:34:12 -07003846 return (http_file_download_by_chrome, (ad, file_url, file_size, True,
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003847 timeout))
Betty Zhou2e01bc82017-03-17 10:55:57 -07003848
3849
Betty Zhoua3f248f2018-03-05 17:33:49 -08003850def active_file_download_test(log, ad, file_name="5MB", method="sl4a"):
Betty Zhouf1cc3b62018-02-28 12:02:05 -08003851 task = active_file_download_task(log, ad, file_name, method=method)
Betty Zhouf0577582018-06-06 11:34:52 -07003852 if not task:
3853 return False
Betty Zhou2e01bc82017-03-17 10:55:57 -07003854 return task[0](*task[1])
3855
3856
Betty Zhou8aafcc12018-05-01 20:54:15 -07003857def verify_internet_connection_by_ping(log,
3858 ad,
3859 retries=1,
3860 expected_state=True,
3861 timeout=60):
Betty Zhou8e11e442017-03-30 20:00:34 -07003862 """Verify internet connection by ping test.
3863
3864 Args:
3865 log: log object
3866 ad: Android Device Object.
3867
3868 """
Betty Zhou8aafcc12018-05-01 20:54:15 -07003869 begin_time = get_current_epoch_time()
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003870 ip_addr = "54.230.144.105"
3871 for dest in ("www.google.com", "www.amazon.com", ip_addr):
3872 for i in range(retries):
3873 ad.log.info("Ping %s - attempt %d", dest, i + 1)
Jaineel6d747722017-11-20 15:03:02 -08003874 result = adb_shell_ping(
Betty Zhou8aafcc12018-05-01 20:54:15 -07003875 ad, count=5, timeout=timeout, loss_tolerance=40, dest_ip=dest)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003876 if result == expected_state:
3877 ad.log.info(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003878 "Internet connection by pinging to %s is %s as expected",
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003879 dest, expected_state)
3880 if dest == ip_addr:
3881 ad.log.warning("Suspect dns failure")
3882 ad.log.info("DNS config: %s",
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003883 ad.adb.shell("getprop | grep dns").replace(
3884 "\n", " "))
3885 return False
Jaineel6d747722017-11-20 15:03:02 -08003886 return True
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003887 else:
Betty Zhou8aafcc12018-05-01 20:54:15 -07003888 ad.log.warning(
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07003889 "Internet connection test by pinging %s is %s, expecting %s",
3890 dest, result, expected_state)
Betty Zhou8aafcc12018-05-01 20:54:15 -07003891 if get_current_epoch_time() - begin_time < timeout * 1000:
3892 time.sleep(5)
3893 ad.log.error("Ping test doesn't meet expected %s", expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003894 return False
3895
3896
3897def verify_internet_connection(log, ad, retries=3, expected_state=True):
3898 """Verify internet connection by ping test and http connection.
3899
3900 Args:
3901 log: log object
3902 ad: Android Device Object.
3903
3904 """
Betty Zhoub707ef22018-05-14 16:47:05 -07003905 if ad.droid.connectivityNetworkIsConnected() != expected_state:
3906 ad.log.info("NetworkIsConnected = %s, expecting %s",
3907 not expected_state, expected_state)
Betty Zhou9f4dfbb2018-03-20 16:00:42 -07003908 if verify_internet_connection_by_ping(
3909 log, ad, retries=retries, expected_state=expected_state):
3910 return True
3911 for url in ("https://www.google.com", "https://www.amazon.com"):
3912 if verify_http_connection(
3913 log, ad, url=url, retry=retries,
3914 expected_state=expected_state):
3915 return True
Betty Zhoue123c672018-03-21 19:57:11 -07003916 ad.log.info("DNS config: %s", " ".join(
3917 ad.adb.shell("getprop | grep dns").split()))
Betty Zhoufe726dc2018-04-25 19:31:33 -07003918 ad.log.info("Interface info:\n%s", ad.adb.shell("ifconfig"))
Betty Zhoue123c672018-03-21 19:57:11 -07003919 ad.log.info("NetworkAgentInfo: %s",
3920 ad.adb.shell("dumpsys connectivity | grep NetworkAgentInfo"))
Jaineel6c576c92017-09-11 10:02:23 -07003921 return False
Betty Zhou8e11e442017-03-30 20:00:34 -07003922
3923
monikermine61898b92019-10-31 17:21:16 -07003924def iperf_test_with_options(log,
3925 ad,
3926 iperf_server,
3927 iperf_option,
3928 timeout=180,
3929 rate_dict=None,
3930 blocking=True,
3931 log_file_path=None):
3932 """Iperf adb run helper.
3933
3934 Args:
3935 log: log object
3936 ad: Android Device Object.
3937 iperf_server: The iperf host url".
3938 iperf_option: The options to pass to iperf client
3939 timeout: timeout for file download to complete.
3940 rate_dict: dictionary that can be passed in to save data
3941 blocking: run iperf in blocking mode if True
3942 log_file_path: location to save logs
3943 Returns:
3944 True if IPerf runs without throwing an exception
3945 """
3946 try:
3947 if log_file_path:
3948 ad.adb.shell("rm %s" % log_file_path, ignore_status=True)
3949 ad.log.info("Running adb iperf test with server %s", iperf_server)
3950 ad.log.info("IPerf options are %s", iperf_option)
3951 if not blocking:
3952 ad.run_iperf_client_nb(
3953 iperf_server,
3954 iperf_option,
3955 timeout=timeout + 60,
3956 log_file_path=log_file_path)
3957 return True
3958 result, data = ad.run_iperf_client(
3959 iperf_server, iperf_option, timeout=timeout + 60)
3960 ad.log.info("IPerf test result with server %s is %s", iperf_server,
3961 result)
3962 if result:
3963 iperf_str = ''.join(data)
3964 iperf_result = ipf.IPerfResult(iperf_str)
3965 if "-u" in iperf_option:
3966 udp_rate = iperf_result.avg_rate
3967 if udp_rate is None:
3968 ad.log.warning(
3969 "UDP rate is none, IPerf server returned error: %s",
3970 iperf_result.error)
3971 ad.log.info("IPerf3 udp speed is %sbps", udp_rate)
3972 else:
3973 tx_rate = iperf_result.avg_send_rate
3974 rx_rate = iperf_result.avg_receive_rate
3975 if (tx_rate or rx_rate) is None:
3976 ad.log.warning(
3977 "A TCP rate is none, IPerf server returned error: %s",
3978 iperf_result.error)
3979 ad.log.info(
3980 "IPerf3 upload speed is %sbps, download speed is %sbps",
3981 tx_rate, rx_rate)
3982 if rate_dict is not None:
3983 rate_dict["Uplink"] = tx_rate
3984 rate_dict["Downlink"] = rx_rate
3985 return result
3986 except AdbError as e:
3987 ad.log.warning("Fail to run iperf test with exception %s", e)
3988 raise
3989
3990
3991def iperf_udp_test_by_adb(log,
3992 ad,
3993 iperf_server,
3994 port_num=None,
3995 reverse=False,
3996 timeout=180,
3997 limit_rate=None,
3998 omit=10,
3999 ipv6=False,
4000 rate_dict=None,
4001 blocking=True,
4002 log_file_path=None):
4003 """Iperf test by adb using UDP.
4004
4005 Args:
4006 log: log object
4007 ad: Android Device Object.
4008 iperf_Server: The iperf host url".
4009 port_num: TCP/UDP server port
4010 reverse: whether to test download instead of upload
4011 timeout: timeout for file download to complete.
4012 limit_rate: iperf bandwidth option. None by default
4013 omit: the omit option provided in iperf command.
4014 ipv6: whether to run the test as ipv6
4015 rate_dict: dictionary that can be passed in to save data
4016 blocking: run iperf in blocking mode if True
4017 log_file_path: location to save logs
4018 """
4019 iperf_option = "-u -i 1 -t %s -O %s -J" % (timeout, omit)
4020 if limit_rate:
4021 iperf_option += " -b %s" % limit_rate
4022 if port_num:
4023 iperf_option += " -p %s" % port_num
4024 if ipv6:
4025 iperf_option += " -6"
4026 if reverse:
4027 iperf_option += " -R"
4028 try:
4029 return iperf_test_with_options(log,
4030 ad,
4031 iperf_server,
4032 iperf_option,
4033 timeout,
4034 rate_dict,
4035 blocking,
4036 log_file_path)
4037 except AdbError:
4038 return False
4039
Betty Zhou2e01bc82017-03-17 10:55:57 -07004040def iperf_test_by_adb(log,
4041 ad,
4042 iperf_server,
Jaineel6f88b5b2017-04-17 09:58:46 -07004043 port_num=None,
4044 reverse=False,
Betty Zhou2e01bc82017-03-17 10:55:57 -07004045 timeout=180,
Jaineel6f88b5b2017-04-17 09:58:46 -07004046 limit_rate=None,
Betty Zhou2e01bc82017-03-17 10:55:57 -07004047 omit=10,
Jaineele74e8e12017-05-08 15:59:42 -07004048 ipv6=False,
Patrick Chiang75b89862017-10-13 17:02:29 -07004049 rate_dict=None,
4050 blocking=True,
4051 log_file_path=None):
monikermine61898b92019-10-31 17:21:16 -07004052 """Iperf test by adb using TCP.
Betty Zhou2e01bc82017-03-17 10:55:57 -07004053
4054 Args:
4055 log: log object
4056 ad: Android Device Object.
monikermine61898b92019-10-31 17:21:16 -07004057 iperf_server: The iperf host url".
Jaineel6f88b5b2017-04-17 09:58:46 -07004058 port_num: TCP/UDP server port
monikermine61898b92019-10-31 17:21:16 -07004059 reverse: whether to test download instead of upload
Betty Zhou2e01bc82017-03-17 10:55:57 -07004060 timeout: timeout for file download to complete.
4061 limit_rate: iperf bandwidth option. None by default
4062 omit: the omit option provided in iperf command.
monikermine61898b92019-10-31 17:21:16 -07004063 ipv6: whether to run the test as ipv6
4064 rate_dict: dictionary that can be passed in to save data
4065 blocking: run iperf in blocking mode if True
4066 log_file_path: location to save logs
Betty Zhou2e01bc82017-03-17 10:55:57 -07004067 """
4068 iperf_option = "-t %s -O %s -J" % (timeout, omit)
monikermine61898b92019-10-31 17:21:16 -07004069 if limit_rate:
4070 iperf_option += " -b %s" % limit_rate
4071 if port_num:
4072 iperf_option += " -p %s" % port_num
4073 if ipv6:
4074 iperf_option += " -6"
4075 if reverse:
4076 iperf_option += " -R"
Betty Zhou2e01bc82017-03-17 10:55:57 -07004077 try:
monikermine61898b92019-10-31 17:21:16 -07004078 return iperf_test_with_options(log,
4079 ad,
4080 iperf_server,
4081 iperf_option,
4082 timeout,
4083 rate_dict,
4084 blocking,
4085 log_file_path)
4086 except AdbError:
Betty Zhou2e01bc82017-03-17 10:55:57 -07004087 return False
4088
Betty Zhoue955be22017-04-12 17:28:05 -07004089
Betty Zhou86671922017-05-10 15:32:10 -07004090def http_file_download_by_curl(ad,
4091 url,
4092 out_path=None,
4093 expected_file_size=None,
4094 remove_file_after_check=True,
Betty Zhou35ea5952017-06-26 10:01:09 -07004095 timeout=3600,
Betty Zhou86671922017-05-10 15:32:10 -07004096 limit_rate=None,
4097 retry=3):
Betty Zhouccd171d2017-02-13 15:11:33 -08004098 """Download http file by adb curl.
4099
4100 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08004101 ad: Android Device Object.
4102 url: The url that file to be downloaded from".
4103 out_path: Optional. Where to download file to.
4104 out_path is /sdcard/Download/ by default.
4105 expected_file_size: Optional. Provided if checking the download file meet
4106 expected file size in unit of byte.
4107 remove_file_after_check: Whether to remove the downloaded file after
4108 check.
4109 timeout: timeout for file download to complete.
4110 limit_rate: download rate in bps. None, if do not apply rate limit.
4111 retry: the retry request times provided in curl command.
4112 """
Betty Zhoucea4b432017-07-20 18:29:24 -07004113 file_directory, file_name = _generate_file_directory_and_file_name(
4114 url, out_path)
4115 file_path = os.path.join(file_directory, file_name)
Jaineel3ee37012017-08-21 15:21:57 -07004116 curl_cmd = "/data/curl"
Betty Zhouccd171d2017-02-13 15:11:33 -08004117 if limit_rate:
4118 curl_cmd += " --limit-rate %s" % limit_rate
4119 if retry:
4120 curl_cmd += " --retry %s" % retry
Betty Zhoucea4b432017-07-20 18:29:24 -07004121 curl_cmd += " --url %s > %s" % (url, file_path)
Betty Zhouccd171d2017-02-13 15:11:33 -08004122 try:
Betty Zhoucea4b432017-07-20 18:29:24 -07004123 ad.log.info("Download %s to %s by adb shell command %s", url,
4124 file_path, curl_cmd)
Jaineel667e92d2018-09-11 14:47:15 -07004125
Betty Zhouccd171d2017-02-13 15:11:33 -08004126 ad.adb.shell(curl_cmd, timeout=timeout)
Betty Zhoucea4b432017-07-20 18:29:24 -07004127 if _check_file_existance(ad, file_path, expected_file_size):
4128 ad.log.info("%s is downloaded to %s successfully", url, file_path)
Jaineel667e92d2018-09-11 14:47:15 -07004129 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08004130 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004131 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004132 return False
4133 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07004134 ad.log.warning("Download %s failed with exception %s", url, e)
Jaineel0df4eaa2018-09-06 15:23:23 -07004135 for cmd in ("ls -lh /data/local/tmp/tcpdump/",
4136 "ls -lh /sdcard/Download/",
4137 "ls -lh /data/vendor/radio/diag_logs/logs/",
4138 "df -h",
4139 "du -d 4 -h /data"):
4140 out = ad.adb.shell(cmd)
Jaineeld4993e12018-08-30 15:09:55 -07004141 ad.log.debug("%s", out)
Betty Zhouccd171d2017-02-13 15:11:33 -08004142 return False
4143 finally:
4144 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004145 ad.log.info("Remove the downloaded file %s", file_path)
4146 ad.adb.shell("rm %s" % file_path, ignore_status=True)
4147
4148
4149def open_url_by_adb(ad, url):
Betty Zhou8da03782017-07-28 18:02:24 -07004150 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004151
4152
Betty Zhou86671922017-05-10 15:32:10 -07004153def http_file_download_by_chrome(ad,
4154 url,
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 """Download http file by chrome.
4159
4160 Args:
4161 ad: Android Device Object.
4162 url: The url that file to be downloaded from".
Betty Zhou86671922017-05-10 15:32:10 -07004163 expected_file_size: Optional. Provided if checking the download file meet
4164 expected file size in unit of byte.
4165 remove_file_after_check: Whether to remove the downloaded file after
4166 check.
4167 timeout: timeout for file download to complete.
4168 """
Betty Zhou92437702018-02-07 19:49:07 -08004169 chrome_apk = "com.android.chrome"
Betty Zhoucea4b432017-07-20 18:29:24 -07004170 file_directory, file_name = _generate_file_directory_and_file_name(
Betty Zhoubcffe442017-07-05 17:27:55 -07004171 url, "/sdcard/Download/")
Betty Zhoucea4b432017-07-20 18:29:24 -07004172 file_path = os.path.join(file_directory, file_name)
Betty Zhouf17f0692017-06-28 13:10:31 -07004173 # Remove pre-existing file
Betty Zhou92437702018-02-07 19:49:07 -08004174 ad.force_stop_apk(chrome_apk)
markdr6607bf12018-01-02 14:45:38 -08004175 file_to_be_delete = os.path.join(file_directory, "*%s*" % file_name)
Betty Zhoue5f61b32018-01-26 10:48:00 -08004176 ad.adb.shell("rm -f %s" % file_to_be_delete)
4177 ad.adb.shell("rm -rf /sdcard/Download/.*")
4178 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou92437702018-02-07 19:49:07 -08004179 data_accounting = {
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004180 "total_rx_bytes": ad.droid.getTotalRxBytes(),
4181 "mobile_rx_bytes": ad.droid.getMobileRxBytes(),
4182 "subscriber_mobile_data_usage": get_mobile_data_usage(ad, None, None),
4183 "chrome_mobile_data_usage": get_mobile_data_usage(
4184 ad, None, chrome_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08004185 }
Jaineelf8be1892019-04-04 18:19:45 -07004186 ad.log.debug("Before downloading: %s", data_accounting)
Betty Zhoucea4b432017-07-20 18:29:24 -07004187 ad.log.info("Download %s with timeout %s", url, timeout)
Betty Zhouc80af152018-04-27 18:22:17 -07004188 ad.ensure_screen_on()
Betty Zhoucea4b432017-07-20 18:29:24 -07004189 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07004190 elapse_time = 0
Betty Zhou92437702018-02-07 19:49:07 -08004191 result = True
Betty Zhou86671922017-05-10 15:32:10 -07004192 while elapse_time < timeout:
4193 time.sleep(30)
Betty Zhoucea4b432017-07-20 18:29:24 -07004194 if _check_file_existance(ad, file_path, expected_file_size):
4195 ad.log.info("%s is downloaded successfully", url)
Betty Zhou86671922017-05-10 15:32:10 -07004196 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004197 ad.log.info("Remove the downloaded file %s", file_path)
Betty Zhoue5f61b32018-01-26 10:48:00 -08004198 ad.adb.shell("rm -f %s" % file_to_be_delete)
4199 ad.adb.shell("rm -rf /sdcard/Download/.*")
4200 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou08c1a572018-02-13 20:07:55 -08004201 #time.sleep(30)
Betty Zhou92437702018-02-07 19:49:07 -08004202 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004203 "mobile_rx_bytes":
4204 ad.droid.getMobileRxBytes(),
4205 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004206 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004207 "chrome_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004208 get_mobile_data_usage(ad, None, chrome_apk)
Betty Zhou92437702018-02-07 19:49:07 -08004209 }
4210 ad.log.info("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08004211 accounting_diff = {
4212 key: value - data_accounting[key]
4213 for key, value in new_data_accounting.items()
4214 }
Jaineelf8be1892019-04-04 18:19:45 -07004215 ad.log.debug("Data accounting difference: %s", accounting_diff)
Betty Zhou1b302fd2017-11-17 11:43:09 -08004216 if getattr(ad, "on_mobile_data", False):
Betty Zhou92437702018-02-07 19:49:07 -08004217 for key, value in accounting_diff.items():
4218 if value < expected_file_size:
Betty Zhou02571f52018-02-16 14:11:16 -08004219 ad.log.warning("%s diff is %s less than %s", key,
4220 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08004221 ad.data_accounting["%s_failure" % key] += 1
Betty Zhou1b302fd2017-11-17 11:43:09 -08004222 else:
Betty Zhou92437702018-02-07 19:49:07 -08004223 for key, value in accounting_diff.items():
4224 if value >= expected_file_size:
4225 ad.log.error("%s diff is %s. File download is "
4226 "consuming mobile data", key, value)
4227 result = False
4228 return result
Betty Zhoucea4b432017-07-20 18:29:24 -07004229 elif _check_file_existance(ad, "%s.crdownload" % file_path):
4230 ad.log.info("Chrome is downloading %s", url)
4231 elif elapse_time < 60:
4232 # download not started, retry download wit chrome again
4233 open_url_by_adb(ad, url)
Betty Zhou86671922017-05-10 15:32:10 -07004234 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004235 ad.log.error("Unable to download file from %s", url)
4236 break
4237 elapse_time += 30
Betty Zhouf3366012017-11-21 18:23:20 -08004238 ad.log.warning("Fail to download file from %s", url)
Betty Zhou95ed1862017-07-21 13:29:02 -07004239 ad.force_stop_apk("com.android.chrome")
Betty Zhoue5f61b32018-01-26 10:48:00 -08004240 ad.adb.shell("rm -f %s" % file_to_be_delete)
4241 ad.adb.shell("rm -rf /sdcard/Download/.*")
4242 ad.adb.shell("rm -f /sdcard/Download/.*")
Betty Zhou86671922017-05-10 15:32:10 -07004243 return False
4244
4245
Betty Zhou92437702018-02-07 19:49:07 -08004246def http_file_download_by_sl4a(ad,
Betty Zhouccd171d2017-02-13 15:11:33 -08004247 url,
4248 out_path=None,
4249 expected_file_size=None,
4250 remove_file_after_check=True,
4251 timeout=300):
4252 """Download http file by sl4a RPC call.
4253
4254 Args:
Betty Zhouccd171d2017-02-13 15:11:33 -08004255 ad: Android Device Object.
4256 url: The url that file to be downloaded from".
4257 out_path: Optional. Where to download file to.
4258 out_path is /sdcard/Download/ by default.
4259 expected_file_size: Optional. Provided if checking the download file meet
4260 expected file size in unit of byte.
4261 remove_file_after_check: Whether to remove the downloaded file after
4262 check.
4263 timeout: timeout for file download to complete.
4264 """
Betty Zhouee311052017-12-19 13:09:56 -08004265 file_folder, file_name = _generate_file_directory_and_file_name(
4266 url, out_path)
Betty Zhoucea4b432017-07-20 18:29:24 -07004267 file_path = os.path.join(file_folder, file_name)
Betty Zhou08c1a572018-02-13 20:07:55 -08004268 ad.adb.shell("rm -f %s" % file_path)
Betty Zhou92437702018-02-07 19:49:07 -08004269 accounting_apk = SL4A_APK_NAME
4270 result = True
Betty Zhouccd171d2017-02-13 15:11:33 -08004271 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004272 if not getattr(ad, "data_droid", None):
4273 ad.data_droid, ad.data_ed = ad.get_droid()
4274 ad.data_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08004275 else:
4276 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004277 if not ad.data_droid.is_live:
4278 ad.data_droid, ad.data_ed = ad.get_droid()
4279 ad.data_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08004280 except Exception:
4281 ad.log.info("Start new sl4a session for file download")
Betty Zhou03bd3f92018-06-06 17:37:56 -07004282 ad.data_droid, ad.data_ed = ad.get_droid()
4283 ad.data_ed.start()
Betty Zhou92437702018-02-07 19:49:07 -08004284 data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004285 "mobile_rx_bytes":
4286 ad.droid.getMobileRxBytes(),
4287 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004288 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004289 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004290 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou02571f52018-02-16 14:11:16 -08004291 }
Jaineelf8be1892019-04-04 18:19:45 -07004292 ad.log.debug("Before downloading: %s", data_accounting)
Betty Zhouccd171d2017-02-13 15:11:33 -08004293 ad.log.info("Download file from %s to %s by sl4a RPC call", url,
Betty Zhoucea4b432017-07-20 18:29:24 -07004294 file_path)
Betty Zhou14c08372018-02-15 10:26:23 -08004295 try:
Betty Zhou03bd3f92018-06-06 17:37:56 -07004296 ad.data_droid.httpDownloadFile(url, file_path, timeout=timeout)
Betty Zhou14c08372018-02-15 10:26:23 -08004297 except Exception as e:
4298 ad.log.warning("SL4A file download error: %s", e)
Jaineel0df4eaa2018-09-06 15:23:23 -07004299 for cmd in ("ls -lh /data/local/tmp/tcpdump/",
4300 "ls -lh /sdcard/Download/",
4301 "ls -lh /data/vendor/radio/diag_logs/logs/",
4302 "df -h",
4303 "du -d 4 -h /data"):
4304 out = ad.adb.shell(cmd)
Jaineeld4993e12018-08-30 15:09:55 -07004305 ad.log.debug("%s", out)
Betty Zhou03bd3f92018-06-06 17:37:56 -07004306 ad.data_droid.terminate()
Betty Zhou14c08372018-02-15 10:26:23 -08004307 return False
Betty Zhoucea4b432017-07-20 18:29:24 -07004308 if _check_file_existance(ad, file_path, expected_file_size):
4309 ad.log.info("%s is downloaded successfully", url)
Betty Zhou92437702018-02-07 19:49:07 -08004310 new_data_accounting = {
Betty Zhou02571f52018-02-16 14:11:16 -08004311 "mobile_rx_bytes":
4312 ad.droid.getMobileRxBytes(),
4313 "subscriber_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004314 get_mobile_data_usage(ad, None, None),
Betty Zhou02571f52018-02-16 14:11:16 -08004315 "sl4a_mobile_data_usage":
Betty Zhouf1cc3b62018-02-28 12:02:05 -08004316 get_mobile_data_usage(ad, None, accounting_apk)
Betty Zhou92437702018-02-07 19:49:07 -08004317 }
Jaineelf8be1892019-04-04 18:19:45 -07004318 ad.log.debug("After downloading: %s", new_data_accounting)
Betty Zhou02571f52018-02-16 14:11:16 -08004319 accounting_diff = {
4320 key: value - data_accounting[key]
4321 for key, value in new_data_accounting.items()
4322 }
Jaineelf8be1892019-04-04 18:19:45 -07004323 ad.log.debug("Data accounting difference: %s", accounting_diff)
Betty Zhou92437702018-02-07 19:49:07 -08004324 if getattr(ad, "on_mobile_data", False):
4325 for key, value in accounting_diff.items():
4326 if value < expected_file_size:
Jaineelf8be1892019-04-04 18:19:45 -07004327 ad.log.debug("%s diff is %s less than %s", key,
Betty Zhou02571f52018-02-16 14:11:16 -08004328 value, expected_file_size)
Betty Zhou92437702018-02-07 19:49:07 -08004329 ad.data_accounting["%s_failure"] += 1
4330 else:
4331 for key, value in accounting_diff.items():
4332 if value >= expected_file_size:
4333 ad.log.error("%s diff is %s. File download is "
4334 "consuming mobile data", key, value)
4335 result = False
4336 return result
Betty Zhouccd171d2017-02-13 15:11:33 -08004337 else:
Betty Zhoucea4b432017-07-20 18:29:24 -07004338 ad.log.warning("Fail to download %s", url)
Betty Zhouccd171d2017-02-13 15:11:33 -08004339 return False
4340 except Exception as e:
Betty Zhoucea4b432017-07-20 18:29:24 -07004341 ad.log.error("Download %s failed with exception %s", url, e)
Betty Zhouccd171d2017-02-13 15:11:33 -08004342 raise
4343 finally:
4344 if remove_file_after_check:
Betty Zhoucea4b432017-07-20 18:29:24 -07004345 ad.log.info("Remove the downloaded file %s", file_path)
4346 ad.adb.shell("rm %s" % file_path, ignore_status=True)
Betty Zhouccd171d2017-02-13 15:11:33 -08004347
Betty Zhou2cf788e2017-06-27 17:25:53 -07004348
Markus Liu1acb5922020-01-02 18:21:46 +08004349def get_wifi_usage(ad, sid=None, apk=None):
4350 if not sid:
4351 sid = ad.droid.subscriptionGetDefaultDataSubId()
4352 current_time = int(time.time() * 1000)
4353 begin_time = current_time - 10 * 24 * 60 * 60 * 1000
4354 end_time = current_time + 10 * 24 * 60 * 60 * 1000
4355
4356 if apk:
4357 uid = ad.get_apk_uid(apk)
4358 ad.log.debug("apk %s uid = %s", apk, uid)
4359 try:
4360 return ad.droid.connectivityQueryDetailsForUid(
4361 TYPE_WIFI,
4362 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4363 begin_time, end_time, uid)
4364 except:
4365 return ad.droid.connectivityQueryDetailsForUid(
4366 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4367 begin_time, end_time, uid)
4368 else:
4369 try:
4370 return ad.droid.connectivityQuerySummaryForDevice(
4371 TYPE_WIFI,
4372 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4373 begin_time, end_time)
4374 except:
4375 return ad.droid.connectivityQuerySummaryForDevice(
4376 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4377 begin_time, end_time)
4378
4379
Betty Zhou65666862018-06-05 13:51:48 -07004380def get_mobile_data_usage(ad, sid=None, apk=None):
4381 if not sid:
Markus Liu05a05652019-08-01 17:30:47 +08004382 sid = ad.droid.subscriptionGetDefaultDataSubId()
Betty Zhou65666862018-06-05 13:51:48 -07004383 current_time = int(time.time() * 1000)
4384 begin_time = current_time - 10 * 24 * 60 * 60 * 1000
4385 end_time = current_time + 10 * 24 * 60 * 60 * 1000
Betty Zhoua3f248f2018-03-05 17:33:49 -08004386
Betty Zhou92437702018-02-07 19:49:07 -08004387 if apk:
4388 uid = ad.get_apk_uid(apk)
Jaineelf8be1892019-04-04 18:19:45 -07004389 ad.log.debug("apk %s uid = %s", apk, uid)
Betty Zhou92437702018-02-07 19:49:07 -08004390 try:
Betty Zhou65666862018-06-05 13:51:48 -07004391 usage_info = ad.droid.getMobileDataUsageInfoForUid(uid, sid)
Jaineelf8be1892019-04-04 18:19:45 -07004392 ad.log.debug("Mobile data usage info for uid %s = %s", uid,
Betty Zhou65666862018-06-05 13:51:48 -07004393 usage_info)
4394 return usage_info["UsageLevel"]
4395 except:
4396 try:
4397 return ad.droid.connectivityQueryDetailsForUid(
4398 TYPE_MOBILE,
4399 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4400 begin_time, end_time, uid)
4401 except:
4402 return ad.droid.connectivityQueryDetailsForUid(
4403 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4404 begin_time, end_time, uid)
4405 else:
4406 try:
4407 usage_info = ad.droid.getMobileDataUsageInfo(sid)
Jaineelf8be1892019-04-04 18:19:45 -07004408 ad.log.debug("Mobile data usage info = %s", usage_info)
Betty Zhou65666862018-06-05 13:51:48 -07004409 return usage_info["UsageLevel"]
4410 except:
4411 try:
4412 return ad.droid.connectivityQuerySummaryForDevice(
4413 TYPE_MOBILE,
4414 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4415 begin_time, end_time)
4416 except:
4417 return ad.droid.connectivityQuerySummaryForDevice(
4418 ad.droid.telephonyGetSubscriberIdForSubscription(sid),
4419 begin_time, end_time)
Betty Zhouf3366012017-11-21 18:23:20 -08004420
4421
4422def set_mobile_data_usage_limit(ad, limit, subscriber_id=None):
4423 if not subscriber_id:
4424 subscriber_id = ad.droid.telephonyGetSubscriberId()
Jaineelf8be1892019-04-04 18:19:45 -07004425 ad.log.debug("Set subscriber mobile data usage limit to %s", limit)
Betty Zhou10f887e2018-04-10 12:45:00 -07004426 ad.droid.logV("Setting subscriber mobile data usage limit to %s" % limit)
Betty Zhou65666862018-06-05 13:51:48 -07004427 try:
4428 ad.droid.connectivitySetDataUsageLimit(subscriber_id, str(limit))
4429 except:
4430 ad.droid.connectivitySetDataUsageLimit(subscriber_id, limit)
Betty Zhouf3366012017-11-21 18:23:20 -08004431
4432
4433def remove_mobile_data_usage_limit(ad, subscriber_id=None):
4434 if not subscriber_id:
4435 subscriber_id = ad.droid.telephonyGetSubscriberId()
Betty Zhoue57ab692018-03-09 18:39:30 -08004436 ad.log.debug("Remove subscriber mobile data usage limit")
Betty Zhou10f887e2018-04-10 12:45:00 -07004437 ad.droid.logV(
4438 "Setting subscriber mobile data usage limit to -1, unlimited")
Betty Zhou65666862018-06-05 13:51:48 -07004439 try:
4440 ad.droid.connectivitySetDataUsageLimit(subscriber_id, "-1")
4441 except:
4442 ad.droid.connectivitySetDataUsageLimit(subscriber_id, -1)
Betty Zhouf3366012017-11-21 18:23:20 -08004443
4444
Betty Zhouae9d6a82018-02-15 20:05:34 -08004445def trigger_modem_crash(ad, timeout=120):
Jaineel40884782017-06-08 15:53:39 -07004446 cmd = "echo restart > /sys/kernel/debug/msm_subsys/modem"
Betty Zhouae9d6a82018-02-15 20:05:34 -08004447 ad.log.info("Triggering Modem Crash from kernel using adb command %s", cmd)
4448 ad.adb.shell(cmd)
4449 time.sleep(timeout)
Jaineel40884782017-06-08 15:53:39 -07004450 return True
Betty Zhouccd171d2017-02-13 15:11:33 -08004451
Betty Zhou2cf788e2017-06-27 17:25:53 -07004452
Betty Zhouae9d6a82018-02-15 20:05:34 -08004453def trigger_modem_crash_by_modem(ad, timeout=120):
Betty Zhoued13b712018-05-02 19:40:10 -07004454 begin_time = get_device_epoch_time(ad)
Betty Zhouae9d6a82018-02-15 20:05:34 -08004455 ad.adb.shell(
Betty Zhouc8213812018-04-02 14:06:50 -07004456 "setprop persist.vendor.sys.modem.diag.mdlog false",
4457 ignore_status=True)
Jaekyun Seok7e8ba572018-03-19 12:31:31 +09004458 # Legacy pixels use persist.sys.modem.diag.mdlog.
4459 ad.adb.shell(
Betty Zhouae9d6a82018-02-15 20:05:34 -08004460 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
Betty Zhoud8630832018-06-06 18:58:02 -07004461 disable_qxdm_logger(ad)
Betty Zhou02571f52018-02-16 14:11:16 -08004462 cmd = ('am instrument -w -e request "4b 25 03 00" '
4463 '"com.google.mdstest/com.google.mdstest.instrument.'
4464 'ModemCommandInstrumentation"')
4465 ad.log.info("Crash modem by %s", cmd)
4466 ad.adb.shell(cmd, ignore_status=True)
4467 time.sleep(timeout) # sleep time for sl4a stability
Betty Zhouae9d6a82018-02-15 20:05:34 -08004468 reasons = ad.search_logcat("modem subsystem failure reason", begin_time)
4469 if reasons:
4470 ad.log.info("Modem crash is triggered successfully")
4471 ad.log.info(reasons[-1]["log_message"])
4472 return True
4473 else:
Betty Zhoufe726dc2018-04-25 19:31:33 -07004474 ad.log.warning("There is no modem subsystem failure reason logcat")
Betty Zhouae9d6a82018-02-15 20:05:34 -08004475 return False
4476
4477
Jaineelfc5a4e02019-02-12 15:31:44 -08004478def phone_switch_to_msim_mode(ad, retries=3, timeout=60):
4479 result = False
Jaineel15c50562019-03-29 15:45:32 -07004480 if not ad.is_apk_installed("com.google.mdstest"):
Xianyuan Jia821cf572019-10-08 12:24:00 -07004481 raise signals.TestAbortClass("mdstest is not installed")
Jaineel15c50562019-03-29 15:45:32 -07004482 mode = ad.droid.telephonyGetPhoneCount()
4483 if mode == 2:
4484 ad.log.info("Device already in MSIM mode")
4485 return True
Jaineelfc5a4e02019-02-12 15:31:44 -08004486 for i in range(retries):
4487 ad.adb.shell(
4488 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True)
4489 ad.adb.shell(
4490 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
4491 disable_qxdm_logger(ad)
4492 cmd = ('am instrument -w -e request "WriteEFS" -e item '
4493 '"/google/pixel_multisim_config" -e data "02 00 00 00" '
4494 '"com.google.mdstest/com.google.mdstest.instrument.'
4495 'ModemConfigInstrumentation"')
4496 ad.log.info("Switch to MSIM mode by using %s", cmd)
4497 ad.adb.shell(cmd, ignore_status=True)
4498 time.sleep(timeout)
4499 ad.adb.shell("setprop persist.radio.multisim.config dsds")
4500 reboot_device(ad)
4501 # Verify if device is really in msim mode
Jaineel15c50562019-03-29 15:45:32 -07004502 mode = ad.droid.telephonyGetPhoneCount()
4503 if mode == 2:
Jaineelfc5a4e02019-02-12 15:31:44 -08004504 ad.log.info("Device correctly switched to MSIM mode")
4505 result = True
Jaineel12cf1952019-06-14 13:15:45 -07004506 if "Sprint" in ad.adb.getprop("gsm.sim.operator.alpha"):
4507 cmd = ('am instrument -w -e request "WriteEFS" -e item '
4508 '"/google/pixel_dsds_imei_mapping_slot_record" -e data "03"'
4509 ' "com.google.mdstest/com.google.mdstest.instrument.'
4510 'ModemConfigInstrumentation"')
4511 ad.log.info("Switch Sprint to IMEI1 slot using %s", cmd)
4512 ad.adb.shell(cmd, ignore_status=True)
4513 time.sleep(timeout)
4514 reboot_device(ad)
Jaineelfc5a4e02019-02-12 15:31:44 -08004515 break
4516 else:
4517 ad.log.warning("Attempt %d - failed to switch to MSIM", (i + 1))
4518 return result
4519
4520
4521def phone_switch_to_ssim_mode(ad, retries=3, timeout=30):
4522 result = False
Jaineel15c50562019-03-29 15:45:32 -07004523 if not ad.is_apk_installed("com.google.mdstest"):
Xianyuan Jia821cf572019-10-08 12:24:00 -07004524 raise signals.TestAbortClass("mdstest is not installed")
Jaineel15c50562019-03-29 15:45:32 -07004525 mode = ad.droid.telephonyGetPhoneCount()
4526 if mode == 1:
4527 ad.log.info("Device already in SSIM mode")
4528 return True
Jaineelfc5a4e02019-02-12 15:31:44 -08004529 for i in range(retries):
4530 ad.adb.shell(
4531 "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True)
4532 ad.adb.shell(
4533 "setprop persist.sys.modem.diag.mdlog false", ignore_status=True)
4534 disable_qxdm_logger(ad)
4535 cmds = ('am instrument -w -e request "WriteEFS" -e item '
4536 '"/google/pixel_multisim_config" -e data "01 00 00 00" '
4537 '"com.google.mdstest/com.google.mdstest.instrument.'
4538 'ModemConfigInstrumentation"',
4539 'am instrument -w -e request "WriteEFS" -e item "/nv/item_files'
4540 '/modem/uim/uimdrv/uim_extended_slot_mapping_config" -e data '
4541 '"00 01 02 01" "com.google.mdstest/com.google.mdstest.'
4542 'instrument.ModemConfigInstrumentation"')
4543 for cmd in cmds:
4544 ad.log.info("Switch to SSIM 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 ssss")
4548 reboot_device(ad)
4549 # Verify if device is really in ssim mode
Jaineel15c50562019-03-29 15:45:32 -07004550 mode = ad.droid.telephonyGetPhoneCount()
4551 if mode == 1:
Jaineelfc5a4e02019-02-12 15:31:44 -08004552 ad.log.info("Device correctly switched to SSIM mode")
4553 result = True
4554 break
4555 else:
4556 ad.log.warning("Attempt %d - failed to switch to SSIM", (i + 1))
4557 return result
4558
4559
Betty Zhou4d97af82018-06-07 14:05:52 -07004560def lock_lte_band_by_mds(ad, band):
Betty Zhoud8630832018-06-06 18:58:02 -07004561 disable_qxdm_logger(ad)
4562 ad.log.info("Write band %s locking to efs file", band)
4563 if band == "4":
4564 item_string = (
4565 "4B 13 26 00 08 00 00 00 40 00 08 00 0B 00 08 00 00 00 00 00 00 00 "
4566 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D "
4567 "6D 6F 64 65 2F 6C 74 65 5F 62 61 6E 64 70 72 65 66 00")
4568 elif band == "13":
4569 item_string = (
4570 "4B 13 26 00 08 00 00 00 40 00 08 00 0A 00 00 10 00 00 00 00 00 00 "
4571 "2F 6E 76 2F 69 74 65 6D 5F 66 69 6C 65 73 2F 6D 6F 64 65 6D 2F 6D "
4572 "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 -07004573 else:
4574 ad.log.error("Band %s is not supported", band)
4575 return False
Betty Zhoud8630832018-06-06 18:58:02 -07004576 cmd = ('am instrument -w -e request "%s" com.google.mdstest/com.google.'
4577 'mdstest.instrument.ModemCommandInstrumentation')
4578 for _ in range(3):
4579 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True):
4580 break
4581 else:
4582 ad.log.error("Fail to write band by %s" % (cmd % item_string))
4583 return False
4584
Betty Zhoud8630832018-06-06 18:58:02 -07004585 # EFS Sync
4586 item_string = "4B 13 30 00 2A 00 2F 00"
4587
4588 for _ in range(3):
4589 if "SUCCESS" in ad.adb.shell(cmd % item_string, ignore_status=True):
4590 break
4591 else:
4592 ad.log.error("Fail to sync efs by %s" % (cmd % item_string))
4593 return False
4594 time.sleep(5)
4595 reboot_device(ad)
4596
4597
Ang Li73697b32015-12-03 00:41:53 +00004598def _connection_state_change(_event, target_state, connection_type):
4599 if connection_type:
4600 if 'TypeName' not in _event['data']:
4601 return False
4602 connection_type_string_in_event = _event['data']['TypeName']
Nathan Harold123c9da2015-12-30 16:33:25 -08004603 cur_type = connection_type_from_type_string(
4604 connection_type_string_in_event)
Ang Li73697b32015-12-03 00:41:53 +00004605 if cur_type != connection_type:
4606 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08004607 "_connection_state_change expect: %s, received: %s <type %s>",
4608 connection_type, connection_type_string_in_event, cur_type)
Ang Li73697b32015-12-03 00:41:53 +00004609 return False
4610
Betty Zhouee311052017-12-19 13:09:56 -08004611 if 'isConnected' in _event['data'] and _event['data']['isConnected'] == target_state:
Ang Li73697b32015-12-03 00:41:53 +00004612 return True
4613 return False
4614
4615
Nathan Harold123c9da2015-12-30 16:33:25 -08004616def wait_for_cell_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08004617 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004618 """Wait for data connection status to be expected value for default
4619 data subscription.
4620
4621 Wait for the data connection status to be DATA_STATE_CONNECTED
4622 or DATA_STATE_DISCONNECTED.
4623
4624 Args:
4625 log: Log object.
4626 ad: Android Device Object.
4627 state: Expected status: True or False.
4628 If True, it will wait for status to be DATA_STATE_CONNECTED.
4629 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4630 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004631 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004632
4633 Returns:
4634 True if success.
4635 False if failed.
4636 """
Yang Liu963c93c2016-04-05 10:52:00 -07004637 sub_id = get_default_data_sub_id(ad)
Betty Zhouee311052017-12-19 13:09:56 -08004638 return wait_for_cell_data_connection_for_subscription(
4639 log, ad, sub_id, state, timeout_value)
Nathan Harold123c9da2015-12-30 16:33:25 -08004640
Ang Li73697b32015-12-03 00:41:53 +00004641
4642def _is_data_connection_state_match(log, ad, expected_data_connection_state):
Nathan Harold123c9da2015-12-30 16:33:25 -08004643 return (expected_data_connection_state ==
4644 ad.droid.telephonyGetDataConnectionState())
Ang Li73697b32015-12-03 00:41:53 +00004645
Ang Li73697b32015-12-03 00:41:53 +00004646
Nathan Harold123c9da2015-12-30 16:33:25 -08004647def _is_network_connected_state_match(log, ad,
4648 expected_network_connected_state):
4649 return (expected_network_connected_state ==
4650 ad.droid.connectivityNetworkIsConnected())
4651
4652
4653def wait_for_cell_data_connection_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08004654 log,
4655 ad,
4656 sub_id,
4657 state,
4658 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004659 """Wait for data connection status to be expected value for specified
4660 subscrption id.
4661
4662 Wait for the data connection status to be DATA_STATE_CONNECTED
4663 or DATA_STATE_DISCONNECTED.
4664
4665 Args:
4666 log: Log object.
4667 ad: Android Device Object.
4668 sub_id: subscription Id
4669 state: Expected status: True or False.
4670 If True, it will wait for status to be DATA_STATE_CONNECTED.
4671 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4672 timeout_value: wait for cell data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004673 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004674
4675 Returns:
4676 True if success.
4677 False if failed.
4678 """
Yang Liu8e6adff2016-02-05 10:24:04 -08004679 state_str = {
4680 True: DATA_STATE_CONNECTED,
4681 False: DATA_STATE_DISCONNECTED
Ang Li73697b32015-12-03 00:41:53 +00004682 }[state]
4683
Betty Zhou68fc0d02017-04-26 13:42:54 -07004684 data_state = ad.droid.telephonyGetDataConnectionState()
4685 if not state and ad.droid.telephonyGetDataConnectionState() == state_str:
4686 return True
Betty Zhouc9f723b2018-04-10 18:08:21 -07004687
Betty Zhou287f9df2018-01-23 10:57:55 -08004688 ad.ed.clear_events(EventDataConnectionStateChanged)
Nathan Harold123c9da2015-12-30 16:33:25 -08004689 ad.droid.telephonyStartTrackingDataConnectionStateChangeForSubscription(
4690 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004691 ad.droid.connectivityStartTrackingConnectivityStateChange()
4692 try:
Betty Zhouc9f723b2018-04-10 18:08:21 -07004693 ad.log.info("User data enabled for sub_id %s: %s", sub_id,
4694 ad.droid.telephonyIsDataEnabledForSubscription(sub_id))
Yang Liuaed3eef2015-12-15 18:40:25 -08004695 data_state = ad.droid.telephonyGetDataConnectionState()
Betty Zhouc9f723b2018-04-10 18:08:21 -07004696 ad.log.info("Data connection state is %s", data_state)
4697 ad.log.info("Network is connected: %s",
4698 ad.droid.connectivityNetworkIsConnected())
Ang Li73697b32015-12-03 00:41:53 +00004699 if data_state == state_str:
Nathan Harold123c9da2015-12-30 16:33:25 -08004700 return _wait_for_nw_data_connection(
4701 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004702
4703 try:
Betty Zhou1c8c8d42018-03-14 12:43:50 -07004704 ad.ed.wait_for_event(
Nathan Harold7642fc92016-05-02 18:29:11 -07004705 EventDataConnectionStateChanged,
4706 is_event_match,
4707 timeout=timeout_value,
Yang Liu8e6adff2016-02-05 10:24:04 -08004708 field=DataConnectionStateContainer.DATA_CONNECTION_STATE,
4709 value=state_str)
Ang Li73697b32015-12-03 00:41:53 +00004710 except Empty:
Betty Zhouf25ce442017-03-03 14:28:36 -08004711 ad.log.info("No expected event EventDataConnectionStateChanged %s",
4712 state_str)
Ang Li73697b32015-12-03 00:41:53 +00004713
Yang Liudf164e32016-01-07 16:49:32 -08004714 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00004715 # data connection state.
4716 # Otherwise, the network state will not be correct.
4717 # The bug is tracked here: b/20921915
Ang Li73697b32015-12-03 00:41:53 +00004718
Yang Liu7a2e7ee2015-12-28 15:32:44 -08004719 # Previously we use _is_data_connection_state_match,
4720 # but telephonyGetDataConnectionState sometimes return wrong value.
4721 # The bug is tracked here: b/22612607
4722 # So we use _is_network_connected_state_match.
Ang Li73697b32015-12-03 00:41:53 +00004723
Betty Zhou58ad52a2018-02-08 16:38:16 -08004724 if _wait_for_droid_in_state(log, ad, timeout_value,
Nathan Harold123c9da2015-12-30 16:33:25 -08004725 _is_network_connected_state_match, state):
4726 return _wait_for_nw_data_connection(
4727 log, ad, state, NETWORK_CONNECTION_TYPE_CELL, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004728 else:
4729 return False
4730
4731 finally:
Nathan Harold123c9da2015-12-30 16:33:25 -08004732 ad.droid.telephonyStopTrackingDataConnectionStateChangeForSubscription(
4733 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00004734
Nathan Harold123c9da2015-12-30 16:33:25 -08004735
4736def wait_for_wifi_data_connection(
Betty Zhou58ad52a2018-02-08 16:38:16 -08004737 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004738 """Wait for data connection status to be expected value and connection is by WiFi.
4739
4740 Args:
4741 log: Log object.
4742 ad: Android Device Object.
4743 state: Expected status: True or False.
4744 If True, it will wait for status to be DATA_STATE_CONNECTED.
4745 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4746 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004747 This is optional, default value is MAX_WAIT_TIME_NW_SELECTION
Ang Li73697b32015-12-03 00:41:53 +00004748
4749 Returns:
4750 True if success.
4751 False if failed.
4752 """
Betty Zhoua37acd32017-02-23 20:04:24 -08004753 ad.log.info("wait_for_wifi_data_connection")
Nathan Harold123c9da2015-12-30 16:33:25 -08004754 return _wait_for_nw_data_connection(
4755 log, ad, state, NETWORK_CONNECTION_TYPE_WIFI, timeout_value)
Ang Li73697b32015-12-03 00:41:53 +00004756
4757
Betty Zhou02571f52018-02-16 14:11:16 -08004758def wait_for_data_connection(
4759 log, ad, state, timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004760 """Wait for data connection status to be expected value.
4761
4762 Wait for the data connection status to be DATA_STATE_CONNECTED
4763 or DATA_STATE_DISCONNECTED.
4764
4765 Args:
4766 log: Log object.
4767 ad: Android Device Object.
4768 state: Expected status: True or False.
4769 If True, it will wait for status to be DATA_STATE_CONNECTED.
4770 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4771 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004772 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004773
4774 Returns:
4775 True if success.
4776 False if failed.
4777 """
4778 return _wait_for_nw_data_connection(log, ad, state, None, timeout_value)
4779
4780
Nathan Harold123c9da2015-12-30 16:33:25 -08004781def _wait_for_nw_data_connection(
4782 log,
4783 ad,
4784 is_connected,
4785 connection_type=None,
Betty Zhou58ad52a2018-02-08 16:38:16 -08004786 timeout_value=MAX_WAIT_TIME_CONNECTION_STATE_UPDATE):
Ang Li73697b32015-12-03 00:41:53 +00004787 """Wait for data connection status to be expected value.
4788
4789 Wait for the data connection status to be DATA_STATE_CONNECTED
4790 or DATA_STATE_DISCONNECTED.
4791
4792 Args:
4793 log: Log object.
4794 ad: Android Device Object.
4795 is_connected: Expected connection status: True or False.
4796 If True, it will wait for status to be DATA_STATE_CONNECTED.
4797 If False, it will wait for status ti be DATA_STATE_DISCONNECTED.
4798 connection_type: expected connection type.
4799 This is optional, if it is None, then any connection type will return True.
4800 timeout_value: wait for network data timeout value.
Betty Zhou58ad52a2018-02-08 16:38:16 -08004801 This is optional, default value is MAX_WAIT_TIME_CONNECTION_STATE_UPDATE
Ang Li73697b32015-12-03 00:41:53 +00004802
4803 Returns:
4804 True if success.
4805 False if failed.
4806 """
Betty Zhoue34f9e22018-01-23 18:58:24 -08004807 ad.ed.clear_events(EventConnectivityChanged)
Ang Li73697b32015-12-03 00:41:53 +00004808 ad.droid.connectivityStartTrackingConnectivityStateChange()
4809 try:
4810 cur_data_connection_state = ad.droid.connectivityNetworkIsConnected()
4811 if is_connected == cur_data_connection_state:
4812 current_type = get_internet_connection_type(log, ad)
Betty Zhoue955be22017-04-12 17:28:05 -07004813 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00004814 if not connection_type:
4815 return True
4816 else:
4817 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004818 ad.log.info("data connection not on %s!", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004819 return True
4820 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004821 ad.log.info("data connection on %s as expected",
4822 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004823 return True
4824 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08004825 ad.log.info("current data connection state: %s target: %s",
4826 cur_data_connection_state, is_connected)
Ang Li73697b32015-12-03 00:41:53 +00004827
4828 try:
Nathan Harold123c9da2015-12-30 16:33:25 -08004829 event = ad.ed.wait_for_event(
4830 EventConnectivityChanged, _connection_state_change,
4831 timeout_value, is_connected, connection_type)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07004832 ad.log.info("Got event: %s", event)
Ang Li73697b32015-12-03 00:41:53 +00004833 except Empty:
4834 pass
4835
Nathan Harold123c9da2015-12-30 16:33:25 -08004836 log.info(
4837 "_wait_for_nw_data_connection: check connection after wait event.")
Yang Liudf164e32016-01-07 16:49:32 -08004838 # TODO: Wait for <MAX_WAIT_TIME_CONNECTION_STATE_UPDATE> seconds for
Ang Li73697b32015-12-03 00:41:53 +00004839 # data connection state.
4840 # Otherwise, the network state will not be correct.
4841 # The bug is tracked here: b/20921915
Betty Zhou02571f52018-02-16 14:11:16 -08004842 if _wait_for_droid_in_state(log, ad, timeout_value,
4843 _is_network_connected_state_match,
4844 is_connected):
Ang Li73697b32015-12-03 00:41:53 +00004845 current_type = get_internet_connection_type(log, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08004846 ad.log.info("current data connection type: %s", current_type)
Ang Li73697b32015-12-03 00:41:53 +00004847 if not connection_type:
4848 return True
4849 else:
4850 if not is_connected and current_type != connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004851 ad.log.info("data connection not on %s", connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004852 return True
4853 elif is_connected and current_type == connection_type:
Betty Zhoua37acd32017-02-23 20:04:24 -08004854 ad.log.info("after event wait, data connection on %s",
4855 connection_type)
Ang Li73697b32015-12-03 00:41:53 +00004856 return True
4857 else:
4858 return False
4859 else:
4860 return False
4861 except Exception as e:
Betty Zhoua37acd32017-02-23 20:04:24 -08004862 ad.log.error("Exception error %s", str(e))
Ang Li73697b32015-12-03 00:41:53 +00004863 return False
4864 finally:
4865 ad.droid.connectivityStopTrackingConnectivityStateChange()
4866
Nathan Harold123c9da2015-12-30 16:33:25 -08004867
Betty Zhou2cf788e2017-06-27 17:25:53 -07004868def get_cell_data_roaming_state_by_adb(ad):
4869 """Get Cell Data Roaming state. True for enabled, False for disabled"""
Betty Zhou2cf788e2017-06-27 17:25:53 -07004870 state_mapping = {"1": True, "0": False}
4871 return state_mapping[ad.adb.shell("settings get global data_roaming")]
4872
4873
4874def set_cell_data_roaming_state_by_adb(ad, state):
4875 """Set Cell Data Roaming state."""
4876 state_mapping = {True: "1", False: "0"}
4877 ad.log.info("Set data roaming to %s", state)
4878 ad.adb.shell("settings put global data_roaming %s" % state_mapping[state])
4879
4880
Betty Zhou9e2bf402017-02-01 19:04:09 -08004881def toggle_cell_data_roaming(ad, state):
4882 """Enable cell data roaming for default data subscription.
4883
4884 Wait for the data roaming status to be DATA_STATE_CONNECTED
4885 or DATA_STATE_DISCONNECTED.
4886
4887 Args:
4888 log: Log object.
4889 ad: Android Device Object.
4890 state: True or False for enable or disable cell data roaming.
4891
4892 Returns:
4893 True if success.
4894 False if failed.
4895 """
4896 state_int = {True: DATA_ROAMING_ENABLE, False: DATA_ROAMING_DISABLE}[state]
4897 action_str = {True: "Enable", False: "Disable"}[state]
4898 if ad.droid.connectivityCheckDataRoamingMode() == state:
4899 ad.log.info("Data roaming is already in state %s", state)
4900 return True
4901 if not ad.droid.connectivitySetDataRoaming(state_int):
4902 ad.error.info("Fail to config data roaming into state %s", state)
4903 return False
4904 if ad.droid.connectivityCheckDataRoamingMode() == state:
4905 ad.log.info("Data roaming is configured into state %s", state)
4906 return True
4907 else:
4908 ad.log.error("Data roaming is not configured into state %s", state)
4909 return False
4910
4911
Ang Li73697b32015-12-03 00:41:53 +00004912def verify_incall_state(log, ads, expected_status):
4913 """Verify phones in incall state or not.
4914
4915 Verify if all phones in the array <ads> are in <expected_status>.
4916
4917 Args:
4918 log: Log object.
4919 ads: Array of Android Device Object. All droid in this array will be tested.
4920 expected_status: If True, verify all Phones in incall state.
4921 If False, verify all Phones not in incall state.
4922
4923 """
4924 result = True
4925 for ad in ads:
4926 if ad.droid.telecomIsInCall() is not expected_status:
Betty Zhoua37acd32017-02-23 20:04:24 -08004927 ad.log.error("InCall status:%s, expected:%s",
4928 ad.droid.telecomIsInCall(), expected_status)
Ang Li73697b32015-12-03 00:41:53 +00004929 result = False
4930 return result
4931
Nathan Harold123c9da2015-12-30 16:33:25 -08004932
Ang Li73697b32015-12-03 00:41:53 +00004933def verify_active_call_number(log, ad, expected_number):
4934 """Verify the number of current active call.
4935
4936 Verify if the number of current active call in <ad> is
4937 equal to <expected_number>.
4938
4939 Args:
4940 ad: Android Device Object.
4941 expected_number: Expected active call number.
4942 """
4943 calls = ad.droid.telecomCallGetCallIds()
4944 if calls is None:
4945 actual_number = 0
4946 else:
4947 actual_number = len(calls)
4948 if actual_number != expected_number:
Betty Zhoua37acd32017-02-23 20:04:24 -08004949 ad.log.error("Active Call number is %s, expecting", actual_number,
4950 expected_number)
Ang Li73697b32015-12-03 00:41:53 +00004951 return False
4952 return True
4953
Nathan Harold123c9da2015-12-30 16:33:25 -08004954
Ang Li73697b32015-12-03 00:41:53 +00004955def num_active_calls(log, ad):
4956 """Get the count of current active calls.
4957
4958 Args:
4959 log: Log object.
4960 ad: Android Device Object.
4961
4962 Returns:
4963 Count of current active calls.
4964 """
4965 calls = ad.droid.telecomCallGetCallIds()
4966 return len(calls) if calls else 0
4967
Nathan Harold123c9da2015-12-30 16:33:25 -08004968
Markus Liu2cf8d0b2019-10-04 11:13:17 +08004969def show_enhanced_4g_lte(ad, sub_id):
4970 result = True
4971 capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
4972 if capabilities:
4973 if "hide_enhanced_4g_lte" in capabilities:
4974 result = False
Markus Liu6b41e092020-08-17 15:55:28 +08004975 ad.log.info(
4976 '"Enhanced 4G LTE MODE" is hidden for sub ID %s.', sub_id)
4977 show_enhanced_4g_lte_mode = getattr(
4978 ad, "show_enhanced_4g_lte_mode", False)
Markus Liu2cf8d0b2019-10-04 11:13:17 +08004979 if show_enhanced_4g_lte_mode in ["true", "True"]:
4980 current_voice_sub_id = get_outgoing_voice_sub_id(ad)
4981 if sub_id != current_voice_sub_id:
4982 set_incoming_voice_sub_id(ad, sub_id)
4983
Markus Liu6b41e092020-08-17 15:55:28 +08004984 ad.log.info(
4985 'Show "Enhanced 4G LTE MODE" forcibly for sub ID %s.',
4986 sub_id)
4987 ad.adb.shell(
4988 "am broadcast \
4989 -a com.google.android.carrier.action.LOCAL_OVERRIDE \
4990 -n com.google.android.carrier/.ConfigOverridingReceiver \
4991 --ez hide_enhanced_4g_lte_bool false")
4992 ad.telephony["subscription"][sub_id]["capabilities"].remove(
4993 "hide_enhanced_4g_lte")
Markus Liu2cf8d0b2019-10-04 11:13:17 +08004994
4995 if sub_id != current_voice_sub_id:
4996 set_incoming_voice_sub_id(ad, current_voice_sub_id)
4997
4998 result = True
4999 return result
5000
5001
Ang Li73697b32015-12-03 00:41:53 +00005002def toggle_volte(log, ad, new_state=None):
5003 """Toggle enable/disable VoLTE for default voice subscription.
Markus Liu6b41e092020-08-17 15:55:28 +08005004
Ang Li73697b32015-12-03 00:41:53 +00005005 Args:
5006 ad: Android device object.
5007 new_state: VoLTE mode state to set to.
5008 True for enable, False for disable.
5009 If None, opposite of the current state.
Markus Liu6b41e092020-08-17 15:55:28 +08005010
Ang Li73697b32015-12-03 00:41:53 +00005011 Raises:
5012 TelTestUtilsError if platform does not support VoLTE.
5013 """
Betty Zhouee311052017-12-19 13:09:56 -08005014 return toggle_volte_for_subscription(
5015 log, ad, get_outgoing_voice_sub_id(ad), new_state)
Ang Li73697b32015-12-03 00:41:53 +00005016
5017
5018def toggle_volte_for_subscription(log, ad, sub_id, new_state=None):
5019 """Toggle enable/disable VoLTE for specified voice subscription.
5020
5021 Args:
5022 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005023 sub_id: Optional. If not assigned the default sub ID for voice call will
5024 be used.
Ang Li73697b32015-12-03 00:41:53 +00005025 new_state: VoLTE mode state to set to.
5026 True for enable, False for disable.
5027 If None, opposite of the current state.
5028
Ang Li73697b32015-12-03 00:41:53 +00005029 """
Markus Liu2cf8d0b2019-10-04 11:13:17 +08005030 if not show_enhanced_4g_lte(ad, sub_id):
5031 return False
5032
Markus Liu6b41e092020-08-17 15:55:28 +08005033 current_state = None
5034 result = True
5035
5036 if sub_id is None:
5037 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5038
5039 try:
5040 current_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id)
5041 except Exception as e:
5042 ad.log.warning(e)
5043
5044 if current_state is not None:
5045 if new_state is None:
5046 new_state = not current_state
5047 if new_state != current_state:
5048 ad.log.info(
5049 "Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s",
5050 current_state, new_state, sub_id)
5051 ad.droid.imsMmTelSetAdvancedCallingEnabled(sub_id, new_state)
5052 check_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id)
5053 if check_state != new_state:
5054 ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, still \
5055 set to %s on sub_id %s", new_state, check_state, sub_id)
5056 result = False
5057 return result
5058 else:
5059 # TODO: b/26293960 No framework API available to set IMS by SubId.
5060 voice_sub_id_changed = False
5061 current_sub_id = get_incoming_voice_sub_id(ad)
5062 if current_sub_id != sub_id:
5063 set_incoming_voice_sub_id(ad, sub_id)
5064 voice_sub_id_changed = True
5065
5066 # b/139641554
5067 ad.terminate_all_sessions()
5068 bring_up_sl4a(ad)
5069
5070 if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
5071 ad.log.info(
5072 "Enhanced 4G Lte Mode Setting is not enabled by platform for \
5073 sub ID %s.", sub_id)
5074 return False
5075
5076 current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5077 ad.log.info("Current state of Enhanced 4G Lte Mode Setting for sub \
5078 ID %s: %s", sub_id, current_state)
5079 ad.log.info("New desired state of Enhanced 4G Lte Mode Setting for sub \
5080 ID %s: %s", sub_id, new_state)
5081
5082 if new_state is None:
5083 new_state = not current_state
5084 if new_state != current_state:
5085 ad.log.info(
5086 "Toggle Enhanced 4G LTE Mode from %s to %s for sub ID %s.",
5087 current_state, new_state, sub_id)
5088 ad.droid.imsSetEnhanced4gMode(new_state)
5089 time.sleep(5)
5090
5091 check_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5092 if check_state != new_state:
5093 ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, \
5094 still set to %s on sub_id %s", new_state, check_state, sub_id)
5095 result = False
5096
5097 if voice_sub_id_changed:
5098 set_incoming_voice_sub_id(ad, current_sub_id)
5099
5100 return result
Ang Li73697b32015-12-03 00:41:53 +00005101
Nathan Harold123c9da2015-12-30 16:33:25 -08005102
Betty Zhou8aafcc12018-05-01 20:54:15 -07005103def toggle_wfc(log, ad, new_state=None):
Jaineel002cc052020-02-07 14:04:05 -08005104 """ Toggle WFC enable/disable
5105
5106 Args:
5107 log: Log object
5108 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005109 new_state: WFC state to set to.
5110 True for enable, False for disable.
5111 If None, opposite of the current state.
Jaineel002cc052020-02-07 14:04:05 -08005112 """
Markus Liu6b41e092020-08-17 15:55:28 +08005113 return toggle_wfc_for_subscription(
5114 log, ad, new_state, get_outgoing_voice_sub_id(ad))
Betty Zhou8aafcc12018-05-01 20:54:15 -07005115
5116
Markus Liu6b41e092020-08-17 15:55:28 +08005117def toggle_wfc_for_subscription(log, ad, new_state=None, sub_id=None):
5118 """ Toggle WFC enable/disable for specified voice subscription.
Jaineel002cc052020-02-07 14:04:05 -08005119
5120 Args:
5121 ad: Android device object.
Markus Liu6b41e092020-08-17 15:55:28 +08005122 sub_id: Optional. If not assigned the default sub ID for voice call will
5123 be used.
5124 new_state: WFC state to set to.
5125 True for enable, False for disable.
5126 If None, opposite of the current state.
Jaineel002cc052020-02-07 14:04:05 -08005127 """
Markus Liu6b41e092020-08-17 15:55:28 +08005128 current_state = None
5129 result = True
5130
Jaineel002cc052020-02-07 14:04:05 -08005131 if sub_id is None:
5132 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
Markus Liu6b41e092020-08-17 15:55:28 +08005133
5134 try:
5135 current_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id)
5136 except Exception as e:
5137 ad.log.warning(e)
5138
5139 if current_state is not None:
5140 if new_state is None:
5141 new_state = not current_state
5142 if new_state != current_state:
5143 ad.log.info(
5144 "Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s",
5145 current_state, new_state, sub_id)
5146 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, new_state)
5147 check_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id)
5148 if check_state != new_state:
5149 ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, \
5150 still set to %s on sub_id %s", new_state, check_state, sub_id)
5151 result = False
5152 return result
5153 else:
5154 voice_sub_id_changed = False
5155 if not sub_id:
5156 sub_id = get_outgoing_voice_sub_id(ad)
5157 else:
5158 current_sub_id = get_incoming_voice_sub_id(ad)
5159 if current_sub_id != sub_id:
5160 set_incoming_voice_sub_id(ad, sub_id)
5161 voice_sub_id_changed = True
5162
5163 # b/139641554
5164 ad.terminate_all_sessions()
5165 bring_up_sl4a(ad)
5166
5167 if not ad.droid.imsIsWfcEnabledByPlatform():
5168 ad.log.info("WFC is not enabled by platform for sub ID %s.", sub_id)
5169 return False
5170
5171 current_state = ad.droid.imsIsWfcEnabledByUser()
5172 ad.log.info("Current state of WFC Setting for sub ID %s: %s",
5173 sub_id, current_state)
5174 ad.log.info("New desired state of WFC Setting for sub ID %s: %s",
5175 sub_id, new_state)
5176
5177 if new_state is None:
5178 new_state = not current_state
5179 if new_state != current_state:
5180 ad.log.info("Toggle WFC user enabled from %s to %s for sub ID %s",
5181 current_state, new_state, sub_id)
5182 ad.droid.imsSetWfcSetting(new_state)
5183
5184 if voice_sub_id_changed:
5185 set_incoming_voice_sub_id(ad, current_sub_id)
5186
5187 return True
5188
5189def is_enhanced_4g_lte_mode_setting_enabled(ad, sub_id, enabled_by="platform"):
5190 voice_sub_id_changed = False
5191 current_sub_id = get_incoming_voice_sub_id(ad)
5192 if current_sub_id != sub_id:
5193 set_incoming_voice_sub_id(ad, sub_id)
5194 voice_sub_id_changed = True
5195 if enabled_by == "platform":
5196 res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform()
5197 else:
5198 res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser()
5199 if not res:
5200 ad.log.info("Enhanced 4G Lte Mode Setting is NOT enabled by %s for sub \
5201 ID %s.", enabled_by, sub_id)
5202 if voice_sub_id_changed:
5203 set_incoming_voice_sub_id(ad, current_sub_id)
5204 return False
5205 if voice_sub_id_changed:
5206 set_incoming_voice_sub_id(ad, current_sub_id)
5207 ad.log.info("Enhanced 4G Lte Mode Setting is enabled by %s for sub ID %s.",
5208 enabled_by, sub_id)
Jaineel002cc052020-02-07 14:04:05 -08005209 return True
5210
Markus Liu6b41e092020-08-17 15:55:28 +08005211def set_enhanced_4g_mode(ad, sub_id, state):
5212 voice_sub_id_changed = False
5213 current_sub_id = get_incoming_voice_sub_id(ad)
5214 if current_sub_id != sub_id:
5215 set_incoming_voice_sub_id(ad, sub_id)
5216 voice_sub_id_changed = True
5217
5218 ad.droid.imsSetEnhanced4gMode(state)
5219 time.sleep(5)
5220
5221 if voice_sub_id_changed:
5222 set_incoming_voice_sub_id(ad, current_sub_id)
Jaineel002cc052020-02-07 14:04:05 -08005223
Betty Zhoub14c1012018-04-20 11:27:00 -07005224def wait_for_enhanced_4g_lte_setting(log,
5225 ad,
Markus Liu6b41e092020-08-17 15:55:28 +08005226 sub_id,
Betty Zhoub14c1012018-04-20 11:27:00 -07005227 max_time=MAX_WAIT_TIME_FOR_STATE_CHANGE):
5228 """Wait for android device to enable enhance 4G LTE setting.
5229
5230 Args:
5231 log: log object.
5232 ad: android device.
5233 max_time: maximal wait time.
5234
5235 Returns:
5236 Return True if device report VoLTE enabled bit true within max_time.
5237 Return False if timeout.
5238 """
5239 return wait_for_state(
Markus Liu6b41e092020-08-17 15:55:28 +08005240 is_enhanced_4g_lte_mode_setting_enabled,
Betty Zhoub14c1012018-04-20 11:27:00 -07005241 True,
Markus Liu6b41e092020-08-17 15:55:28 +08005242 max_time,
5243 WAIT_TIME_BETWEEN_STATE_CHECK,
5244 ad,
5245 sub_id,
5246 enabled_by="platform")
Betty Zhoub14c1012018-04-20 11:27:00 -07005247
5248
Ang Li73697b32015-12-03 00:41:53 +00005249def set_wfc_mode(log, ad, wfc_mode):
5250 """Set WFC enable/disable and mode.
5251
5252 Args:
5253 log: Log object
5254 ad: Android device object.
5255 wfc_mode: WFC mode to set to.
5256 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
5257 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
5258
5259 Returns:
5260 True if success. False if ad does not support WFC or error happened.
5261 """
Markus Liu6b41e092020-08-17 15:55:28 +08005262 return set_wfc_mode_for_subscription(
5263 ad, wfc_mode, get_outgoing_voice_sub_id(ad))
Ang Li73697b32015-12-03 00:41:53 +00005264
Nathan Harold123c9da2015-12-30 16:33:25 -08005265
Jaineel002cc052020-02-07 14:04:05 -08005266def set_wfc_mode_for_subscription(ad, wfc_mode, sub_id=None):
5267 """Set WFC enable/disable and mode subscription based
5268
5269 Args:
5270 ad: Android device object.
5271 wfc_mode: WFC mode to set to.
5272 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
5273 WFC_MODE_WIFI_PREFERRED.
5274 sub_id: subscription Id
5275
5276 Returns:
5277 True if success. False if ad does not support WFC or error happened.
5278 """
Markus Liu6b41e092020-08-17 15:55:28 +08005279 if wfc_mode not in [
5280 WFC_MODE_WIFI_ONLY,
5281 WFC_MODE_CELLULAR_PREFERRED,
5282 WFC_MODE_WIFI_PREFERRED,
5283 WFC_MODE_DISABLED]:
5284
5285 ad.log.error("Given WFC mode (%s) is not correct.", wfc_mode)
Jaineel002cc052020-02-07 14:04:05 -08005286 return False
Markus Liu6b41e092020-08-17 15:55:28 +08005287
5288 current_mode = None
5289 result = True
5290
5291 if sub_id is None:
5292 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5293
5294 try:
5295 current_mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
5296 ad.log.info("Current WFC mode of sub ID: %s", current_mode)
5297 except Exception as e:
5298 ad.log.warning(e)
5299
5300 if current_mode is not None:
5301 try:
5302 if not ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id):
5303 if wfc_mode is WFC_MODE_DISABLED:
5304 return True
5305 ad.log.info(
5306 "WFC is disabled for sub ID %s. Enabling WFC...", sub_id)
5307 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, True)
5308
5309 if wfc_mode is WFC_MODE_DISABLED:
5310 ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, False)
5311 return True
5312
5313 ad.log.info("Set wfc mode to %s for sub ID %s.", wfc_mode, sub_id)
5314 ad.droid.imsMmTelSetVoWiFiModeSetting(sub_id, wfc_mode)
5315 mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id)
5316 if mode != wfc_mode:
5317 ad.log.error("WFC mode for sub ID %s is %s, not in %s",
5318 sub_id, mode, wfc_mode)
5319 return False
5320 except Exception as e:
5321 ad.log.error(e)
5322 return False
5323 return True
5324 else:
5325 voice_sub_id_changed = False
5326 if not sub_id:
5327 sub_id = get_outgoing_voice_sub_id(ad)
5328 else:
5329 current_sub_id = get_incoming_voice_sub_id(ad)
5330 if current_sub_id != sub_id:
5331 set_incoming_voice_sub_id(ad, sub_id)
5332 voice_sub_id_changed = True
5333
5334 # b/139641554
5335 ad.terminate_all_sessions()
5336 bring_up_sl4a(ad)
5337
5338 if wfc_mode != WFC_MODE_DISABLED and wfc_mode not in ad.telephony[
5339 "subscription"][get_outgoing_voice_sub_id(ad)].get("wfc_modes", []):
5340 ad.log.error("WFC mode %s is not supported", wfc_mode)
5341 raise signals.TestSkip("WFC mode %s is not supported" % wfc_mode)
5342 try:
5343 ad.log.info("Set wfc mode to %s", wfc_mode)
5344 if wfc_mode != WFC_MODE_DISABLED:
5345 start_adb_tcpdump(ad, interface="wlan0", mask="all")
5346 if not ad.droid.imsIsWfcEnabledByPlatform():
5347 if wfc_mode == WFC_MODE_DISABLED:
5348 if voice_sub_id_changed:
5349 set_incoming_voice_sub_id(ad, current_sub_id)
5350 return True
5351 else:
5352 ad.log.error("WFC not supported by platform.")
5353 if voice_sub_id_changed:
5354 set_incoming_voice_sub_id(ad, current_sub_id)
5355 return False
5356 ad.droid.imsSetWfcMode(wfc_mode)
5357 mode = ad.droid.imsGetWfcMode()
5358 if voice_sub_id_changed:
5359 set_incoming_voice_sub_id(ad, current_sub_id)
5360 if mode != wfc_mode:
5361 ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode)
5362 return False
5363 except Exception as e:
5364 log.error(e)
5365 if voice_sub_id_changed:
5366 set_incoming_voice_sub_id(ad, current_sub_id)
5367 return False
5368 return True
5369
Jaineel002cc052020-02-07 14:04:05 -08005370
5371
5372def set_ims_provisioning_for_subscription(ad, feature_flag, value, sub_id=None):
5373 """ Sets Provisioning Values for Subscription Id
5374
5375 Args:
5376 ad: Android device object.
5377 sub_id: Subscription Id
5378 feature_flag: voice or video
5379 value: enable or disable
5380
5381 """
5382 try:
5383 if sub_id is None:
5384 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5385 ad.log.info("SubId %s - setprovisioning for %s to %s",
5386 sub_id, feature_flag, value)
5387 result = ad.droid.provisioningSetProvisioningIntValue(sub_id,
5388 feature_flag, value)
5389 if result == 0:
5390 return True
5391 return False
5392 except Exception as e:
5393 ad.log.error(e)
5394 return False
5395
5396
5397def get_ims_provisioning_for_subscription(ad, feature_flag, tech, sub_id=None):
5398 """ Gets Provisioning Values for Subscription Id
5399
5400 Args:
5401 ad: Android device object.
5402 sub_id: Subscription Id
5403 feature_flag: voice, video, ut, sms
5404 tech: lte, iwlan
5405
5406 """
5407 try:
5408 if sub_id is None:
5409 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5410 result = ad.droid.provisioningGetProvisioningStatusForCapability(
5411 sub_id, feature_flag, tech)
5412 ad.log.info("SubId %s - getprovisioning for %s on %s - %s",
5413 sub_id, feature_flag, tech, result)
5414 return result
5415 except Exception as e:
5416 ad.log.error(e)
5417 return False
5418
5419
5420def get_carrier_provisioning_for_subscription(ad, feature_flag,
5421 tech, sub_id=None):
5422 """ Gets Provisioning Values for Subscription Id
5423
5424 Args:
5425 ad: Android device object.
5426 sub_id: Subscription Id
5427 feature_flag: voice, video, ut, sms
5428 tech: wlan, wwan
5429
5430 """
5431 try:
5432 if sub_id is None:
5433 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5434 result = ad.droid.imsMmTelIsSupported(sub_id, feature_flag, tech)
5435 ad.log.info("SubId %s - imsMmTelIsSupported for %s on %s - %s",
5436 sub_id, feature_flag, tech, result)
5437 return result
5438 except Exception as e:
5439 ad.log.error(e)
5440 return False
5441
Shaju Sebastian0b847e72019-01-31 16:40:37 -08005442def activate_wfc_on_device(log, ad):
5443 """ Activates WiFi calling on device.
5444
5445 Required for certain network operators.
5446
5447 Args:
5448 log: Log object
5449 ad: Android device object
5450
5451 """
5452 activate_wfc_on_device_for_subscription(log, ad,
5453 ad.droid.subscriptionGetDefaultSubId())
5454
5455
5456def activate_wfc_on_device_for_subscription(log, ad, sub_id):
5457 """ Activates WiFi calling on device for a subscription.
5458
5459 Args:
5460 log: Log object
5461 ad: Android device object
5462 sub_id: Subscription id (integer)
5463
5464 """
5465 if not sub_id or INVALID_SUB_ID == sub_id:
5466 ad.log.error("Subscription id invalid")
5467 return
5468 operator_name = get_operator_name(log, ad, sub_id)
5469 if operator_name in (CARRIER_VZW, CARRIER_ATT, CARRIER_BELL, CARRIER_ROGERS,
5470 CARRIER_TELUS, CARRIER_KOODO, CARRIER_VIDEOTRON, CARRIER_FRE):
5471 ad.log.info("Activating WFC on operator : %s", operator_name)
5472 if not ad.is_apk_installed("com.google.android.wfcactivation"):
5473 ad.log.error("WFC Activation Failed, wfc activation apk not installed")
5474 return
5475 wfc_activate_cmd ="am start --ei EXTRA_LAUNCH_CARRIER_APP 0 --ei " \
5476 "android.telephony.extra.SUBSCRIPTION_INDEX {} -n ".format(sub_id)
5477 if CARRIER_ATT == operator_name:
5478 ad.adb.shell("setprop dbg.att.force_wfc_nv_enabled true")
5479 wfc_activate_cmd = wfc_activate_cmd+\
5480 "\"com.google.android.wfcactivation/" \
5481 ".WfcActivationActivity\""
5482 elif CARRIER_VZW == operator_name:
5483 ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
5484 wfc_activate_cmd = wfc_activate_cmd + \
5485 "\"com.google.android.wfcactivation/" \
5486 ".VzwEmergencyAddressActivity\""
5487 else:
5488 wfc_activate_cmd = wfc_activate_cmd+ \
5489 "\"com.google.android.wfcactivation/" \
5490 ".can.WfcActivationCanadaActivity\""
5491 ad.adb.shell(wfc_activate_cmd)
5492
5493
Nathan Harold0a011532016-08-24 19:17:44 -07005494def toggle_video_calling(log, ad, new_state=None):
5495 """Toggle enable/disable Video calling for default voice subscription.
5496
5497 Args:
5498 ad: Android device object.
5499 new_state: Video mode state to set to.
5500 True for enable, False for disable.
5501 If None, opposite of the current state.
5502
5503 Raises:
5504 TelTestUtilsError if platform does not support Video calling.
5505 """
5506 if not ad.droid.imsIsVtEnabledByPlatform():
5507 if new_state is not False:
5508 raise TelTestUtilsError("VT not supported by platform.")
5509 # if the user sets VT false and it's unavailable we just let it go
5510 return False
5511
5512 current_state = ad.droid.imsIsVtEnabledByUser()
5513 if new_state is None:
5514 new_state = not current_state
5515 if new_state != current_state:
5516 ad.droid.imsSetVtSetting(new_state)
5517 return True
Nathan Harold123c9da2015-12-30 16:33:25 -08005518
Nathan Harold72f9bff2016-09-19 14:16:24 -07005519
Jaineel002cc052020-02-07 14:04:05 -08005520def toggle_video_calling_for_subscription(ad, new_state=None, sub_id=None):
5521 """Toggle enable/disable Video calling for subscription.
5522
5523 Args:
5524 ad: Android device object.
5525 new_state: Video mode state to set to.
5526 True for enable, False for disable.
5527 If None, opposite of the current state.
5528 sub_id: subscription Id
5529
5530 """
5531 try:
5532 if sub_id is None:
5533 sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
5534 current_state = ad.droid.imsMmTelIsVtSettingEnabled(sub_id)
5535 if new_state is None:
5536 new_state = not current_state
5537 if new_state != current_state:
5538 ad.log.info("SubId %s - Toggle VT from %s to %s", sub_id,
5539 current_state, new_state)
5540 ad.droid.imsMmTelSetVtSettingEnabled(sub_id, new_state)
5541 except Exception as e:
5542 ad.log.error(e)
5543 return False
5544 return True
5545
5546
Nathan Harold123c9da2015-12-30 16:33:25 -08005547def _wait_for_droid_in_state(log, ad, max_time, state_check_func, *args,
5548 **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07005549 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00005550 if state_check_func(log, ad, *args, **kwargs):
5551 return True
5552
Betty Zhouf25ce442017-03-03 14:28:36 -08005553 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5554 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005555
5556 return False
5557
5558
Nathan Harold123c9da2015-12-30 16:33:25 -08005559def _wait_for_droid_in_state_for_subscription(
5560 log, ad, sub_id, max_time, state_check_func, *args, **kwargs):
Nathan Harold97cd3f82016-09-29 10:58:29 -07005561 while max_time >= 0:
Ang Li73697b32015-12-03 00:41:53 +00005562 if state_check_func(log, ad, sub_id, *args, **kwargs):
5563 return True
5564
Betty Zhouf25ce442017-03-03 14:28:36 -08005565 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5566 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005567
5568 return False
5569
5570
Nathan Harold123c9da2015-12-30 16:33:25 -08005571def _wait_for_droids_in_state(log, ads, max_time, state_check_func, *args,
5572 **kwargs):
Ang Li73697b32015-12-03 00:41:53 +00005573 while max_time > 0:
5574 success = True
5575 for ad in ads:
5576 if not state_check_func(log, ad, *args, **kwargs):
5577 success = False
5578 break
5579 if success:
5580 return True
5581
Betty Zhouf25ce442017-03-03 14:28:36 -08005582 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
5583 max_time -= WAIT_TIME_BETWEEN_STATE_CHECK
Ang Li73697b32015-12-03 00:41:53 +00005584
5585 return False
5586
Nathan Harold123c9da2015-12-30 16:33:25 -08005587
Ang Li73697b32015-12-03 00:41:53 +00005588def is_phone_in_call(log, ad):
5589 """Return True if phone in call.
5590
5591 Args:
5592 log: log object.
5593 ad: android device.
5594 """
Betty Zhou377f72b2018-01-12 19:43:26 -08005595 try:
5596 return ad.droid.telecomIsInCall()
5597 except:
5598 return "mCallState=2" in ad.adb.shell(
5599 "dumpsys telephony.registry | grep mCallState")
Ang Li73697b32015-12-03 00:41:53 +00005600
Nathan Harold123c9da2015-12-30 16:33:25 -08005601
Ang Li73697b32015-12-03 00:41:53 +00005602def is_phone_not_in_call(log, ad):
5603 """Return True if phone not in call.
5604
5605 Args:
5606 log: log object.
5607 ad: android device.
5608 """
Betty Zhou94023182017-06-07 18:02:14 -07005609 in_call = ad.droid.telecomIsInCall()
5610 call_state = ad.droid.telephonyGetCallState()
5611 if in_call:
5612 ad.log.info("Device is In Call")
5613 if call_state != TELEPHONY_STATE_IDLE:
5614 ad.log.info("Call_state is %s, not %s", call_state,
5615 TELEPHONY_STATE_IDLE)
5616 return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))
Ang Li73697b32015-12-03 00:41:53 +00005617
Nathan Harold123c9da2015-12-30 16:33:25 -08005618
Ang Li73697b32015-12-03 00:41:53 +00005619def wait_for_droid_in_call(log, ad, max_time):
5620 """Wait for android to be in call state.
5621
5622 Args:
5623 log: log object.
5624 ad: android device.
5625 max_time: maximal wait time.
5626
5627 Returns:
5628 If phone become in call state within max_time, return True.
5629 Return False if timeout.
5630 """
5631 return _wait_for_droid_in_state(log, ad, max_time, is_phone_in_call)
5632
Nathan Harold7642fc92016-05-02 18:29:11 -07005633
Betty Zhoucf048542018-02-22 17:14:08 -08005634def is_phone_in_call_active(ad, call_id=None):
5635 """Return True if phone in active call.
5636
5637 Args:
5638 log: log object.
5639 ad: android device.
5640 call_id: the call id
5641 """
Jaineel78b05dd2018-03-27 13:54:17 -07005642 if ad.droid.telecomIsInCall():
5643 if not call_id:
5644 call_id = ad.droid.telecomCallGetCallIds()[0]
5645 call_state = ad.droid.telecomCallGetCallState(call_id)
5646 ad.log.info("%s state is %s", call_id, call_state)
5647 return call_state == "ACTIVE"
5648 else:
Betty Zhouabe4a442018-05-21 12:37:26 -07005649 ad.log.info("Not in telecomIsInCall")
Jaineel78b05dd2018-03-27 13:54:17 -07005650 return False
Betty Zhoucf048542018-02-22 17:14:08 -08005651
Betty Zhou4411c202018-03-29 18:27:25 -07005652
Betty Zhoua9e35a42018-05-22 14:57:38 -07005653def wait_for_in_call_active(ad,
5654 timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
5655 interval=WAIT_TIME_BETWEEN_STATE_CHECK,
5656 call_id=None):
Betty Zhoucf048542018-02-22 17:14:08 -08005657 """Wait for call reach active state.
5658
5659 Args:
5660 log: log object.
5661 ad: android device.
5662 call_id: the call id
5663 """
5664 if not call_id:
5665 call_id = ad.droid.telecomCallGetCallIds()[0]
5666 args = [ad, call_id]
5667 if not wait_for_state(is_phone_in_call_active, True, timeout, interval,
5668 *args):
5669 ad.log.error("Call did not reach ACTIVE state")
5670 return False
5671 else:
5672 return True
5673
5674
Yang Liu855d5f82016-01-27 15:35:48 -08005675def wait_for_telecom_ringing(log, ad, max_time=MAX_WAIT_TIME_TELECOM_RINGING):
5676 """Wait for android to be in telecom ringing state.
5677
5678 Args:
5679 log: log object.
5680 ad: android device.
5681 max_time: maximal wait time. This is optional.
5682 Default Value is MAX_WAIT_TIME_TELECOM_RINGING.
5683
5684 Returns:
5685 If phone become in telecom ringing state within max_time, return True.
5686 Return False if timeout.
5687 """
Nathan Harold7642fc92016-05-02 18:29:11 -07005688 return _wait_for_droid_in_state(
5689 log, ad, max_time, lambda log, ad: ad.droid.telecomIsRinging())
Yang Liu855d5f82016-01-27 15:35:48 -08005690
Nathan Harold123c9da2015-12-30 16:33:25 -08005691
Nathan Haroldeb60b192016-08-24 14:41:55 -07005692def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00005693 """Wait for android to be not in call state.
5694
5695 Args:
5696 log: log object.
5697 ad: android device.
5698 max_time: maximal wait time.
5699
5700 Returns:
5701 If phone become not in call state within max_time, return True.
5702 Return False if timeout.
5703 """
5704 return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)
5705
Nathan Harold123c9da2015-12-30 16:33:25 -08005706
Ang Li73697b32015-12-03 00:41:53 +00005707def _is_attached(log, ad, voice_or_data):
5708 return _is_attached_for_subscription(
5709 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
5710
Nathan Harold123c9da2015-12-30 16:33:25 -08005711
Ang Li73697b32015-12-03 00:41:53 +00005712def _is_attached_for_subscription(log, ad, sub_id, voice_or_data):
Betty Zhouf25ce442017-03-03 14:28:36 -08005713 rat = get_network_rat_for_subscription(log, ad, sub_id, voice_or_data)
Betty Zhoucb2cbc42017-06-29 14:39:34 -07005714 ad.log.info("Sub_id %s network RAT is %s for %s", sub_id, rat,
Betty Zhouf25ce442017-03-03 14:28:36 -08005715 voice_or_data)
5716 return rat != RAT_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00005717
Nathan Harold123c9da2015-12-30 16:33:25 -08005718
Betty Zhou33c05292017-05-24 15:12:43 -07005719def is_voice_attached(log, ad):
5720 return _is_attached_for_subscription(
5721 log, ad, ad.droid.subscriptionGetDefaultSubId(), NETWORK_SERVICE_VOICE)
5722
5723
Betty Zhoub25ba2d2018-05-03 15:52:54 -07005724def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION):
Ang Li73697b32015-12-03 00:41:53 +00005725 """Wait for android device to attach on voice.
5726
5727 Args:
5728 log: log object.
5729 ad: android device.
5730 max_time: maximal wait time.
5731
5732 Returns:
5733 Return True if device attach voice within max_time.
5734 Return False if timeout.
5735 """
5736 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
5737 NETWORK_SERVICE_VOICE)
5738
Nathan Harold123c9da2015-12-30 16:33:25 -08005739
Betty Zhoub25ba2d2018-05-03 15:52:54 -07005740def wait_for_voice_attach_for_subscription(
5741 log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION):
Ang Li73697b32015-12-03 00:41:53 +00005742 """Wait for android device to attach on voice in subscription id.
5743
5744 Args:
5745 log: log object.
5746 ad: android device.
5747 sub_id: subscription id.
5748 max_time: maximal wait time.
5749
5750 Returns:
5751 Return True if device attach voice within max_time.
5752 Return False if timeout.
5753 """
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005754 if not _wait_for_droid_in_state_for_subscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08005755 log, ad, sub_id, max_time, _is_attached_for_subscription,
5756 NETWORK_SERVICE_VOICE):
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005757 return False
5758
5759 # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
5760 # receive incoming call immediately.
5761 if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
Yang Liudf164e32016-01-07 16:49:32 -08005762 time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
Yang Liu7a2e7ee2015-12-28 15:32:44 -08005763 return True
Ang Li73697b32015-12-03 00:41:53 +00005764
Nathan Harold123c9da2015-12-30 16:33:25 -08005765
Ang Li73697b32015-12-03 00:41:53 +00005766def wait_for_data_attach(log, ad, max_time):
5767 """Wait for android device to attach on data.
5768
5769 Args:
5770 log: log object.
5771 ad: android device.
5772 max_time: maximal wait time.
5773
5774 Returns:
5775 Return True if device attach data within max_time.
5776 Return False if timeout.
5777 """
5778 return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
5779 NETWORK_SERVICE_DATA)
5780
Nathan Harold123c9da2015-12-30 16:33:25 -08005781
Ang Li73697b32015-12-03 00:41:53 +00005782def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time):
5783 """Wait for android device to attach on data in subscription id.
5784
5785 Args:
5786 log: log object.
5787 ad: android device.
5788 sub_id: subscription id.
5789 max_time: maximal wait time.
5790
5791 Returns:
5792 Return True if device attach data within max_time.
5793 Return False if timeout.
5794 """
5795 return _wait_for_droid_in_state_for_subscription(
5796 log, ad, sub_id, max_time, _is_attached_for_subscription,
5797 NETWORK_SERVICE_DATA)
5798
Nathan Harold123c9da2015-12-30 16:33:25 -08005799
Markus Liu6b41e092020-08-17 15:55:28 +08005800def is_ims_registered(log, ad, sub_id=None):
Yang Liu9b85ce52016-02-16 12:25:11 -08005801 """Return True if IMS registered.
5802
5803 Args:
5804 log: log object.
5805 ad: android device.
Markus Liu6b41e092020-08-17 15:55:28 +08005806 sub_id: Optional. If not assigned the default sub ID of voice call will
5807 be used.
Yang Liu9b85ce52016-02-16 12:25:11 -08005808
5809 Returns:
5810 Return True if IMS registered.
5811 Return False if IMS not registered.
5812 """
Markus Liu6b41e092020-08-17 15:55:28 +08005813 if not sub_id:
5814 return ad.droid.telephonyIsImsRegistered()
5815 else:
5816 return change_voice_subid_temporarily(
5817 ad, sub_id, ad.droid.telephonyIsImsRegistered)
Ang Li73697b32015-12-03 00:41:53 +00005818
Nathan Harold123c9da2015-12-30 16:33:25 -08005819
Betty Zhou8aafcc12018-05-01 20:54:15 -07005820def wait_for_ims_registered(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00005821 """Wait for android device to register on ims.
5822
5823 Args:
5824 log: log object.
5825 ad: android device.
5826 max_time: maximal wait time.
5827
5828 Returns:
5829 Return True if device register ims successfully within max_time.
5830 Return False if timeout.
5831 """
Yang Liu9b85ce52016-02-16 12:25:11 -08005832 return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered)
Ang Li73697b32015-12-03 00:41:53 +00005833
Markus Liu6b41e092020-08-17 15:55:28 +08005834def is_volte_available(log, ad, sub_id):
5835 """Return True if VoLTE is available.
Nathan Harold123c9da2015-12-30 16:33:25 -08005836
Markus Liu6b41e092020-08-17 15:55:28 +08005837 Args:
5838 log: log object.
5839 ad: android device.
5840 sub_id: Optional. If not assigned the default sub ID of voice call will
5841 be used.
5842
5843 Returns:
5844 Return True if VoLTE is available.
5845 Return False if VoLTE is not available.
5846 """
5847 if not sub_id:
5848 return ad.droid.telephonyIsVolteAvailable()
5849 else:
5850 return change_voice_subid_temporarily(
5851 ad, sub_id, ad.droid.telephonyIsVolteAvailable)
5852
5853def is_volte_enabled(log, ad, sub_id=None):
Yang Liu9b85ce52016-02-16 12:25:11 -08005854 """Return True if VoLTE feature bit is True.
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 VoLTE feature bit is True and IMS registered.
5864 Return False if VoLTE feature bit is False or IMS not registered.
5865 """
Markus Liu6b41e092020-08-17 15:55:28 +08005866 if not is_ims_registered(log, ad, sub_id):
5867 ad.log.info("IMS is not registered for sub ID %s.", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005868 return False
Markus Liu6b41e092020-08-17 15:55:28 +08005869 if not is_volte_available(log, ad, sub_id):
5870 ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable \
5871 is False", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005872 return False
Betty Zhoue32dd3b2017-11-28 19:05:55 -08005873 else:
Markus Liu6b41e092020-08-17 15:55:28 +08005874 ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable \
5875 is True", sub_id)
Betty Zhoub66d48f2018-04-09 12:00:53 -07005876 return True
Ang Li73697b32015-12-03 00:41:53 +00005877
Nathan Harold123c9da2015-12-30 16:33:25 -08005878
Yang Liu9b85ce52016-02-16 12:25:11 -08005879def is_video_enabled(log, ad):
5880 """Return True if Video Calling feature bit is True.
5881
5882 Args:
5883 log: log object.
5884 ad: android device.
5885
5886 Returns:
5887 Return True if Video Calling feature bit is True and IMS registered.
5888 Return False if Video Calling feature bit is False or IMS not registered.
5889 """
Yang Liub93d7292016-02-19 10:41:40 -08005890 video_status = ad.droid.telephonyIsVideoCallingAvailable()
5891 if video_status is True and is_ims_registered(log, ad) is False:
Betty Zhou8aafcc12018-05-01 20:54:15 -07005892 ad.log.error(
5893 "Error! Video Call is Available, but IMS is not registered.")
Yang Liu9b85ce52016-02-16 12:25:11 -08005894 return False
Yang Liub93d7292016-02-19 10:41:40 -08005895 return video_status
Ang Li73697b32015-12-03 00:41:53 +00005896
Nathan Harold123c9da2015-12-30 16:33:25 -08005897
Markus Liu6b41e092020-08-17 15:55:28 +08005898def wait_for_volte_enabled(
5899 log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED,sub_id=None):
Ang Li73697b32015-12-03 00:41:53 +00005900 """Wait for android device to report VoLTE enabled bit true.
5901
5902 Args:
5903 log: log object.
5904 ad: android device.
5905 max_time: maximal wait time.
5906
5907 Returns:
5908 Return True if device report VoLTE enabled bit true within max_time.
5909 Return False if timeout.
5910 """
Markus Liu6b41e092020-08-17 15:55:28 +08005911 if not sub_id:
5912 return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled)
5913 else:
5914 return _wait_for_droid_in_state_for_subscription(
5915 log, ad, sub_id, max_time, is_volte_enabled)
Ang Li73697b32015-12-03 00:41:53 +00005916
Nathan Harold123c9da2015-12-30 16:33:25 -08005917
Betty Zhou8aafcc12018-05-01 20:54:15 -07005918def wait_for_video_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00005919 """Wait for android device to report Video Telephony enabled bit true.
5920
5921 Args:
5922 log: log object.
5923 ad: android device.
5924 max_time: maximal wait time.
5925
5926 Returns:
5927 Return True if device report Video Telephony enabled bit true within max_time.
5928 Return False if timeout.
5929 """
Yang Liu9b85ce52016-02-16 12:25:11 -08005930 return _wait_for_droid_in_state(log, ad, max_time, is_video_enabled)
Ang Li73697b32015-12-03 00:41:53 +00005931
Nathan Harold123c9da2015-12-30 16:33:25 -08005932
Ang Li73697b32015-12-03 00:41:53 +00005933def is_wfc_enabled(log, ad):
5934 """Return True if WiFi Calling feature bit is True.
5935
5936 Args:
5937 log: log object.
5938 ad: android device.
5939
5940 Returns:
Yang Liu9b85ce52016-02-16 12:25:11 -08005941 Return True if WiFi Calling feature bit is True and IMS registered.
5942 Return False if WiFi Calling feature bit is False or IMS not registered.
Ang Li73697b32015-12-03 00:41:53 +00005943 """
Betty Zhoub66d48f2018-04-09 12:00:53 -07005944 if not is_ims_registered(log, ad):
5945 ad.log.info("IMS is not registered.")
5946 return False
Betty Zhou94023182017-06-07 18:02:14 -07005947 if not ad.droid.telephonyIsWifiCallingAvailable():
Markus Liu6b41e092020-08-17 15:55:28 +08005948 ad.log.info("IMS is registered, IsWifiCallingAvailable is False")
Yang Liu9b85ce52016-02-16 12:25:11 -08005949 return False
Betty Zhou94023182017-06-07 18:02:14 -07005950 else:
Markus Liu6b41e092020-08-17 15:55:28 +08005951 ad.log.info("IMS is registered, IsWifiCallingAvailable is True")
Betty Zhou94023182017-06-07 18:02:14 -07005952 return True
Ang Li73697b32015-12-03 00:41:53 +00005953
Nathan Harold123c9da2015-12-30 16:33:25 -08005954
Yang Liudfc37b62016-01-20 18:08:47 -08005955def wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
Ang Li73697b32015-12-03 00:41:53 +00005956 """Wait for android device to report WiFi Calling enabled bit true.
5957
5958 Args:
5959 log: log object.
5960 ad: android device.
5961 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08005962 Default value is MAX_WAIT_TIME_WFC_ENABLED.
Ang Li73697b32015-12-03 00:41:53 +00005963
5964 Returns:
5965 Return True if device report WiFi Calling enabled bit true within max_time.
5966 Return False if timeout.
5967 """
5968 return _wait_for_droid_in_state(log, ad, max_time, is_wfc_enabled)
5969
Nathan Harold123c9da2015-12-30 16:33:25 -08005970
Yang Liudfc37b62016-01-20 18:08:47 -08005971def wait_for_wfc_disabled(log, ad, max_time=MAX_WAIT_TIME_WFC_DISABLED):
Ang Li73697b32015-12-03 00:41:53 +00005972 """Wait for android device to report WiFi Calling enabled bit false.
5973
5974 Args:
5975 log: log object.
5976 ad: android device.
5977 max_time: maximal wait time.
Yang Liudfc37b62016-01-20 18:08:47 -08005978 Default value is MAX_WAIT_TIME_WFC_DISABLED.
Ang Li73697b32015-12-03 00:41:53 +00005979
5980 Returns:
5981 Return True if device report WiFi Calling enabled bit false within max_time.
5982 Return False if timeout.
5983 """
Nathan Harold123c9da2015-12-30 16:33:25 -08005984 return _wait_for_droid_in_state(
5985 log, ad, max_time, lambda log, ad: not is_wfc_enabled(log, ad))
5986
Ang Li73697b32015-12-03 00:41:53 +00005987
5988def get_phone_number(log, ad):
5989 """Get phone number for default subscription
5990
5991 Args:
5992 log: log object.
5993 ad: Android device object.
5994
5995 Returns:
5996 Phone number.
5997 """
Nathan Harold7642fc92016-05-02 18:29:11 -07005998 return get_phone_number_for_subscription(log, ad,
5999 get_outgoing_voice_sub_id(ad))
Nathan Harold123c9da2015-12-30 16:33:25 -08006000
Ang Li73697b32015-12-03 00:41:53 +00006001
6002def get_phone_number_for_subscription(log, ad, subid):
6003 """Get phone number for subscription
6004
6005 Args:
6006 log: log object.
6007 ad: Android device object.
6008 subid: subscription id.
6009
6010 Returns:
6011 Phone number.
6012 """
6013 number = None
6014 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07006015 number = ad.telephony['subscription'][subid]['phone_num']
Ang Li73697b32015-12-03 00:41:53 +00006016 except KeyError:
Yang Liuaed3eef2015-12-15 18:40:25 -08006017 number = ad.droid.telephonyGetLine1NumberForSubscription(subid)
Ang Li73697b32015-12-03 00:41:53 +00006018 return number
6019
Nathan Harold123c9da2015-12-30 16:33:25 -08006020
Ang Li73697b32015-12-03 00:41:53 +00006021def set_phone_number(log, ad, phone_num):
6022 """Set phone number for default subscription
6023
6024 Args:
6025 log: log object.
6026 ad: Android device object.
6027 phone_num: phone number string.
6028
6029 Returns:
6030 True if success.
6031 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07006032 return set_phone_number_for_subscription(log, ad,
6033 get_outgoing_voice_sub_id(ad),
6034 phone_num)
Nathan Harold123c9da2015-12-30 16:33:25 -08006035
Ang Li73697b32015-12-03 00:41:53 +00006036
6037def set_phone_number_for_subscription(log, ad, subid, phone_num):
6038 """Set phone number for subscription
6039
6040 Args:
6041 log: log object.
6042 ad: Android device object.
6043 subid: subscription id.
6044 phone_num: phone number string.
6045
6046 Returns:
6047 True if success.
6048 """
6049 try:
Betty Zhou3b2de072018-03-15 16:46:26 -07006050 ad.telephony['subscription'][subid]['phone_num'] = phone_num
Ang Li73697b32015-12-03 00:41:53 +00006051 except Exception:
6052 return False
6053 return True
6054
Nathan Harold123c9da2015-12-30 16:33:25 -08006055
Ang Li73697b32015-12-03 00:41:53 +00006056def get_operator_name(log, ad, subId=None):
6057 """Get operator name (e.g. vzw, tmo) of droid.
6058
6059 Args:
6060 ad: Android device object.
6061 sub_id: subscription ID
6062 Optional, default is None
6063
6064 Returns:
6065 Operator name.
6066 """
6067 try:
6068 if subId is not None:
6069 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006070 ad.droid.telephonyGetNetworkOperatorForSubscription(subId))
Ang Li73697b32015-12-03 00:41:53 +00006071 else:
6072 result = operator_name_from_plmn_id(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006073 ad.droid.telephonyGetNetworkOperator())
Ang Li73697b32015-12-03 00:41:53 +00006074 except KeyError:
Betty Zhou3ea56122018-03-14 17:37:24 -07006075 try:
6076 if subId is not None:
6077 result = ad.droid.telephonyGetNetworkOperatorNameForSubscription(
Shaju Sebastian2f88cdc2019-01-29 19:06:18 -08006078 subId)
Betty Zhou3ea56122018-03-14 17:37:24 -07006079 else:
6080 result = ad.droid.telephonyGetNetworkOperatorName()
Betty Zhoub14c1012018-04-20 11:27:00 -07006081 result = operator_name_from_network_name(result)
Betty Zhou3ea56122018-03-14 17:37:24 -07006082 except Exception:
6083 result = CARRIER_UNKNOWN
Jaineelde547262018-08-16 14:27:43 -07006084 ad.log.info("Operator Name is %s", result)
Ang Li73697b32015-12-03 00:41:53 +00006085 return result
6086
Nathan Harold123c9da2015-12-30 16:33:25 -08006087
Yang Liu9a9a4f72016-02-19 10:45:04 -08006088def get_model_name(ad):
6089 """Get android device model name
6090
6091 Args:
6092 ad: Android device object
6093
6094 Returns:
6095 model name string
6096 """
6097 # TODO: Create translate table.
6098 model = ad.model
Nathan Harold7642fc92016-05-02 18:29:11 -07006099 if (model.startswith(AOSP_PREFIX)):
Yang Liu9a9a4f72016-02-19 10:45:04 -08006100 model = model[len(AOSP_PREFIX):]
6101 return model
6102
6103
Ang Li73697b32015-12-03 00:41:53 +00006104def is_sms_match(event, phonenumber_tx, text):
6105 """Return True if 'text' equals to event['data']['Text']
6106 and phone number match.
6107
6108 Args:
6109 event: Event object to verify.
6110 phonenumber_tx: phone number for sender.
6111 text: text string to verify.
6112
6113 Returns:
6114 Return True if 'text' equals to event['data']['Text']
6115 and phone number match.
6116 """
Betty Zhouee311052017-12-19 13:09:56 -08006117 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
Shaju Sebastian4526c892019-02-28 13:55:15 -08006118 and event['data']['Text'].strip() == text)
Nathan Harold123c9da2015-12-30 16:33:25 -08006119
Ang Li73697b32015-12-03 00:41:53 +00006120
6121def is_sms_partial_match(event, phonenumber_tx, text):
6122 """Return True if 'text' starts with event['data']['Text']
6123 and phone number match.
6124
6125 Args:
6126 event: Event object to verify.
6127 phonenumber_tx: phone number for sender.
6128 text: text string to verify.
6129
6130 Returns:
6131 Return True if 'text' starts with event['data']['Text']
6132 and phone number match.
6133 """
Shaju Sebastian4526c892019-02-28 13:55:15 -08006134 event_text = event['data']['Text'].strip()
Betty Zhou1bc12092018-03-19 14:00:23 -07006135 if event_text.startswith("("):
6136 event_text = event_text.split(")")[-1]
Betty Zhouee311052017-12-19 13:09:56 -08006137 return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
Betty Zhou1bc12092018-03-19 14:00:23 -07006138 and text.startswith(event_text))
Nathan Harold123c9da2015-12-30 16:33:25 -08006139
Ang Li73697b32015-12-03 00:41:53 +00006140
Betty Zhou02571f52018-02-16 14:11:16 -08006141def sms_send_receive_verify(log,
6142 ad_tx,
6143 ad_rx,
6144 array_message,
Betty Zhoued13b712018-05-02 19:40:10 -07006145 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006146 expected_result=True,
6147 slot_id_rx=None):
Ang Li73697b32015-12-03 00:41:53 +00006148 """Send SMS, receive SMS, and verify content and sender's number.
6149
6150 Send (several) SMS from droid_tx to droid_rx.
6151 Verify SMS is sent, delivered and received.
6152 Verify received content and sender's number are correct.
6153
6154 Args:
6155 log: Log object.
6156 ad_tx: Sender's Android Device Object
6157 ad_rx: Receiver's Android Device Object
6158 array_message: the array of message to send/receive
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006159 slot_id_rx: the slot on the Receiver's android device (0/1)
Ang Li73697b32015-12-03 00:41:53 +00006160 """
Yang Liu963c93c2016-04-05 10:52:00 -07006161 subid_tx = get_outgoing_message_sub_id(ad_tx)
Visweswara Kumar541c0c72018-09-05 12:53:31 -07006162 if slot_id_rx is None:
6163 subid_rx = get_incoming_message_sub_id(ad_rx)
6164 else:
6165 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
6166
Betty Zhou74cf9922018-04-18 20:18:12 -07006167 result = sms_send_receive_verify_for_subscription(
Betty Zhou632793c2018-02-09 18:45:39 -08006168 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
Betty Zhoued13b712018-05-02 19:40:10 -07006169 if result != expected_result:
Betty Zhou74cf9922018-04-18 20:18:12 -07006170 log_messaging_screen_shot(ad_tx, test_name="sms_tx")
6171 log_messaging_screen_shot(ad_rx, test_name="sms_rx")
Betty Zhoued13b712018-05-02 19:40:10 -07006172 return result == expected_result
Ang Li73697b32015-12-03 00:41:53 +00006173
Nathan Harold123c9da2015-12-30 16:33:25 -08006174
6175def wait_for_matching_sms(log,
6176 ad_rx,
6177 phonenumber_tx,
6178 text,
Jaineel8e978552020-06-25 19:21:56 -07006179 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
6180 allow_multi_part_long_sms=True):
Ang Li73697b32015-12-03 00:41:53 +00006181 """Wait for matching incoming SMS.
6182
6183 Args:
6184 log: Log object.
6185 ad_rx: Receiver's Android Device Object
6186 phonenumber_tx: Sender's phone number.
6187 text: SMS content string.
6188 allow_multi_part_long_sms: is long SMS allowed to be received as
6189 multiple short SMS. This is optional, default value is True.
6190
6191 Returns:
6192 True if matching incoming SMS is received.
6193 """
6194 if not allow_multi_part_long_sms:
6195 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006196 ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
6197 max_wait_time, phonenumber_tx,
6198 text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07006199 ad_rx.log.info("Got event %s", EventSmsReceived)
Ang Li73697b32015-12-03 00:41:53 +00006200 return True
6201 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006202 ad_rx.log.error("No matched SMS received event.")
Ang Li73697b32015-12-03 00:41:53 +00006203 return False
6204 else:
6205 try:
6206 received_sms = ''
Betty Zhou1bc12092018-03-19 14:00:23 -07006207 remaining_text = text
6208 while (remaining_text != ''):
Betty Zhou1c8c8d42018-03-14 12:43:50 -07006209 event = ad_rx.messaging_ed.wait_for_event(
Betty Zhou02571f52018-02-16 14:11:16 -08006210 EventSmsReceived, is_sms_partial_match, max_wait_time,
Betty Zhou1bc12092018-03-19 14:00:23 -07006211 phonenumber_tx, remaining_text)
Shaju Sebastian4526c892019-02-28 13:55:15 -08006212 event_text = event['data']['Text'].split(")")[-1].strip()
Betty Zhou1bc12092018-03-19 14:00:23 -07006213 event_text_length = len(event_text)
6214 ad_rx.log.info("Got event %s of text length %s from %s",
6215 EventSmsReceived, event_text_length,
6216 phonenumber_tx)
6217 remaining_text = remaining_text[event_text_length:]
6218 received_sms += event_text
6219 ad_rx.log.info("Received SMS of length %s", len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00006220 return True
6221 except Empty:
Betty Zhou1bc12092018-03-19 14:00:23 -07006222 ad_rx.log.error(
6223 "Missing SMS received event of text length %s from %s",
6224 len(remaining_text), phonenumber_tx)
Ang Li73697b32015-12-03 00:41:53 +00006225 if received_sms != '':
Betty Zhou1bc12092018-03-19 14:00:23 -07006226 ad_rx.log.error(
6227 "Only received partial matched SMS of length %s",
6228 len(received_sms))
Ang Li73697b32015-12-03 00:41:53 +00006229 return False
6230
Nathan Harold123c9da2015-12-30 16:33:25 -08006231
Betty Zhoua27e5d42017-01-17 11:33:04 -08006232def is_mms_match(event, phonenumber_tx, text):
6233 """Return True if 'text' equals to event['data']['Text']
6234 and phone number match.
6235
6236 Args:
6237 event: Event object to verify.
6238 phonenumber_tx: phone number for sender.
6239 text: text string to verify.
6240
6241 Returns:
6242 Return True if 'text' equals to event['data']['Text']
6243 and phone number match.
6244 """
6245 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
6246 return True
6247
6248
Betty Zhou02571f52018-02-16 14:11:16 -08006249def wait_for_matching_mms(log,
6250 ad_rx,
6251 phonenumber_tx,
6252 text,
Betty Zhou632793c2018-02-09 18:45:39 -08006253 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhoua27e5d42017-01-17 11:33:04 -08006254 """Wait for matching incoming SMS.
6255
6256 Args:
6257 log: Log object.
6258 ad_rx: Receiver's Android Device Object
6259 phonenumber_tx: Sender's phone number.
6260 text: SMS content string.
6261 allow_multi_part_long_sms: is long SMS allowed to be received as
6262 multiple short SMS. This is optional, default value is True.
6263
6264 Returns:
6265 True if matching incoming SMS is received.
6266 """
6267 try:
6268 #TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08006269 ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
6270 max_wait_time, phonenumber_tx, text)
Betty Zhou5c7dbd12018-03-13 18:27:44 -07006271 ad_rx.log.info("Got event %s", EventMmsDownloaded)
Betty Zhoua27e5d42017-01-17 11:33:04 -08006272 return True
6273 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006274 ad_rx.log.warning("No matched MMS downloaded event.")
Betty Zhoua27e5d42017-01-17 11:33:04 -08006275 return False
6276
6277
Betty Zhou632793c2018-02-09 18:45:39 -08006278def sms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006279 log,
6280 ad_tx,
6281 ad_rx,
6282 subid_tx,
6283 subid_rx,
6284 array_message,
6285 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Ang Li73697b32015-12-03 00:41:53 +00006286 """Send SMS, receive SMS, and verify content and sender's number.
6287
6288 Send (several) SMS from droid_tx to droid_rx.
6289 Verify SMS is sent, delivered and received.
6290 Verify received content and sender's number are correct.
6291
6292 Args:
6293 log: Log object.
6294 ad_tx: Sender's Android Device Object..
6295 ad_rx: Receiver's Android Device Object.
6296 subid_tx: Sender's subsciption ID to be used for SMS
6297 subid_rx: Receiver's subsciption ID to be used for SMS
6298 array_message: the array of message to send/receive
6299 """
Betty Zhou3b2de072018-03-15 16:46:26 -07006300 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6301 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhoud32e0bd2017-12-19 19:44:58 -08006302
Betty Zhou632793c2018-02-09 18:45:39 -08006303 for ad in (ad_tx, ad_rx):
Betty Zhoued13b712018-05-02 19:40:10 -07006304 ad.send_keycode("BACK")
Betty Zhou632793c2018-02-09 18:45:39 -08006305 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08006306 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6307 ad.messaging_ed.start()
Betty Zhouf31dffe2018-02-23 19:29:28 -08006308 else:
6309 try:
6310 if not ad.messaging_droid.is_live:
6311 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6312 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006313 else:
6314 ad.messaging_ed.clear_all_events()
6315 ad.messaging_droid.logI(
6316 "Start sms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08006317 except Exception:
6318 ad.log.info("Create new sl4a session for messaging")
Betty Zhouf31dffe2018-02-23 19:29:28 -08006319 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6320 ad.messaging_ed.start()
6321
Ang Li73697b32015-12-03 00:41:53 +00006322 for text in array_message:
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006323 length = len(text)
Betty Zhoua37acd32017-02-23 20:04:24 -08006324 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006325 phonenumber_tx, phonenumber_rx, length, text)
Ang Li73697b32015-12-03 00:41:53 +00006326 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006327 ad_rx.messaging_ed.clear_events(EventSmsReceived)
6328 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07006329 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08006330 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006331 time.sleep(1) #sleep 100ms after starting event tracking
Betty Zhou4411c202018-03-29 18:27:25 -07006332 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
6333 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
Betty Zhou02571f52018-02-16 14:11:16 -08006334 ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
Betty Zhou4411c202018-03-29 18:27:25 -07006335 True)
Ang Li73697b32015-12-03 00:41:53 +00006336 try:
Betty Zhou4411c202018-03-29 18:27:25 -07006337 events = ad_tx.messaging_ed.pop_events(
Betty Zhouc9f723b2018-04-10 18:08:21 -07006338 "(%s|%s|%s|%s)" %
6339 (EventSmsSentSuccess, EventSmsSentFailure,
6340 EventSmsDeliverSuccess,
6341 EventSmsDeliverFailure), max_wait_time)
Betty Zhou4411c202018-03-29 18:27:25 -07006342 for event in events:
6343 ad_tx.log.info("Got event %s", event["name"])
Betty Zhouc9f723b2018-04-10 18:08:21 -07006344 if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
Betty Zhou4411c202018-03-29 18:27:25 -07006345 if event.get("data") and event["data"].get("Reason"):
6346 ad_tx.log.error("%s with reason: %s",
6347 event["name"],
6348 event["data"]["Reason"])
6349 return False
Betty Zhouc9f723b2018-04-10 18:08:21 -07006350 elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
Betty Zhou4411c202018-03-29 18:27:25 -07006351 break
Ang Li73697b32015-12-03 00:41:53 +00006352 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07006353 ad_tx.log.error("No %s or %s event for SMS of length %s.",
6354 EventSmsSentSuccess, EventSmsSentFailure,
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006355 length)
Betty Zhoued13b712018-05-02 19:40:10 -07006356 return False
Ang Li73697b32015-12-03 00:41:53 +00006357
Nathan Harold4a144a42016-09-19 14:16:24 -07006358 if not wait_for_matching_sms(
6359 log,
6360 ad_rx,
6361 phonenumber_tx,
6362 text,
Jaineel8e978552020-06-25 19:21:56 -07006363 max_wait_time,
Betty Zhoued13b712018-05-02 19:40:10 -07006364 allow_multi_part_long_sms=True):
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006365 ad_rx.log.error("No matching received SMS of length %s.",
6366 length)
Ang Li73697b32015-12-03 00:41:53 +00006367 return False
Betty Zhou632793c2018-02-09 18:45:39 -08006368 except Exception as e:
6369 log.error("Exception error %s", e)
6370 raise
Ang Li73697b32015-12-03 00:41:53 +00006371 finally:
Betty Zhou632793c2018-02-09 18:45:39 -08006372 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00006373 return True
6374
Nathan Harold123c9da2015-12-30 16:33:25 -08006375
Betty Zhou02571f52018-02-16 14:11:16 -08006376def mms_send_receive_verify(log,
6377 ad_tx,
6378 ad_rx,
6379 array_message,
Betty Zhoued13b712018-05-02 19:40:10 -07006380 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
Jaineelf76b37b2019-01-15 16:08:22 -08006381 expected_result=True,
6382 slot_id_rx=None):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006383 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00006384
Betty Zhou2e08ac32017-01-27 14:21:29 -08006385 Send (several) MMS from droid_tx to droid_rx.
6386 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00006387 Verify received content and sender's number are correct.
6388
6389 Args:
6390 log: Log object.
6391 ad_tx: Sender's Android Device Object
6392 ad_rx: Receiver's Android Device Object
6393 array_message: the array of message to send/receive
6394 """
Jaineelf76b37b2019-01-15 16:08:22 -08006395 subid_tx = get_outgoing_message_sub_id(ad_tx)
6396 if slot_id_rx is None:
6397 subid_rx = get_incoming_message_sub_id(ad_rx)
6398 else:
6399 subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
6400
Betty Zhou74cf9922018-04-18 20:18:12 -07006401 result = mms_send_receive_verify_for_subscription(
Jaineelf76b37b2019-01-15 16:08:22 -08006402 log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
Betty Zhoued13b712018-05-02 19:40:10 -07006403 if result != expected_result:
Betty Zhou74cf9922018-04-18 20:18:12 -07006404 log_messaging_screen_shot(ad_tx, test_name="mms_tx")
6405 log_messaging_screen_shot(ad_rx, test_name="mms_rx")
Betty Zhoued13b712018-05-02 19:40:10 -07006406 return result == expected_result
Nathan Harold123c9da2015-12-30 16:33:25 -08006407
Ang Li73697b32015-12-03 00:41:53 +00006408
Betty Zhou38028b72017-12-20 17:54:12 -08006409def sms_mms_send_logcat_check(ad, type, begin_time):
6410 type = type.upper()
6411 log_results = ad.search_logcat(
6412 "%s Message sent successfully" % type, begin_time=begin_time)
6413 if log_results:
Betty Zhou1bc12092018-03-19 14:00:23 -07006414 ad.log.info("Found %s sent successful log message: %s", type,
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006415 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006416 return True
6417 else:
6418 log_results = ad.search_logcat(
6419 "ProcessSentMessageAction: Done sending %s message" % type,
6420 begin_time=begin_time)
6421 if log_results:
6422 for log_result in log_results:
6423 if "status is SUCCEEDED" in log_result["log_message"]:
6424 ad.log.info(
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006425 "Found BugleDataModel %s send succeed log message: %s",
6426 type, log_result["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006427 return True
6428 return False
6429
6430
6431def sms_mms_receive_logcat_check(ad, type, begin_time):
6432 type = type.upper()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006433 smshandle_logs = ad.search_logcat(
Betty Zhou1bc12092018-03-19 14:00:23 -07006434 "InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
Betty Zhou6b3593f2018-03-16 20:13:55 -07006435 begin_time=begin_time)
6436 if smshandle_logs:
6437 ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006438 log_results = ad.search_logcat(
Jaineel6cd6d442018-01-08 14:50:44 -08006439 "New %s Received" % type, begin_time=begin_time) or \
6440 ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
Betty Zhou38028b72017-12-20 17:54:12 -08006441 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006442 ad.log.info("Found SL4A %s received log message: %s", type,
6443 log_results[-1]["log_message"])
Betty Zhou38028b72017-12-20 17:54:12 -08006444 return True
6445 else:
6446 log_results = ad.search_logcat(
6447 "Received %s message" % type, begin_time=begin_time)
6448 if log_results:
Betty Zhouf1cc3b62018-02-28 12:02:05 -08006449 ad.log.info("Found %s received log message: %s", type,
6450 log_results[-1]["log_message"])
Betty Zhou10f887e2018-04-10 12:45:00 -07006451 log_results = ad.search_logcat(
6452 "ProcessDownloadedMmsAction", begin_time=begin_time)
6453 for log_result in log_results:
6454 ad.log.info("Found %s", log_result["log_message"])
6455 if "status is SUCCEEDED" in log_result["log_message"]:
6456 ad.log.info("Download succeed with ProcessDownloadedMmsAction")
6457 return True
Betty Zhou38028b72017-12-20 17:54:12 -08006458 return False
6459
6460
Betty Zhoua27e5d42017-01-17 11:33:04 -08006461#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
Betty Zhou632793c2018-02-09 18:45:39 -08006462def mms_send_receive_verify_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006463 log,
6464 ad_tx,
6465 ad_rx,
6466 subid_tx,
6467 subid_rx,
6468 array_payload,
6469 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006470 """Send MMS, receive MMS, and verify content and sender's number.
Ang Li73697b32015-12-03 00:41:53 +00006471
Betty Zhou2e08ac32017-01-27 14:21:29 -08006472 Send (several) MMS from droid_tx to droid_rx.
6473 Verify MMS is sent, delivered and received.
Ang Li73697b32015-12-03 00:41:53 +00006474 Verify received content and sender's number are correct.
6475
6476 Args:
6477 log: Log object.
6478 ad_tx: Sender's Android Device Object..
6479 ad_rx: Receiver's Android Device Object.
6480 subid_tx: Sender's subsciption ID to be used for SMS
6481 subid_rx: Receiver's subsciption ID to be used for SMS
6482 array_message: the array of message to send/receive
6483 """
6484
Betty Zhou3b2de072018-03-15 16:46:26 -07006485 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6486 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Jaineel6f689de2019-08-07 10:20:02 -07006487 toggle_enforce = False
Betty Zhouf715c792018-02-12 17:32:10 -08006488
Betty Zhoue57ab692018-03-09 18:39:30 -08006489 for ad in (ad_tx, ad_rx):
Betty Zhoued13b712018-05-02 19:40:10 -07006490 ad.send_keycode("BACK")
Jaineel72e5d472019-04-01 16:31:27 -07006491 if "Permissive" not in ad.adb.shell("su root getenforce"):
6492 ad.adb.shell("su root setenforce 0")
Jaineel6f689de2019-08-07 10:20:02 -07006493 toggle_enforce = True
Betty Zhou632793c2018-02-09 18:45:39 -08006494 if not getattr(ad, "messaging_droid", None):
Betty Zhou08c1a572018-02-13 20:07:55 -08006495 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6496 ad.messaging_ed.start()
Betty Zhoue57ab692018-03-09 18:39:30 -08006497 else:
6498 try:
6499 if not ad.messaging_droid.is_live:
6500 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6501 ad.messaging_ed.start()
Betty Zhou6b3593f2018-03-16 20:13:55 -07006502 else:
6503 ad.messaging_ed.clear_all_events()
6504 ad.messaging_droid.logI(
6505 "Start mms_send_receive_verify_for_subscription test")
Betty Zhoue57ab692018-03-09 18:39:30 -08006506 except Exception:
6507 ad.log.info("Create new sl4a session for messaging")
6508 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6509 ad.messaging_ed.start()
Betty Zhou38028b72017-12-20 17:54:12 -08006510
Ang Li73697b32015-12-03 00:41:53 +00006511 for subject, message, filename in array_payload:
Betty Zhou632793c2018-02-09 18:45:39 -08006512 ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
Betty Zhou4411c202018-03-29 18:27:25 -07006513 ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
Betty Zhou632793c2018-02-09 18:45:39 -08006514 ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
6515 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhouf715c792018-02-12 17:32:10 -08006516 ad_tx.log.info(
6517 "Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
6518 phonenumber_tx, phonenumber_rx, subject, message, filename)
Ang Li73697b32015-12-03 00:41:53 +00006519 try:
Betty Zhou632793c2018-02-09 18:45:39 -08006520 ad_tx.messaging_droid.smsSendMultimediaMessage(
Nathan Harold123c9da2015-12-30 16:33:25 -08006521 phonenumber_rx, subject, message, phonenumber_tx, filename)
Betty Zhoua27e5d42017-01-17 11:33:04 -08006522 try:
Betty Zhou4411c202018-03-29 18:27:25 -07006523 events = ad_tx.messaging_ed.pop_events(
6524 "(%s|%s)" % (EventMmsSentSuccess,
6525 EventMmsSentFailure), max_wait_time)
6526 for event in events:
6527 ad_tx.log.info("Got event %s", event["name"])
6528 if event["name"] == EventMmsSentFailure:
6529 if event.get("data") and event["data"].get("Reason"):
6530 ad_tx.log.error("%s with reason: %s",
6531 event["name"],
6532 event["data"]["Reason"])
6533 return False
6534 elif event["name"] == EventMmsSentSuccess:
6535 break
Betty Zhoua27e5d42017-01-17 11:33:04 -08006536 except Empty:
Betty Zhou4411c202018-03-29 18:27:25 -07006537 ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
6538 EventMmsSentFailure)
Jaineel8e978552020-06-25 19:21:56 -07006539 return False
Betty Zhou2e08ac32017-01-27 14:21:29 -08006540
Jaineel4b9760a2018-12-13 14:42:10 -08006541 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx,
6542 message, max_wait_time):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006543 return False
Betty Zhou632793c2018-02-09 18:45:39 -08006544 except Exception as e:
6545 log.error("Exception error %s", e)
6546 raise
Betty Zhou2e08ac32017-01-27 14:21:29 -08006547 finally:
Jaineel8e978552020-06-25 19:21:56 -07006548 ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
Jaineel72e5d472019-04-01 16:31:27 -07006549 for ad in (ad_tx, ad_rx):
Jaineel6f689de2019-08-07 10:20:02 -07006550 if toggle_enforce:
6551 ad.send_keycode("BACK")
6552 ad.adb.shell("su root setenforce 1")
Betty Zhou2e08ac32017-01-27 14:21:29 -08006553 return True
6554
6555
Betty Zhou632793c2018-02-09 18:45:39 -08006556def mms_receive_verify_after_call_hangup(
Betty Zhou02571f52018-02-16 14:11:16 -08006557 log, ad_tx, ad_rx, array_message,
6558 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006559 """Verify the suspanded MMS during call will send out after call release.
6560
6561 Hangup call from droid_tx to droid_rx.
6562 Verify MMS is sent, delivered and received.
6563 Verify received content and sender's number are correct.
6564
6565 Args:
6566 log: Log object.
6567 ad_tx: Sender's Android Device Object
6568 ad_rx: Receiver's Android Device Object
6569 array_message: the array of message to send/receive
6570 """
6571 return mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006572 log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
Betty Zhou632793c2018-02-09 18:45:39 -08006573 get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
Betty Zhou2e08ac32017-01-27 14:21:29 -08006574
6575
6576#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
6577def mms_receive_verify_after_call_hangup_for_subscription(
Betty Zhou02571f52018-02-16 14:11:16 -08006578 log,
6579 ad_tx,
6580 ad_rx,
6581 subid_tx,
6582 subid_rx,
6583 array_payload,
Betty Zhou632793c2018-02-09 18:45:39 -08006584 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
Betty Zhou2e08ac32017-01-27 14:21:29 -08006585 """Verify the suspanded MMS during call will send out after call release.
6586
6587 Hangup call from droid_tx to droid_rx.
6588 Verify MMS is sent, delivered and received.
6589 Verify received content and sender's number are correct.
6590
6591 Args:
6592 log: Log object.
6593 ad_tx: Sender's Android Device Object..
6594 ad_rx: Receiver's Android Device Object.
6595 subid_tx: Sender's subsciption ID to be used for SMS
6596 subid_rx: Receiver's subsciption ID to be used for SMS
6597 array_message: the array of message to send/receive
6598 """
6599
Betty Zhou3b2de072018-03-15 16:46:26 -07006600 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
6601 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
Betty Zhou08c1a572018-02-13 20:07:55 -08006602 for ad in (ad_tx, ad_rx):
6603 if not getattr(ad, "messaging_droid", None):
6604 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
6605 ad.messaging_ed.start()
Betty Zhou2e08ac32017-01-27 14:21:29 -08006606 for subject, message, filename in array_payload:
Betty Zhoua37acd32017-02-23 20:04:24 -08006607 ad_rx.log.info(
6608 "Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
6609 phonenumber_tx, phonenumber_rx, subject, message, filename)
Betty Zhou632793c2018-02-09 18:45:39 -08006610 ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
Betty Zhou2e08ac32017-01-27 14:21:29 -08006611 time.sleep(5)
6612 try:
6613 hangup_call(log, ad_tx)
6614 hangup_call(log, ad_rx)
6615 try:
Betty Zhou3ea56122018-03-14 17:37:24 -07006616 ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
6617 max_wait_time)
Betty Zhou1c8c8d42018-03-14 12:43:50 -07006618 ad_tx.log.info("Got event %s", EventMmsSentSuccess)
Betty Zhou2e08ac32017-01-27 14:21:29 -08006619 except Empty:
Betty Zhouf809c5c2017-03-21 14:55:59 -07006620 log.warning("No sent_success event.")
Betty Zhoued13b712018-05-02 19:40:10 -07006621 if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
Ang Li73697b32015-12-03 00:41:53 +00006622 return False
6623 finally:
Markus Liu6b41e092020-08-17 15:55:28 +08006624 ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
Ang Li73697b32015-12-03 00:41:53 +00006625 return True
6626
Nathan Harold123c9da2015-12-30 16:33:25 -08006627
Preetesh Barretto0b64c8e2019-03-07 08:43:29 -08006628def ensure_preferred_network_type_for_subscription(
6629 ad,
6630 network_preference
6631 ):
6632 sub_id = ad.droid.subscriptionGetDefaultSubId()
6633 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6634 network_preference, sub_id):
6635 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
6636 sub_id, network_preference)
6637 return True
6638
6639
Nathan Harold123c9da2015-12-30 16:33:25 -08006640def ensure_network_rat(log,
6641 ad,
6642 network_preference,
6643 rat_family,
6644 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006645 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006646 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006647 """Ensure ad's current network is in expected rat_family.
6648 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006649 return ensure_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006650 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
6651 rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)
Ang Li73697b32015-12-03 00:41:53 +00006652
Nathan Harold123c9da2015-12-30 16:33:25 -08006653
Nathan Harold7642fc92016-05-02 18:29:11 -07006654def ensure_network_rat_for_subscription(
6655 log,
6656 ad,
6657 sub_id,
6658 network_preference,
6659 rat_family,
6660 voice_or_data=None,
6661 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
6662 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006663 """Ensure ad's current network is in expected rat_family.
6664 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006665 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6666 network_preference, sub_id):
Betty Zhoua37acd32017-02-23 20:04:24 -08006667 ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
6668 sub_id, network_preference)
Yang Liue23e5b12015-12-07 17:17:27 -08006669 return False
6670 if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
Nathan Harold123c9da2015-12-30 16:33:25 -08006671 voice_or_data):
Betty Zhoua37acd32017-02-23 20:04:24 -08006672 ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
6673 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08006674 return True
6675
6676 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006677 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006678 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006679 toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006680
6681 result = wait_for_network_rat_for_subscription(
6682 log, ad, sub_id, rat_family, max_wait_time, voice_or_data)
6683
Nathan Harold123c9da2015-12-30 16:33:25 -08006684 log.info(
Betty Zhoua37acd32017-02-23 20:04:24 -08006685 "End of ensure_network_rat_for_subscription for %s. "
6686 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
6687 "data: %s(family: %s)", ad.serial, network_preference, rat_family,
6688 voice_or_data,
6689 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6690 rat_family_from_rat(
6691 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6692 sub_id)),
6693 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6694 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006695 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006696 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08006697 return result
6698
Nathan Harold123c9da2015-12-30 16:33:25 -08006699
6700def ensure_network_preference(log,
6701 ad,
6702 network_preference,
6703 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006704 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006705 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006706 """Ensure that current rat is within the device's preferred network rats.
6707 """
Nathan Harold123c9da2015-12-30 16:33:25 -08006708 return ensure_network_preference_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006709 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08006710 voice_or_data, max_wait_time, toggle_apm_after_setting)
6711
Nathan Harold123c9da2015-12-30 16:33:25 -08006712
6713def ensure_network_preference_for_subscription(
6714 log,
6715 ad,
6716 sub_id,
6717 network_preference,
6718 voice_or_data=None,
Yang Liudf164e32016-01-07 16:49:32 -08006719 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006720 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006721 """Ensure ad's network preference is <network_preference> for sub_id.
6722 """
6723 rat_family_list = rat_families_for_network_preference(network_preference)
Nathan Harold123c9da2015-12-30 16:33:25 -08006724 if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
6725 network_preference, sub_id):
Yang Liue23e5b12015-12-07 17:17:27 -08006726 log.error("Set Preferred Networks failed.")
6727 return False
Nathan Harold123c9da2015-12-30 16:33:25 -08006728 if is_droid_in_rat_family_list_for_subscription(
6729 log, ad, sub_id, rat_family_list, voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08006730 return True
6731
6732 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006733 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006734 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006735 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006736
6737 result = wait_for_preferred_network_for_subscription(
6738 log, ad, sub_id, network_preference, max_wait_time, voice_or_data)
6739
Betty Zhoua37acd32017-02-23 20:04:24 -08006740 ad.log.info(
6741 "End of ensure_network_preference_for_subscription. "
6742 "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
6743 "data: %s(family: %s)", network_preference, rat_family_list,
6744 voice_or_data,
6745 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6746 rat_family_from_rat(
6747 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6748 sub_id)),
6749 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6750 rat_family_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006751 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006752 sub_id)))
Yang Liue23e5b12015-12-07 17:17:27 -08006753 return result
6754
Nathan Harold123c9da2015-12-30 16:33:25 -08006755
6756def ensure_network_generation(log,
6757 ad,
6758 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006759 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006760 voice_or_data=None,
6761 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006762 """Ensure ad's network is <network generation> for default subscription ID.
6763
6764 Set preferred network generation to <generation>.
6765 Toggle ON/OFF airplane mode if necessary.
6766 Wait for ad in expected network type.
6767 """
6768 return ensure_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006769 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
6770 max_wait_time, voice_or_data, toggle_apm_after_setting)
Yang Liue23e5b12015-12-07 17:17:27 -08006771
Nathan Harold123c9da2015-12-30 16:33:25 -08006772
6773def ensure_network_generation_for_subscription(
6774 log,
6775 ad,
6776 sub_id,
6777 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006778 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006779 voice_or_data=None,
6780 toggle_apm_after_setting=False):
Yang Liue23e5b12015-12-07 17:17:27 -08006781 """Ensure ad's network is <network generation> for specified subscription ID.
6782
6783 Set preferred network generation to <generation>.
6784 Toggle ON/OFF airplane mode if necessary.
6785 Wait for ad in expected network type.
6786 """
Betty Zhoua37acd32017-02-23 20:04:24 -08006787 ad.log.info(
6788 "RAT network type voice: %s, data: %s",
6789 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6790 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))
Betty Zhoua37acd32017-02-23 20:04:24 -08006791
Yang Liue23e5b12015-12-07 17:17:27 -08006792 try:
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006793 ad.log.info("Finding the network preference for generation %s for "
6794 "operator %s phone type %s", generation,
Betty Zhou3b2de072018-03-15 16:46:26 -07006795 ad.telephony["subscription"][sub_id]["operator"],
6796 ad.telephony["subscription"][sub_id]["phone_type"])
Jaineelc52d6852017-10-27 15:03:54 -07006797 network_preference = network_preference_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07006798 generation, ad.telephony["subscription"][sub_id]["operator"],
6799 ad.telephony["subscription"][sub_id]["phone_type"])
Jaineel254dd5d2018-12-03 18:46:36 -08006800 if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \
6801 and generation == GEN_4G:
6802 network_preference = NETWORK_MODE_LTE_ONLY
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006803 ad.log.info("Network preference for %s is %s", generation,
6804 network_preference)
6805 rat_family = rat_family_for_generation(
Betty Zhou3b2de072018-03-15 16:46:26 -07006806 generation, ad.telephony["subscription"][sub_id]["operator"],
6807 ad.telephony["subscription"][sub_id]["phone_type"])
Betty Zhoud2da7ba2017-03-24 12:54:34 -07006808 except KeyError as e:
6809 ad.log.error("Failed to find a rat_family entry for generation %s"
Markus Liu9b24f712018-11-12 15:31:14 +08006810 " for subscriber id %s with error %s", generation,
6811 sub_id, e)
Yang Liue23e5b12015-12-07 17:17:27 -08006812 return False
6813
Betty Zhou1eedf722018-04-27 14:27:04 -07006814 if not set_preferred_network_mode_pref(log, ad, sub_id,
6815 network_preference):
6816 return False
Yang Liue23e5b12015-12-07 17:17:27 -08006817
Jaineel15c50562019-03-29 15:45:32 -07006818 if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad):
6819 ad.log.info("MSIM - Non DDS, ignore data RAT")
6820 return True
6821
Nathan Harold4a144a42016-09-19 14:16:24 -07006822 if is_droid_in_network_generation_for_subscription(
6823 log, ad, sub_id, generation, voice_or_data):
6824 return True
6825
Yang Liue23e5b12015-12-07 17:17:27 -08006826 if toggle_apm_after_setting:
Betty Zhoua37acd32017-02-23 20:04:24 -08006827 toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006828 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
Betty Zhoua37acd32017-02-23 20:04:24 -08006829 toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)
Yang Liue23e5b12015-12-07 17:17:27 -08006830
6831 result = wait_for_network_generation_for_subscription(
6832 log, ad, sub_id, generation, max_wait_time, voice_or_data)
6833
Betty Zhoua37acd32017-02-23 20:04:24 -08006834 ad.log.info(
Betty Zhou0f5efc42017-04-10 18:38:14 -07006835 "Ensure network %s %s %s. With network preference %s, "
Betty Zhoue955be22017-04-12 17:28:05 -07006836 "current: voice: %s(family: %s), data: %s(family: %s)", generation,
6837 voice_or_data, result, network_preference,
Betty Zhoua37acd32017-02-23 20:04:24 -08006838 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
6839 rat_generation_from_rat(
6840 ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
6841 sub_id)),
6842 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
6843 rat_generation_from_rat(
Nathan Harold123c9da2015-12-30 16:33:25 -08006844 ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
Betty Zhoua37acd32017-02-23 20:04:24 -08006845 sub_id)))
Betty Zhou351d1792017-11-10 16:26:30 -08006846 if not result:
Betty Zhoufe726dc2018-04-25 19:31:33 -07006847 get_telephony_signal_strength(ad)
Yang Liue23e5b12015-12-07 17:17:27 -08006848 return result
6849
Yang Liue23e5b12015-12-07 17:17:27 -08006850
Nathan Harold123c9da2015-12-30 16:33:25 -08006851def wait_for_network_rat(log,
6852 ad,
6853 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006854 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006855 voice_or_data=None):
6856 return wait_for_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006857 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
6858 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006859
6860
Nathan Harold7642fc92016-05-02 18:29:11 -07006861def wait_for_network_rat_for_subscription(
6862 log,
6863 ad,
6864 sub_id,
6865 rat_family,
6866 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
6867 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006868 return _wait_for_droid_in_state_for_subscription(
6869 log, ad, sub_id, max_wait_time,
6870 is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)
6871
Yang Liue23e5b12015-12-07 17:17:27 -08006872
Nathan Harold123c9da2015-12-30 16:33:25 -08006873def wait_for_not_network_rat(log,
6874 ad,
6875 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006876 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006877 voice_or_data=None):
6878 return wait_for_not_network_rat_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006879 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
6880 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006881
6882
6883def wait_for_not_network_rat_for_subscription(
6884 log,
6885 ad,
6886 sub_id,
6887 rat_family,
Yang Liudf164e32016-01-07 16:49:32 -08006888 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006889 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006890 return _wait_for_droid_in_state_for_subscription(
6891 log, ad, sub_id, max_wait_time,
Betty Zhouf809c5c2017-03-21 14:55:59 -07006892 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 -08006893 )
Yang Liue23e5b12015-12-07 17:17:27 -08006894
Nathan Harold123c9da2015-12-30 16:33:25 -08006895
6896def wait_for_preferred_network(log,
6897 ad,
6898 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08006899 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006900 voice_or_data=None):
6901 return wait_for_preferred_network_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006902 log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
Yang Liue23e5b12015-12-07 17:17:27 -08006903 max_wait_time, voice_or_data)
6904
Nathan Harold123c9da2015-12-30 16:33:25 -08006905
6906def wait_for_preferred_network_for_subscription(
6907 log,
6908 ad,
6909 sub_id,
6910 network_preference,
Yang Liudf164e32016-01-07 16:49:32 -08006911 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006912 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006913 rat_family_list = rat_families_for_network_preference(network_preference)
6914 return _wait_for_droid_in_state_for_subscription(
6915 log, ad, sub_id, max_wait_time,
6916 is_droid_in_rat_family_list_for_subscription, rat_family_list,
6917 voice_or_data)
6918
Nathan Harold123c9da2015-12-30 16:33:25 -08006919
6920def wait_for_network_generation(log,
6921 ad,
6922 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006923 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006924 voice_or_data=None):
6925 return wait_for_network_generation_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006926 log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
6927 max_wait_time, voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006928
6929
6930def wait_for_network_generation_for_subscription(
6931 log,
6932 ad,
6933 sub_id,
6934 generation,
Yang Liudf164e32016-01-07 16:49:32 -08006935 max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
Nathan Harold123c9da2015-12-30 16:33:25 -08006936 voice_or_data=None):
6937 return _wait_for_droid_in_state_for_subscription(
6938 log, ad, sub_id, max_wait_time,
6939 is_droid_in_network_generation_for_subscription, generation,
Yang Liue23e5b12015-12-07 17:17:27 -08006940 voice_or_data)
6941
Yang Liue23e5b12015-12-07 17:17:27 -08006942
6943def is_droid_in_rat_family(log, ad, rat_family, voice_or_data=None):
Nathan Harold123c9da2015-12-30 16:33:25 -08006944 return is_droid_in_rat_family_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006945 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
6946 voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08006947
Yang Liue23e5b12015-12-07 17:17:27 -08006948
Nathan Harold123c9da2015-12-30 16:33:25 -08006949def is_droid_in_rat_family_for_subscription(log,
6950 ad,
6951 sub_id,
6952 rat_family,
6953 voice_or_data=None):
6954 return is_droid_in_rat_family_list_for_subscription(
6955 log, ad, sub_id, [rat_family], voice_or_data)
Yang Liue23e5b12015-12-07 17:17:27 -08006956
Nathan Harold123c9da2015-12-30 16:33:25 -08006957
6958def is_droid_in_rat_familiy_list(log, ad, rat_family_list, voice_or_data=None):
6959 return is_droid_in_rat_family_list_for_subscription(
Betty Zhouee311052017-12-19 13:09:56 -08006960 log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family_list,
6961 voice_or_data)
Nathan Harold123c9da2015-12-30 16:33:25 -08006962
6963
6964def is_droid_in_rat_family_list_for_subscription(log,
6965 ad,
6966 sub_id,
6967 rat_family_list,
6968 voice_or_data=None):
Yang Liue23e5b12015-12-07 17:17:27 -08006969 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
6970 if voice_or_data:
6971 service_list = [voice_or_data]
6972
6973 for service in service_list:
6974 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
6975 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
6976 continue
Yang Liu7a2e7ee2015-12-28 15:32:44 -08006977 if rat_family_from_rat(nw_rat) in rat_family_list:
Yang Liue23e5b12015-12-07 17:17:27 -08006978 return True
6979 return False
6980
Nathan Harold123c9da2015-12-30 16:33:25 -08006981
Yang Liue23e5b12015-12-07 17:17:27 -08006982def is_droid_in_network_generation(log, ad, nw_gen, voice_or_data):
6983 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00006984
6985 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08006986 log: log object.
6987 ad: android device.
6988 nw_gen: expected generation "4g", "3g", "2g".
6989 voice_or_data: check voice network generation or data network generation
6990 This parameter is optional. If voice_or_data is None, then if
6991 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00006992
6993 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08006994 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00006995 """
Yang Liue23e5b12015-12-07 17:17:27 -08006996 return is_droid_in_network_generation_for_subscription(
6997 log, ad, ad.droid.subscriptionGetDefaultSubId(), nw_gen, voice_or_data)
Ang Li73697b32015-12-03 00:41:53 +00006998
Nathan Harold123c9da2015-12-30 16:33:25 -08006999
7000def is_droid_in_network_generation_for_subscription(log, ad, sub_id, nw_gen,
7001 voice_or_data):
Yang Liue23e5b12015-12-07 17:17:27 -08007002 """Checks if a droid in expected network generation ("2g", "3g" or "4g").
Ang Li73697b32015-12-03 00:41:53 +00007003
7004 Args:
Yang Liue23e5b12015-12-07 17:17:27 -08007005 log: log object.
7006 ad: android device.
7007 nw_gen: expected generation "4g", "3g", "2g".
7008 voice_or_data: check voice network generation or data network generation
7009 This parameter is optional. If voice_or_data is None, then if
7010 either voice or data in expected generation, function will return True.
Ang Li73697b32015-12-03 00:41:53 +00007011
7012 Returns:
Yang Liue23e5b12015-12-07 17:17:27 -08007013 True if droid in expected network generation. Otherwise False.
Ang Li73697b32015-12-03 00:41:53 +00007014 """
Yang Liue23e5b12015-12-07 17:17:27 -08007015 service_list = [NETWORK_SERVICE_DATA, NETWORK_SERVICE_VOICE]
Ang Li73697b32015-12-03 00:41:53 +00007016
Yang Liue23e5b12015-12-07 17:17:27 -08007017 if voice_or_data:
7018 service_list = [voice_or_data]
Ang Li73697b32015-12-03 00:41:53 +00007019
Yang Liue23e5b12015-12-07 17:17:27 -08007020 for service in service_list:
7021 nw_rat = get_network_rat_for_subscription(log, ad, sub_id, service)
Betty Zhou89d090b2017-05-23 11:12:19 -07007022 ad.log.info("%s network rat is %s", service, nw_rat)
Yang Liue23e5b12015-12-07 17:17:27 -08007023 if nw_rat == RAT_UNKNOWN or not is_valid_rat(nw_rat):
7024 continue
7025
Yang Liu7a2e7ee2015-12-28 15:32:44 -08007026 if rat_generation_from_rat(nw_rat) == nw_gen:
Betty Zhou89d090b2017-05-23 11:12:19 -07007027 ad.log.info("%s network rat %s is expected %s", service, nw_rat,
7028 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08007029 return True
7030 else:
Betty Zhou89d090b2017-05-23 11:12:19 -07007031 ad.log.info("%s network rat %s is %s, does not meet expected %s",
Betty Zhouee311052017-12-19 13:09:56 -08007032 service, nw_rat, rat_generation_from_rat(nw_rat),
7033 nw_gen)
Yang Liue23e5b12015-12-07 17:17:27 -08007034 return False
7035
7036 return False
Ang Li73697b32015-12-03 00:41:53 +00007037
Nathan Harold123c9da2015-12-30 16:33:25 -08007038
Ang Li73697b32015-12-03 00:41:53 +00007039def get_network_rat(log, ad, voice_or_data):
7040 """Get current network type (Voice network type, or data network type)
7041 for default subscription id
7042
7043 Args:
7044 ad: Android Device Object
7045 voice_or_data: Input parameter indicating to get voice network type or
7046 data network type.
7047
7048 Returns:
7049 Current voice/data network type.
7050 """
7051 return get_network_rat_for_subscription(
7052 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
7053
Nathan Harold123c9da2015-12-30 16:33:25 -08007054
Ang Li73697b32015-12-03 00:41:53 +00007055def get_network_rat_for_subscription(log, ad, sub_id, voice_or_data):
7056 """Get current network type (Voice network type, or data network type)
7057 for specified subscription id
7058
7059 Args:
7060 ad: Android Device Object
7061 sub_id: subscription ID
7062 voice_or_data: Input parameter indicating to get voice network type or
7063 data network type.
7064
7065 Returns:
7066 Current voice/data network type.
7067 """
7068 if voice_or_data == NETWORK_SERVICE_VOICE:
Nathan Harold123c9da2015-12-30 16:33:25 -08007069 ret_val = ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
7070 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007071 elif voice_or_data == NETWORK_SERVICE_DATA:
Nathan Harold123c9da2015-12-30 16:33:25 -08007072 ret_val = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
7073 sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007074 else:
Yang Liuaed3eef2015-12-15 18:40:25 -08007075 ret_val = ad.droid.telephonyGetNetworkTypeForSubscription(sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007076
7077 if ret_val is None:
7078 log.error("get_network_rat(): Unexpected null return value")
7079 return RAT_UNKNOWN
7080 else:
7081 return ret_val
7082
Nathan Harold123c9da2015-12-30 16:33:25 -08007083
Ang Li73697b32015-12-03 00:41:53 +00007084def get_network_gen(log, ad, voice_or_data):
7085 """Get current network generation string (Voice network type, or data network type)
7086
7087 Args:
7088 ad: Android Device Object
7089 voice_or_data: Input parameter indicating to get voice network generation
7090 or data network generation.
7091
7092 Returns:
7093 Current voice/data network generation.
7094 """
7095 return get_network_gen_for_subscription(
7096 log, ad, ad.droid.subscriptionGetDefaultSubId(), voice_or_data)
7097
Nathan Harold123c9da2015-12-30 16:33:25 -08007098
Ang Li73697b32015-12-03 00:41:53 +00007099def get_network_gen_for_subscription(log, ad, sub_id, voice_or_data):
7100 """Get current network generation string (Voice network type, or data network type)
7101
7102 Args:
7103 ad: Android Device Object
7104 voice_or_data: Input parameter indicating to get voice network generation
7105 or data network generation.
7106
7107 Returns:
7108 Current voice/data network generation.
7109 """
7110 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07007111 return rat_generation_from_rat(
7112 get_network_rat_for_subscription(log, ad, sub_id, voice_or_data))
Betty Zhoua37acd32017-02-23 20:04:24 -08007113 except KeyError as e:
7114 ad.log.error("KeyError %s", e)
Yang Liue23e5b12015-12-07 17:17:27 -08007115 return GEN_UNKNOWN
Ang Li73697b32015-12-03 00:41:53 +00007116
Nathan Harold123c9da2015-12-30 16:33:25 -08007117
7118def check_voice_mail_count(log, ad, voice_mail_count_before,
7119 voice_mail_count_after):
Ang Li73697b32015-12-03 00:41:53 +00007120 """function to check if voice mail count is correct after leaving a new voice message.
7121 """
7122 return get_voice_mail_count_check_function(get_operator_name(log, ad))(
7123 voice_mail_count_before, voice_mail_count_after)
7124
Nathan Harold123c9da2015-12-30 16:33:25 -08007125
Ang Li73697b32015-12-03 00:41:53 +00007126def get_voice_mail_number(log, ad):
7127 """function to get the voice mail number
7128 """
Betty Zhou94023182017-06-07 18:02:14 -07007129 voice_mail_number = get_voice_mail_check_number(get_operator_name(log, ad))
Ang Li73697b32015-12-03 00:41:53 +00007130 if voice_mail_number is None:
7131 return get_phone_number(log, ad)
7132 return voice_mail_number
7133
Nathan Harold123c9da2015-12-30 16:33:25 -08007134
Betty Zhouf809c5c2017-03-21 14:55:59 -07007135def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
Ang Li73697b32015-12-03 00:41:53 +00007136 """Ensure ads idle (not in call).
7137 """
Betty Zhouf809c5c2017-03-21 14:55:59 -07007138 result = True
Ang Li73697b32015-12-03 00:41:53 +00007139 for ad in ads:
Betty Zhouf809c5c2017-03-21 14:55:59 -07007140 if not ensure_phone_idle(log, ad, max_time=max_time):
7141 result = False
7142 return result
Ang Li73697b32015-12-03 00:41:53 +00007143
Nathan Harold123c9da2015-12-30 16:33:25 -08007144
Markus Liu61220b72019-08-01 16:26:22 +08007145def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP, retry=2):
Ang Li73697b32015-12-03 00:41:53 +00007146 """Ensure ad idle (not in call).
7147 """
Markus Liu61220b72019-08-01 16:26:22 +08007148 while ad.droid.telecomIsInCall() and retry > 0:
Betty Zhouf809c5c2017-03-21 14:55:59 -07007149 ad.droid.telecomEndCall()
Markus Liu61220b72019-08-01 16:26:22 +08007150 time.sleep(3)
7151 retry -= 1
Betty Zhouf809c5c2017-03-21 14:55:59 -07007152 if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
Betty Zhou94023182017-06-07 18:02:14 -07007153 ad.log.error("Failed to end call")
Betty Zhouf809c5c2017-03-21 14:55:59 -07007154 return False
7155 return True
Ang Li73697b32015-12-03 00:41:53 +00007156
Nathan Harold123c9da2015-12-30 16:33:25 -08007157
Betty Zhou7f45f552017-03-15 19:12:52 -07007158def ensure_phone_subscription(log, ad):
7159 """Ensure Phone Subscription.
7160 """
7161 #check for sim and service
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007162 duration = 0
7163 while duration < MAX_WAIT_TIME_NW_SELECTION:
7164 subInfo = ad.droid.subscriptionGetAllSubInfoList()
7165 if subInfo and len(subInfo) >= 1:
Betty Zhoue32dd3b2017-11-28 19:05:55 -08007166 ad.log.debug("Find valid subcription %s", subInfo)
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007167 break
7168 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07007169 ad.log.info("Did not find any subscription")
Betty Zhou9ba6d2e2017-07-24 14:03:45 -07007170 time.sleep(5)
7171 duration += 5
7172 else:
Betty Zhoub14c1012018-04-20 11:27:00 -07007173 ad.log.error("Unable to find a valid subscription!")
Betty Zhou7f45f552017-03-15 19:12:52 -07007174 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07007175 while duration < MAX_WAIT_TIME_NW_SELECTION:
7176 data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
7177 voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
7178 if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
7179 ad.log.debug("Find valid voice or data sub id")
7180 break
7181 else:
7182 ad.log.info("Did not find valid data or voice sub id")
7183 time.sleep(5)
7184 duration += 5
7185 else:
7186 ad.log.error("Unable to find valid data or voice sub id")
Betty Zhou7f45f552017-03-15 19:12:52 -07007187 return False
Betty Zhoub14c1012018-04-20 11:27:00 -07007188 while duration < MAX_WAIT_TIME_NW_SELECTION:
7189 data_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
7190 if data_sub_id > INVALID_SUB_ID:
7191 data_rat = get_network_rat_for_subscription(
7192 log, ad, data_sub_id, NETWORK_SERVICE_DATA)
7193 else:
7194 data_rat = RAT_UNKNOWN
7195 if voice_sub_id > INVALID_SUB_ID:
7196 voice_rat = get_network_rat_for_subscription(
7197 log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
7198 else:
7199 voice_rat = RAT_UNKNOWN
7200 if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
7201 ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
7202 data_sub_id, data_rat, voice_sub_id, voice_rat)
7203 return True
7204 else:
7205 ad.log.info("Did not attach for data or voice service")
7206 time.sleep(5)
7207 duration += 5
7208 else:
7209 ad.log.error("Did not attach for voice or data service")
Betty Zhou7f45f552017-03-15 19:12:52 -07007210 return False
Betty Zhou7f45f552017-03-15 19:12:52 -07007211
7212
Markus Liu61220b72019-08-01 16:26:22 +08007213def ensure_phone_default_state(log, ad, check_subscription=True, retry=2):
Ang Li73697b32015-12-03 00:41:53 +00007214 """Ensure ad in default state.
7215 Phone not in call.
7216 Phone have no stored WiFi network and WiFi disconnected.
7217 Phone not in airplane mode.
7218 """
7219 result = True
Betty Zhouf25ce442017-03-03 14:28:36 -08007220 if not toggle_airplane_mode(log, ad, False, False):
7221 ad.log.error("Fail to turn off airplane mode")
7222 result = False
Betty Zhou94023182017-06-07 18:02:14 -07007223 try:
Betty Zhou77f2bed2017-10-04 18:39:07 -07007224 set_wifi_to_default(log, ad)
Markus Liu61220b72019-08-01 16:26:22 +08007225 while ad.droid.telecomIsInCall() and retry > 0:
Betty Zhou94023182017-06-07 18:02:14 -07007226 ad.droid.telecomEndCall()
Markus Liu61220b72019-08-01 16:26:22 +08007227 time.sleep(3)
7228 retry -= 1
7229 if not wait_for_droid_not_in_call(log, ad):
7230 ad.log.error("Failed to end call")
Jaineelcb217b62020-11-03 14:33:40 -08007231 #ad.droid.telephonyFactoryReset()
Betty Zhou2cf788e2017-06-27 17:25:53 -07007232 data_roaming = getattr(ad, 'roaming', False)
7233 if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
7234 set_cell_data_roaming_state_by_adb(ad, data_roaming)
Betty Zhouf3366012017-11-21 18:23:20 -08007235 remove_mobile_data_usage_limit(ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07007236 if not wait_for_not_network_rat(
7237 log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
7238 ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
7239 RAT_FAMILY_WLAN)
7240 result = False
7241
7242 if check_subscription and not ensure_phone_subscription(log, ad):
7243 ad.log.error("Unable to find a valid subscription!")
7244 result = False
Betty Zhou94023182017-06-07 18:02:14 -07007245 except Exception as e:
7246 ad.log.error("%s failure, toggle APM instead", e)
Betty Zhou77f2bed2017-10-04 18:39:07 -07007247 toggle_airplane_mode_by_adb(log, ad, True)
7248 toggle_airplane_mode_by_adb(log, ad, False)
7249 ad.send_keycode("ENDCALL")
7250 ad.adb.shell("settings put global wfc_ims_enabled 0")
7251 ad.adb.shell("settings put global mobile_data 1")
Betty Zhouf809c5c2017-03-21 14:55:59 -07007252
Ang Li73697b32015-12-03 00:41:53 +00007253 return result
7254
Nathan Harold123c9da2015-12-30 16:33:25 -08007255
Betty Zhou68fc0d02017-04-26 13:42:54 -07007256def ensure_phones_default_state(log, ads, check_subscription=True):
Ang Li73697b32015-12-03 00:41:53 +00007257 """Ensure ads in default state.
7258 Phone not in call.
7259 Phone have no stored WiFi network and WiFi disconnected.
7260 Phone not in airplane mode.
Nathan Haroldeb60b192016-08-24 14:41:55 -07007261
7262 Returns:
7263 True if all steps of restoring default state succeed.
7264 False if any of the steps to restore default state fails.
Ang Li73697b32015-12-03 00:41:53 +00007265 """
7266 tasks = []
7267 for ad in ads:
Betty Zhou68fc0d02017-04-26 13:42:54 -07007268 tasks.append((ensure_phone_default_state, (log, ad,
7269 check_subscription)))
Ang Li73697b32015-12-03 00:41:53 +00007270 if not multithread_func(log, tasks):
7271 log.error("Ensure_phones_default_state Fail.")
7272 return False
7273 return True
7274
Nathan Harold123c9da2015-12-30 16:33:25 -08007275
Betty Zhoua37acd32017-02-23 20:04:24 -08007276def check_is_wifi_connected(log, ad, wifi_ssid):
7277 """Check if ad is connected to wifi wifi_ssid.
Ang Li73697b32015-12-03 00:41:53 +00007278
7279 Args:
7280 log: Log object.
7281 ad: Android device object.
7282 wifi_ssid: WiFi network SSID.
Ang Li73697b32015-12-03 00:41:53 +00007283
Betty Zhoua37acd32017-02-23 20:04:24 -08007284 Returns:
7285 True if wifi is connected to wifi_ssid
7286 False if wifi is not connected to wifi_ssid
Ang Li73697b32015-12-03 00:41:53 +00007287 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007288 wifi_info = ad.droid.wifiGetConnectionInfo()
Betty Zhouee311052017-12-19 13:09:56 -08007289 if wifi_info["supplicant_state"] == "completed" and wifi_info["SSID"] == wifi_ssid:
Betty Zhoua37acd32017-02-23 20:04:24 -08007290 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007291 ad.on_mobile_data = False
Betty Zhouccd171d2017-02-13 15:11:33 -08007292 return True
Betty Zhoua37acd32017-02-23 20:04:24 -08007293 else:
7294 ad.log.info("Wifi is not connected to %s", wifi_ssid)
7295 ad.log.debug("Wifi connection_info=%s", wifi_info)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007296 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007297 return False
7298
7299
Markus Liud1468dc2020-03-05 18:43:17 +08007300def ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd=None, retries=3, apm=False):
Betty Zhoua37acd32017-02-23 20:04:24 -08007301 """Ensure ad connected to wifi on network wifi_ssid.
7302
7303 Args:
7304 log: Log object.
7305 ad: Android device object.
7306 wifi_ssid: WiFi network SSID.
7307 wifi_pwd: optional secure network password.
7308 retries: the number of retries.
7309
7310 Returns:
7311 True if wifi is connected to wifi_ssid
7312 False if wifi is not connected to wifi_ssid
7313 """
Markus Liud1468dc2020-03-05 18:43:17 +08007314 if not toggle_airplane_mode(log, ad, apm, strict_checking=False):
7315 return False
7316
Betty Zhouf987b8f2017-03-09 16:34:00 -08007317 network = {WIFI_SSID_KEY: wifi_ssid}
Betty Zhouf25ce442017-03-03 14:28:36 -08007318 if wifi_pwd:
Betty Zhouf987b8f2017-03-09 16:34:00 -08007319 network[WIFI_PWD_KEY] = wifi_pwd
Betty Zhouf25ce442017-03-03 14:28:36 -08007320 for i in range(retries):
7321 if not ad.droid.wifiCheckState():
7322 ad.log.info("Wifi state is down. Turn on Wifi")
7323 ad.droid.wifiToggleState(True)
7324 if check_is_wifi_connected(log, ad, wifi_ssid):
7325 ad.log.info("Wifi is connected to %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07007326 return verify_internet_connection(log, ad, retries=3)
Betty Zhouf25ce442017-03-03 14:28:36 -08007327 else:
Betty Zhoua37acd32017-02-23 20:04:24 -08007328 ad.log.info("Connecting to wifi %s", wifi_ssid)
Betty Zhou9a27c6a2017-05-22 12:55:50 -07007329 try:
7330 ad.droid.wifiConnectByConfig(network)
7331 except Exception:
Betty Zhou94023182017-06-07 18:02:14 -07007332 ad.log.info("Connecting to wifi by wifiConnect instead")
Betty Zhou9a27c6a2017-05-22 12:55:50 -07007333 ad.droid.wifiConnect(network)
Betty Zhoua37acd32017-02-23 20:04:24 -08007334 time.sleep(20)
7335 if check_is_wifi_connected(log, ad, wifi_ssid):
Betty Zhou68fc0d02017-04-26 13:42:54 -07007336 ad.log.info("Connected to Wifi %s", wifi_ssid)
Betty Zhou5dd53c02018-03-22 20:08:33 -07007337 return verify_internet_connection(log, ad, retries=3)
Betty Zhoua37acd32017-02-23 20:04:24 -08007338 ad.log.info("Fail to connected to wifi %s", wifi_ssid)
Ang Li73697b32015-12-03 00:41:53 +00007339 return False
7340
Nathan Harold123c9da2015-12-30 16:33:25 -08007341
Betty Zhoua37acd32017-02-23 20:04:24 -08007342def forget_all_wifi_networks(log, ad):
7343 """Forget all stored wifi network information
7344
7345 Args:
7346 log: log object
7347 ad: AndroidDevice object
7348
7349 Returns:
7350 boolean success (True) or failure (False)
7351 """
7352 if not ad.droid.wifiGetConfiguredNetworks():
Betty Zhou1b302fd2017-11-17 11:43:09 -08007353 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007354 return True
7355 try:
7356 old_state = ad.droid.wifiCheckState()
Betty Zhouf987b8f2017-03-09 16:34:00 -08007357 wifi_test_utils.reset_wifi(ad)
Betty Zhou7f45f552017-03-15 19:12:52 -07007358 wifi_toggle_state(log, ad, old_state)
Betty Zhoua37acd32017-02-23 20:04:24 -08007359 except Exception as e:
7360 log.error("forget_all_wifi_networks with exception: %s", e)
7361 return False
Betty Zhou1b302fd2017-11-17 11:43:09 -08007362 ad.on_mobile_data = True
Betty Zhoua37acd32017-02-23 20:04:24 -08007363 return True
7364
7365
Betty Zhouf987b8f2017-03-09 16:34:00 -08007366def wifi_reset(log, ad, disable_wifi=True):
7367 """Forget all stored wifi networks and (optionally) disable WiFi
7368
7369 Args:
7370 log: log object
7371 ad: AndroidDevice object
7372 disable_wifi: boolean to disable wifi, defaults to True
7373 Returns:
7374 boolean success (True) or failure (False)
7375 """
7376 if not forget_all_wifi_networks(log, ad):
7377 ad.log.error("Unable to forget all networks")
7378 return False
7379 if not wifi_toggle_state(log, ad, not disable_wifi):
7380 ad.log.error("Failed to toggle WiFi state to %s!", not disable_wifi)
7381 return False
7382 return True
7383
7384
Betty Zhoua37acd32017-02-23 20:04:24 -08007385def set_wifi_to_default(log, ad):
7386 """Set wifi to default state (Wifi disabled and no configured network)
7387
7388 Args:
7389 log: log object
7390 ad: AndroidDevice object
7391
7392 Returns:
7393 boolean success (True) or failure (False)
7394 """
Betty Zhouf25ce442017-03-03 14:28:36 -08007395 ad.droid.wifiFactoryReset()
Betty Zhoua37acd32017-02-23 20:04:24 -08007396 ad.droid.wifiToggleState(False)
Betty Zhou1b302fd2017-11-17 11:43:09 -08007397 ad.on_mobile_data = True
Betty Zhouf987b8f2017-03-09 16:34:00 -08007398
7399
7400def wifi_toggle_state(log, ad, state, retries=3):
7401 """Toggle the WiFi State
7402
7403 Args:
7404 log: log object
7405 ad: AndroidDevice object
7406 state: True, False, or None
7407
7408 Returns:
7409 boolean success (True) or failure (False)
7410 """
7411 for i in range(retries):
7412 if wifi_test_utils.wifi_toggle_state(ad, state, assert_on_fail=False):
Betty Zhou1b302fd2017-11-17 11:43:09 -08007413 ad.on_mobile_data = not state
Betty Zhouf987b8f2017-03-09 16:34:00 -08007414 return True
7415 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
7416 return False
7417
7418
7419def start_wifi_tethering(log, ad, ssid, password, ap_band=None):
7420 """Start a Tethering Session
7421
7422 Args:
7423 log: log object
7424 ad: AndroidDevice object
7425 ssid: the name of the WiFi network
7426 password: optional password, used for secure networks.
7427 ap_band=DEPRECATED specification of 2G or 5G tethering
7428 Returns:
7429 boolean success (True) or failure (False)
7430 """
7431 return wifi_test_utils._assert_on_fail_handler(
7432 wifi_test_utils.start_wifi_tethering,
7433 False,
7434 ad,
7435 ssid,
7436 password,
7437 band=ap_band)
7438
7439
7440def stop_wifi_tethering(log, ad):
7441 """Stop a Tethering Session
7442
7443 Args:
7444 log: log object
7445 ad: AndroidDevice object
7446 Returns:
7447 boolean success (True) or failure (False)
7448 """
7449 return wifi_test_utils._assert_on_fail_handler(
7450 wifi_test_utils.stop_wifi_tethering, False, ad)
Betty Zhoua37acd32017-02-23 20:04:24 -08007451
7452
Yang Liu98fd9d72016-03-04 12:14:49 -08007453def reset_preferred_network_type_to_allowable_range(log, ad):
7454 """If preferred network type is not in allowable range, reset to GEN_4G
7455 preferred network type.
7456
7457 Args:
7458 log: log object
7459 ad: android device object
7460
7461 Returns:
7462 None
7463 """
Betty Zhou3b2de072018-03-15 16:46:26 -07007464 for sub_id, sub_info in ad.telephony["subscription"].items():
Yang Liu98fd9d72016-03-04 12:14:49 -08007465 current_preference = \
7466 ad.droid.telephonyGetPreferredNetworkTypesForSubscription(sub_id)
Betty Zhoubb192482017-03-01 14:38:56 -08007467 ad.log.debug("sub_id network preference is %s", current_preference)
Yang Liu4072cfa2016-04-06 11:25:07 -07007468 try:
Nathan Harold7642fc92016-05-02 18:29:11 -07007469 if current_preference not in get_allowable_network_preference(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07007470 sub_info["operator"], sub_info["phone_type"]):
Jaineelc52d6852017-10-27 15:03:54 -07007471 network_preference = network_preference_for_generation(
Betty Zhoud2da7ba2017-03-24 12:54:34 -07007472 GEN_4G, sub_info["operator"], sub_info["phone_type"])
Yang Liu4072cfa2016-04-06 11:25:07 -07007473 ad.droid.telephonySetPreferredNetworkTypesForSubscription(
7474 network_preference, sub_id)
7475 except KeyError:
7476 pass
Yang Liu98fd9d72016-03-04 12:14:49 -08007477
Nathan Harold7642fc92016-05-02 18:29:11 -07007478
Ang Li73697b32015-12-03 00:41:53 +00007479def task_wrapper(task):
7480 """Task wrapper for multithread_func
7481
7482 Args:
7483 task[0]: function to be wrapped.
7484 task[1]: function args.
7485
7486 Returns:
7487 Return value of wrapped function call.
7488 """
7489 func = task[0]
7490 params = task[1]
7491 return func(*params)
7492
Nathan Harold123c9da2015-12-30 16:33:25 -08007493
Patrick Chiang75b89862017-10-13 17:02:29 -07007494def run_multithread_func_async(log, task):
7495 """Starts a multi-threaded function asynchronously.
7496
7497 Args:
7498 log: log object.
7499 task: a task to be executed in parallel.
7500
7501 Returns:
7502 Future object representing the execution of the task.
7503 """
7504 executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
7505 try:
7506 future_object = executor.submit(task_wrapper, task)
7507 except Exception as e:
7508 log.error("Exception error %s", e)
7509 raise
7510 return future_object
7511
7512
Betty Zhouccd171d2017-02-13 15:11:33 -08007513def run_multithread_func(log, tasks):
7514 """Run multi-thread functions and return results.
7515
7516 Args:
7517 log: log object.
7518 tasks: a list of tasks to be executed in parallel.
7519
7520 Returns:
7521 results for tasks.
7522 """
Betty Zhouee311052017-12-19 13:09:56 -08007523 MAX_NUMBER_OF_WORKERS = 10
Betty Zhouccd171d2017-02-13 15:11:33 -08007524 number_of_workers = min(MAX_NUMBER_OF_WORKERS, len(tasks))
7525 executor = concurrent.futures.ThreadPoolExecutor(
7526 max_workers=number_of_workers)
Betty Zhou8802ec62017-12-18 19:44:29 -08007527 if not log: log = logging
Betty Zhou95ed1862017-07-21 13:29:02 -07007528 try:
7529 results = list(executor.map(task_wrapper, tasks))
7530 except Exception as e:
7531 log.error("Exception error %s", e)
7532 raise
Betty Zhouccd171d2017-02-13 15:11:33 -08007533 executor.shutdown()
Betty Zhou0111ae02017-11-29 20:37:26 -08007534 if log:
7535 log.info("multithread_func %s result: %s",
7536 [task[0].__name__ for task in tasks], results)
Betty Zhouccd171d2017-02-13 15:11:33 -08007537 return results
7538
7539
Ang Li73697b32015-12-03 00:41:53 +00007540def multithread_func(log, tasks):
7541 """Multi-thread function wrapper.
7542
7543 Args:
7544 log: log object.
7545 tasks: tasks to be executed in parallel.
7546
7547 Returns:
7548 True if all tasks return True.
7549 False if any task return False.
7550 """
Betty Zhouccd171d2017-02-13 15:11:33 -08007551 results = run_multithread_func(log, tasks)
Ang Li73697b32015-12-03 00:41:53 +00007552 for r in results:
7553 if not r:
7554 return False
7555 return True
7556
Nathan Harold123c9da2015-12-30 16:33:25 -08007557
Betty Zhouccd171d2017-02-13 15:11:33 -08007558def multithread_func_and_check_results(log, tasks, expected_results):
7559 """Multi-thread function wrapper.
7560
7561 Args:
7562 log: log object.
7563 tasks: tasks to be executed in parallel.
7564 expected_results: check if the results from tasks match expected_results.
7565
7566 Returns:
7567 True if expected_results are met.
7568 False if expected_results are not met.
7569 """
7570 return_value = True
7571 results = run_multithread_func(log, tasks)
7572 log.info("multithread_func result: %s, expecting %s", results,
7573 expected_results)
7574 for task, result, expected_result in zip(tasks, results, expected_results):
7575 if result != expected_result:
7576 logging.info("Result for task %s is %s, expecting %s", task[0],
7577 result, expected_result)
7578 return_value = False
7579 return return_value
7580
7581
Ang Li73697b32015-12-03 00:41:53 +00007582def set_phone_screen_on(log, ad, screen_on_time=MAX_SCREEN_ON_TIME):
7583 """Set phone screen on time.
7584
7585 Args:
7586 log: Log object.
7587 ad: Android device object.
7588 screen_on_time: screen on time.
7589 This is optional, default value is MAX_SCREEN_ON_TIME.
7590 Returns:
7591 True if set successfully.
7592 """
7593 ad.droid.setScreenTimeout(screen_on_time)
7594 return screen_on_time == ad.droid.getScreenTimeout()
7595
Nathan Harold123c9da2015-12-30 16:33:25 -08007596
Ang Li73697b32015-12-03 00:41:53 +00007597def set_phone_silent_mode(log, ad, silent_mode=True):
7598 """Set phone silent mode.
7599
7600 Args:
7601 log: Log object.
7602 ad: Android device object.
7603 silent_mode: set phone silent or not.
7604 This is optional, default value is True (silent mode on).
7605 Returns:
7606 True if set successfully.
7607 """
7608 ad.droid.toggleRingerSilentMode(silent_mode)
Betty Zhoua37acd32017-02-23 20:04:24 -08007609 ad.droid.setMediaVolume(0)
7610 ad.droid.setVoiceCallVolume(0)
7611 ad.droid.setAlarmVolume(0)
Betty Zhoub4f52102018-05-29 14:39:25 -07007612 ad.adb.ensure_root()
Betty Zhoub7663ba2018-05-23 11:56:22 -07007613 ad.adb.shell("setprop ro.audio.silent 1", ignore_status=True)
Jaineelf0c76cf2019-06-20 14:35:06 -07007614 ad.adb.shell("cmd notification set_dnd on", ignore_status=True)
Ang Li73697b32015-12-03 00:41:53 +00007615 return silent_mode == ad.droid.checkRingerSilentMode()
7616
Nathan Harold123c9da2015-12-30 16:33:25 -08007617
Betty Zhou1eedf722018-04-27 14:27:04 -07007618def set_preferred_network_mode_pref(log,
7619 ad,
7620 sub_id,
7621 network_preference,
7622 timeout=WAIT_TIME_ANDROID_STATE_SETTLING):
Jaineelcd748202017-08-10 12:23:42 -07007623 """Set Preferred Network Mode for Sub_id
7624 Args:
7625 log: Log object.
7626 ad: Android device object.
7627 sub_id: Subscription ID.
7628 network_preference: Network Mode Type
7629 """
Betty Zhou1eedf722018-04-27 14:27:04 -07007630 begin_time = get_device_epoch_time(ad)
7631 if ad.droid.telephonyGetPreferredNetworkTypesForSubscription(
7632 sub_id) == network_preference:
7633 ad.log.info("Current ModePref for Sub %s is in %s", sub_id,
7634 network_preference)
7635 return True
Jaineelcd748202017-08-10 12:23:42 -07007636 ad.log.info("Setting ModePref to %s for Sub %s", network_preference,
7637 sub_id)
Betty Zhou1eedf722018-04-27 14:27:04 -07007638 while timeout >= 0:
7639 if ad.droid.telephonySetPreferredNetworkTypesForSubscription(
7640 network_preference, sub_id):
7641 return True
7642 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
7643 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
7644 error_msg = "Failed to set sub_id %s PreferredNetworkType to %s" % (
7645 sub_id, network_preference)
7646 search_results = ad.search_logcat(
7647 "REQUEST_SET_PREFERRED_NETWORK_TYPE error", begin_time=begin_time)
7648 if search_results:
7649 log_message = search_results[-1]["log_message"]
7650 if "DEVICE_IN_USE" in log_message:
7651 error_msg = "%s due to DEVICE_IN_USE" % error_msg
7652 else:
7653 error_msg = "%s due to %s" % (error_msg, log_message)
7654 ad.log.error(error_msg)
7655 return False
Jaineelcd748202017-08-10 12:23:42 -07007656
7657
Jaineel823f7922020-05-14 16:38:10 -07007658def set_preferred_mode_for_5g(ad, sub_id=None, mode=None):
7659 """Set Preferred Network Mode for 5G NSA
7660 Args:
7661 ad: Android device object.
7662 sub_id: Subscription ID.
7663 mode: 5G Network Mode Type
7664 """
7665 if sub_id is None:
7666 sub_id = ad.droid.subscriptionGetDefaultSubId()
7667 if mode is None:
7668 mode = NETWORK_MODE_NR_LTE_GSM_WCDMA
7669 return set_preferred_network_mode_pref(ad.log, ad, sub_id, mode)
7670
7671
7672
Ang Li73697b32015-12-03 00:41:53 +00007673def set_preferred_subid_for_sms(log, ad, sub_id):
7674 """set subscription id for SMS
7675
7676 Args:
7677 log: Log object.
7678 ad: Android device object.
7679 sub_id :Subscription ID.
7680
7681 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007682 ad.log.info("Setting subscription %s as preferred SMS SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007683 ad.droid.subscriptionSetDefaultSmsSubId(sub_id)
7684 # Wait to make sure settings take effect
7685 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7686 return sub_id == ad.droid.subscriptionGetDefaultSmsSubId()
7687
Nathan Harold123c9da2015-12-30 16:33:25 -08007688
Ang Li73697b32015-12-03 00:41:53 +00007689def set_preferred_subid_for_data(log, ad, sub_id):
7690 """set subscription id for data
7691
7692 Args:
7693 log: Log object.
7694 ad: Android device object.
7695 sub_id :Subscription ID.
7696
7697 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007698 ad.log.info("Setting subscription %s as preferred Data SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007699 ad.droid.subscriptionSetDefaultDataSubId(sub_id)
7700 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7701 # Wait to make sure settings take effect
7702 # Data SIM change takes around 1 min
7703 # Check whether data has changed to selected sim
Nathan Harold7642fc92016-05-02 18:29:11 -07007704 if not wait_for_data_connection(log, ad, True,
7705 MAX_WAIT_TIME_DATA_SUB_CHANGE):
Ang Li73697b32015-12-03 00:41:53 +00007706 log.error("Data Connection failed - Not able to switch Data SIM")
7707 return False
7708 return True
7709
Nathan Harold123c9da2015-12-30 16:33:25 -08007710
Ang Li73697b32015-12-03 00:41:53 +00007711def set_preferred_subid_for_voice(log, ad, sub_id):
7712 """set subscription id for voice
7713
7714 Args:
7715 log: Log object.
7716 ad: Android device object.
7717 sub_id :Subscription ID.
7718
7719 """
Betty Zhoua37acd32017-02-23 20:04:24 -08007720 ad.log.info("Setting subscription %s as Voice SIM", sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007721 ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
7722 ad.droid.telecomSetUserSelectedOutgoingPhoneAccountBySubId(sub_id)
7723 # Wait to make sure settings take effect
7724 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
7725 return True
7726
Nathan Harold123c9da2015-12-30 16:33:25 -08007727
Ang Li73697b32015-12-03 00:41:53 +00007728def set_call_state_listen_level(log, ad, value, sub_id):
7729 """Set call state listen level for subscription id.
7730
7731 Args:
7732 log: Log object.
7733 ad: Android device object.
7734 value: True or False
7735 sub_id :Subscription ID.
7736
7737 Returns:
7738 True or False
7739 """
7740 if sub_id == INVALID_SUB_ID:
7741 log.error("Invalid Subscription ID")
7742 return False
Yang Liuaed3eef2015-12-15 18:40:25 -08007743 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007744 "Foreground", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08007745 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007746 "Ringing", value, sub_id)
Yang Liuaed3eef2015-12-15 18:40:25 -08007747 ad.droid.telephonyAdjustPreciseCallStateListenLevelForSubscription(
Nathan Harold123c9da2015-12-30 16:33:25 -08007748 "Background", value, sub_id)
Ang Li73697b32015-12-03 00:41:53 +00007749 return True
7750
Nathan Harold123c9da2015-12-30 16:33:25 -08007751
Ang Li73697b32015-12-03 00:41:53 +00007752def setup_sim(log, ad, sub_id, voice=False, sms=False, data=False):
7753 """set subscription id for voice, sms and data
7754
7755 Args:
7756 log: Log object.
7757 ad: Android device object.
7758 sub_id :Subscription ID.
7759 voice: True if to set subscription as default voice subscription
7760 sms: True if to set subscription as default sms subscription
7761 data: True if to set subscription as default data subscription
7762
7763 """
7764 if sub_id == INVALID_SUB_ID:
7765 log.error("Invalid Subscription ID")
7766 return False
7767 else:
7768 if voice:
7769 if not set_preferred_subid_for_voice(log, ad, sub_id):
7770 return False
7771 if sms:
7772 if not set_preferred_subid_for_sms(log, ad, sub_id):
7773 return False
7774 if data:
Nathan Harold123c9da2015-12-30 16:33:25 -08007775 if not set_preferred_subid_for_data(log, ad, sub_id):
Ang Li73697b32015-12-03 00:41:53 +00007776 return False
7777 return True
7778
Nathan Harold7642fc92016-05-02 18:29:11 -07007779
Yang Liu8e6adff2016-02-05 10:24:04 -08007780def is_event_match(event, field, value):
7781 """Return if <field> in "event" match <value> or not.
Ang Li73697b32015-12-03 00:41:53 +00007782
7783 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08007784 event: event to test. This event need to have <field>.
7785 field: field to match.
7786 value: value to match.
Ang Li73697b32015-12-03 00:41:53 +00007787
7788 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08007789 True if <field> in "event" match <value>.
Ang Li73697b32015-12-03 00:41:53 +00007790 False otherwise.
7791 """
Yang Liu8e6adff2016-02-05 10:24:04 -08007792 return is_event_match_for_list(event, field, [value])
Ang Li73697b32015-12-03 00:41:53 +00007793
Nathan Harold123c9da2015-12-30 16:33:25 -08007794
Yang Liu8e6adff2016-02-05 10:24:04 -08007795def is_event_match_for_list(event, field, value_list):
7796 """Return if <field> in "event" match any one of the value
7797 in "value_list" or not.
Ang Li73697b32015-12-03 00:41:53 +00007798
7799 Args:
Yang Liu8e6adff2016-02-05 10:24:04 -08007800 event: event to test. This event need to have <field>.
7801 field: field to match.
7802 value_list: a list of value to match.
Ang Li73697b32015-12-03 00:41:53 +00007803
7804 Returns:
Yang Liu8e6adff2016-02-05 10:24:04 -08007805 True if <field> in "event" match one of the value in "value_list".
Ang Li73697b32015-12-03 00:41:53 +00007806 False otherwise.
7807 """
7808 try:
Yang Liu8e6adff2016-02-05 10:24:04 -08007809 value_in_event = event['data'][field]
Ang Li73697b32015-12-03 00:41:53 +00007810 except KeyError:
7811 return False
Yang Liu8e6adff2016-02-05 10:24:04 -08007812 for value in value_list:
7813 if value_in_event == value:
Ang Li73697b32015-12-03 00:41:53 +00007814 return True
7815 return False
7816
Nathan Harold123c9da2015-12-30 16:33:25 -08007817
Yang Liu8e6adff2016-02-05 10:24:04 -08007818def is_network_call_back_event_match(event, network_callback_id,
7819 network_callback_event):
Ang Li73697b32015-12-03 00:41:53 +00007820 try:
Nathan Harold4a144a42016-09-19 14:16:24 -07007821 return (
7822 (network_callback_id == event['data'][NetworkCallbackContainer.ID])
Betty Zhouee311052017-12-19 13:09:56 -08007823 and (network_callback_event == event['data']
7824 [NetworkCallbackContainer.NETWORK_CALLBACK_EVENT]))
Ang Li73697b32015-12-03 00:41:53 +00007825 except KeyError:
7826 return False
7827
Nathan Harold123c9da2015-12-30 16:33:25 -08007828
Ang Li73697b32015-12-03 00:41:53 +00007829def is_build_id(log, ad, build_id):
7830 """Return if ad's build id is the same as input parameter build_id.
7831
7832 Args:
7833 log: log object.
7834 ad: android device object.
7835 build_id: android build id.
7836
7837 Returns:
7838 True if ad's build id is the same as input parameter build_id.
7839 False otherwise.
7840 """
7841 actual_bid = ad.droid.getBuildID()
7842
Betty Zhoua37acd32017-02-23 20:04:24 -08007843 ad.log.info("BUILD DISPLAY: %s", ad.droid.getBuildDisplay())
Ang Li73697b32015-12-03 00:41:53 +00007844 #In case we want to log more stuff/more granularity...
7845 #log.info("{} BUILD ID:{} ".format(ad.serial, ad.droid.getBuildID()))
7846 #log.info("{} BUILD FINGERPRINT: {} "
7847 # .format(ad.serial), ad.droid.getBuildFingerprint())
7848 #log.info("{} BUILD TYPE: {} "
7849 # .format(ad.serial), ad.droid.getBuildType())
7850 #log.info("{} BUILD NUMBER: {} "
7851 # .format(ad.serial), ad.droid.getBuildNumber())
7852 if actual_bid.upper() != build_id.upper():
Betty Zhoua37acd32017-02-23 20:04:24 -08007853 ad.log.error("%s: Incorrect Build ID", ad.model)
Ang Li73697b32015-12-03 00:41:53 +00007854 return False
7855 return True
7856
Nathan Harold123c9da2015-12-30 16:33:25 -08007857
Ang Li73697b32015-12-03 00:41:53 +00007858def is_uri_equivalent(uri1, uri2):
7859 """Check whether two input uris match or not.
7860
7861 Compare Uris.
7862 If Uris are tel URI, it will only take the digit part
7863 and compare as phone number.
7864 Else, it will just do string compare.
7865
7866 Args:
7867 uri1: 1st uri to be compared.
7868 uri2: 2nd uri to be compared.
7869
7870 Returns:
7871 True if two uris match. Otherwise False.
7872 """
Nathan Harold23683d22015-12-14 16:19:08 -08007873
7874 #If either is None/empty we return false
7875 if not uri1 or not uri2:
7876 return False
7877
7878 try:
7879 if uri1.startswith('tel:') and uri2.startswith('tel:'):
Yang Liu598b93d2016-03-22 17:07:59 -07007880 uri1_number = get_number_from_tel_uri(uri1)
7881 uri2_number = get_number_from_tel_uri(uri2)
Nathan Harold23683d22015-12-14 16:19:08 -08007882 return check_phone_number_match(uri1_number, uri2_number)
7883 else:
7884 return uri1 == uri2
7885 except AttributeError as e:
7886 return False
Ang Li73697b32015-12-03 00:41:53 +00007887
Nathan Harold123c9da2015-12-30 16:33:25 -08007888
Ang Li73697b32015-12-03 00:41:53 +00007889def get_call_uri(ad, call_id):
7890 """Get call's uri field.
7891
7892 Get Uri for call_id in ad.
7893
7894 Args:
7895 ad: android device object.
7896 call_id: the call id to get Uri from.
7897
7898 Returns:
7899 call's Uri if call is active and have uri field. None otherwise.
7900 """
7901 try:
7902 call_detail = ad.droid.telecomCallGetDetails(call_id)
7903 return call_detail["Handle"]["Uri"]
7904 except:
7905 return None
7906
Nathan Harold7642fc92016-05-02 18:29:11 -07007907
Yang Liu598b93d2016-03-22 17:07:59 -07007908def get_number_from_tel_uri(uri):
7909 """Get Uri number from tel uri
7910
7911 Args:
7912 uri: input uri
7913
7914 Returns:
7915 If input uri is tel uri, return the number part.
7916 else return None.
7917 """
7918 if uri.startswith('tel:'):
Nathan Harold4a144a42016-09-19 14:16:24 -07007919 uri_number = ''.join(
7920 i for i in urllib.parse.unquote(uri) if i.isdigit())
Yang Liu598b93d2016-03-22 17:07:59 -07007921 return uri_number
7922 else:
7923 return None
Betty Zhou5cf94d82017-06-09 19:18:09 -07007924
7925
Betty Zhou9a96fc32018-02-01 16:44:05 -08007926def find_qxdm_log_mask(ad, mask="default.cfg"):
Betty Zhou550fd372017-10-16 17:22:47 -07007927 """Find QXDM logger mask."""
7928 if "/" not in mask:
Betty Zhoua18d0982017-10-18 14:30:43 -07007929 # Call nexuslogger to generate log mask
7930 start_nexuslogger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07007931 # Find the log mask path
Betty Zhou9a96fc32018-02-01 16:44:05 -08007932 for path in (DEFAULT_QXDM_LOG_PATH, "/data/diag_logs",
7933 "/vendor/etc/mdlog/"):
Betty Zhou02571f52018-02-16 14:11:16 -08007934 out = ad.adb.shell(
7935 "find %s -type f -iname %s" % (path, mask), ignore_status=True)
Betty Zhou9a96fc32018-02-01 16:44:05 -08007936 if out and "No such" not in out and "Permission denied" not in out:
7937 if path.startswith("/vendor/"):
Betty Zhou739d6b72018-04-18 10:38:53 -07007938 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
Betty Zhou9a96fc32018-02-01 16:44:05 -08007939 else:
Betty Zhou739d6b72018-04-18 10:38:53 -07007940 setattr(ad, "qxdm_log_path", path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08007941 return out.split("\n")[0]
7942 if mask in ad.adb.shell("ls /vendor/etc/mdlog/"):
Betty Zhou739d6b72018-04-18 10:38:53 -07007943 setattr(ad, "qxdm_log_path", DEFAULT_QXDM_LOG_PATH)
Betty Zhou9a96fc32018-02-01 16:44:05 -08007944 return "%s/%s" % ("/vendor/etc/mdlog/", mask)
Betty Zhou550fd372017-10-16 17:22:47 -07007945 else:
7946 out = ad.adb.shell("ls %s" % mask, ignore_status=True)
7947 if out and "No such" not in out:
Betty Zhou739d6b72018-04-18 10:38:53 -07007948 qxdm_log_path, cfg_name = os.path.split(mask)
7949 setattr(ad, "qxdm_log_path", qxdm_log_path)
Betty Zhoua18d0982017-10-18 14:30:43 -07007950 return mask
Betty Zhou550fd372017-10-16 17:22:47 -07007951 ad.log.warning("Could NOT find QXDM logger mask path for %s", mask)
7952
7953
7954def set_qxdm_logger_command(ad, mask=None):
7955 """Set QXDM logger always on.
7956
7957 Args:
7958 ad: android device object.
7959
7960 """
7961 ## Neet to check if log mask will be generated without starting nexus logger
Betty Zhou9a96fc32018-02-01 16:44:05 -08007962 masks = []
7963 mask_path = None
Betty Zhou550fd372017-10-16 17:22:47 -07007964 if mask:
Betty Zhou9a96fc32018-02-01 16:44:05 -08007965 masks = [mask]
7966 masks.extend(["QC_Default.cfg", "default.cfg"])
7967 for mask in masks:
7968 mask_path = find_qxdm_log_mask(ad, mask)
7969 if mask_path: break
Betty Zhou550fd372017-10-16 17:22:47 -07007970 if not mask_path:
Betty Zhou9a96fc32018-02-01 16:44:05 -08007971 ad.log.error("Cannot find QXDM mask %s", mask)
Betty Zhou550fd372017-10-16 17:22:47 -07007972 ad.qxdm_logger_command = None
Betty Zhoua18d0982017-10-18 14:30:43 -07007973 return False
Betty Zhou550fd372017-10-16 17:22:47 -07007974 else:
Betty Zhoua18d0982017-10-18 14:30:43 -07007975 ad.log.info("Use QXDM log mask %s", mask_path)
Betty Zhou9a96fc32018-02-01 16:44:05 -08007976 ad.log.debug("qxdm_log_path = %s", ad.qxdm_log_path)
7977 output_path = os.path.join(ad.qxdm_log_path, "logs")
Betty Zhou1fdebb02018-05-30 17:02:53 -07007978 ad.qxdm_logger_command = ("diag_mdlog -f %s -o %s -s 90 -c" %
Betty Zhou9a96fc32018-02-01 16:44:05 -08007979 (mask_path, output_path))
Betty Zhoue7cc3672018-04-26 16:58:56 -07007980 for prop in ("persist.sys.modem.diag.mdlog",
7981 "persist.vendor.sys.modem.diag.mdlog"):
7982 if ad.adb.getprop(prop):
7983 # Enable qxdm always on if supported
7984 for conf_path in ("/data/vendor/radio/diag_logs",
7985 "/vendor/etc/mdlog"):
7986 if "diag.conf" in ad.adb.shell(
7987 "ls %s" % conf_path, ignore_status=True):
7988 conf_path = "%s/diag.conf" % conf_path
7989 ad.adb.shell('echo "%s" > %s' %
Xianyuan Jia03d4f6c2020-10-12 10:46:45 -07007990 (ad.qxdm_logger_command, conf_path),
7991 ignore_status=True)
Betty Zhoue7cc3672018-04-26 16:58:56 -07007992 break
Betty Zhou1fdebb02018-05-30 17:02:53 -07007993 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
Betty Zhoue7cc3672018-04-26 16:58:56 -07007994 break
Betty Zhoua18d0982017-10-18 14:30:43 -07007995 return True
Betty Zhou550fd372017-10-16 17:22:47 -07007996
7997
Jaineel72d2c242019-07-23 12:00:07 -07007998def start_sdm_logger(ad):
7999 """Start SDM logger."""
8000 if not getattr(ad, "sdm_log", True): return
8001 # Delete existing SDM logs which were created 15 mins prior
8002 ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
8003 file_count = ad.adb.shell(
Jaineel0cdb4a92020-01-31 12:58:20 -08008004 "find %s -type f -iname sbuff_[0-9]*.sdm* | wc -l" % ad.sdm_log_path)
Jaineel72d2c242019-07-23 12:00:07 -07008005 if int(file_count) > 3:
8006 seconds = 15 * 60
8007 # Remove sdm logs modified more than specified seconds ago
8008 ad.adb.shell(
Jaineel0cdb4a92020-01-31 12:58:20 -08008009 "find %s -type f -iname sbuff_[0-9]*.sdm* -not -mtime -%ss -delete" %
Jaineel72d2c242019-07-23 12:00:07 -07008010 (ad.sdm_log_path, seconds))
8011 # start logging
8012 cmd = "setprop vendor.sys.modem.logging.enable true"
8013 ad.log.debug("start sdm logging")
8014 ad.adb.shell(cmd, ignore_status=True)
8015 time.sleep(5)
8016
8017
8018def stop_sdm_logger(ad):
8019 """Stop SDM logger."""
8020 cmd = "setprop vendor.sys.modem.logging.enable false"
8021 ad.log.debug("stop sdm logging")
8022 ad.adb.shell(cmd, ignore_status=True)
8023 time.sleep(5)
8024
8025
Betty Zhou0111ae02017-11-29 20:37:26 -08008026def stop_qxdm_logger(ad):
8027 """Stop QXDM logger."""
8028 for cmd in ("diag_mdlog -k", "killall diag_mdlog"):
8029 output = ad.adb.shell("ps -ef | grep mdlog") or ""
8030 if "diag_mdlog" not in output:
8031 break
8032 ad.log.debug("Kill the existing qxdm process")
8033 ad.adb.shell(cmd, ignore_status=True)
8034 time.sleep(5)
8035
8036
Betty Zhouee311052017-12-19 13:09:56 -08008037def start_qxdm_logger(ad, begin_time=None):
Betty Zhou550fd372017-10-16 17:22:47 -07008038 """Start QXDM logger."""
Betty Zhou3eceae02018-02-09 12:27:51 -08008039 if not getattr(ad, "qxdm_log", True): return
Betty Zhouee311052017-12-19 13:09:56 -08008040 # Delete existing QXDM logs 5 minutes earlier than the begin_time
Betty Zhoua9a354a2018-03-21 15:01:59 -07008041 current_time = get_current_epoch_time()
Betty Zhou9a96fc32018-02-01 16:44:05 -08008042 if getattr(ad, "qxdm_log_path", None):
8043 seconds = None
Betty Zhoua9a354a2018-03-21 15:01:59 -07008044 file_count = ad.adb.shell(
8045 "find %s -type f -iname *.qmdl | wc -l" % ad.qxdm_log_path)
8046 if int(file_count) > 50:
8047 if begin_time:
8048 # if begin_time specified, delete old qxdm logs modified
8049 # 10 minutes before begin time
8050 seconds = int((current_time - begin_time) / 1000.0) + 10 * 60
8051 else:
8052 # if begin_time is not specified, delete old qxdm logs modified
8053 # 15 minutes before current time
8054 seconds = 15 * 60
Betty Zhou9a96fc32018-02-01 16:44:05 -08008055 if seconds:
Betty Zhoua9a354a2018-03-21 15:01:59 -07008056 # Remove qxdm logs modified more than specified seconds ago
Betty Zhou9a96fc32018-02-01 16:44:05 -08008057 ad.adb.shell(
Betty Zhou02571f52018-02-16 14:11:16 -08008058 "find %s -type f -iname *.qmdl -not -mtime -%ss -delete" %
8059 (ad.qxdm_log_path, seconds))
Betty Zhoua9a354a2018-03-21 15:01:59 -07008060 ad.adb.shell(
8061 "find %s -type f -iname *.xml -not -mtime -%ss -delete" %
8062 (ad.qxdm_log_path, seconds))
Betty Zhou550fd372017-10-16 17:22:47 -07008063 if getattr(ad, "qxdm_logger_command", None):
8064 output = ad.adb.shell("ps -ef | grep mdlog") or ""
8065 if ad.qxdm_logger_command not in output:
8066 ad.log.debug("QXDM logging command %s is not running",
8067 ad.qxdm_logger_command)
8068 if "diag_mdlog" in output:
Betty Zhoua9a354a2018-03-21 15:01:59 -07008069 # Kill the existing non-matching diag_mdlog process
Betty Zhou550fd372017-10-16 17:22:47 -07008070 # Only one diag_mdlog process can be run
Betty Zhou0111ae02017-11-29 20:37:26 -08008071 stop_qxdm_logger(ad)
Betty Zhou550fd372017-10-16 17:22:47 -07008072 ad.log.info("Start QXDM logger")
Betty Zhou88a39392017-12-01 17:33:57 -08008073 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07008074 time.sleep(10)
Betty Zhoua9a354a2018-03-21 15:01:59 -07008075 else:
Betty Zhoua19e4442018-04-19 19:38:42 -07008076 run_time = check_qxdm_logger_run_time(ad)
8077 if run_time < 600:
8078 # the last diag_mdlog started within 10 minutes ago
8079 # no need to restart
8080 return True
Betty Zhoua9a354a2018-03-21 15:01:59 -07008081 if ad.search_logcat(
8082 "Diag_Lib: diag: In delete_log",
Betty Zhoua19e4442018-04-19 19:38:42 -07008083 begin_time=current_time -
8084 run_time) or not ad.get_file_names(
8085 ad.qxdm_log_path,
8086 begin_time=current_time - 600000,
8087 match_string="*.qmdl"):
Betty Zhoua9a354a2018-03-21 15:01:59 -07008088 # diag_mdlog starts deleting files or no qmdl logs were
Betty Zhoua19e4442018-04-19 19:38:42 -07008089 # modified in the past 10 minutes
Betty Zhoua9a354a2018-03-21 15:01:59 -07008090 ad.log.debug("Quit existing diag_mdlog and start a new one")
8091 stop_qxdm_logger(ad)
8092 ad.adb.shell_nb(ad.qxdm_logger_command)
Betty Zhoua19e4442018-04-19 19:38:42 -07008093 time.sleep(10)
Betty Zhou0111ae02017-11-29 20:37:26 -08008094 return True
Betty Zhou550fd372017-10-16 17:22:47 -07008095
8096
Betty Zhouf0577582018-06-06 11:34:52 -07008097def disable_qxdm_logger(ad):
8098 for prop in ("persist.sys.modem.diag.mdlog",
Betty Zhou4d97af82018-06-07 14:05:52 -07008099 "persist.vendor.sys.modem.diag.mdlog",
8100 "vendor.sys.modem.diag.mdlog_on"):
Betty Zhouf0577582018-06-06 11:34:52 -07008101 if ad.adb.getprop(prop):
8102 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
8103 for apk in ("com.android.nexuslogger", "com.android.pixellogger"):
8104 if ad.is_apk_installed(apk) and ad.is_apk_running(apk):
8105 ad.force_stop_apk(apk)
8106 stop_qxdm_logger(ad)
8107 return True
8108
8109
Betty Zhoua19e4442018-04-19 19:38:42 -07008110def check_qxdm_logger_run_time(ad):
8111 output = ad.adb.shell("ps -eo etime,cmd | grep diag_mdlog")
8112 result = re.search(r"(\d+):(\d+):(\d+) diag_mdlog", output)
8113 if result:
8114 return int(result.group(1)) * 60 * 60 + int(
8115 result.group(2)) * 60 + int(result.group(3))
8116 else:
8117 result = re.search(r"(\d+):(\d+) diag_mdlog", output)
8118 if result:
8119 return int(result.group(1)) * 60 + int(result.group(2))
8120 else:
8121 return 0
8122
8123
Betty Zhouee311052017-12-19 13:09:56 -08008124def start_qxdm_loggers(log, ads, begin_time=None):
Betty Zhou02571f52018-02-16 14:11:16 -08008125 tasks = [(start_qxdm_logger, [ad, begin_time]) for ad in ads
8126 if getattr(ad, "qxdm_log", True)]
Betty Zhou3eceae02018-02-09 12:27:51 -08008127 if tasks: run_multithread_func(log, tasks)
Betty Zhou550fd372017-10-16 17:22:47 -07008128
8129
Betty Zhou0111ae02017-11-29 20:37:26 -08008130def stop_qxdm_loggers(log, ads):
8131 tasks = [(stop_qxdm_logger, [ad]) for ad in ads]
8132 run_multithread_func(log, tasks)
8133
8134
Jaineel72d2c242019-07-23 12:00:07 -07008135def start_sdm_loggers(log, ads):
8136 tasks = [(start_sdm_logger, [ad]) for ad in ads
8137 if getattr(ad, "sdm_log", True)]
8138 if tasks: run_multithread_func(log, tasks)
8139
8140
8141def stop_sdm_loggers(log, ads):
8142 tasks = [(stop_sdm_logger, [ad]) for ad in ads]
8143 run_multithread_func(log, tasks)
8144
8145
Betty Zhou550fd372017-10-16 17:22:47 -07008146def start_nexuslogger(ad):
Betty Zhou807a81f2017-11-27 14:53:48 -08008147 """Start Nexus/Pixel Logger Apk."""
8148 qxdm_logger_apk = None
Betty Zhouee311052017-12-19 13:09:56 -08008149 for apk, activity in (("com.android.nexuslogger", ".MainActivity"),
8150 ("com.android.pixellogger",
8151 ".ui.main.MainActivity")):
Betty Zhou807a81f2017-11-27 14:53:48 -08008152 if ad.is_apk_installed(apk):
8153 qxdm_logger_apk = apk
8154 break
8155 if not qxdm_logger_apk: return
8156 if ad.is_apk_running(qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07008157 if "granted=true" in ad.adb.shell(
Betty Zhou807a81f2017-11-27 14:53:48 -08008158 "dumpsys package %s | grep WRITE_EXTERN" % qxdm_logger_apk):
Betty Zhoua18d0982017-10-18 14:30:43 -07008159 return True
8160 else:
Betty Zhou807a81f2017-11-27 14:53:48 -08008161 ad.log.info("Kill %s" % qxdm_logger_apk)
8162 ad.force_stop_apk(qxdm_logger_apk)
Betty Zhou32e403a2017-10-25 20:08:12 -07008163 time.sleep(5)
Betty Zhou807a81f2017-11-27 14:53:48 -08008164 for perm in ("READ", "WRITE"):
8165 ad.adb.shell("pm grant %s android.permission.%s_EXTERNAL_STORAGE" %
8166 (qxdm_logger_apk, perm))
8167 time.sleep(2)
Jaineel464a18e2017-12-21 14:37:41 -08008168 for i in range(3):
Betty Zhou3814cbc2018-06-11 19:39:36 -07008169 ad.unlock_screen()
Jaineel464a18e2017-12-21 14:37:41 -08008170 ad.log.info("Start %s Attempt %d" % (qxdm_logger_apk, i + 1))
8171 ad.adb.shell("am start -n %s/%s" % (qxdm_logger_apk, activity))
8172 time.sleep(5)
8173 if ad.is_apk_running(qxdm_logger_apk):
8174 ad.send_keycode("HOME")
8175 return True
8176 return False
Betty Zhou5cf94d82017-06-09 19:18:09 -07008177
8178
Betty Zhou8ac04da2017-10-12 15:27:15 -07008179def check_qxdm_logger_mask(ad, mask_file="QC_Default.cfg"):
Betty Zhou5cf94d82017-06-09 19:18:09 -07008180 """Check if QXDM logger always on is set.
8181
8182 Args:
8183 ad: android device object.
8184
8185 """
Betty Zhou4b0f1712017-10-12 20:20:14 -07008186 output = ad.adb.shell(
8187 "ls /data/vendor/radio/diag_logs/", ignore_status=True)
8188 if not output or "No such" in output:
8189 return True
Betty Zhou5cf94d82017-06-09 19:18:09 -07008190 if mask_file not in ad.adb.shell(
8191 "cat /data/vendor/radio/diag_logs/diag.conf", ignore_status=True):
8192 return False
8193 return True
Jaineel55ae6f92017-06-29 17:44:19 -07008194
8195
Betty Zhou9d0366a2018-03-26 13:49:57 -07008196def start_tcpdumps(ads,
8197 test_name="",
8198 begin_time=None,
8199 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07008200 mask="all"):
Betty Zhoue123c672018-03-21 19:57:11 -07008201 for ad in ads:
Betty Zhou819cb732018-05-10 18:45:41 -07008202 try:
8203 start_adb_tcpdump(
8204 ad,
8205 test_name=test_name,
8206 begin_time=begin_time,
8207 interface=interface,
8208 mask=mask)
8209 except Exception as e:
8210 ad.log.warning("Fail to start tcpdump due to %s", e)
Betty Zhoue123c672018-03-21 19:57:11 -07008211
8212
Betty Zhou9d0366a2018-03-26 13:49:57 -07008213def start_adb_tcpdump(ad,
8214 test_name="",
8215 begin_time=None,
8216 interface="any",
Betty Zhou2bb11682018-04-19 17:05:30 -07008217 mask="all"):
Jaineel55ae6f92017-06-29 17:44:19 -07008218 """Start tcpdump on any iface
8219
8220 Args:
8221 ad: android device object.
8222 test_name: tcpdump file name will have this
8223
8224 """
Scott Honge54cb0c2020-10-13 15:10:35 +08008225 out = ad.adb.shell("ls -l /data/local/tmp/tcpdump/", ignore_status=True)
Jaineel7d0408e2017-12-22 15:52:59 -08008226 if "No such file" in out or not out:
Jaineel6cd64742018-06-29 15:43:15 -07008227 ad.adb.shell("mkdir /data/local/tmp/tcpdump")
Jaineel7d0408e2017-12-22 15:52:59 -08008228 else:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008229 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008230 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
8231 ignore_status=True)
Jaineel560ad5d2018-08-23 17:14:14 -07008232 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008233 "find /data/local/tmp/tcpdump -type f -size +5G -delete",
8234 ignore_status=True)
Jaineel7d0408e2017-12-22 15:52:59 -08008235
Betty Zhoue123c672018-03-21 19:57:11 -07008236 if not begin_time:
8237 begin_time = get_current_epoch_time()
Jaineel7d0408e2017-12-22 15:52:59 -08008238
Betty Zhou819cb732018-05-10 18:45:41 -07008239 out = ad.adb.shell(
Betty Zhou80c64cf2018-06-08 18:01:18 -07008240 'ifconfig | grep -v -E "r_|-rmnet" | grep -E "lan|data"',
8241 ignore_status=True,
8242 timeout=180)
8243 intfs = re.findall(r"(\S+).*", out)
8244 if interface and interface not in ("any", "all"):
8245 if interface not in intfs: return
Betty Zhou5dd53c02018-03-22 20:08:33 -07008246 intfs = [interface]
8247
8248 out = ad.adb.shell("ps -ef | grep tcpdump")
8249 cmds = []
8250 for intf in intfs:
8251 if intf in out:
8252 ad.log.info("tcpdump on interface %s is already running", intf)
8253 continue
8254 else:
Jaineel6cd64742018-06-29 15:43:15 -07008255 log_file_name = "/data/local/tmp/tcpdump/tcpdump_%s_%s_%s_%s.pcap" \
8256 % (ad.serial, intf, test_name, begin_time)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008257 if mask == "ims":
8258 cmds.append(
8259 "adb -s %s shell tcpdump -i %s -s0 -n -p udp port 500 or "
Betty Zhou9d0366a2018-03-26 13:49:57 -07008260 "udp port 4500 -w %s" % (ad.serial, intf, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07008261 else:
Betty Zhou9d0366a2018-03-26 13:49:57 -07008262 cmds.append("adb -s %s shell tcpdump -i %s -s0 -w %s" %
8263 (ad.serial, intf, log_file_name))
Betty Zhou5dd53c02018-03-22 20:08:33 -07008264 for cmd in cmds:
8265 ad.log.info(cmd)
8266 try:
8267 start_standing_subprocess(cmd, 10)
8268 except Exception as e:
Betty Zhoudd9a9ea2018-04-04 13:23:56 -07008269 ad.log.error(e)
Betty Zhou80c64cf2018-06-08 18:01:18 -07008270 if cmds:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008271 time.sleep(5)
Jaineel55ae6f92017-06-29 17:44:19 -07008272
8273
Betty Zhoue123c672018-03-21 19:57:11 -07008274def stop_tcpdumps(ads):
8275 for ad in ads:
8276 stop_adb_tcpdump(ad)
8277
8278
Betty Zhou5dd53c02018-03-22 20:08:33 -07008279def stop_adb_tcpdump(ad, interface="any"):
Jaineel55ae6f92017-06-29 17:44:19 -07008280 """Stops tcpdump on any iface
8281 Pulls the tcpdump file in the tcpdump dir
8282
8283 Args:
8284 ad: android device object.
Jaineel55ae6f92017-06-29 17:44:19 -07008285
8286 """
Betty Zhou5dd53c02018-03-22 20:08:33 -07008287 if interface == "any":
8288 try:
Jaineel1ef929e2020-10-24 12:43:44 -07008289 ad.adb.shell("killall -9 tcpdump", ignore_status=True)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008290 except Exception as e:
Betty Zhoua36c4352018-04-05 18:49:32 -07008291 ad.log.error("Killing tcpdump with exception %s", e)
Betty Zhou5dd53c02018-03-22 20:08:33 -07008292 else:
8293 out = ad.adb.shell("ps -ef | grep tcpdump | grep %s" % interface)
8294 if "tcpdump -i" in out:
8295 pids = re.findall(r"\S+\s+(\d+).*tcpdump -i", out)
8296 for pid in pids:
8297 ad.adb.shell("kill -9 %s" % pid)
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008298 ad.adb.shell(
Xianyuan Jia7a185a62020-10-09 09:28:43 -07008299 "find /data/local/tmp/tcpdump -type f -not -mtime -1800s -delete",
8300 ignore_status=True)
Betty Zhoue123c672018-03-21 19:57:11 -07008301
8302
8303def get_tcpdump_log(ad, test_name="", begin_time=None):
8304 """Stops tcpdump on any iface
8305 Pulls the tcpdump file in the tcpdump dir
jasonkmlu2565d892019-11-12 15:31:26 +08008306 Zips all tcpdump files
Betty Zhoue123c672018-03-21 19:57:11 -07008307
8308 Args:
8309 ad: android device object.
8310 test_name: test case name
8311 begin_time: test begin time
8312 """
Jaineel6cd64742018-06-29 15:43:15 -07008313 logs = ad.get_file_names("/data/local/tmp/tcpdump", begin_time=begin_time)
Betty Zhoue123c672018-03-21 19:57:11 -07008314 if logs:
8315 ad.log.info("Pulling tcpdumps %s", logs)
jasonkmlu2565d892019-11-12 15:31:26 +08008316 log_path = os.path.join(
8317 ad.device_log_path, "TCPDUMP_%s_%s" % (ad.model, ad.serial))
Mark De Ruyter72f8df92020-02-12 13:44:49 -08008318 os.makedirs(log_path, exist_ok=True)
Betty Zhoue123c672018-03-21 19:57:11 -07008319 ad.pull_files(logs, log_path)
jasonkmlu2565d892019-11-12 15:31:26 +08008320 shutil.make_archive(log_path, "zip", log_path)
8321 shutil.rmtree(log_path)
Jaineel55ae6f92017-06-29 17:44:19 -07008322 return True
Betty Zhou166a51c2017-08-14 17:40:59 -07008323
8324
8325def fastboot_wipe(ad, skip_setup_wizard=True):
8326 """Wipe the device in fastboot mode.
8327
8328 Pull sl4a apk from device. Terminate all sl4a sessions,
8329 Reboot the device to bootloader, wipe the device by fastboot.
8330 Reboot the device. wait for device to complete booting
8331 Re-intall and start an sl4a session.
8332 """
Betty Zhou77f2bed2017-10-04 18:39:07 -07008333 status = True
Betty Zhou166a51c2017-08-14 17:40:59 -07008334 # Pull sl4a apk from device
Betty Zhou92437702018-02-07 19:49:07 -08008335 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
Betty Zhou166a51c2017-08-14 17:40:59 -07008336 result = re.search(r"package:(.*)", out)
8337 if not result:
8338 ad.log.error("Couldn't find sl4a apk")
8339 else:
8340 sl4a_apk = result.group(1)
8341 ad.log.info("Get sl4a apk from %s", sl4a_apk)
8342 ad.pull_files([sl4a_apk], "/tmp/")
8343 ad.stop_services()
Betty Zhou3e983f22018-04-09 20:37:36 -07008344 attemps = 3
8345 for i in range(1, attemps + 1):
Betty Zhou77f2bed2017-10-04 18:39:07 -07008346 try:
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008347 if ad.serial in list_adb_devices():
8348 ad.log.info("Reboot to bootloader")
8349 ad.adb.reboot("bootloader", ignore_status=True)
8350 time.sleep(10)
8351 if ad.serial in list_fastboot_devices():
8352 ad.log.info("Wipe in fastboot")
Betty Zhou6b678c62018-05-21 12:23:04 -07008353 ad.fastboot._w(timeout=300, ignore_status=True)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008354 time.sleep(30)
8355 ad.log.info("Reboot in fastboot")
8356 ad.fastboot.reboot()
Betty Zhou77f2bed2017-10-04 18:39:07 -07008357 ad.wait_for_boot_completion()
Betty Zhou3e983f22018-04-09 20:37:36 -07008358 ad.root_adb()
8359 if ad.skip_sl4a:
8360 break
Betty Zhou02589bb2017-09-06 15:04:25 -07008361 if ad.is_sl4a_installed():
8362 break
Betty Zhou166a51c2017-08-14 17:40:59 -07008363 ad.log.info("Re-install sl4a")
Xianyuan Jia4d4b3a22019-09-27 11:00:14 -07008364 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
Betty Zhou3e983f22018-04-09 20:37:36 -07008365 ad.adb.install("-r /tmp/base.apk")
Betty Zhou166a51c2017-08-14 17:40:59 -07008366 time.sleep(10)
Betty Zhou3e983f22018-04-09 20:37:36 -07008367 break
8368 except Exception as e:
8369 ad.log.warning(e)
8370 if i == attemps:
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008371 abort_all_tests(log, str(e))
8372 time.sleep(5)
Betty Zhou3c2e2542018-02-21 12:23:04 -08008373 try:
8374 ad.start_adb_logcat()
8375 except:
Betty Zhoua36c4352018-04-05 18:49:32 -07008376 ad.log.error("Failed to start adb logcat!")
Betty Zhou3c2e2542018-02-21 12:23:04 -08008377 if skip_setup_wizard:
8378 ad.exit_setup_wizard()
Jaineel1cde17b2019-01-04 14:26:55 -08008379 if getattr(ad, "qxdm_log", True):
8380 set_qxdm_logger_command(ad, mask=getattr(ad, "qxdm_log_mask", None))
8381 start_qxdm_logger(ad)
Betty Zhouf25fdab2018-04-23 19:20:17 -07008382 if ad.skip_sl4a: return status
8383 bring_up_sl4a(ad)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008384 synchronize_device_time(ad)
Betty Zhoub7663ba2018-05-23 11:56:22 -07008385 set_phone_silent_mode(ad.log, ad)
Shaju Sebastian0b847e72019-01-31 16:40:37 -08008386 # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 &
8387 # b/122327716
8388 activate_wfc_on_device(ad.log, ad)
Betty Zhou77f2bed2017-10-04 18:39:07 -07008389 return status
Betty Zhou166a51c2017-08-14 17:40:59 -07008390
Jaineel1cde17b2019-01-04 14:26:55 -08008391def install_carriersettings_apk(ad, carriersettingsapk, skip_setup_wizard=True):
8392 """ Carrier Setting Installation Steps
8393
8394 Pull sl4a apk from device. Terminate all sl4a sessions,
8395 Reboot the device to bootloader, wipe the device by fastboot.
8396 Reboot the device. wait for device to complete booting
8397 """
8398 status = True
8399 if carriersettingsapk is None:
8400 ad.log.warning("CarrierSettingsApk is not provided, aborting")
8401 return False
8402 ad.log.info("Push carriersettings apk to the Android device.")
8403 android_apk_path = "/product/priv-app/CarrierSettings/CarrierSettings.apk"
8404 ad.adb.push("%s %s" % (carriersettingsapk, android_apk_path))
8405 ad.stop_services()
8406
8407 attempts = 3
8408 for i in range(1, attempts + 1):
8409 try:
8410 if ad.serial in list_adb_devices():
8411 ad.log.info("Reboot to bootloader")
8412 ad.adb.reboot("bootloader", ignore_status=True)
8413 time.sleep(30)
8414 if ad.serial in list_fastboot_devices():
8415 ad.log.info("Reboot in fastboot")
8416 ad.fastboot.reboot()
8417 ad.wait_for_boot_completion()
8418 ad.root_adb()
8419 if ad.is_sl4a_installed():
8420 break
8421 time.sleep(10)
8422 break
8423 except Exception as e:
8424 ad.log.warning(e)
8425 if i == attempts:
8426 abort_all_tests(log, str(e))
8427 time.sleep(5)
8428 try:
8429 ad.start_adb_logcat()
8430 except:
8431 ad.log.error("Failed to start adb logcat!")
8432 if skip_setup_wizard:
8433 ad.exit_setup_wizard()
8434 return status
8435
Betty Zhou166a51c2017-08-14 17:40:59 -07008436
Betty Zhou3c2e2542018-02-21 12:23:04 -08008437def bring_up_sl4a(ad, attemps=3):
8438 for i in range(attemps):
8439 try:
8440 droid, ed = ad.get_droid()
8441 ed.start()
Jaineel1cde17b2019-01-04 14:26:55 -08008442 ad.log.info("Brought up new sl4a session")
Betty Zhou3e983f22018-04-09 20:37:36 -07008443 break
Betty Zhou3c2e2542018-02-21 12:23:04 -08008444 except Exception as e:
8445 if i < attemps - 1:
8446 ad.log.info(e)
8447 time.sleep(10)
8448 else:
8449 ad.log.error(e)
8450 raise
8451
8452
Betty Zhou4f1d9eb2018-06-15 11:27:18 -07008453def reboot_device(ad, recover_sim_state=True):
8454 sim_state = is_sim_ready(ad.log, ad)
Betty Zhouae9d6a82018-02-15 20:05:34 -08008455 ad.reboot()
Jaineel43e4b682019-02-15 12:28:19 -08008456 if ad.qxdm_log:
8457 start_qxdm_logger(ad)
Betty Zhou4f1d9eb2018-06-15 11:27:18 -07008458 ad.unlock_screen()
8459 if recover_sim_state:
8460 if not unlock_sim(ad):
8461 ad.log.error("Unable to unlock SIM")
8462 return False
8463 if sim_state and not _wait_for_droid_in_state(
8464 log, ad, MAX_WAIT_TIME_FOR_STATE_CHANGE, is_sim_ready):
8465 ad.log.error("Sim state didn't reach pre-reboot ready state")
8466 return False
8467 return True
Betty Zhouae9d6a82018-02-15 20:05:34 -08008468
8469
Betty Zhou166a51c2017-08-14 17:40:59 -07008470def unlocking_device(ad, device_password=None):
8471 """First unlock device attempt, required after reboot"""
8472 ad.unlock_screen(device_password)
8473 time.sleep(2)
8474 ad.adb.wait_for_device(timeout=180)
8475 if not ad.is_waiting_for_unlock_pin():
8476 return True
8477 else:
8478 ad.unlock_screen(device_password)
8479 time.sleep(2)
8480 ad.adb.wait_for_device(timeout=180)
8481 if ad.wait_for_window_ready():
8482 return True
8483 ad.log.error("Unable to unlock to user window")
8484 return False
8485
8486
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008487def refresh_sl4a_session(ad):
8488 try:
8489 ad.droid.logI("Checking SL4A connection")
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008490 ad.log.debug("Existing sl4a session is active")
8491 return True
8492 except Exception as e:
Betty Zhoufe726dc2018-04-25 19:31:33 -07008493 ad.log.warning("Existing sl4a session is NOT active: %s", e)
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008494 try:
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008495 ad.terminate_all_sessions()
Betty Zhou4bc31fc2018-03-12 18:28:50 -07008496 except Exception as e:
8497 ad.log.info("terminate_all_sessions with error %s", e)
8498 ad.ensure_screen_on()
8499 ad.log.info("Open new sl4a connection")
8500 bring_up_sl4a(ad)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008501
8502
Betty Zhou166a51c2017-08-14 17:40:59 -07008503def reset_device_password(ad, device_password=None):
8504 # Enable or Disable Device Password per test bed config
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008505 unlock_sim(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008506 screen_lock = ad.is_screen_lock_enabled()
8507 if device_password:
Betty Zhoue66efb42018-01-31 19:45:56 -08008508 try:
Betty Zhouf715c792018-02-12 17:32:10 -08008509 refresh_sl4a_session(ad)
Betty Zhoue66efb42018-01-31 19:45:56 -08008510 ad.droid.setDevicePassword(device_password)
8511 except Exception as e:
8512 ad.log.warning("setDevicePassword failed with %s", e)
Betty Zhou3c2e2542018-02-21 12:23:04 -08008513 try:
8514 ad.droid.setDevicePassword(device_password, "1111")
8515 except Exception as e:
8516 ad.log.warning(
8517 "setDevicePassword providing previous password error: %s",
8518 e)
Betty Zhou166a51c2017-08-14 17:40:59 -07008519 time.sleep(2)
8520 if screen_lock:
8521 # existing password changed
8522 return
8523 else:
8524 # enable device password and log in for the first time
8525 ad.log.info("Enable device password")
8526 ad.adb.wait_for_device(timeout=180)
Betty Zhou166a51c2017-08-14 17:40:59 -07008527 else:
8528 if not screen_lock:
8529 # no existing password, do not set password
8530 return
8531 else:
8532 # password is enabled on the device
8533 # need to disable the password and log in on the first time
8534 # with unlocking with a swipe
8535 ad.log.info("Disable device password")
Betty Zhou688c1032017-11-20 20:08:04 -08008536 ad.unlock_screen(password="1111")
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008537 refresh_sl4a_session(ad)
Betty Zhou351d1792017-11-10 16:26:30 -08008538 ad.ensure_screen_on()
Betty Zhoue66efb42018-01-31 19:45:56 -08008539 try:
8540 ad.droid.disableDevicePassword()
8541 except Exception as e:
8542 ad.log.warning("disableDevicePassword failed with %s", e)
Betty Zhouf715c792018-02-12 17:32:10 -08008543 fastboot_wipe(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008544 time.sleep(2)
8545 ad.adb.wait_for_device(timeout=180)
Betty Zhou0fbf86f2017-09-21 18:09:32 -07008546 refresh_sl4a_session(ad)
Betty Zhou166a51c2017-08-14 17:40:59 -07008547 if not ad.is_adb_logcat_on:
8548 ad.start_adb_logcat()
Betty Zhou59ccab62017-08-17 18:17:29 -07008549
8550
Betty Zhoue66efb42018-01-31 19:45:56 -08008551def get_sim_state(ad):
Betty Zhou13e7adf2017-09-06 14:01:10 -07008552 try:
Betty Zhoue66efb42018-01-31 19:45:56 -08008553 state = ad.droid.telephonyGetSimState()
Jaineel3d14c432018-09-20 19:00:20 -07008554 except Exception as e:
8555 ad.log.error(e)
Betty Zhoue66efb42018-01-31 19:45:56 -08008556 state = ad.adb.getprop("gsm.sim.state")
8557 return state
8558
8559
8560def is_sim_locked(ad):
Betty Zhoub554e342018-02-01 19:01:38 -08008561 return get_sim_state(ad) == SIM_STATE_PIN_REQUIRED
Betty Zhou59ccab62017-08-17 18:17:29 -07008562
8563
Betty Zhou28e07e12018-04-11 12:12:11 -07008564def is_sim_lock_enabled(ad):
8565 # TODO: add sl4a fascade to check if sim is locked
8566 return getattr(ad, "is_sim_locked", False)
8567
8568
Betty Zhou59ccab62017-08-17 18:17:29 -07008569def unlock_sim(ad):
8570 #The puk and pin can be provided in testbed config file.
8571 #"AndroidDevice": [{"serial": "84B5T15A29018214",
8572 # "adb_logcat_param": "-b all",
8573 # "puk": "12345678",
8574 # "puk_pin": "1234"}]
Betty Zhouc3f1f9c2017-08-18 15:50:41 -07008575 if not is_sim_locked(ad):
8576 return True
Betty Zhoue66efb42018-01-31 19:45:56 -08008577 else:
8578 ad.is_sim_locked = True
Betty Zhou59ccab62017-08-17 18:17:29 -07008579 puk_pin = getattr(ad, "puk_pin", "1111")
8580 try:
8581 if not hasattr(ad, 'puk'):
Betty Zhoub47a4ea2017-09-06 11:18:40 -07008582 ad.log.info("Enter SIM pin code")
Betty Zhoue66efb42018-01-31 19:45:56 -08008583 ad.droid.telephonySupplyPin(puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07008584 else:
8585 ad.log.info("Enter PUK code and pin")
Betty Zhoue66efb42018-01-31 19:45:56 -08008586 ad.droid.telephonySupplyPuk(ad.puk, puk_pin)
Betty Zhou59ccab62017-08-17 18:17:29 -07008587 except:
8588 # if sl4a is not available, use adb command
8589 ad.unlock_screen(puk_pin)
8590 if is_sim_locked(ad):
8591 ad.unlock_screen(puk_pin)
Betty Zhoub47a4ea2017-09-06 11:18:40 -07008592 time.sleep(30)
Betty Zhou59ccab62017-08-17 18:17:29 -07008593 return not is_sim_locked(ad)
Betty Zhouf3c5bc32017-08-28 17:09:19 -07008594
8595
8596def send_dialer_secret_code(ad, secret_code):
8597 """Send dialer secret code.
8598
8599 ad: android device controller
8600 secret_code: the secret code to be sent to dialer. the string between
8601 code prefix *#*# and code postfix #*#*. *#*#<xxx>#*#*
8602 """
8603 action = 'android.provider.Telephony.SECRET_CODE'
8604 uri = 'android_secret_code://%s' % secret_code
8605 intent = ad.droid.makeIntent(
8606 action,
8607 uri,
8608 None, # type
8609 None, # extras
8610 None, # categories,
8611 None, # packagename,
8612 None, # classname,
8613 0x01000000) # flags
8614 ad.log.info('Issuing dialer secret dialer code: %s', secret_code)
8615 ad.droid.sendBroadcastIntent(intent)
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008616
8617
Betty Zhouf7da39e2018-04-16 16:28:58 -07008618def enable_radio_log_on(ad):
Betty Zhou8aafcc12018-05-01 20:54:15 -07008619 if ad.adb.getprop("persist.vendor.radio.adb_log_on") != "1":
8620 ad.log.info("Enable radio adb_log_on and reboot")
Betty Zhouf7da39e2018-04-16 16:28:58 -07008621 adb_disable_verity(ad)
8622 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1")
8623 reboot_device(ad)
8624
8625
8626def adb_disable_verity(ad):
8627 if ad.adb.getprop("ro.boot.veritymode") == "enforcing":
8628 ad.adb.disable_verity()
8629 reboot_device(ad)
8630 ad.adb.remount()
8631
8632
Betty Zhou90472382018-05-25 15:58:36 -07008633def recover_build_id(ad):
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008634 build_fingerprint = ad.adb.getprop(
monikerminea601efc2019-11-11 13:14:49 -08008635 "ro.vendor.build.fingerprint") or ad.adb.getprop(
8636 "ro.build.fingerprint")
Betty Zhou90472382018-05-25 15:58:36 -07008637 if not build_fingerprint:
8638 return
8639 build_id = build_fingerprint.split("/")[3]
8640 if ad.adb.getprop("ro.build.id") != build_id:
8641 build_id_override(ad, build_id)
8642
“Jamesf11d7222020-04-13 14:49:24 -07008643def enable_privacy_usage_diagnostics(ad):
8644 try:
8645 ad.ensure_screen_on()
8646 ad.send_keycode('HOME')
8647 # open the UI page on which we need to enable the setting
8648 cmd = ('am start -n com.google.android.gms/com.google.android.gms.'
8649 'usagereporting.settings.UsageReportingActivity')
8650 ad.adb.shell(cmd)
8651 # perform the toggle
8652 ad.send_keycode('TAB')
“Jamesab922b82020-05-18 16:57:11 -07008653 ad.send_keycode('ENTER')
“Jamesf11d7222020-04-13 14:49:24 -07008654 except Exception:
8655 ad.log.info("Unable to toggle Usage and Diagnostics")
Betty Zhou90472382018-05-25 15:58:36 -07008656
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008657def build_id_override(ad, new_build_id=None, postfix=None):
8658 build_fingerprint = ad.adb.getprop(
8659 "ro.build.fingerprint") or ad.adb.getprop(
8660 "ro.vendor.build.fingerprint")
8661 if build_fingerprint:
8662 build_id = build_fingerprint.split("/")[3]
8663 else:
8664 build_id = None
Betty Zhou90472382018-05-25 15:58:36 -07008665 existing_build_id = ad.adb.getprop("ro.build.id")
monikerminea601efc2019-11-11 13:14:49 -08008666 if postfix is not None and postfix in build_id:
Jaineelebd278b2019-02-21 10:56:32 -08008667 ad.log.info("Build id already contains %s", postfix)
8668 return
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008669 if not new_build_id:
8670 if postfix and build_id:
8671 new_build_id = "%s.%s" % (build_id, postfix)
8672 if not new_build_id or existing_build_id == new_build_id:
Betty Zhou90472382018-05-25 15:58:36 -07008673 return
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008674 ad.log.info("Override build id %s with %s", existing_build_id,
8675 new_build_id)
“Jamesf11d7222020-04-13 14:49:24 -07008676 enable_privacy_usage_diagnostics(ad)
Betty Zhou90472382018-05-25 15:58:36 -07008677 adb_disable_verity(ad)
8678 ad.adb.remount()
8679 if "backup.prop" not in ad.adb.shell("ls /sdcard/"):
monikerminea601efc2019-11-11 13:14:49 -08008680 ad.adb.shell("cp /system/build.prop /sdcard/backup.prop")
8681 ad.adb.shell("cat /system/build.prop | grep -v ro.build.id > /sdcard/test.prop")
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008682 ad.adb.shell("echo ro.build.id=%s >> /sdcard/test.prop" % new_build_id)
monikerminea601efc2019-11-11 13:14:49 -08008683 ad.adb.shell("cp /sdcard/test.prop /system/build.prop")
Betty Zhou90472382018-05-25 15:58:36 -07008684 reboot_device(ad)
8685 ad.log.info("ro.build.id = %s", ad.adb.getprop("ro.build.id"))
8686
8687
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008688def enable_connectivity_metrics(ad):
8689 cmds = [
8690 "pm enable com.android.connectivity.metrics",
Betty Zhoue204f462018-06-08 18:36:01 -07008691 "am startservice -a com.google.android.gms.usagereporting.OPTIN_UR",
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008692 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
8693 " -e usagestats:connectivity_metrics:enable_data_collection 1",
8694 "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
Betty Zhoue204f462018-06-08 18:36:01 -07008695 " -e usagestats:connectivity_metrics:telephony_snapshot_period_millis 180000"
8696 # By default it turn on all modules
8697 #"am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE"
8698 #" -e usagestats:connectivity_metrics:data_collection_bitmap 62"
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008699 ]
8700 for cmd in cmds:
Jaineelab5a1c82019-03-25 19:14:16 -07008701 ad.adb.shell(cmd, ignore_status=True)
Betty Zhou8a53f0f2018-06-06 14:35:50 -07008702
8703
Betty Zhoue204f462018-06-08 18:36:01 -07008704def force_connectivity_metrics_upload(ad):
8705 cmd = "cmd jobscheduler run --force com.android.connectivity.metrics %s"
8706 for job_id in [2, 3, 5, 4, 1, 6]:
Jaineelab5a1c82019-03-25 19:14:16 -07008707 ad.adb.shell(cmd % job_id, ignore_status=True)
Betty Zhoue204f462018-06-08 18:36:01 -07008708
8709
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008710def system_file_push(ad, src_file_path, dst_file_path):
8711 """Push system file on a device.
8712
8713 Push system file need to change some system setting and remount.
8714 """
Betty Zhoua9a70f62017-11-16 14:53:11 -08008715 cmd = "%s %s" % (src_file_path, dst_file_path)
8716 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
markdr6607bf12018-01-02 14:45:38 -08008717 skip_sl4a = True if "sl4a.apk" in src_file_path else False
Betty Zhoua9a70f62017-11-16 14:53:11 -08008718 if "Read-only file system" in out:
8719 ad.log.info("Change read-only file system")
Betty Zhouf7da39e2018-04-16 16:28:58 -07008720 adb_disable_verity(ad)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008721 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
8722 if "Read-only file system" in out:
Betty Zhou856ae212018-01-18 19:49:35 -08008723 ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008724 out = ad.adb.push(cmd, timeout=300, ignore_status=True)
8725 if "error" in out:
8726 ad.log.error("%s failed with %s", cmd, out)
8727 return False
8728 else:
Betty Zhou856ae212018-01-18 19:49:35 -08008729 ad.log.info("push %s succeed")
8730 if skip_sl4a: ad.reboot(skip_sl4a)
Betty Zhoua9a70f62017-11-16 14:53:11 -08008731 return True
8732 else:
8733 return True
8734 elif "error" in out:
Betty Zhou5b5f80a2017-09-29 18:24:01 -07008735 return False
Betty Zhoua9a70f62017-11-16 14:53:11 -08008736 else:
8737 return True
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008738
8739
8740def flash_radio(ad, file_path, skip_setup_wizard=True):
8741 """Flash radio image."""
8742 ad.stop_services()
8743 ad.log.info("Reboot to bootloader")
8744 ad.adb.reboot_bootloader(ignore_status=True)
8745 ad.log.info("Flash radio in fastboot")
8746 try:
8747 ad.fastboot.flash("radio %s" % file_path, timeout=300)
8748 except Exception as e:
8749 ad.log.error(e)
Betty Zhoud4b75c52018-04-03 15:20:00 -07008750 ad.fastboot.reboot("bootloader")
8751 time.sleep(5)
8752 output = ad.fastboot.getvar("version-baseband")
8753 result = re.search(r"version-baseband: (\S+)", output)
8754 if not result:
8755 ad.log.error("fastboot getvar version-baseband output = %s", output)
8756 abort_all_tests(ad.log, "Radio version-baseband is not provided")
8757 fastboot_radio_version_output = result.group(1)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008758 for _ in range(2):
8759 try:
8760 ad.log.info("Reboot in fastboot")
8761 ad.fastboot.reboot()
8762 ad.wait_for_boot_completion()
8763 break
8764 except Exception as e:
8765 ad.log.error("Exception error %s", e)
8766 ad.root_adb()
Betty Zhoud4b75c52018-04-03 15:20:00 -07008767 adb_radio_version_output = ad.adb.getprop("gsm.version.baseband")
8768 ad.log.info("adb getprop gsm.version.baseband = %s",
8769 adb_radio_version_output)
8770 if adb_radio_version_output != fastboot_radio_version_output:
8771 msg = ("fastboot radio version output %s does not match with adb"
8772 " radio version output %s" % (fastboot_radio_version_output,
8773 adb_radio_version_output))
8774 abort_all_tests(ad.log, msg)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008775 if not ad.ensure_screen_on():
8776 ad.log.error("User window cannot come up")
Xianyuan Jia8f6a8e62019-01-07 23:32:47 +00008777 ad.start_services(skip_setup_wizard=skip_setup_wizard)
Betty Zhou447080c2018-02-06 10:43:26 -08008778 unlock_sim(ad)
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008779
8780
Jaineel13ac2fc2017-10-26 16:25:50 -07008781def set_preferred_apn_by_adb(ad, pref_apn_name):
8782 """Select Pref APN
8783 Set Preferred APN on UI using content query/insert
8784 It needs apn name as arg, and it will match with plmn id
8785 """
8786 try:
8787 plmn_id = get_plmn_by_adb(ad)
8788 out = ad.adb.shell("content query --uri content://telephony/carriers "
8789 "--where \"apn='%s' and numeric='%s'\"" %
8790 (pref_apn_name, plmn_id))
8791 if "No result found" in out:
8792 ad.log.warning("Cannot find APN %s on device", pref_apn_name)
8793 return False
8794 else:
8795 apn_id = re.search(r'_id=(\d+)', out).group(1)
8796 ad.log.info("APN ID is %s", apn_id)
8797 ad.adb.shell("content insert --uri content:"
8798 "//telephony/carriers/preferapn --bind apn_id:i:%s" %
8799 (apn_id))
8800 out = ad.adb.shell("content query --uri "
8801 "content://telephony/carriers/preferapn")
8802 if "No result found" in out:
8803 ad.log.error("Failed to set prefer APN %s", pref_apn_name)
8804 return False
8805 elif apn_id == re.search(r'_id=(\d+)', out).group(1):
8806 ad.log.info("Preferred APN set to %s", pref_apn_name)
8807 return True
8808 except Exception as e:
8809 ad.log.error("Exception while setting pref apn %s", e)
8810 return True
8811
8812
Jaineel13fb98d2017-10-20 12:26:50 -07008813def check_apm_mode_on_by_serial(ad, serial_id):
8814 try:
8815 apm_check_cmd = "|".join(("adb -s %s shell dumpsys wifi" % serial_id,
8816 "grep -i airplanemodeon", "cut -f2 -d ' '"))
8817 output = exe_cmd(apm_check_cmd)
8818 if output.decode("utf-8").split("\n")[0] == "true":
8819 return True
8820 else:
8821 return False
8822 except Exception as e:
8823 ad.log.warning("Exception during check apm mode on %s", e)
Jaineel5576d432017-10-19 15:36:42 -07008824 return True
Jaineel5576d432017-10-19 15:36:42 -07008825
8826
Jaineel13fb98d2017-10-20 12:26:50 -07008827def set_apm_mode_on_by_serial(ad, serial_id):
8828 try:
8829 cmd1 = "adb -s %s shell settings put global airplane_mode_on 1" % serial_id
8830 cmd2 = "adb -s %s shell am broadcast -a android.intent.action.AIRPLANE_MODE" % serial_id
8831 exe_cmd(cmd1)
8832 exe_cmd(cmd2)
8833 except Exception as e:
8834 ad.log.warning("Exception during set apm mode on %s", e)
8835 return True
Jaineel5576d432017-10-19 15:36:42 -07008836
8837
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008838def print_radio_info(ad, extra_msg=""):
8839 for prop in ("gsm.version.baseband", "persist.radio.ver_info",
Betty Zhou447080c2018-02-06 10:43:26 -08008840 "persist.radio.cnv.ver_info"):
Betty Zhou8ecd1da2017-10-05 15:44:24 -07008841 output = ad.adb.getprop(prop)
Betty Zhou447080c2018-02-06 10:43:26 -08008842 ad.log.info("%s%s = %s", extra_msg, prop, output)
Betty Zhou32e403a2017-10-25 20:08:12 -07008843
8844
8845def wait_for_state(state_check_func,
8846 state,
Betty Zhouddc76402018-01-23 16:29:25 -08008847 max_wait_time=MAX_WAIT_TIME_FOR_STATE_CHANGE,
markdr6607bf12018-01-02 14:45:38 -08008848 checking_interval=WAIT_TIME_BETWEEN_STATE_CHECK,
Betty Zhou32e403a2017-10-25 20:08:12 -07008849 *args,
8850 **kwargs):
8851 while max_wait_time >= 0:
8852 if state_check_func(*args, **kwargs) == state:
8853 return True
8854 time.sleep(checking_interval)
8855 max_wait_time -= checking_interval
8856 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008857
8858
Betty Zhou6dd0ac62018-04-27 18:59:12 -07008859def power_off_sim(ad, sim_slot_id=None,
8860 timeout=MAX_WAIT_TIME_FOR_STATE_CHANGE):
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008861 try:
8862 if sim_slot_id is None:
8863 ad.droid.telephonySetSimPowerState(CARD_POWER_DOWN)
8864 verify_func = ad.droid.telephonyGetSimState
8865 verify_args = []
8866 else:
markdr6607bf12018-01-02 14:45:38 -08008867 ad.droid.telephonySetSimStateForSlotId(sim_slot_id,
8868 CARD_POWER_DOWN)
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008869 verify_func = ad.droid.telephonyGetSimStateForSlotId
8870 verify_args = [sim_slot_id]
8871 except Exception as e:
8872 ad.log.error(e)
8873 return False
Betty Zhou6dd0ac62018-04-27 18:59:12 -07008874 while timeout > 0:
8875 sim_state = verify_func(*verify_args)
8876 if sim_state in (SIM_STATE_UNKNOWN, SIM_STATE_ABSENT):
8877 ad.log.info("SIM slot is powered off, SIM state is %s", sim_state)
8878 return True
8879 timeout = timeout - WAIT_TIME_BETWEEN_STATE_CHECK
8880 time.sleep(WAIT_TIME_BETWEEN_STATE_CHECK)
8881 ad.log.warning("Fail to power off SIM slot, sim_state=%s",
8882 verify_func(*verify_args))
8883 return False
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008884
8885
8886def power_on_sim(ad, sim_slot_id=None):
8887 try:
8888 if sim_slot_id is None:
8889 ad.droid.telephonySetSimPowerState(CARD_POWER_UP)
8890 verify_func = ad.droid.telephonyGetSimState
8891 verify_args = []
8892 else:
8893 ad.droid.telephonySetSimStateForSlotId(sim_slot_id, CARD_POWER_UP)
8894 verify_func = ad.droid.telephonyGetSimStateForSlotId
8895 verify_args = [sim_slot_id]
8896 except Exception as e:
8897 ad.log.error(e)
8898 return False
Betty Zhouddc76402018-01-23 16:29:25 -08008899 if wait_for_state(verify_func, SIM_STATE_READY,
8900 MAX_WAIT_TIME_FOR_STATE_CHANGE,
8901 WAIT_TIME_BETWEEN_STATE_CHECK, *verify_args):
Betty Zhoua0469792018-01-22 18:48:02 -08008902 ad.log.info("SIM slot is powered on, SIM state is READY")
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008903 return True
8904 elif verify_func(*verify_args) == SIM_STATE_PIN_REQUIRED:
Betty Zhoue66efb42018-01-31 19:45:56 -08008905 ad.log.info("SIM is pin locked")
8906 return True
Betty Zhoud49a0ce2018-01-19 17:49:53 -08008907 else:
8908 ad.log.error("Fail to power on SIM slot")
markdr6607bf12018-01-02 14:45:38 -08008909 return False
Betty Zhou6357f452018-02-05 18:09:07 -08008910
8911
Betty Zhou3db27a32018-04-23 14:31:25 -07008912def extract_test_log(log, src_file, dst_file, test_tag):
Mark De Ruyter72f8df92020-02-12 13:44:49 -08008913 os.makedirs(os.path.dirname(dst_file), exist_ok=True)
Betty Zhoub25ba2d2018-05-03 15:52:54 -07008914 cmd = "grep -n '%s' %s" % (test_tag, src_file)
Betty Zhou3db27a32018-04-23 14:31:25 -07008915 result = job.run(cmd, ignore_status=True)
8916 if not result.stdout or result.exit_status == 1:
Betty Zhoue26fe892018-04-23 15:29:53 -07008917 log.warning("Command %s returns %s", cmd, result)
Betty Zhou3db27a32018-04-23 14:31:25 -07008918 return
8919 line_nums = re.findall(r"(\d+).*", result.stdout)
8920 if line_nums:
Betty Zhouc9a4d0c2018-06-18 16:26:07 -07008921 begin_line = int(line_nums[0])
8922 end_line = int(line_nums[-1])
8923 if end_line - begin_line <= 5:
8924 result = job.run("wc -l < %s" % src_file)
8925 if result.stdout:
8926 end_line = int(result.stdout)
Betty Zhou3db27a32018-04-23 14:31:25 -07008927 log.info("Extract %s from line %s to line %s to %s", src_file,
8928 begin_line, end_line, dst_file)
8929 job.run("awk 'NR >= %s && NR <= %s' %s > %s" % (begin_line, end_line,
8930 src_file, dst_file))
8931
8932
Betty Zhou0ca65c52018-04-26 15:47:38 -07008933def get_device_epoch_time(ad):
8934 return int(1000 * float(ad.adb.shell("date +%s.%N")))
8935
8936
8937def synchronize_device_time(ad):
Betty Zhouff2a3fa2018-05-02 16:58:27 -07008938 ad.adb.shell("put global auto_time 0", ignore_status=True)
8939 try:
Betty Zhouff2a3fa2018-05-02 16:58:27 -07008940 ad.adb.droid.setTime(get_current_epoch_time())
Betty Zhou819cb732018-05-10 18:45:41 -07008941 except Exception:
8942 try:
8943 ad.adb.shell("date `date +%m%d%H%M%G.%S`")
8944 except Exception:
8945 pass
8946 try:
8947 ad.adb.shell(
8948 "am broadcast -a android.intent.action.TIME_SET",
8949 ignore_status=True)
8950 except Exception:
8951 pass
Betty Zhou0ca65c52018-04-26 15:47:38 -07008952
8953
Betty Zhou8aafcc12018-05-01 20:54:15 -07008954def revert_default_telephony_setting(ad):
8955 toggle_airplane_mode_by_adb(ad.log, ad, True)
8956 default_data_roaming = int(
8957 ad.adb.getprop("ro.com.android.dataroaming") == 'true')
8958 default_network_preference = int(
8959 ad.adb.getprop("ro.telephony.default_network"))
8960 ad.log.info("Default data roaming %s, network preference %s",
8961 default_data_roaming, default_network_preference)
8962 new_data_roaming = abs(default_data_roaming - 1)
8963 new_network_preference = abs(default_network_preference - 1)
8964 ad.log.info(
8965 "Set data roaming = %s, mobile data = 0, network preference = %s",
8966 new_data_roaming, new_network_preference)
8967 ad.adb.shell("settings put global mobile_data 0")
8968 ad.adb.shell("settings put global data_roaming %s" % new_data_roaming)
8969 ad.adb.shell("settings put global preferred_network_mode %s" %
8970 new_network_preference)
8971
8972
8973def verify_default_telephony_setting(ad):
8974 ad.log.info("carrier_config: %s", dumpsys_carrier_config(ad))
8975 default_data_roaming = int(
8976 ad.adb.getprop("ro.com.android.dataroaming") == 'true')
8977 default_network_preference = int(
8978 ad.adb.getprop("ro.telephony.default_network"))
8979 ad.log.info("Default data roaming %s, network preference %s",
8980 default_data_roaming, default_network_preference)
8981 data_roaming = int(ad.adb.shell("settings get global data_roaming"))
8982 mobile_data = int(ad.adb.shell("settings get global mobile_data"))
8983 network_preference = int(
8984 ad.adb.shell("settings get global preferred_network_mode"))
8985 airplane_mode = int(ad.adb.shell("settings get global airplane_mode_on"))
8986 result = True
Betty Zhouff2a3fa2018-05-02 16:58:27 -07008987 ad.log.info("data_roaming = %s, mobile_data = %s, "
8988 "network_perference = %s, airplane_mode = %s", data_roaming,
8989 mobile_data, network_preference, airplane_mode)
Betty Zhou8aafcc12018-05-01 20:54:15 -07008990 if airplane_mode:
8991 ad.log.error("Airplane mode is on")
8992 result = False
8993 if data_roaming != default_data_roaming:
8994 ad.log.error("Data roaming is %s, expecting %s", data_roaming,
8995 default_data_roaming)
8996 result = False
8997 if not mobile_data:
8998 ad.log.error("Mobile data is off")
8999 result = False
9000 if network_preference != default_network_preference:
9001 ad.log.error("preferred_network_mode is %s, expecting %s",
9002 network_preference, default_network_preference)
9003 result = False
9004 return result
9005
9006
Betty Zhou74cf9922018-04-18 20:18:12 -07009007def log_messaging_screen_shot(ad, test_name=""):
Betty Zhou2186ebc2018-05-09 16:50:26 -07009008 ad.ensure_screen_on()
Betty Zhou1ffbc832018-05-08 19:02:56 -07009009 ad.send_keycode("HOME")
Betty Zhou2186ebc2018-05-09 16:50:26 -07009010 ad.adb.shell("am start -n com.google.android.apps.messaging/.ui."
9011 "ConversationListActivity")
Betty Zhou74cf9922018-04-18 20:18:12 -07009012 log_screen_shot(ad, test_name)
Betty Zhou2186ebc2018-05-09 16:50:26 -07009013 ad.adb.shell("am start -n com.google.android.apps.messaging/com.google."
9014 "android.apps.messaging.ui.conversation.ConversationActivity"
9015 " -e conversation_id 1")
Betty Zhou74cf9922018-04-18 20:18:12 -07009016 log_screen_shot(ad, test_name)
9017 ad.send_keycode("HOME")
9018
9019
Betty Zhoua36c4352018-04-05 18:49:32 -07009020def log_screen_shot(ad, test_name=""):
Betty Zhou74cf9922018-04-18 20:18:12 -07009021 file_name = "/sdcard/Pictures/screencap"
9022 if test_name:
9023 file_name = "%s_%s" % (file_name, test_name)
9024 file_name = "%s_%s.png" % (file_name, utils.get_current_epoch_time())
Betty Zhoue57ab692018-03-09 18:39:30 -08009025 try:
9026 ad.adb.shell("screencap -p %s" % file_name)
Betty Zhoue57ab692018-03-09 18:39:30 -08009027 except:
Betty Zhoue123c672018-03-21 19:57:11 -07009028 ad.log.error("Fail to log screen shot to %s", file_name)
9029
9030
9031def get_screen_shot_log(ad, test_name="", begin_time=None):
9032 logs = ad.get_file_names("/sdcard/Pictures", begin_time=begin_time)
9033 if logs:
9034 ad.log.info("Pulling %s", logs)
Xianyuan Jiad6b2a632019-05-24 17:40:45 +00009035 log_path = os.path.join(ad.device_log_path, "Screenshot_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08009036 os.makedirs(log_path, exist_ok=True)
Betty Zhoua36c4352018-04-05 18:49:32 -07009037 ad.pull_files(logs, log_path)
Betty Zhoue123c672018-03-21 19:57:11 -07009038 ad.adb.shell("rm -rf /sdcard/Pictures/screencap_*", ignore_status=True)
9039
9040
9041def get_screen_shot_logs(ads, test_name="", begin_time=None):
9042 for ad in ads:
9043 get_screen_shot_log(ad, test_name=test_name, begin_time=begin_time)
Betty Zhouc8213812018-04-02 14:06:50 -07009044
9045
Jaineela03017f2019-03-07 17:30:17 -08009046def get_carrier_id_version(ad):
9047 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | " \
9048 "grep -i carrier_list_version")
9049 if out and ":" in out:
9050 version = out.split(':')[1].lstrip()
9051 else:
9052 version = "0"
9053 ad.log.debug("Carrier Config Version is %s", version)
9054 return version
9055
9056
Jaineel1cde17b2019-01-04 14:26:55 -08009057def get_carrier_config_version(ad):
9058 out = ad.adb.shell("dumpsys carrier_config | grep version_string")
9059 if out and "-" in out:
9060 version = out.split('-')[1]
9061 else:
9062 version = "0"
9063 ad.log.debug("Carrier Config Version is %s", version)
9064 return version
9065
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009066def get_er_db_id_version(ad):
9067 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \
9068 grep -i \"Database Version\"")
9069 if out and ":" in out:
Ashutosh Rajmani Singh4d1c9bf2020-04-16 14:40:02 -07009070 version = out.split(':', 2)[2].lstrip()
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009071 else:
9072 version = "0"
9073 ad.log.debug("Emergency database Version is %s", version)
9074 return version
9075
Ashutosh Rajmani Singh8a8ee3e2020-04-20 19:47:44 -07009076def get_database_content(ad):
9077 out = ad.adb.shell("dumpsys activity service TelephonyDebugService | \
9078 egrep -i \EmergencyNumber:Number-54321")
9079 if out:
9080 return True
9081 result = ad.adb.shell(r"dumpsys activity service TelephonyDebugService | \
9082 egrep -i \updateOtaEmergencyNumberListDatabaseAndNotify")
9083 ad.log.error("Emergency Number is incorrect. %s ", result)
9084 return False
Ashutosh Rajmani Singhf5cecf42020-04-06 05:06:03 -07009085
9086def add_whitelisted_account(ad, user_account,user_password, retries=3):
9087 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9088 ad.log.error("GoogleAccountUtil is not installed")
9089 return False
9090 for _ in range(retries):
9091 ad.ensure_screen_on()
9092 output = ad.adb.shell(
9093 'am instrument -w -e account "%s@gmail.com" -e password '
9094 '"%s" -e sync true -e wait-for-checkin false '
9095 'com.google.android.tradefed.account/.AddAccount' %
9096 (user_account, user_password))
9097 if "result=SUCCESS" in output:
9098 ad.log.info("Google account is added successfully")
9099 return True
9100 ad.log.error("Failed to add google account - %s", output)
9101 return False
9102
Jaineel1cde17b2019-01-04 14:26:55 -08009103
Jaineelc50c2e62019-02-15 16:46:36 -08009104def install_googleaccountutil_apk(ad, account_util):
9105 ad.log.info("Install account_util %s", account_util)
9106 ad.ensure_screen_on()
9107 ad.adb.install("-r %s" % account_util, timeout=300, ignore_status=True)
9108 time.sleep(3)
9109 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9110 ad.log.info("com.google.android.tradefed.account is not installed")
9111 return False
9112 return True
9113
9114
Jaineel5865cac2019-02-20 16:30:42 -08009115def install_googlefi_apk(ad, fi_util):
9116 ad.log.info("Install fi_util %s", fi_util)
9117 ad.ensure_screen_on()
9118 ad.adb.install("-r -g --user 0 %s" % fi_util,
9119 timeout=300, ignore_status=True)
9120 time.sleep(3)
Jaineel39e72882019-03-21 13:20:49 -07009121 if not check_fi_apk_installed(ad):
9122 return False
9123 return True
9124
9125
9126def check_fi_apk_installed(ad):
Jaineel5865cac2019-02-20 16:30:42 -08009127 if not ad.is_apk_installed("com.google.android.apps.tycho"):
Jaineel39e72882019-03-21 13:20:49 -07009128 ad.log.warning("com.google.android.apps.tycho is not installed")
Jaineel5865cac2019-02-20 16:30:42 -08009129 return False
9130 return True
9131
9132
Jaineelc50c2e62019-02-15 16:46:36 -08009133def add_google_account(ad, retries=3):
9134 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9135 ad.log.error("GoogleAccountUtil is not installed")
9136 return False
9137 for _ in range(retries):
9138 ad.ensure_screen_on()
9139 output = ad.adb.shell(
9140 'am instrument -w -e account "%s@gmail.com" -e password '
9141 '"%s" -e sync true -e wait-for-checkin false '
9142 'com.google.android.tradefed.account/.AddAccount' %
9143 (ad.user_account, ad.user_password))
9144 if "result=SUCCESS" in output:
9145 ad.log.info("Google account is added successfully")
9146 return True
9147 ad.log.error("Failed to add google account - %s", output)
9148 return False
9149
9150
9151def remove_google_account(ad, retries=3):
9152 if not ad.is_apk_installed("com.google.android.tradefed.account"):
9153 ad.log.error("GoogleAccountUtil is not installed")
9154 return False
9155 for _ in range(retries):
9156 ad.ensure_screen_on()
9157 output = ad.adb.shell(
9158 'am instrument -w '
9159 'com.google.android.tradefed.account/.RemoveAccounts')
9160 if "result=SUCCESS" in output:
9161 ad.log.info("google account is removed successfully")
9162 return True
9163 ad.log.error("Fail to remove google account due to %s", output)
9164 return False
9165
9166
Jaineele74193b2019-02-19 17:52:50 -08009167def my_current_screen_content(ad, content):
9168 ad.adb.shell("uiautomator dump --window=WINDOW")
9169 out = ad.adb.shell("cat /sdcard/window_dump.xml | grep -E '%s'" % content)
9170 if not out:
Jaineel39e72882019-03-21 13:20:49 -07009171 ad.log.warning("NOT FOUND - %s", content)
Jaineele74193b2019-02-19 17:52:50 -08009172 return False
9173 return True
9174
9175
Jaineelea47b1e2019-09-18 11:11:03 -07009176def activate_esim_using_suw(ad):
9177 _START_SUW = ('am start -a android.intent.action.MAIN -n '
9178 'com.google.android.setupwizard/.SetupWizardTestActivity')
9179 _STOP_SUW = ('am start -a com.android.setupwizard.EXIT')
9180
9181 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
9182 ad.adb.shell("settings put system screen_off_timeout 1800000")
9183 ad.ensure_screen_on()
9184 ad.send_keycode("MENU")
9185 ad.send_keycode("HOME")
9186 for _ in range(3):
9187 ad.log.info("Attempt %d - activating eSIM", (_ + 1))
9188 ad.adb.shell(_START_SUW)
9189 time.sleep(10)
9190 log_screen_shot(ad, "start_suw")
9191 for _ in range(4):
9192 ad.send_keycode("TAB")
9193 time.sleep(0.5)
9194 ad.send_keycode("ENTER")
9195 time.sleep(15)
9196 log_screen_shot(ad, "activate_esim")
9197 get_screen_shot_log(ad)
9198 ad.adb.shell(_STOP_SUW)
9199 time.sleep(5)
9200 current_sim = get_sim_state(ad)
9201 ad.log.info("Current SIM status is %s", current_sim)
9202 if current_sim not in (SIM_STATE_ABSENT, SIM_STATE_UNKNOWN):
9203 break
9204 return True
9205
Jaineele1b182a2019-04-12 15:47:48 -07009206def activate_google_fi_account(ad, retries=10):
Jaineele74193b2019-02-19 17:52:50 -08009207 _FI_APK = "com.google.android.apps.tycho"
9208 _FI_ACTIVATE_CMD = ('am start -c android.intent.category.DEFAULT -n '
Jaineelfc742862019-05-16 14:57:56 -07009209 'com.google.android.apps.tycho/.AccountDetailsActivity --ez '
Jaineele74193b2019-02-19 17:52:50 -08009210 'in_setup_wizard false --ez force_show_account_chooser '
9211 'false')
Jaineel39e72882019-03-21 13:20:49 -07009212 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
Jaineele74193b2019-02-19 17:52:50 -08009213 ad.adb.shell("settings put system screen_off_timeout 1800000")
9214 page_match_dict = {
Jaineelfc742862019-05-16 14:57:56 -07009215 "SelectAccount" : "Choose an account to use",
Jaineele74193b2019-02-19 17:52:50 -08009216 "Setup" : "Activate Google Fi to use your device for calls",
9217 "Switch" : "Switch to the Google Fi mobile network",
Jaineelfc742862019-05-16 14:57:56 -07009218 "WiFi" : "Fi to download your SIM",
Jaineel39e72882019-03-21 13:20:49 -07009219 "Connect" : "Connect to the Google Fi mobile network",
9220 "Move" : "Move number",
Jaineele1b182a2019-04-12 15:47:48 -07009221 "Data" : "first turn on mobile data",
Jaineele74193b2019-02-19 17:52:50 -08009222 "Activate" : "This takes a minute or two, sometimes longer",
9223 "Welcome" : "Welcome to Google Fi",
Jaineel39e72882019-03-21 13:20:49 -07009224 "Account" : "Your current cycle ends in"
Jaineele74193b2019-02-19 17:52:50 -08009225 }
Jaineelfc742862019-05-16 14:57:56 -07009226 page_list = ["Account", "Setup", "WiFi", "Switch", "Connect",
Jaineele1b182a2019-04-12 15:47:48 -07009227 "Activate", "Move", "Welcome", "Data"]
Jaineele74193b2019-02-19 17:52:50 -08009228 for _ in range(retries):
9229 ad.force_stop_apk(_FI_APK)
9230 ad.ensure_screen_on()
Jaineel687a67c2019-04-08 13:08:37 -07009231 ad.send_keycode("MENU")
Jaineele74193b2019-02-19 17:52:50 -08009232 ad.send_keycode("HOME")
9233 ad.adb.shell(_FI_ACTIVATE_CMD)
9234 time.sleep(15)
Jaineel39e72882019-03-21 13:20:49 -07009235 for page in page_list:
Jaineele74193b2019-02-19 17:52:50 -08009236 if my_current_screen_content(ad, page_match_dict[page]):
9237 ad.log.info("Ready for Step %s", page)
9238 log_screen_shot(ad, "fi_activation_step_%s" % page)
Jaineelfc742862019-05-16 14:57:56 -07009239 if page in ("Setup", "Switch", "Connect", "WiFi"):
Jaineele74193b2019-02-19 17:52:50 -08009240 ad.send_keycode("TAB")
9241 ad.send_keycode("TAB")
9242 ad.send_keycode("ENTER")
9243 time.sleep(30)
Jaineelfc742862019-05-16 14:57:56 -07009244 elif page == "Move" or page == "SelectAccount":
Jaineel39e72882019-03-21 13:20:49 -07009245 ad.send_keycode("TAB")
9246 ad.send_keycode("ENTER")
9247 time.sleep(5)
Jaineele74193b2019-02-19 17:52:50 -08009248 elif page == "Welcome":
9249 ad.send_keycode("TAB")
9250 ad.send_keycode("TAB")
9251 ad.send_keycode("TAB")
9252 ad.send_keycode("ENTER")
9253 ad.log.info("Activation SUCCESS using Fi App")
9254 time.sleep(5)
9255 ad.send_keycode("TAB")
9256 ad.send_keycode("TAB")
9257 ad.send_keycode("ENTER")
9258 return True
9259 elif page == "Activate":
9260 time.sleep(60)
9261 if my_current_screen_content(ad, page_match_dict[page]):
9262 time.sleep(60)
Jaineel39e72882019-03-21 13:20:49 -07009263 elif page == "Account":
9264 return True
Jaineele1b182a2019-04-12 15:47:48 -07009265 elif page == "Data":
9266 ad.log.error("Mobile Data is turned OFF by default")
9267 ad.send_keycode("TAB")
9268 ad.send_keycode("TAB")
9269 ad.send_keycode("ENTER")
Jaineele74193b2019-02-19 17:52:50 -08009270 else:
Jaineel39e72882019-03-21 13:20:49 -07009271 ad.log.info("NOT FOUND - Page %s", page)
Jaineele74193b2019-02-19 17:52:50 -08009272 log_screen_shot(ad, "fi_activation_step_%s_failure" % page)
Jaineelfc742862019-05-16 14:57:56 -07009273 get_screen_shot_log(ad)
Jaineele74193b2019-02-19 17:52:50 -08009274 return False
9275
9276
9277def check_google_fi_activated(ad, retries=20):
Jaineel39e72882019-03-21 13:20:49 -07009278 if check_fi_apk_installed(ad):
9279 _FI_APK = "com.google.android.apps.tycho"
9280 _FI_LAUNCH_CMD = ("am start -n %s/%s.AccountDetailsActivity" \
9281 % (_FI_APK, _FI_APK))
9282 toggle_airplane_mode(ad.log, ad, new_state=False, strict_checking=False)
9283 ad.adb.shell("settings put system screen_off_timeout 1800000")
9284 ad.force_stop_apk(_FI_APK)
9285 ad.ensure_screen_on()
9286 ad.send_keycode("HOME")
9287 ad.adb.shell(_FI_LAUNCH_CMD)
9288 time.sleep(10)
9289 if not my_current_screen_content(ad, "Your current cycle ends in"):
9290 ad.log.warning("Fi is not activated")
9291 return False
9292 ad.send_keycode("HOME")
9293 return True
9294 else:
9295 ad.log.info("Fi Apk is not yet installed")
9296 return False
Jaineele74193b2019-02-19 17:52:50 -08009297
9298
Jaineela03017f2019-03-07 17:30:17 -08009299def cleanup_configupdater(ad):
9300 cmds = ('rm -rf /data/data/com.google.android.configupdater/shared_prefs',
9301 'rm /data/misc/carrierid/carrier_list.pb',
9302 'setprop persist.telephony.test.carrierid.ota true',
9303 'rm /data/user_de/0/com.android.providers.telephony/shared_prefs'
9304 '/CarrierIdProvider.xml')
9305 for cmd in cmds:
9306 ad.log.info("Cleanup ConfigUpdater - %s", cmd)
9307 ad.adb.shell(cmd, ignore_status=True)
9308
9309
9310def pull_carrier_id_files(ad, carrier_id_path):
Mark De Ruyter72f8df92020-02-12 13:44:49 -08009311 os.makedirs(carrier_id_path, exist_ok=True)
Jaineela03017f2019-03-07 17:30:17 -08009312 ad.log.info("Pull CarrierId Files")
Jaineel3fc8ad02019-03-14 09:53:20 -07009313 cmds = ('/data/data/com.google.android.configupdater/shared_prefs/',
9314 '/data/misc/carrierid/',
9315 '/data/user_de/0/com.android.providers.telephony/shared_prefs/',
9316 '/data/data/com.android.providers.downloads/databases/downloads.db')
Jaineela03017f2019-03-07 17:30:17 -08009317 for cmd in cmds:
Jaineel3fc8ad02019-03-14 09:53:20 -07009318 cmd = cmd + " %s" % carrier_id_path
Jaineela03017f2019-03-07 17:30:17 -08009319 ad.adb.pull(cmd, timeout=30, ignore_status=True)
9320
9321
Betty Zhouc8213812018-04-02 14:06:50 -07009322def bring_up_connectivity_monitor(ad):
9323 monitor_apk = None
9324 for apk in ("com.google.telephonymonitor",
9325 "com.google.android.connectivitymonitor"):
9326 if ad.is_apk_installed(apk):
9327 ad.log.info("apk %s is installed", apk)
9328 monitor_apk = apk
9329 break
9330 if not monitor_apk:
9331 ad.log.info("ConnectivityMonitor|TelephonyMonitor is not installed")
9332 return False
9333 toggle_connectivity_monitor_setting(ad, True)
9334
9335 if not ad.is_apk_running(monitor_apk):
9336 ad.log.info("%s is not running", monitor_apk)
9337 # Reboot
9338 ad.log.info("reboot to bring up %s", monitor_apk)
9339 reboot_device(ad)
9340 for i in range(30):
Betty Zhoue21f4922018-04-02 18:41:44 -07009341 if ad.is_apk_running(monitor_apk):
9342 ad.log.info("%s is running after reboot", monitor_apk)
Betty Zhouc8213812018-04-02 14:06:50 -07009343 return True
9344 else:
Betty Zhoue21f4922018-04-02 18:41:44 -07009345 ad.log.info(
Betty Zhouc8213812018-04-02 14:06:50 -07009346 "%s is not running after reboot. Wait and check again",
9347 monitor_apk)
9348 time.sleep(30)
9349 ad.log.error("%s is not running after reboot", monitor_apk)
9350 return False
9351 else:
9352 ad.log.info("%s is running", monitor_apk)
9353 return True
9354
9355
monikermine709efcd2019-10-04 14:06:26 -07009356def get_host_ip_address(ad):
9357 cmd = "|".join(("ifconfig", "grep eno1 -A1", "grep inet", "awk '{$1=$1};1'", "cut -d ' ' -f 2"))
9358 destination_ip = exe_cmd(cmd)
9359 destination_ip = (destination_ip.decode("utf-8")).split("\n")[0]
9360 ad.log.info("Host IP is %s", destination_ip)
9361 return destination_ip
9362
9363
Mars Linc6e99602019-12-02 12:00:06 +08009364def load_scone_cat_simulate_data(ad, simulate_data, sub_id=None):
9365 """ Load radio simulate data
9366 ad: android device controller
9367 simulate_data: JSON object of simulate data
9368 sub_id: RIL sub id, should be 0 or 1
9369 """
9370 ad.log.info("load_scone_cat_simulate_data")
9371
9372 #Check RIL sub id
9373 if sub_id is None or sub_id > 1:
9374 ad.log.error("The value of RIL sub_id should be 0 or 1")
9375 return False
9376
9377 action = "com.google.android.apps.scone.cat.action.SetSimulateData"
9378
9379 #add sub id
9380 simulate_data["SubId"] = sub_id
9381 try:
9382 #dump json
9383 extra = json.dumps(simulate_data)
9384 ad.log.info("send simulate_data=[%s]" % extra)
9385 #send data
9386 ad.adb.shell("am broadcast -a " + action + " --es simulate_data '" + extra + "'")
9387 except Exception as e:
9388 ad.log.error("Exception error to send CAT: %s", e)
9389 return False
9390
9391 return True
9392
9393
9394def load_scone_cat_data_from_file(ad, simulate_file_path, sub_id=None):
9395 """ Load radio simulate data
9396 ad: android device controller
9397 simulate_file_path: JSON file of simulate data
9398 sub_id: RIL sub id, should be 0 or 1
9399 """
9400 ad.log.info("load_radio_simulate_data_from_file from %s" % simulate_file_path)
9401 radio_simulate_data = {}
9402
9403 #Check RIL sub id
9404 if sub_id is None or sub_id > 1:
9405 ad.log.error("The value of RIL sub_id should be 0 or 1")
9406 raise ValueError
9407
9408 with open(simulate_file_path, 'r') as f:
9409 try:
9410 radio_simulate_data = json.load(f)
9411 except Exception as e:
9412 self.log.error("Exception error to load %s: %s", f, e)
9413 return False
9414
9415 for item in radio_simulate_data:
9416 result = load_scone_cat_simulate_data(ad, item, sub_id)
9417 if result == False:
9418 ad.log.error("Load CAT command fail")
9419 return False
9420 time.sleep(0.1)
9421
9422 return True
9423
9424
Betty Zhouc8213812018-04-02 14:06:50 -07009425def toggle_connectivity_monitor_setting(ad, state=True):
9426 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon")
9427 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting)
9428 current_state = True if monitor_setting == "user_enabled" else False
9429 if current_state == state:
9430 return True
9431 elif state is None:
9432 state = not current_state
9433 expected_monitor_setting = "user_enabled" if state else "disabled"
9434 cmd = "setprop persist.radio.enable_tel_mon %s" % expected_monitor_setting
9435 ad.log.info("Toggle connectivity monitor by %s", cmd)
9436 ad.adb.shell(
9437 "am start -n com.android.settings/.DevelopmentSettings",
9438 ignore_status=True)
9439 ad.adb.shell(cmd)
9440 monitor_setting = ad.adb.getprop("persist.radio.enable_tel_mon")
9441 ad.log.info("radio.enable_tel_mon setting is %s", monitor_setting)
9442 return monitor_setting == expected_monitor_setting
Markus Liu1cca96e2019-11-26 15:05:25 +08009443
9444def get_call_forwarding_by_adb(log, ad, call_forwarding_type="unconditional"):
9445 """ Get call forwarding status by adb shell command
9446 'dumpsys telephony.registry'.
9447
9448 Args:
9449 log: log object
9450 ad: android object
9451 call_forwarding_type:
9452 - "unconditional"
9453 - "busy" (todo)
9454 - "not_answered" (todo)
9455 - "not_reachable" (todo)
9456 Returns:
9457 - "true": if call forwarding unconditional is enabled.
9458 - "false": if call forwarding unconditional is disabled.
9459 - "unknown": if the type is other than 'unconditional'.
9460 - False: any case other than above 3 cases.
9461 """
9462 if call_forwarding_type != "unconditional":
9463 return "unknown"
9464
9465 slot_index_of_default_voice_subid = get_slot_index_from_subid(log, ad,
9466 get_incoming_voice_sub_id(ad))
9467 output = ad.adb.shell("dumpsys telephony.registry | grep mCallForwarding")
9468 if "mCallForwarding" in output:
9469 result_list = re.findall(r"mCallForwarding=(true|false)", output)
9470 if result_list:
9471 result = result_list[slot_index_of_default_voice_subid]
9472 ad.log.info("mCallForwarding is %s", result)
9473
9474 if re.search("false", result, re.I):
9475 return "false"
9476 elif re.search("true", result, re.I):
9477 return "true"
9478 else:
9479 return False
9480 else:
9481 return False
9482 else:
9483 ad.log.error("'mCallForwarding' cannot be found in dumpsys.")
9484 return False
9485
9486def erase_call_forwarding_by_mmi(
9487 log,
9488 ad,
9489 retry=2,
9490 call_forwarding_type="unconditional"):
9491 """ Erase setting of call forwarding (erase the number and disable call
9492 forwarding) by MMI code.
9493
9494 Args:
9495 log: log object
9496 ad: android object
9497 retry: times of retry if the erasure failed.
9498 call_forwarding_type:
9499 - "unconditional"
9500 - "busy"
9501 - "not_answered"
9502 - "not_reachable"
9503 Returns:
9504 True by successful erasure. Otherwise False.
9505 """
9506 res = get_call_forwarding_by_adb(log, ad,
9507 call_forwarding_type=call_forwarding_type)
9508 if res == "false":
9509 return True
9510
9511 user_config_profile = get_user_config_profile(ad)
9512 is_airplane_mode = user_config_profile["Airplane Mode"]
9513 is_wfc_enabled = user_config_profile["WFC Enabled"]
9514 wfc_mode = user_config_profile["WFC Mode"]
9515 is_wifi_on = user_config_profile["WiFi State"]
9516
9517 if is_airplane_mode:
9518 if not toggle_airplane_mode(log, ad, False):
9519 ad.log.error("Failed to disable airplane mode.")
9520 return False
9521
9522 operator_name = get_operator_name(log, ad)
9523
9524 code_dict = {
9525 "Verizon": {
9526 "unconditional": "73",
9527 "busy": "73",
9528 "not_answered": "73",
9529 "not_reachable": "73",
9530 "mmi": "*%s"
9531 },
9532 "Sprint": {
9533 "unconditional": "720",
9534 "busy": "740",
9535 "not_answered": "730",
9536 "not_reachable": "720",
9537 "mmi": "*%s"
9538 },
9539 'Generic': {
9540 "unconditional": "21",
9541 "busy": "67",
9542 "not_answered": "61",
9543 "not_reachable": "62",
9544 "mmi": "##%s#"
9545 }
9546 }
9547
9548 if operator_name in code_dict:
9549 code = code_dict[operator_name][call_forwarding_type]
9550 mmi = code_dict[operator_name]["mmi"]
9551 else:
9552 code = code_dict['Generic'][call_forwarding_type]
9553 mmi = code_dict['Generic']["mmi"]
9554
9555 result = False
9556 while retry >= 0:
9557 res = get_call_forwarding_by_adb(
9558 log, ad, call_forwarding_type=call_forwarding_type)
9559 if res == "false":
9560 ad.log.info("Call forwarding is already disabled.")
9561 result = True
9562 break
9563
9564 ad.log.info("Erasing and deactivating call forwarding %s..." %
9565 call_forwarding_type)
9566
9567 ad.droid.telecomDialNumber(mmi % code)
9568
9569 time.sleep(3)
9570 ad.send_keycode("ENTER")
9571 time.sleep(15)
9572
9573 # To dismiss the pop-out dialog
9574 ad.send_keycode("BACK")
9575 time.sleep(5)
9576 ad.send_keycode("BACK")
9577
9578 res = get_call_forwarding_by_adb(
9579 log, ad, call_forwarding_type=call_forwarding_type)
9580 if res == "false" or res == "unknown":
9581 result = True
9582 break
9583 else:
9584 ad.log.error("Failed to erase and deactivate call forwarding by "
9585 "MMI code ##%s#." % code)
9586 retry = retry - 1
9587 time.sleep(30)
9588
9589 if is_airplane_mode:
9590 if not toggle_airplane_mode(log, ad, True):
9591 ad.log.error("Failed to enable airplane mode again.")
9592 else:
9593 if is_wifi_on:
9594 ad.droid.wifiToggleState(True)
9595 if is_wfc_enabled:
9596 if not wait_for_wfc_enabled(
9597 log, ad,max_time=MAX_WAIT_TIME_WFC_ENABLED):
9598 ad.log.error("WFC is not enabled")
9599
9600 return result
9601
9602def set_call_forwarding_by_mmi(
9603 log,
9604 ad,
9605 ad_forwarded,
9606 call_forwarding_type="unconditional",
9607 retry=2):
9608 """ Set up the forwarded number and enable call forwarding by MMI code.
9609
9610 Args:
9611 log: log object
9612 ad: android object of the device forwarding the call (primary device)
9613 ad_forwarded: android object of the device receiving forwarded call.
9614 retry: times of retry if the erasure failed.
9615 call_forwarding_type:
9616 - "unconditional"
9617 - "busy"
9618 - "not_answered"
9619 - "not_reachable"
9620 Returns:
9621 True by successful erasure. Otherwise False.
9622 """
9623
9624 res = get_call_forwarding_by_adb(log, ad,
9625 call_forwarding_type=call_forwarding_type)
9626 if res == "true":
9627 return True
9628
9629 if ad.droid.connectivityCheckAirplaneMode():
9630 ad.log.warning("%s is now in airplane mode.", ad.serial)
9631 return False
9632
9633 operator_name = get_operator_name(log, ad)
9634
9635 code_dict = {
9636 "Verizon": {
9637 "unconditional": "72",
9638 "busy": "71",
9639 "not_answered": "71",
9640 "not_reachable": "72",
9641 "mmi": "*%s%s"
9642 },
9643 "Sprint": {
9644 "unconditional": "72",
9645 "busy": "74",
9646 "not_answered": "73",
9647 "not_reachable": "72",
9648 "mmi": "*%s%s"
9649 },
9650 'Generic': {
9651 "unconditional": "21",
9652 "busy": "67",
9653 "not_answered": "61",
9654 "not_reachable": "62",
9655 "mmi": "*%s*%s#",
9656 "mmi_for_plus_sign": "*%s*"
9657 }
9658 }
9659
9660 if operator_name in code_dict:
9661 code = code_dict[operator_name][call_forwarding_type]
9662 mmi = code_dict[operator_name]["mmi"]
9663 else:
9664 code = code_dict['Generic'][call_forwarding_type]
9665 mmi = code_dict['Generic']["mmi"]
9666 mmi_for_plus_sign = code_dict['Generic']["mmi_for_plus_sign"]
9667
9668 while retry >= 0:
9669 if not erase_call_forwarding_by_mmi(
9670 log, ad, call_forwarding_type=call_forwarding_type):
9671 retry = retry - 1
9672 continue
9673
9674 forwarded_number = ad_forwarded.telephony['subscription'][
9675 ad_forwarded.droid.subscriptionGetDefaultVoiceSubId()][
9676 'phone_num']
9677 ad.log.info("Registering and activating call forwarding %s to %s..." %
9678 (call_forwarding_type, forwarded_number))
9679
9680 (forwarded_number_no_prefix, _) = _phone_number_remove_prefix(
9681 forwarded_number)
9682
9683 _found_plus_sign = 0
9684 if re.search("^\+", forwarded_number):
9685 _found_plus_sign = 1
9686 forwarded_number.replace("+", "")
9687
9688 if operator_name in code_dict:
9689 ad.droid.telecomDialNumber(mmi % (code, forwarded_number_no_prefix))
9690 else:
9691 if _found_plus_sign == 0:
9692 ad.droid.telecomDialNumber(mmi % (code, forwarded_number))
9693 else:
9694 ad.droid.telecomDialNumber(mmi_for_plus_sign % code)
9695 ad.send_keycode("PLUS")
9696 dial_phone_number(ad, forwarded_number + "#")
9697
9698 time.sleep(3)
9699 ad.send_keycode("ENTER")
9700 time.sleep(15)
9701
9702 # To dismiss the pop-out dialog
9703 ad.send_keycode("BACK")
9704 time.sleep(5)
9705 ad.send_keycode("BACK")
9706
9707 result = get_call_forwarding_by_adb(
9708 log, ad, call_forwarding_type=call_forwarding_type)
9709 if result == "false":
9710 retry = retry - 1
9711 elif result == "true":
9712 return True
9713 elif result == "unknown":
9714 return True
9715 else:
9716 retry = retry - 1
9717
9718 if retry >= 0:
9719 ad.log.warning("Failed to register or activate call forwarding %s "
9720 "to %s. Retry after 15 seconds." % (call_forwarding_type,
9721 forwarded_number))
9722 time.sleep(15)
9723
9724 ad.log.error("Failed to register or activate call forwarding %s to %s." %
9725 (call_forwarding_type, forwarded_number))
Jaineel51bf49b2020-01-15 11:02:13 -08009726 return False
Ignacio Guarna9c63ef52020-02-06 17:08:09 -03009727
Markus Liude6e5db2019-12-18 15:31:54 +08009728def get_call_waiting_status(log, ad):
9729 """ (Todo) Get call waiting status (activated or deactivated) when there is
9730 any proper method available.
9731 """
9732 return True
9733
9734def set_call_waiting(log, ad, enable=1, retry=1):
9735 """ Activate/deactivate call waiting by dialing MMI code.
9736
9737 Args:
9738 log: log object.
9739 ad: android object.
9740 enable: 1 for activation and 0 fir deactivation
9741 retry: times of retry if activation/deactivation fails
9742
9743 Returns:
9744 True by successful activation/deactivation; otherwise False.
9745 """
9746 operator_name = get_operator_name(log, ad)
9747
9748 if operator_name in ["Verizon", "Sprint"]:
9749 return True
9750
9751 while retry >= 0:
9752 if enable:
9753 ad.log.info("Activating call waiting...")
9754 ad.droid.telecomDialNumber("*43#")
9755 else:
9756 ad.log.info("Deactivating call waiting...")
9757 ad.droid.telecomDialNumber("#43#")
9758
9759 time.sleep(3)
9760 ad.send_keycode("ENTER")
9761 time.sleep(15)
9762
9763 ad.send_keycode("BACK")
9764 time.sleep(5)
9765 ad.send_keycode("BACK")
9766
9767 if get_call_waiting_status(log, ad):
9768 return True
9769 else:
9770 retry = retry + 1
9771
9772 return False
Ignacio Guarna9c63ef52020-02-06 17:08:09 -03009773
9774def get_rx_tx_power_levels(log, ad):
9775 """ Obtains Rx and Tx power levels from the MDS application.
9776
9777 The method requires the MDS app to be installed in the DUT.
9778
9779 Args:
9780 log: logger object
9781 ad: an android device
9782
9783 Return:
9784 A tuple where the first element is an array array with the RSRP value
9785 in Rx chain, and the second element is the transmitted power in dBm.
9786 Values for invalid Rx / Tx chains are set to None.
9787 """
9788 cmd = ('am instrument -w -e request "80 00 e8 03 00 08 00 00 00" -e '
9789 'response wait "com.google.mdstest/com.google.mdstest.instrument.'
9790 'ModemCommandInstrumentation"')
9791 output = ad.adb.shell(cmd)
9792
9793 if 'result=SUCCESS' not in output:
9794 raise RuntimeError('Could not obtain Tx/Rx power levels from MDS. Is '
9795 'the MDS app installed?')
9796
9797 response = re.search(r"(?<=response=).+", output)
9798
9799 if not response:
9800 raise RuntimeError('Invalid response from the MDS app:\n' + output)
9801
9802 # Obtain a list of bytes in hex format from the response string
9803 response_hex = response.group(0).split(' ')
9804
9805 def get_bool(pos):
9806 """ Obtain a boolean variable from the byte array. """
9807 return response_hex[pos] == '01'
9808
9809 def get_int32(pos):
9810 """ Obtain an int from the byte array. Bytes are printed in
9811 little endian format."""
9812 return struct.unpack(
9813 '<i', bytearray.fromhex(''.join(response_hex[pos:pos + 4])))[0]
9814
9815 rx_power = []
9816 RX_CHAINS = 4
9817
9818 for i in range(RX_CHAINS):
9819 # Calculate starting position for the Rx chain data structure
9820 start = 12 + i * 22
9821
9822 # The first byte in the data structure indicates if the rx chain is
9823 # valid.
9824 if get_bool(start):
9825 rx_power.append(get_int32(start + 2) / 10)
9826 else:
9827 rx_power.append(None)
9828
9829 # Calculate the position for the tx chain data structure
9830 tx_pos = 12 + RX_CHAINS * 22
9831
9832 tx_valid = get_bool(tx_pos)
9833 if tx_valid:
9834 tx_power = get_int32(tx_pos + 2) / -10
9835 else:
9836 tx_power = None
9837
9838 return rx_power, tx_power
Markus Liud7850222020-04-14 17:11:12 +08009839
9840def sms_in_collision_send_receive_verify(
9841 log,
9842 ad_rx,
9843 ad_rx2,
9844 ad_tx,
9845 ad_tx2,
9846 array_message,
9847 array_message2,
9848 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
9849 """Send 2 SMS', receive both SMS', and verify content and sender's number of
9850 each SMS.
9851
9852 Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
9853 When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
9854 be tested.
9855 Verify both SMS' are sent, delivered and received.
9856 Verify received content and sender's number of each SMS is correct.
9857
9858 Args:
9859 log: Log object.
9860 ad_tx: Sender's Android Device Object..
9861 ad_rx: Receiver's Android Device Object.
9862 ad_tx2: 2nd sender's Android Device Object..
9863 ad_rx2: 2nd receiver's Android Device Object.
9864 array_message: the array of message to send/receive from ad_tx to ad_rx
9865 array_message2: the array of message to send/receive from ad_tx2 to
9866 ad_rx2
9867 max_wait_time: Max time to wait for reception of SMS
9868 """
9869
9870 rx_sub_id = get_outgoing_message_sub_id(ad_rx)
9871 rx2_sub_id = get_outgoing_message_sub_id(ad_rx2)
9872
9873 _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
9874 [ad_rx, ad_tx, ad_tx2],
9875 host_sub_id=rx_sub_id)
9876 set_subid_for_message(ad_tx, tx_sub_id)
9877
9878 _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
9879 [ad_rx2, ad_tx, ad_tx2],
9880 host_sub_id=rx2_sub_id)
9881 set_subid_for_message(ad_tx2, tx2_sub_id)
9882
9883 if not sms_in_collision_send_receive_verify_for_subscription(
9884 log,
9885 ad_tx,
9886 ad_tx2,
9887 ad_rx,
9888 ad_rx2,
9889 tx_sub_id,
9890 tx2_sub_id,
9891 rx_sub_id,
9892 rx_sub_id,
9893 array_message,
9894 array_message2,
9895 max_wait_time):
9896 log_messaging_screen_shot(
9897 ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
9898 log_messaging_screen_shot(
9899 ad_rx2, test_name="sms rx2 subid: %s" % rx2_sub_id)
9900 log_messaging_screen_shot(
9901 ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
9902 log_messaging_screen_shot(
9903 ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
9904 return False
9905 return True
9906
9907def sms_in_collision_send_receive_verify_for_subscription(
9908 log,
9909 ad_tx,
9910 ad_tx2,
9911 ad_rx,
9912 ad_rx2,
9913 subid_tx,
9914 subid_tx2,
9915 subid_rx,
9916 subid_rx2,
9917 array_message,
9918 array_message2,
9919 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
9920 """Send 2 SMS', receive both SMS', and verify content and sender's number of
9921 each SMS.
9922
9923 Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
9924 When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
9925 be tested.
9926 Verify both SMS' are sent, delivered and received.
9927 Verify received content and sender's number of each SMS is correct.
9928
9929 Args:
9930 log: Log object.
9931 ad_tx: Sender's Android Device Object..
9932 ad_rx: Receiver's Android Device Object.
9933 ad_tx2: 2nd sender's Android Device Object..
9934 ad_rx2: 2nd receiver's Android Device Object.
9935 subid_tx: Sub ID of ad_tx as default Sub ID for outgoing SMS
9936 subid_tx2: Sub ID of ad_tx2 as default Sub ID for outgoing SMS
9937 subid_rx: Sub ID of ad_rx as default Sub ID for incoming SMS
9938 subid_rx2: Sub ID of ad_rx2 as default Sub ID for incoming SMS
9939 array_message: the array of message to send/receive from ad_tx to ad_rx
9940 array_message2: the array of message to send/receive from ad_tx2 to
9941 ad_rx2
9942 max_wait_time: Max time to wait for reception of SMS
9943 """
9944
9945 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
9946 phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
9947 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
9948 phonenumber_rx2 = ad_rx2.telephony['subscription'][subid_rx2]['phone_num']
9949
9950 for ad in (ad_tx, ad_tx2, ad_rx, ad_rx2):
9951 ad.send_keycode("BACK")
9952 if not getattr(ad, "messaging_droid", None):
9953 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
9954 ad.messaging_ed.start()
9955 else:
9956 try:
9957 if not ad.messaging_droid.is_live:
9958 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
9959 ad.messaging_ed.start()
9960 else:
9961 ad.messaging_ed.clear_all_events()
9962 ad.messaging_droid.logI(
9963 "Start sms_send_receive_verify_for_subscription test")
9964 except Exception:
9965 ad.log.info("Create new sl4a session for messaging")
9966 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
9967 ad.messaging_ed.start()
9968
9969 for text, text2 in zip(array_message, array_message2):
9970 length = len(text)
9971 length2 = len(text2)
9972 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
9973 phonenumber_tx, phonenumber_rx, length, text)
9974 ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
9975 phonenumber_tx2, phonenumber_rx2, length2, text2)
9976
9977 try:
9978 ad_rx.messaging_ed.clear_events(EventSmsReceived)
9979 ad_rx2.messaging_ed.clear_events(EventSmsReceived)
9980 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
9981 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
9982 ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
9983 ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
9984 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
9985 if ad_rx2 != ad_rx:
9986 ad_rx2.messaging_droid.smsStartTrackingIncomingSmsMessage()
9987 time.sleep(1)
9988 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
9989 ad_tx2.messaging_droid.logI("Sending SMS of length %s" % length2)
9990 ad_rx.messaging_droid.logI(
9991 "Expecting SMS of length %s from %s" % (length, ad_tx.serial))
9992 ad_rx2.messaging_droid.logI(
9993 "Expecting SMS of length %s from %s" % (length2, ad_tx2.serial))
9994
9995 tasks = [
9996 (ad_tx.messaging_droid.smsSendTextMessage,
9997 (phonenumber_rx, text, True)),
9998 (ad_tx2.messaging_droid.smsSendTextMessage,
9999 (phonenumber_rx2, text2, True))]
10000 multithread_func(log, tasks)
10001 try:
10002 tasks = [
10003 (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10004 EventSmsSentSuccess,
10005 EventSmsSentFailure,
10006 EventSmsDeliverSuccess,
10007 EventSmsDeliverFailure), max_wait_time)),
10008 (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10009 EventSmsSentSuccess,
10010 EventSmsSentFailure,
10011 EventSmsDeliverSuccess,
10012 EventSmsDeliverFailure), max_wait_time))
10013 ]
10014 results = run_multithread_func(log, tasks)
10015 res = True
10016 _ad = ad_tx
10017 for ad, events in [(ad_tx, results[0]),(ad_tx2, results[1])]:
10018 _ad = ad
10019 for event in events:
10020 ad.log.info("Got event %s", event["name"])
10021 if event["name"] == EventSmsSentFailure or \
10022 event["name"] == EventSmsDeliverFailure:
10023 if event.get("data") and event["data"].get("Reason"):
10024 ad.log.error("%s with reason: %s",
10025 event["name"],
10026 event["data"]["Reason"])
10027 res = False
10028 elif event["name"] == EventSmsSentSuccess or \
10029 event["name"] == EventSmsDeliverSuccess:
10030 break
10031 if not res:
10032 return False
10033 except Empty:
10034 _ad.log.error("No %s or %s event for SMS of length %s.",
10035 EventSmsSentSuccess, EventSmsSentFailure,
10036 length)
10037 return False
10038 if ad_rx == ad_rx2:
10039 if not wait_for_matching_mt_sms_in_collision(
10040 log,
10041 ad_rx,
10042 phonenumber_tx,
10043 phonenumber_tx2,
10044 text,
10045 text2,
10046 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10047
10048 ad_rx.log.error(
10049 "No matching received SMS of length %s from %s.",
10050 length,
10051 ad_rx.serial)
10052 return False
10053 else:
10054 if not wait_for_matching_mt_sms_in_collision_with_mo_sms(
10055 log,
10056 ad_rx,
10057 ad_rx2,
10058 phonenumber_tx,
10059 phonenumber_tx2,
10060 text,
10061 text2,
10062 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10063 return False
10064 except Exception as e:
10065 log.error("Exception error %s", e)
10066 raise
10067 finally:
10068 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
10069 ad_rx2.messaging_droid.smsStopTrackingIncomingSmsMessage()
10070 return True
10071
10072
10073def sms_rx_power_off_multiple_send_receive_verify(
10074 log,
10075 ad_rx,
10076 ad_tx,
10077 ad_tx2,
10078 array_message_length,
10079 array_message2_length,
10080 num_array_message,
10081 num_array_message2,
10082 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10083
10084 rx_sub_id = get_outgoing_message_sub_id(ad_rx)
10085
10086 _, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
10087 [ad_rx, ad_tx, ad_tx2],
10088 host_sub_id=rx_sub_id)
10089 set_subid_for_message(ad_tx, tx_sub_id)
10090
10091 _, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
10092 [ad_rx, ad_tx, ad_tx2],
10093 host_sub_id=rx_sub_id)
10094 set_subid_for_message(ad_tx2, tx2_sub_id)
10095
10096 if not sms_rx_power_off_multiple_send_receive_verify_for_subscription(
10097 log,
10098 ad_tx,
10099 ad_tx2,
10100 ad_rx,
10101 tx_sub_id,
10102 tx2_sub_id,
10103 rx_sub_id,
10104 rx_sub_id,
10105 array_message_length,
10106 array_message2_length,
10107 num_array_message,
10108 num_array_message2):
10109 log_messaging_screen_shot(
10110 ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
10111 log_messaging_screen_shot(
10112 ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
10113 log_messaging_screen_shot(
10114 ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
10115 return False
10116 return True
10117
10118
10119def sms_rx_power_off_multiple_send_receive_verify_for_subscription(
10120 log,
10121 ad_tx,
10122 ad_tx2,
10123 ad_rx,
10124 subid_tx,
10125 subid_tx2,
10126 subid_rx,
10127 subid_rx2,
10128 array_message_length,
10129 array_message2_length,
10130 num_array_message,
10131 num_array_message2,
10132 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10133
10134 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
10135 phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
10136 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
10137 phonenumber_rx2 = ad_rx.telephony['subscription'][subid_rx2]['phone_num']
10138
10139 if not toggle_airplane_mode(log, ad_rx, True):
10140 ad_rx.log.error("Failed to enable Airplane Mode")
10141 return False
10142 ad_rx.stop_services()
10143 ad_rx.log.info("Rebooting......")
10144 ad_rx.adb.reboot()
10145
10146 message_dict = {phonenumber_tx: [], phonenumber_tx2: []}
10147 for index in range(max(num_array_message, num_array_message2)):
10148 array_message = [rand_ascii_str(array_message_length)]
10149 array_message2 = [rand_ascii_str(array_message2_length)]
10150 for text, text2 in zip(array_message, array_message2):
10151 message_dict[phonenumber_tx].append(text)
10152 message_dict[phonenumber_tx2].append(text2)
10153 length = len(text)
10154 length2 = len(text2)
10155
10156 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10157 phonenumber_tx, phonenumber_rx, length, text)
10158 ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10159 phonenumber_tx2, phonenumber_rx2, length2, text2)
10160
10161 try:
10162 for ad in (ad_tx, ad_tx2):
10163 ad.send_keycode("BACK")
10164 if not getattr(ad, "messaging_droid", None):
10165 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10166 ad.messaging_ed.start()
10167 else:
10168 try:
10169 if not ad.messaging_droid.is_live:
10170 ad.messaging_droid, ad.messaging_ed = \
10171 ad.get_droid()
10172 ad.messaging_ed.start()
10173 else:
10174 ad.messaging_ed.clear_all_events()
10175 ad.messaging_droid.logI(
10176 "Start sms_send_receive_verify_for_subscription"
10177 " test")
10178 except Exception:
10179 ad.log.info("Create new sl4a session for messaging")
10180 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10181 ad.messaging_ed.start()
10182
10183 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
10184 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
10185 ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
10186 ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
10187
10188 if index < num_array_message and index < num_array_message2:
10189 ad_tx.messaging_droid.logI(
10190 "Sending SMS of length %s" % length)
10191 ad_tx2.messaging_droid.logI(
10192 "Sending SMS of length %s" % length2)
10193 tasks = [
10194 (ad_tx.messaging_droid.smsSendTextMessage,
10195 (phonenumber_rx, text, True)),
10196 (ad_tx2.messaging_droid.smsSendTextMessage,
10197 (phonenumber_rx2, text2, True))]
10198 multithread_func(log, tasks)
10199 else:
10200 if index < num_array_message:
10201 ad_tx.messaging_droid.logI(
10202 "Sending SMS of length %s" % length)
10203 ad_tx.messaging_droid.smsSendTextMessage(
10204 phonenumber_rx, text, True)
10205 if index < num_array_message2:
10206 ad_tx2.messaging_droid.logI(
10207 "Sending SMS of length %s" % length2)
10208 ad_tx2.messaging_droid.smsSendTextMessage(
10209 phonenumber_rx2, text2, True)
10210
10211 try:
10212 if index < num_array_message and index < num_array_message2:
10213 tasks = [
10214 (ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10215 EventSmsSentSuccess,
10216 EventSmsSentFailure,
10217 EventSmsDeliverSuccess,
10218 EventSmsDeliverFailure),
10219 max_wait_time)),
10220 (ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
10221 EventSmsSentSuccess,
10222 EventSmsSentFailure,
10223 EventSmsDeliverSuccess,
10224 EventSmsDeliverFailure),
10225 max_wait_time))
10226 ]
10227 results = run_multithread_func(log, tasks)
10228 res = True
10229 _ad = ad_tx
10230 for ad, events in [
10231 (ad_tx, results[0]), (ad_tx2, results[1])]:
10232 _ad = ad
10233 for event in events:
10234 ad.log.info("Got event %s", event["name"])
10235 if event["name"] == EventSmsSentFailure or \
10236 event["name"] == EventSmsDeliverFailure:
10237 if event.get("data") and \
10238 event["data"].get("Reason"):
10239 ad.log.error("%s with reason: %s",
10240 event["name"],
10241 event["data"]["Reason"])
10242 res = False
10243 elif event["name"] == EventSmsSentSuccess or \
10244 event["name"] == EventSmsDeliverSuccess:
10245 break
10246 if not res:
10247 return False
10248 else:
10249 if index < num_array_message:
10250 result = ad_tx.messaging_ed.pop_events(
10251 "(%s|%s|%s|%s)" % (
10252 EventSmsSentSuccess,
10253 EventSmsSentFailure,
10254 EventSmsDeliverSuccess,
10255 EventSmsDeliverFailure),
10256 max_wait_time)
10257 res = True
10258 _ad = ad_tx
10259 for ad, events in [(ad_tx, result)]:
10260 _ad = ad
10261 for event in events:
10262 ad.log.info("Got event %s", event["name"])
10263 if event["name"] == EventSmsSentFailure or \
10264 event["name"] == EventSmsDeliverFailure:
10265 if event.get("data") and \
10266 event["data"].get("Reason"):
10267 ad.log.error(
10268 "%s with reason: %s",
10269 event["name"],
10270 event["data"]["Reason"])
10271 res = False
10272 elif event["name"] == EventSmsSentSuccess \
10273 or event["name"] == EventSmsDeliverSuccess:
10274 break
10275 if not res:
10276 return False
10277 if index < num_array_message2:
10278 result = ad_tx2.messaging_ed.pop_events(
10279 "(%s|%s|%s|%s)" % (
10280 EventSmsSentSuccess,
10281 EventSmsSentFailure,
10282 EventSmsDeliverSuccess,
10283 EventSmsDeliverFailure),
10284 max_wait_time)
10285 res = True
10286 _ad = ad_tx2
10287 for ad, events in [(ad_tx2, result)]:
10288 _ad = ad
10289 for event in events:
10290 ad.log.info("Got event %s", event["name"])
10291 if event["name"] == EventSmsSentFailure or \
10292 event["name"] == EventSmsDeliverFailure:
10293 if event.get("data") and \
10294 event["data"].get("Reason"):
10295 ad.log.error(
10296 "%s with reason: %s",
10297 event["name"],
10298 event["data"]["Reason"])
10299 res = False
10300 elif event["name"] == EventSmsSentSuccess \
10301 or event["name"] == EventSmsDeliverSuccess:
10302 break
10303 if not res:
10304 return False
10305
10306
10307 except Empty:
10308 _ad.log.error("No %s or %s event for SMS of length %s.",
10309 EventSmsSentSuccess, EventSmsSentFailure,
10310 length)
10311 return False
10312
10313 except Exception as e:
10314 log.error("Exception error %s", e)
10315 raise
10316
10317 ad_rx.wait_for_boot_completion()
10318 ad_rx.root_adb()
10319 ad_rx.start_services(skip_setup_wizard=False)
10320
10321 output = ad_rx.adb.logcat("-t 1")
10322 match = re.search(r"\d+-\d+\s\d+:\d+:\d+.\d+", output)
10323 if match:
10324 ad_rx.test_log_begin_time = match.group(0)
10325
10326 ad_rx.messaging_droid, ad_rx.messaging_ed = ad_rx.get_droid()
10327 ad_rx.messaging_ed.start()
10328 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
10329 time.sleep(1) #sleep 100ms after starting event tracking
10330
10331 if not toggle_airplane_mode(log, ad_rx, False):
10332 ad_rx.log.error("Failed to disable Airplane Mode")
10333 return False
10334
10335 res = True
10336 try:
10337 if not wait_for_matching_multiple_sms(log,
10338 ad_rx,
10339 phonenumber_tx,
10340 phonenumber_tx2,
10341 messages=message_dict,
10342 max_wait_time=max_wait_time):
10343 res = False
10344 except Exception as e:
10345 log.error("Exception error %s", e)
10346 raise
10347 finally:
10348 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
10349
10350 return res
10351
10352def wait_for_matching_mt_sms_in_collision(log,
10353 ad_rx,
10354 phonenumber_tx,
10355 phonenumber_tx2,
10356 text,
10357 text2,
10358 allow_multi_part_long_sms=True,
10359 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10360
10361 if not allow_multi_part_long_sms:
10362 try:
10363 ad_rx.messaging_ed.wait_for_event(
10364 EventSmsReceived,
10365 is_sms_in_collision_match,
10366 max_wait_time,
10367 phonenumber_tx,
10368 phonenumber_tx2,
10369 text,
10370 text2)
10371 ad_rx.log.info("Got event %s", EventSmsReceived)
10372 return True
10373 except Empty:
10374 ad_rx.log.error("No matched SMS received event.")
10375 return False
10376 else:
10377 try:
10378 received_sms = ''
10379 received_sms2 = ''
10380 remaining_text = text
10381 remaining_text2 = text2
10382 while (remaining_text != '' or remaining_text2 != ''):
10383 event = ad_rx.messaging_ed.wait_for_event(
10384 EventSmsReceived,
10385 is_sms_in_collision_partial_match,
10386 max_wait_time,
10387 phonenumber_tx,
10388 phonenumber_tx2,
10389 remaining_text,
10390 remaining_text2)
10391 event_text = event['data']['Text'].split(")")[-1].strip()
10392 event_text_length = len(event_text)
10393
10394 if event_text in remaining_text:
10395 ad_rx.log.info("Got event %s of text length %s from %s",
10396 EventSmsReceived, event_text_length,
10397 phonenumber_tx)
10398 remaining_text = remaining_text[event_text_length:]
10399 received_sms += event_text
10400 elif event_text in remaining_text2:
10401 ad_rx.log.info("Got event %s of text length %s from %s",
10402 EventSmsReceived, event_text_length,
10403 phonenumber_tx2)
10404 remaining_text2 = remaining_text2[event_text_length:]
10405 received_sms2 += event_text
10406
10407 ad_rx.log.info("Received SMS of length %s", len(received_sms))
10408 ad_rx.log.info("Received SMS of length %s", len(received_sms2))
10409 return True
10410 except Empty:
10411 ad_rx.log.error(
10412 "Missing SMS received event.")
10413 if received_sms != '':
10414 ad_rx.log.error(
10415 "Only received partial matched SMS of length %s from %s",
10416 len(received_sms), phonenumber_tx)
10417 if received_sms2 != '':
10418 ad_rx.log.error(
10419 "Only received partial matched SMS of length %s from %s",
10420 len(received_sms2), phonenumber_tx2)
10421 return False
10422
10423def wait_for_matching_mt_sms_in_collision_with_mo_sms(log,
10424 ad_rx,
10425 ad_rx2,
10426 phonenumber_tx,
10427 phonenumber_tx2,
10428 text,
10429 text2,
10430 allow_multi_part_long_sms=True,
10431 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
10432
10433 if not allow_multi_part_long_sms:
10434 result = True
10435 try:
10436 ad_rx.messaging_ed.wait_for_call_offhook_event(
10437 EventSmsReceived,
10438 is_sms_match,
10439 max_wait_time,
10440 phonenumber_tx,
10441 text)
10442 ad_rx.log.info("Got event %s", EventSmsReceived)
10443 except Empty:
10444 ad_rx.log.error("No matched SMS received event.")
10445 result = False
10446
10447 try:
10448 ad_rx2.messaging_ed.wait_for_call_offhook_event(
10449 EventSmsReceived,
10450 is_sms_match,
10451 max_wait_time,
10452 phonenumber_tx2,
10453 text2)
10454 ad_rx2.log.info("Got event %s", EventSmsReceived)
10455 except Empty:
10456 ad_rx2.log.error("No matched SMS received event.")
10457 result = False
10458
10459 return result
10460 else:
10461 result = True
10462 try:
10463 received_sms = ''
10464 remaining_text = text
10465 while remaining_text != '':
10466 event = ad_rx.messaging_ed.wait_for_event(
10467 EventSmsReceived, is_sms_partial_match, max_wait_time,
10468 phonenumber_tx, remaining_text)
10469 event_text = event['data']['Text'].split(")")[-1].strip()
10470 event_text_length = len(event_text)
10471
10472 if event_text in remaining_text:
10473 ad_rx.log.info("Got event %s of text length %s from %s",
10474 EventSmsReceived, event_text_length,
10475 phonenumber_tx)
10476 remaining_text = remaining_text[event_text_length:]
10477 received_sms += event_text
10478
10479 ad_rx.log.info("Received SMS of length %s", len(received_sms))
10480 except Empty:
10481 ad_rx.log.error(
10482 "Missing SMS received event.")
10483 if received_sms != '':
10484 ad_rx.log.error(
10485 "Only received partial matched SMS of length %s from %s",
10486 len(received_sms), phonenumber_tx)
10487 result = False
10488
10489 try:
10490 received_sms2 = ''
10491 remaining_text2 = text2
10492 while remaining_text2 != '':
10493 event2 = ad_rx2.messaging_ed.wait_for_event(
10494 EventSmsReceived, is_sms_partial_match, max_wait_time,
10495 phonenumber_tx2, remaining_text2)
10496 event_text2 = event2['data']['Text'].split(")")[-1].strip()
10497 event_text_length2 = len(event_text2)
10498
10499 if event_text2 in remaining_text2:
10500 ad_rx2.log.info("Got event %s of text length %s from %s",
10501 EventSmsReceived, event_text_length2,
10502 phonenumber_tx2)
10503 remaining_text2 = remaining_text2[event_text_length2:]
10504 received_sms2 += event_text2
10505
10506 ad_rx2.log.info("Received SMS of length %s", len(received_sms2))
10507 except Empty:
10508 ad_rx2.log.error(
10509 "Missing SMS received event.")
10510 if received_sms2 != '':
10511 ad_rx2.log.error(
10512 "Only received partial matched SMS of length %s from %s",
10513 len(received_sms2), phonenumber_tx2)
10514 result = False
10515
10516 return result
10517
10518def wait_for_matching_multiple_sms(log,
10519 ad_rx,
10520 phonenumber_tx,
10521 phonenumber_tx2,
10522 messages={},
10523 allow_multi_part_long_sms=True,
10524 max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
10525
10526 if not allow_multi_part_long_sms:
10527 try:
10528 ad_rx.messaging_ed.wait_for_event(
10529 EventSmsReceived,
10530 is_sms_match_among_multiple_sms,
10531 max_wait_time,
10532 phonenumber_tx,
10533 phonenumber_tx2,
10534 messages[phonenumber_tx],
10535 messages[phonenumber_tx2])
10536 ad_rx.log.info("Got event %s", EventSmsReceived)
10537 return True
10538 except Empty:
10539 ad_rx.log.error("No matched SMS received event.")
10540 return False
10541 else:
10542 all_msgs = []
10543 for tx, msgs in messages.items():
10544 for msg in msgs:
10545 all_msgs.append([tx, msg, msg, ''])
10546
10547 all_msgs_copy = all_msgs.copy()
10548
10549 try:
10550 while (all_msgs != []):
10551 event = ad_rx.messaging_ed.wait_for_event(
10552 EventSmsReceived,
10553 is_sms_partial_match_among_multiple_sms,
10554 max_wait_time,
10555 phonenumber_tx,
10556 phonenumber_tx2,
10557 messages[phonenumber_tx],
10558 messages[phonenumber_tx2])
10559 event_text = event['data']['Text'].split(")")[-1].strip()
10560 event_text_length = len(event_text)
10561
10562 for msg in all_msgs_copy:
10563 if event_text in msg[2]:
10564 ad_rx.log.info("Got event %s of text length %s from %s",
10565 EventSmsReceived, event_text_length,
10566 msg[0])
10567 msg[2] = msg[2][event_text_length:]
10568 msg[3] += event_text
10569
10570 if msg[2] == "":
10571 all_msgs.remove(msg)
10572
10573 ad_rx.log.info("Received all SMS' sent when power-off.")
10574 except Empty:
10575 ad_rx.log.error(
10576 "Missing SMS received event.")
10577
10578 for msg in all_msgs_copy:
10579 if msg[3] != '':
10580 ad_rx.log.error(
10581 "Only received partial matched SMS of length %s from %s",
10582 len(msg[3]), msg[0])
10583 return False
10584
10585 return True
10586
Markus Liu6b41e092020-08-17 15:55:28 +080010587def is_sms_in_collision_match(
10588 event, phonenumber_tx, phonenumber_tx2, text, text2):
Markus Liud7850222020-04-14 17:11:12 +080010589 event_text = event['data']['Text'].strip()
10590 if event_text.startswith("("):
10591 event_text = event_text.split(")")[-1]
10592
10593 for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
Markus Liu6b41e092020-08-17 15:55:28 +080010594 if check_phone_number_match(
10595 event['data']['Sender'], phonenumber) and txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010596 return True
10597 return False
10598
Markus Liu6b41e092020-08-17 15:55:28 +080010599def is_sms_in_collision_partial_match(
10600 event, phonenumber_tx, phonenumber_tx2, text, text2):
Markus Liud7850222020-04-14 17:11:12 +080010601 for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
Markus Liu6b41e092020-08-17 15:55:28 +080010602 if check_phone_number_match(
10603 event['data']['Sender'], phonenumber) and \
10604 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010605 return True
10606 return False
10607
Markus Liu6b41e092020-08-17 15:55:28 +080010608def is_sms_match_among_multiple_sms(
10609 event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
Markus Liud7850222020-04-14 17:11:12 +080010610 for txt in texts:
Markus Liu6b41e092020-08-17 15:55:28 +080010611 if check_phone_number_match(
10612 event['data']['Sender'], phonenumber_tx) and \
10613 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010614 return True
10615
10616 for txt in texts2:
Markus Liu6b41e092020-08-17 15:55:28 +080010617 if check_phone_number_match(
10618 event['data']['Sender'], phonenumber_tx2) and \
10619 event['data']['Text'].strip() == txt:
Markus Liud7850222020-04-14 17:11:12 +080010620 return True
10621
10622 return False
10623
Markus Liu6b41e092020-08-17 15:55:28 +080010624def is_sms_partial_match_among_multiple_sms(
10625 event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
Markus Liud7850222020-04-14 17:11:12 +080010626 event_text = event['data']['Text'].strip()
10627 if event_text.startswith("("):
10628 event_text = event_text.split(")")[-1]
10629
10630 for txt in texts:
Markus Liu6b41e092020-08-17 15:55:28 +080010631 if check_phone_number_match(
10632 event['data']['Sender'], phonenumber_tx) and \
10633 txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010634 return True
10635
10636 for txt in texts2:
Markus Liu6b41e092020-08-17 15:55:28 +080010637 if check_phone_number_match(
10638 event['data']['Sender'], phonenumber_tx2) and \
10639 txt.startswith(event_text):
Markus Liud7850222020-04-14 17:11:12 +080010640 return True
10641
Jaineel08466192020-07-13 17:09:03 -070010642 return False
davinkao439e38e2020-07-29 11:34:43 +080010643
10644def set_time_sync_from_network(ad, action):
10645 if (action == 'enable'):
10646 ad.log.info('Enabling sync time from network.')
10647 ad.adb.shell('settings put global auto_time 1')
10648
10649 elif (action == 'disable'):
10650 ad.log.info('Disabling sync time from network.')
10651 ad.adb.shell('settings put global auto_time 0')
10652
10653 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK)
10654
10655def datetime_handle(ad, action, set_datetime_value='', get_year=False):
10656 get_value = ''
10657 if (action == 'get'):
10658 if (get_year):
10659 datetime_string = ad.adb.shell('date')
10660 datetime_list = datetime_string.split()
10661 try:
10662 get_value = datetime_list[5]
10663 except Exception as e:
10664 self.log.error("Fail to get year from datetime: %s. " \
10665 "Exception error: %s", datetime_list
10666 , str(e))
10667 raise signals.TestSkip("Fail to get year from datetime" \
10668 ", the format is changed. Skip the test.")
10669 else:
10670 get_value = ad.adb.shell('date')
10671
10672 elif (action == 'set'):
10673 ad.adb.shell('date %s' % set_datetime_value)
10674 time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK)
10675 ad.adb.shell('am broadcast -a android.intent.action.TIME_SET')
10676
10677 return get_value
Markus Liu6b41e092020-08-17 15:55:28 +080010678
Markus Liucb900da2020-08-17 16:12:31 +080010679def wait_for_sending_sms(ad_tx, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
10680 try:
10681 events = ad_tx.messaging_ed.pop_events(
10682 "(%s|%s|%s|%s)" %
10683 (EventSmsSentSuccess, EventSmsSentFailure,
10684 EventSmsDeliverSuccess,
10685 EventSmsDeliverFailure), max_wait_time)
10686 for event in events:
10687 ad_tx.log.info("Got event %s", event["name"])
10688 if event["name"] == EventSmsSentFailure or \
10689 event["name"] == EventSmsDeliverFailure:
10690 if event.get("data") and event["data"].get("Reason"):
10691 ad_tx.log.error("%s with reason: %s",
10692 event["name"],
10693 event["data"]["Reason"])
10694 return False
10695 elif event["name"] == EventSmsSentSuccess or \
10696 event["name"] == EventSmsDeliverSuccess:
10697 return True
10698 except Empty:
10699 ad_tx.log.error("No %s or %s event for SMS.",
10700 EventSmsSentSuccess, EventSmsSentFailure)
10701 return False
10702
10703def wait_for_call_end(
10704 log,
10705 ad_caller,
10706 ad_callee,
10707 ad_hangup,
10708 verify_caller_func,
10709 verify_callee_func,
10710 check_interval=5,
10711 tel_result_wrapper=TelResultWrapper(CallResult('SUCCESS')),
10712 wait_time_in_call=WAIT_TIME_IN_CALL):
10713 elapsed_time = 0
10714 while (elapsed_time < wait_time_in_call):
10715 check_interval = min(check_interval, wait_time_in_call - elapsed_time)
10716 time.sleep(check_interval)
10717 elapsed_time += check_interval
10718 time_message = "at <%s>/<%s> second." % (elapsed_time, wait_time_in_call)
10719 for ad, call_func in [(ad_caller, verify_caller_func),
10720 (ad_callee, verify_callee_func)]:
10721 if not call_func(log, ad):
10722 ad.log.error(
10723 "NOT in correct %s state at %s, voice in RAT %s",
10724 call_func.__name__,
10725 time_message,
10726 ad.droid.telephonyGetCurrentVoiceNetworkType())
10727 tel_result_wrapper.result_value = CallResult(
10728 'CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED')
10729 else:
10730 ad.log.info("In correct %s state at %s",
10731 call_func.__name__, time_message)
10732 if not ad.droid.telecomCallGetAudioState():
10733 ad.log.error("Audio is not in call state at %s", time_message)
10734 tel_result_wrapper.result_value = CallResult(
10735 'AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED')
10736 if not tel_result_wrapper:
10737 return tel_result_wrapper
10738
10739 if ad_hangup:
10740 if not hangup_call(log, ad_hangup):
10741 ad_hangup.log.info("Failed to hang up the call")
10742 tel_result_wrapper.result_value = CallResult('CALL_HANGUP_FAIL')
10743
10744 if not tel_result_wrapper:
10745 for ad in (ad_caller, ad_callee):
10746 last_call_drop_reason(ad, begin_time)
10747 try:
10748 if ad.droid.telecomIsInCall():
10749 ad.log.info("In call. End now.")
10750 ad.droid.telecomEndCall()
10751 except Exception as e:
10752 log.error(str(e))
10753 if ad_hangup or not tel_result_wrapper:
10754 for ad in (ad_caller, ad_callee):
10755 if not wait_for_call_id_clearing(ad, getattr(ad, "caller_ids", [])):
10756 tel_result_wrapper.result_value = CallResult(
10757 'CALL_ID_CLEANUP_FAIL')
10758
10759 return tel_result_wrapper
10760
10761def voice_call_in_collision_with_mt_sms_msim(
10762 log,
10763 ad_primary,
10764 ad_sms,
10765 ad_voice,
10766 sms_subid_ad_primary,
10767 sms_subid_ad_sms,
10768 voice_subid_ad_primary,
10769 voice_subid_ad_voice,
10770 array_message,
10771 ad_hangup=None,
10772 verify_caller_func=None,
10773 verify_callee_func=None,
10774 call_direction="mo",
10775 wait_time_in_call=WAIT_TIME_IN_CALL,
10776 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
10777 dialing_number_length=None,
10778 video_state=None):
10779
10780 ad_tx = ad_sms
10781 ad_rx = ad_primary
10782 subid_tx = sms_subid_ad_sms
10783 subid_rx = sms_subid_ad_primary
10784
10785 if call_direction == "mo":
10786 ad_caller = ad_primary
10787 ad_callee = ad_voice
10788 subid_caller = voice_subid_ad_primary
10789 subid_callee = voice_subid_ad_voice
10790 elif call_direction == "mt":
10791 ad_callee = ad_primary
10792 ad_caller = ad_voice
10793 subid_callee = voice_subid_ad_primary
10794 subid_caller = voice_subid_ad_voice
10795
10796
10797 phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
10798 phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
10799
10800 tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
10801
10802 for ad in (ad_tx, ad_rx):
10803 ad.send_keycode("BACK")
10804 if not getattr(ad, "messaging_droid", None):
10805 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10806 ad.messaging_ed.start()
10807 else:
10808 try:
10809 if not ad.messaging_droid.is_live:
10810 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10811 ad.messaging_ed.start()
10812 else:
10813 ad.messaging_ed.clear_all_events()
10814 except Exception:
10815 ad.log.info("Create new sl4a session for messaging")
10816 ad.messaging_droid, ad.messaging_ed = ad.get_droid()
10817 ad.messaging_ed.start()
10818
10819 begin_time = get_current_epoch_time()
10820 if not verify_caller_func:
10821 verify_caller_func = is_phone_in_call
10822 if not verify_callee_func:
10823 verify_callee_func = is_phone_in_call
10824
10825 caller_number = ad_caller.telephony['subscription'][subid_caller][
10826 'phone_num']
10827 callee_number = ad_callee.telephony['subscription'][subid_callee][
10828 'phone_num']
10829 if dialing_number_length:
10830 skip_test = False
10831 trunc_position = 0 - int(dialing_number_length)
10832 try:
10833 caller_area_code = caller_number[:trunc_position]
10834 callee_area_code = callee_number[:trunc_position]
10835 callee_dial_number = callee_number[trunc_position:]
10836 except:
10837 skip_test = True
10838 if caller_area_code != callee_area_code:
10839 skip_test = True
10840 if skip_test:
10841 msg = "Cannot make call from %s to %s by %s digits" % (
10842 caller_number, callee_number, dialing_number_length)
10843 ad_caller.log.info(msg)
10844 raise signals.TestSkip(msg)
10845 else:
10846 callee_number = callee_dial_number
10847
10848 msg = "Call from %s to %s" % (caller_number, callee_number)
10849 if video_state:
10850 msg = "Video %s" % msg
10851 video = True
10852 else:
10853 video = False
10854 if ad_hangup:
10855 msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
10856 ad_caller.log.info(msg)
10857
10858 for ad in (ad_caller, ad_callee):
10859 call_ids = ad.droid.telecomCallGetCallIds()
10860 setattr(ad, "call_ids", call_ids)
10861 if call_ids:
10862 ad.log.info("Pre-exist CallId %s before making call", call_ids)
10863
10864 ad_caller.ed.clear_events(EventCallStateChanged)
10865 begin_time = get_device_epoch_time(ad)
10866 ad_caller.droid.telephonyStartTrackingCallStateForSubscription(subid_caller)
10867
10868 for text in array_message:
10869 length = len(text)
10870 ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
10871 phonenumber_tx, phonenumber_rx, length, text)
10872 try:
10873 ad_rx.messaging_ed.clear_events(EventSmsReceived)
10874 ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
10875 ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
10876 ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
10877 time.sleep(1) #sleep 100ms after starting event tracking
10878 ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
10879 ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
10880 ad_caller.log.info("Make a phone call to %s", callee_number)
10881
10882 tasks = [
10883 (ad_tx.messaging_droid.smsSendTextMessage,
10884 (phonenumber_rx, text, True)),
10885 (ad_caller.droid.telecomCallNumber,
10886 (callee_number, video))]
10887
10888 run_multithread_func(log, tasks)
10889
10890 try:
10891 # Verify OFFHOOK state
10892 if not wait_for_call_offhook_for_subscription(
10893 log,
10894 ad_caller,
10895 subid_caller,
10896 event_tracking_started=True):
10897 ad_caller.log.info(
10898 "sub_id %s not in call offhook state", subid_caller)
10899 last_call_drop_reason(ad_caller, begin_time=begin_time)
10900
10901 ad_caller.log.error("Initiate call failed.")
10902 tel_result_wrapper.result_value = CallResult(
10903 'INITIATE_FAILED')
10904 return tel_result_wrapper
10905 else:
10906 ad_caller.log.info("Caller initate call successfully")
10907 finally:
10908 ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription(
10909 subid_caller)
10910 if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
10911 ad_caller.droid.telecomShowInCallScreen()
10912 elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
10913 ad_caller.droid.showHomeScreen()
10914
10915 if not wait_and_answer_call_for_subscription(
10916 log,
10917 ad_callee,
10918 subid_callee,
10919 incoming_number=caller_number,
10920 caller=ad_caller,
10921 incall_ui_display=incall_ui_display,
10922 video_state=video_state):
10923 ad_callee.log.error("Answer call fail.")
10924 tel_result_wrapper.result_value = CallResult(
10925 'NO_RING_EVENT_OR_ANSWER_FAILED')
10926 return tel_result_wrapper
10927 else:
10928 ad_callee.log.info("Callee answered the call successfully")
10929
10930 for ad, call_func in zip([ad_caller, ad_callee],
10931 [verify_caller_func, verify_callee_func]):
10932 call_ids = ad.droid.telecomCallGetCallIds()
10933 new_call_ids = set(call_ids) - set(ad.call_ids)
10934 if not new_call_ids:
10935 ad.log.error(
10936 "No new call ids are found after call establishment")
10937 ad.log.error("telecomCallGetCallIds returns %s",
10938 ad.droid.telecomCallGetCallIds())
10939 tel_result_wrapper.result_value = CallResult(
10940 'NO_CALL_ID_FOUND')
10941 for new_call_id in new_call_ids:
10942 if not wait_for_in_call_active(ad, call_id=new_call_id):
10943 tel_result_wrapper.result_value = CallResult(
10944 'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
10945 else:
10946 ad.log.info(
10947 "callProperties = %s",
10948 ad.droid.telecomCallGetProperties(new_call_id))
10949
10950 if not ad.droid.telecomCallGetAudioState():
10951 ad.log.error("Audio is not in call state")
10952 tel_result_wrapper.result_value = CallResult(
10953 'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
10954
10955 if call_func(log, ad):
10956 ad.log.info("Call is in %s state", call_func.__name__)
10957 else:
10958 ad.log.error("Call is not in %s state, voice in RAT %s",
10959 call_func.__name__,
10960 ad.droid.telephonyGetCurrentVoiceNetworkType())
10961 tel_result_wrapper.result_value = CallResult(
10962 'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
10963 if not tel_result_wrapper:
10964 return tel_result_wrapper
10965
10966 if not wait_for_sending_sms(
10967 ad_tx,
10968 max_wait_time=MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION):
10969 return False
10970
10971 tasks = [
10972 (wait_for_matching_sms,
10973 (log, ad_rx, phonenumber_tx, text,
10974 MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION, True)),
10975 (wait_for_call_end,
10976 (log, ad_caller, ad_callee, ad_hangup, verify_caller_func,
10977 verify_callee_func, 5, tel_result_wrapper,
10978 WAIT_TIME_IN_CALL))]
10979
10980 results = run_multithread_func(log, tasks)
10981
10982 if not results[0]:
10983 ad_rx.log.error("No matching received SMS of length %s.",
10984 length)
10985 return False
10986
10987 tel_result_wrapper = results[1]
10988
10989 except Exception as e:
10990 log.error("Exception error %s", e)
10991 raise
10992 finally:
10993 ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
10994
10995 return tel_result_wrapper
10996
Markus Liu6b41e092020-08-17 15:55:28 +080010997def change_voice_subid_temporarily(ad, sub_id, state_check_func):
10998 result = False
10999 voice_sub_id_changed = False
11000 current_sub_id = get_incoming_voice_sub_id(ad)
11001 if current_sub_id != sub_id:
11002 set_incoming_voice_sub_id(ad, sub_id)
11003 voice_sub_id_changed = True
11004
11005 if state_check_func():
11006 result = True
11007
11008 if voice_sub_id_changed:
11009 set_incoming_voice_sub_id(ad, current_sub_id)
11010
Jaineelcb217b62020-11-03 14:33:40 -080011011 return result