blob: 92e9e76436cb5008757fc83aed56fb7c8006002b [file] [log] [blame]
jasonkmluff0d5b92019-03-21 11:24:45 +08001#!/usr/bin/env python3.5
2#
3# Copyright 2019 - Google
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import time
18import re
19import os
jasonkmlu903ece82019-05-16 14:56:19 +080020import math
jasonkmlu903ece82019-05-16 14:56:19 +080021import shutil
jasonkmlu4fcdcad2019-07-10 14:35:12 +080022import fnmatch
23import posixpath
jasonkmlu8cc1c1e2020-01-06 17:18:27 +080024from collections import namedtuple
jasonkmluff0d5b92019-03-21 11:24:45 +080025
26from acts import utils
27from acts import signals
28from acts.controllers.android_device import list_adb_devices
29from acts.controllers.android_device import list_fastboot_devices
30from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH
31from acts.controllers.android_device import SL4A_APK_NAME
32from acts.test_utils.wifi import wifi_test_utils as wutils
33from acts.test_utils.tel import tel_test_utils as tutils
34from acts.utils import get_current_epoch_time
35
36WifiEnums = wutils.WifiEnums
37PULL_TIMEOUT = 300
jasonkmlu66fda532019-07-16 11:12:45 +080038GNSSSTATUS_LOG_PATH = (
39 "/storage/emulated/0/Android/data/com.android.gpstool/files/")
jasonkmlu214f0d62019-04-08 19:53:59 +080040QXDM_MASKS = ["GPS.cfg", "GPS-general.cfg", "default.cfg"]
jasonkmlu8cc1c1e2020-01-06 17:18:27 +080041TTFF_REPORT = namedtuple("TTFF_REPORT", "ttff_loop ttff_sec ttff_pe ttff_cn")
42TRACK_REPORT = namedtuple(
jasonkmlu4fcdcad2019-07-10 14:35:12 +080043 "TRACK_REPORT", "track_l5flag track_pe track_top4cn track_cn")
jasonkmlu38bd4d12019-10-04 16:38:48 +080044LOCAL_PROP_FILE_CONTENTS = """\
45log.tag.LocationManagerService=VERBOSE
46log.tag.GnssLocationProvider=VERBOSE
47log.tag.GnssMeasurementsProvider=VERBOSE
48log.tag.GpsNetInitiatedHandler=VERBOSE
49log.tag.GnssNetworkConnectivityHandler=VERBOSE
50log.tag.ConnectivityService=VERBOSE
51log.tag.ConnectivityManager=VERBOSE
52log.tag.GnssVisibilityControl=VERBOSE"""
jasonkmluff0d5b92019-03-21 11:24:45 +080053
54
55class GnssTestUtilsError(Exception):
56 pass
57
jasonkmlu0f546de2019-12-13 20:58:41 +080058
jasonkmluff0d5b92019-03-21 11:24:45 +080059def remount_device(ad):
60 """Remount device file system to read and write.
61
62 Args:
63 ad: An AndroidDevice object.
64 """
jasonkmlu81b8b032019-06-21 15:18:27 +080065 for retries in range(5):
jasonkmluff0d5b92019-03-21 11:24:45 +080066 ad.root_adb()
Scott Hong7f3945f2020-02-20 18:04:56 +080067 if ad.adb.getprop("ro.boot.veritymode") == "enforcing":
68 disable_verity_result = ad.adb.disable_verity()
69 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +080070 remount_result = ad.adb.remount()
71 ad.log.info("Attempt %d - %s" % (retries + 1, remount_result))
jasonkmlu81b8b032019-06-21 15:18:27 +080072 if "remount succeeded" in remount_result:
jasonkmluff0d5b92019-03-21 11:24:45 +080073 break
jasonkmlu214f0d62019-04-08 19:53:59 +080074
jasonkmlu0f546de2019-12-13 20:58:41 +080075
jasonkmlu214f0d62019-04-08 19:53:59 +080076def reboot(ad):
77 """Reboot device and check if mobile data is available.
78
79 Args:
80 ad: An AndroidDevice object.
81 """
82 ad.log.info("Reboot device to make changes take effect.")
83 ad.reboot()
84 ad.unlock_screen(password=None)
85 if not int(ad.adb.shell("settings get global mobile_data")) == 1:
86 set_mobile_data(ad, True)
jasonkmlu49c32812019-04-12 18:11:10 +080087 utils.sync_device_time(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +080088
jasonkmlu0f546de2019-12-13 20:58:41 +080089
jasonkmluff0d5b92019-03-21 11:24:45 +080090def enable_gnss_verbose_logging(ad):
jasonkmlu81b8b032019-06-21 15:18:27 +080091 """Enable GNSS VERBOSE Logging and persistent logcat.
jasonkmluff0d5b92019-03-21 11:24:45 +080092
93 Args:
94 ad: An AndroidDevice object.
95 """
96 remount_device(ad)
jasonkmlu97ac56e2019-05-29 15:04:51 +080097 ad.log.info("Enable GNSS VERBOSE Logging and persistent logcat.")
jasonkmluff0d5b92019-03-21 11:24:45 +080098 ad.adb.shell("echo DEBUG_LEVEL = 5 >> /vendor/etc/gps.conf")
jasonkmlu38bd4d12019-10-04 16:38:48 +080099 ad.adb.shell("echo %r >> /data/local.prop" % LOCAL_PROP_FILE_CONTENTS)
jasonkmluff0d5b92019-03-21 11:24:45 +0800100 ad.adb.shell("chmod 644 /data/local.prop")
jasonkmluc1ec3052019-10-25 14:57:53 +0800101 ad.adb.shell("setprop persist.logd.logpersistd.size 20000")
jasonkmlu180a08c2019-04-23 17:24:55 +0800102 ad.adb.shell("setprop persist.logd.size 16777216")
jasonkmluff0d5b92019-03-21 11:24:45 +0800103 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1")
jasonkmlu81b8b032019-06-21 15:18:27 +0800104 ad.adb.shell("setprop persist.logd.logpersistd logcatd")
jasonkmluff0d5b92019-03-21 11:24:45 +0800105 ad.adb.shell("setprop log.tag.copresGcore VERBOSE")
106 ad.adb.shell("sync")
107
jasonkmlu0f546de2019-12-13 20:58:41 +0800108
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800109def get_am_flags(value):
110 """Returns the (value, type) flags for a given python value."""
111 if type(value) is bool:
112 return str(value).lower(), 'boolean'
113 elif type(value) is str:
114 return value, 'string'
115 raise ValueError("%s should be either 'boolean' or 'string'" % value)
116
117
jasonkmlu81b8b032019-06-21 15:18:27 +0800118def enable_compact_and_particle_fusion_log(ad):
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800119 """Enable CompactLog, FLP particle fusion log and disable gms
120 location-based quake monitoring.
jasonkmlu81b8b032019-06-21 15:18:27 +0800121
122 Args:
123 ad: An AndroidDevice object.
124 """
125 ad.root_adb()
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800126 ad.log.info("Enable FLP flags and Disable GMS location-based quake "
127 "monitoring.")
128 overrides = {
129 'compact_log_enabled': True,
130 'flp_use_particle_fusion': True,
131 'flp_particle_fusion_extended_bug_report': True,
132 'flp_event_log_size': '86400',
133 'proks_config': '28',
134 'flp_particle_fusion_bug_report_window_sec': '86400',
135 'flp_particle_fusion_bug_report_max_buffer_size': '86400',
136 'seismic_data_collection': False,
137 'Ealert__enable': False,
138 }
139 for flag, python_value in overrides.items():
140 value, type = get_am_flags(python_value)
141 cmd = ("am broadcast -a com.google.android.gms.phenotype.FLAG_OVERRIDE "
142 "--es package com.google.android.location --es user \* "
143 "--esa flags %s --esa values %s --esa types %s "
144 "com.google.android.gms" % (flag, value, type))
145 ad.adb.shell(cmd)
jasonkmlu81b8b032019-06-21 15:18:27 +0800146 ad.adb.shell("am force-stop com.google.android.gms")
147 ad.adb.shell("am broadcast -a com.google.android.gms.INITIALIZE")
jasonkmlu81b8b032019-06-21 15:18:27 +0800148
jasonkmlu0f546de2019-12-13 20:58:41 +0800149
jasonkmluff0d5b92019-03-21 11:24:45 +0800150def disable_xtra_throttle(ad):
151 """Disable XTRA throttle will have no limit to download XTRA data.
152
153 Args:
154 ad: An AndroidDevice object.
155 """
156 remount_device(ad)
157 ad.log.info("Disable XTRA Throttle.")
158 ad.adb.shell("echo XTRA_TEST_ENABLED=1 >> /vendor/etc/gps.conf")
159 ad.adb.shell("echo XTRA_THROTTLE_ENABLED=0 >> /vendor/etc/gps.conf")
160
jasonkmlu0f546de2019-12-13 20:58:41 +0800161
jasonkmluff0d5b92019-03-21 11:24:45 +0800162def enable_supl_mode(ad):
163 """Enable SUPL back on for next test item.
164
165 Args:
166 ad: An AndroidDevice object.
167 """
168 remount_device(ad)
169 ad.log.info("Enable SUPL mode.")
170 ad.adb.shell("echo SUPL_MODE=1 >> /etc/gps_debug.conf")
171
jasonkmlu0f546de2019-12-13 20:58:41 +0800172
jasonkmluff0d5b92019-03-21 11:24:45 +0800173def disable_supl_mode(ad):
174 """Kill SUPL to test XTRA only test item.
175
176 Args:
177 ad: An AndroidDevice object.
178 """
179 remount_device(ad)
180 ad.log.info("Disable SUPL mode.")
181 ad.adb.shell("echo SUPL_MODE=0 >> /etc/gps_debug.conf")
jasonkmlu214f0d62019-04-08 19:53:59 +0800182 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800183
jasonkmlu0f546de2019-12-13 20:58:41 +0800184
jasonkmluff0d5b92019-03-21 11:24:45 +0800185def kill_xtra_daemon(ad):
186 """Kill XTRA daemon to test SUPL only test item.
187
188 Args:
189 ad: An AndroidDevice object.
190 """
191 ad.root_adb()
192 ad.log.info("Disable XTRA-daemon until next reboot.")
193 ad.adb.shell("killall xtra-daemon")
194
jasonkmlu0f546de2019-12-13 20:58:41 +0800195
jasonkmluff0d5b92019-03-21 11:24:45 +0800196def disable_private_dns_mode(ad):
197 """Due to b/118365122, it's better to disable private DNS mode while
198 testing. 8.8.8.8 private dns sever is unstable now, sometimes server
199 will not response dns query suddenly.
200
201 Args:
202 ad: An AndroidDevice object.
203 """
204 tutils.get_operator_name(ad.log, ad, subId=None)
205 if ad.adb.shell("settings get global private_dns_mode") != "off":
206 ad.log.info("Disable Private DNS mode.")
207 ad.adb.shell("settings put global private_dns_mode off")
208
jasonkmlu0f546de2019-12-13 20:58:41 +0800209
jasonkmluff0d5b92019-03-21 11:24:45 +0800210def _init_device(ad):
211 """Init GNSS test devices.
212
213 Args:
214 ad: An AndroidDevice object.
215 """
216 enable_gnss_verbose_logging(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800217 enable_compact_and_particle_fusion_log(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800218 disable_xtra_throttle(ad)
219 enable_supl_mode(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800220 ad.adb.shell("settings put system screen_off_timeout 1800000")
221 wutils.wifi_toggle_state(ad, False)
222 ad.log.info("Setting Bluetooth state to False")
223 ad.droid.bluetoothToggleState(False)
jasonkmluff0d5b92019-03-21 11:24:45 +0800224 set_gnss_qxdm_mask(ad, QXDM_MASKS)
jasonkmluff0d5b92019-03-21 11:24:45 +0800225 check_location_service(ad)
226 set_wifi_and_bt_scanning(ad, True)
jasonkmlu214f0d62019-04-08 19:53:59 +0800227 disable_private_dns_mode(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800228 init_gtw_gpstool(ad)
jasonkmlu180a08c2019-04-23 17:24:55 +0800229 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800230
jasonkmlu0f546de2019-12-13 20:58:41 +0800231
jasonkmluff0d5b92019-03-21 11:24:45 +0800232def connect_to_wifi_network(ad, network):
233 """Connection logic for open and psk wifi networks.
234
235 Args:
236 ad: An AndroidDevice object.
237 network: Dictionary with network info.
238 """
239 SSID = network[WifiEnums.SSID_KEY]
jasonkmlub663d3e2019-12-30 15:11:07 +0800240 ad.ed.clear_all_events()
241 wutils.reset_wifi(ad)
242 wutils.start_wifi_connection_scan_and_ensure_network_found(ad, SSID)
jasonkmluff0d5b92019-03-21 11:24:45 +0800243 wutils.wifi_connect(ad, network, num_of_tries=5)
244
jasonkmlu0f546de2019-12-13 20:58:41 +0800245
jasonkmluff0d5b92019-03-21 11:24:45 +0800246def set_wifi_and_bt_scanning(ad, state=True):
247 """Set Wi-Fi and Bluetooth scanning on/off in Settings -> Location
248
249 Args:
250 ad: An AndroidDevice object.
jasonkmlu81b8b032019-06-21 15:18:27 +0800251 state: True to turn on "Wi-Fi and Bluetooth scanning".
252 False to turn off "Wi-Fi and Bluetooth scanning".
jasonkmluff0d5b92019-03-21 11:24:45 +0800253 """
254 ad.root_adb()
255 if state:
256 ad.adb.shell("settings put global wifi_scan_always_enabled 1")
257 ad.adb.shell("settings put global ble_scan_always_enabled 1")
258 ad.log.info("Wi-Fi and Bluetooth scanning are enabled")
259 else:
260 ad.adb.shell("settings put global wifi_scan_always_enabled 0")
261 ad.adb.shell("settings put global ble_scan_always_enabled 0")
262 ad.log.info("Wi-Fi and Bluetooth scanning are disabled")
263
jasonkmlu0f546de2019-12-13 20:58:41 +0800264
jasonkmluff0d5b92019-03-21 11:24:45 +0800265def check_location_service(ad):
266 """Set location service on.
267 Verify if location service is available.
268
269 Args:
270 ad: An AndroidDevice object.
jasonkmluff0d5b92019-03-21 11:24:45 +0800271 """
jasonkmlu81b8b032019-06-21 15:18:27 +0800272 remount_device(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800273 utils.set_location_service(ad, True)
jasonkmlu81b8b032019-06-21 15:18:27 +0800274 location_mode = int(ad.adb.shell("settings get secure location_mode"))
275 ad.log.info("Current Location Mode >> %d" % location_mode)
276 if location_mode != 3:
jasonkmlu78540632019-11-15 18:04:20 +0800277 raise signals.TestError("Failed to turn Location on")
jasonkmluff0d5b92019-03-21 11:24:45 +0800278
jasonkmlu0f546de2019-12-13 20:58:41 +0800279
jasonkmluff0d5b92019-03-21 11:24:45 +0800280def clear_logd_gnss_qxdm_log(ad):
281 """Clear /data/misc/logd,
282 /storage/emulated/0/Android/data/com.android.gpstool/files and
283 /data/vendor/radio/diag_logs/logs from previous test item then reboot.
284
285 Args:
286 ad: An AndroidDevice object.
287 """
288 remount_device(ad)
289 ad.log.info("Clear Logd, GNSS and QXDM Log from previous test item.")
290 ad.adb.shell("rm -rf /data/misc/logd", ignore_status=True)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800291 ad.adb.shell('find %s -name "*.txt" -type f -delete' % GNSSSTATUS_LOG_PATH)
292 output_path = posixpath.join(DEFAULT_QXDM_LOG_PATH, "logs")
jasonkmluff0d5b92019-03-21 11:24:45 +0800293 ad.adb.shell("rm -rf %s" % output_path, ignore_status=True)
jasonkmlu214f0d62019-04-08 19:53:59 +0800294 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800295
jasonkmlu0f546de2019-12-13 20:58:41 +0800296
jasonkmlu81b8b032019-06-21 15:18:27 +0800297def get_gnss_qxdm_log(ad, qdb_path):
jasonkmluff0d5b92019-03-21 11:24:45 +0800298 """Get /storage/emulated/0/Android/data/com.android.gpstool/files and
jasonkmlu81b8b032019-06-21 15:18:27 +0800299 /data/vendor/radio/diag_logs/logs for test item.
jasonkmluff0d5b92019-03-21 11:24:45 +0800300
301 Args:
302 ad: An AndroidDevice object.
jasonkmlu81b8b032019-06-21 15:18:27 +0800303 qdb_path: The path of qdsp6m.qdb on different projects.
jasonkmluff0d5b92019-03-21 11:24:45 +0800304 """
jasonkmlu903ece82019-05-16 14:56:19 +0800305 log_path = ad.device_log_path
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800306 os.makedirs(log_path, exist_ok=True)
jasonkmlu903ece82019-05-16 14:56:19 +0800307 gnss_log_name = "gnssstatus_log_%s_%s" % (ad.model, ad.serial)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800308 gnss_log_path = posixpath.join(log_path, gnss_log_name)
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800309 os.makedirs(gnss_log_path, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800310 ad.log.info("Pull GnssStatus Log to %s" % gnss_log_path)
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800311 ad.adb.pull("%s %s" % (GNSSSTATUS_LOG_PATH+".", gnss_log_path),
jasonkmluff0d5b92019-03-21 11:24:45 +0800312 timeout=PULL_TIMEOUT, ignore_status=True)
jasonkmlu903ece82019-05-16 14:56:19 +0800313 shutil.make_archive(gnss_log_path, "zip", gnss_log_path)
314 shutil.rmtree(gnss_log_path)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800315 output_path = posixpath.join(DEFAULT_QXDM_LOG_PATH, "logs/.")
jasonkmlu035eee12019-10-08 17:11:20 +0800316 file_count = ad.adb.shell(
317 "find %s -type f -iname *.qmdl | wc -l" % output_path)
jasonkmluff0d5b92019-03-21 11:24:45 +0800318 if not int(file_count) == 0:
jasonkmlu903ece82019-05-16 14:56:19 +0800319 qxdm_log_name = "QXDM_%s_%s" % (ad.model, ad.serial)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800320 qxdm_log_path = posixpath.join(log_path, qxdm_log_name)
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800321 os.makedirs(qxdm_log_path, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800322 ad.log.info("Pull QXDM Log %s to %s" % (output_path, qxdm_log_path))
323 ad.adb.pull("%s %s" % (output_path, qxdm_log_path),
324 timeout=PULL_TIMEOUT, ignore_status=True)
jasonkmlu81b8b032019-06-21 15:18:27 +0800325 for path in qdb_path:
326 output = ad.adb.pull("%s %s" % (path, qxdm_log_path),
327 timeout=PULL_TIMEOUT, ignore_status=True)
328 if "No such file or directory" in output:
329 continue
330 break
jasonkmlu903ece82019-05-16 14:56:19 +0800331 shutil.make_archive(qxdm_log_path, "zip", qxdm_log_path)
332 shutil.rmtree(qxdm_log_path)
jasonkmluff0d5b92019-03-21 11:24:45 +0800333 else:
334 ad.log.error("QXDM file count is %d. There is no QXDM log on device."
335 % int(file_count))
336
jasonkmlu0f546de2019-12-13 20:58:41 +0800337
jasonkmluff0d5b92019-03-21 11:24:45 +0800338def set_mobile_data(ad, state):
339 """Set mobile data on or off and check mobile data state.
340
341 Args:
342 ad: An AndroidDevice object.
343 state: True to enable mobile data. False to disable mobile data.
344 """
345 ad.root_adb()
346 if state:
347 ad.log.info("Enable mobile data.")
348 ad.adb.shell("svc data enable")
349 else:
350 ad.log.info("Disable mobile data.")
351 ad.adb.shell("svc data disable")
352 time.sleep(5)
353 out = int(ad.adb.shell("settings get global mobile_data"))
354 if state and out == 1:
355 ad.log.info("Mobile data is enabled and set to %d" % out)
356 elif not state and out == 0:
357 ad.log.info("Mobile data is disabled and set to %d" % out)
358 else:
359 ad.log.error("Mobile data is at unknown state and set to %d" % out)
360
jasonkmlu0f546de2019-12-13 20:58:41 +0800361
jasonkmlu78540632019-11-15 18:04:20 +0800362def gnss_trigger_modem_ssr_by_adb(ad, dwelltime=60):
363 """Trigger modem SSR crash by adb and verify if modem crash and recover
jasonkmlu035eee12019-10-08 17:11:20 +0800364 successfully.
jasonkmluff0d5b92019-03-21 11:24:45 +0800365
366 Args:
367 ad: An AndroidDevice object.
jasonkmlu78540632019-11-15 18:04:20 +0800368 dwelltime: Waiting time for modem reset. Default is 60 seconds.
jasonkmluff0d5b92019-03-21 11:24:45 +0800369
370 Returns:
jasonkmlu81b8b032019-06-21 15:18:27 +0800371 True if success.
372 False if failed.
jasonkmluff0d5b92019-03-21 11:24:45 +0800373 """
jasonkmlu81b8b032019-06-21 15:18:27 +0800374 begin_time = get_current_epoch_time()
375 ad.root_adb()
376 cmds = ("echo restart > /sys/kernel/debug/msm_subsys/modem",
377 r"echo 'at+cfun=1,1\r' > /dev/at_mdm0")
378 for cmd in cmds:
379 ad.log.info("Triggering modem SSR crash by %s" % cmd)
380 output = ad.adb.shell(cmd, ignore_status=True)
381 if "No such file or directory" in output:
382 continue
383 break
384 time.sleep(dwelltime)
jasonkmluff0d5b92019-03-21 11:24:45 +0800385 ad.send_keycode("HOME")
jasonkmlu81b8b032019-06-21 15:18:27 +0800386 logcat_results = ad.search_logcat("SSRObserver", begin_time)
387 if logcat_results:
388 for ssr in logcat_results:
389 if "mSubsystem='modem', mCrashReason" in ssr["log_message"]:
390 ad.log.debug(ssr["log_message"])
391 ad.log.info("Triggering modem SSR crash successfully.")
392 return True
jasonkmlu78540632019-11-15 18:04:20 +0800393 raise signals.TestError("Failed to trigger modem SSR crash")
394 raise signals.TestError("No SSRObserver found in logcat")
395
jasonkmlu0f546de2019-12-13 20:58:41 +0800396
jasonkmlu78540632019-11-15 18:04:20 +0800397def gnss_trigger_modem_ssr_by_mds(ad, dwelltime=60):
398 """Trigger modem SSR crash by mds tool and verify if modem crash and recover
399 successfully.
400
401 Args:
402 ad: An AndroidDevice object.
403 dwelltime: Waiting time for modem reset. Default is 60 seconds.
404 """
405 mds_check = ad.adb.shell("pm path com.google.mdstest")
406 if not mds_check:
407 raise signals.TestError("MDS Tool is not properly installed.")
408 ad.root_adb()
409 cmd = ('am instrument -w -e request "4b 25 03 00" '
410 '"com.google.mdstest/com.google.mdstest.instrument'
411 '.ModemCommandInstrumentation"')
412 ad.log.info("Triggering modem SSR crash by MDS")
413 output = ad.adb.shell(cmd, ignore_status=True)
414 ad.log.debug(output)
415 time.sleep(dwelltime)
416 ad.send_keycode("HOME")
417 if "SUCCESS" in output:
418 ad.log.info("Triggering modem SSR crash by MDS successfully.")
419 else:
420 raise signals.TestError(
421 "Failed to trigger modem SSR crash by MDS. \n%s" % output)
422
jasonkmlu0f546de2019-12-13 20:58:41 +0800423
jasonkmlu78540632019-11-15 18:04:20 +0800424def pull_mdstool(ad):
425 """Pull ModemDiagnosticSystemTest.apk from device.
426
427 Args:
428 ad: An AndroidDevice object.
429 """
430 out = ad.adb.shell("pm path com.google.mdstest")
431 result = re.search(r"package:(.*)", out)
432 if not result:
433 raise signals.TestError("No ModemDiagnosticSystemTest.apk found.")
434 else:
435 mds_tool = result.group(1)
436 ad.log.info("Get ModemDiagnosticSystemTest.apk from %s" % mds_tool)
437 apkdir = "/tmp/MDS/"
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800438 os.makedirs(apkdir, exist_ok=True)
jasonkmlu78540632019-11-15 18:04:20 +0800439 ad.pull_files([mds_tool], apkdir)
440
jasonkmlu0f546de2019-12-13 20:58:41 +0800441
jasonkmlu78540632019-11-15 18:04:20 +0800442def reinstall_mdstool(ad):
443 """Reinstall ModemDiagnosticSystemTest.apk.
444
445 Args:
446 ad: An AndroidDevice object.
447 """
448 ad.log.info("Re-install ModemDiagnosticSystemTest.apk")
449 ad.adb.install("-r -g -t /tmp/MDS/base.apk")
450 mds_check = ad.adb.shell("pm path com.google.mdstest")
451 if not mds_check:
452 raise signals.TestError("MDS Tool is not properly re-installed.")
453 ad.log.info("MDS Tool is re-installed successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800454
jasonkmlu0f546de2019-12-13 20:58:41 +0800455
jasonkmluff0d5b92019-03-21 11:24:45 +0800456def check_xtra_download(ad, begin_time):
457 """Verify XTRA download success log message in logcat.
458
459 Args:
460 ad: An AndroidDevice object.
461 begin_time: test begin time
462
463 Returns:
464 True: xtra_download if XTRA downloaded and injected successfully
465 otherwise return False.
466 """
467 ad.send_keycode("HOME")
468 logcat_results = ad.search_logcat("XTRA download success. "
469 "inject data into modem", begin_time)
470 if logcat_results:
jasonkmlu81b8b032019-06-21 15:18:27 +0800471 ad.log.debug("%s" % logcat_results[-1]["log_message"])
jasonkmluff0d5b92019-03-21 11:24:45 +0800472 ad.log.info("XTRA downloaded and injected successfully.")
473 return True
474 ad.log.error("XTRA downloaded FAIL.")
475 return False
476
jasonkmlu0f546de2019-12-13 20:58:41 +0800477
jasonkmluff0d5b92019-03-21 11:24:45 +0800478def pull_gtw_gpstool(ad):
479 """Pull GTW_GPSTool apk from device.
480
481 Args:
482 ad: An AndroidDevice object.
483 """
484 out = ad.adb.shell("pm path com.android.gpstool")
485 result = re.search(r"package:(.*)", out)
486 if not result:
487 tutils.abort_all_tests(ad.log, "Couldn't find GTW GPSTool apk")
488 else:
489 GTW_GPSTool_apk = result.group(1)
490 ad.log.info("Get GTW GPSTool apk from %s" % GTW_GPSTool_apk)
491 apkdir = "/tmp/GNSS/"
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800492 os.makedirs(apkdir, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800493 ad.pull_files([GTW_GPSTool_apk], apkdir)
494
jasonkmlu0f546de2019-12-13 20:58:41 +0800495
jasonkmluff0d5b92019-03-21 11:24:45 +0800496def reinstall_gtw_gpstool(ad):
497 """Reinstall GTW_GPSTool apk.
498
499 Args:
500 ad: An AndroidDevice object.
501 """
502 ad.log.info("Re-install GTW GPSTool")
jasonkmlu903ece82019-05-16 14:56:19 +0800503 ad.adb.install("-r -g -t /tmp/GNSS/base.apk")
jasonkmlu78540632019-11-15 18:04:20 +0800504 gpstool_check = ad.adb.shell("pm path com.android.gpstool")
505 if not gpstool_check:
506 raise signals.TestError("GTW GPSTool is not properly re-installed.")
507 ad.log.info("GTW GPSTool is re-installed successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800508
jasonkmlu0f546de2019-12-13 20:58:41 +0800509
jasonkmlu180a08c2019-04-23 17:24:55 +0800510def init_gtw_gpstool(ad):
511 """Init GTW_GPSTool apk.
512
513 Args:
514 ad: An AndroidDevice object.
515 """
516 remount_device(ad)
517 pull_gtw_gpstool(ad)
518 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
jasonkmlu180a08c2019-04-23 17:24:55 +0800519 reinstall_gtw_gpstool(ad)
520
jasonkmlu0f546de2019-12-13 20:58:41 +0800521
jasonkmluff0d5b92019-03-21 11:24:45 +0800522def fastboot_factory_reset(ad):
523 """Factory reset the device in fastboot mode.
524 Pull sl4a apk from device. Terminate all sl4a sessions,
525 Reboot the device to bootloader,
526 factory reset the device by fastboot.
527 Reboot the device. wait for device to complete booting
528 Re-install and start an sl4a session.
529
530 Args:
531 ad: An AndroidDevice object.
532
533 Returns:
534 True if factory reset process complete.
535 """
536 status = True
537 skip_setup_wizard = True
538 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
539 result = re.search(r"package:(.*)", out)
540 if not result:
541 tutils.abort_all_tests(ad.log, "Couldn't find sl4a apk")
542 else:
543 sl4a_apk = result.group(1)
544 ad.log.info("Get sl4a apk from %s" % sl4a_apk)
545 ad.pull_files([sl4a_apk], "/tmp/")
546 pull_gtw_gpstool(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800547 pull_mdstool(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800548 tutils.stop_qxdm_logger(ad)
549 ad.stop_services()
550 attempts = 3
551 for i in range(1, attempts + 1):
552 try:
553 if ad.serial in list_adb_devices():
554 ad.log.info("Reboot to bootloader")
555 ad.adb.reboot("bootloader", ignore_status=True)
556 time.sleep(10)
557 if ad.serial in list_fastboot_devices():
558 ad.log.info("Factory reset in fastboot")
559 ad.fastboot._w(timeout=300, ignore_status=True)
560 time.sleep(30)
561 ad.log.info("Reboot in fastboot")
562 ad.fastboot.reboot()
563 ad.wait_for_boot_completion()
564 ad.root_adb()
565 if ad.skip_sl4a:
566 break
567 if ad.is_sl4a_installed():
568 break
569 ad.log.info("Re-install sl4a")
570 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
jasonkmlu903ece82019-05-16 14:56:19 +0800571 ad.adb.install("-r -g -t /tmp/base.apk")
jasonkmluff0d5b92019-03-21 11:24:45 +0800572 reinstall_gtw_gpstool(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800573 reinstall_mdstool(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800574 time.sleep(10)
575 break
576 except Exception as e:
577 ad.log.error(e)
578 if i == attempts:
579 tutils.abort_all_tests(ad.log, str(e))
580 time.sleep(5)
581 try:
582 ad.start_adb_logcat()
583 except Exception as e:
584 ad.log.error(e)
585 if skip_setup_wizard:
586 ad.exit_setup_wizard()
587 if ad.skip_sl4a:
588 return status
589 tutils.bring_up_sl4a(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800590 return status
591
jasonkmlu0f546de2019-12-13 20:58:41 +0800592
jasonkmluff0d5b92019-03-21 11:24:45 +0800593def clear_aiding_data_by_gtw_gpstool(ad):
594 """Launch GTW GPSTool and Clear all GNSS aiding data.
595 Wait 5 seconds for GTW GPStool to clear all GNSS aiding
596 data properly.
597
598 Args:
599 ad: An AndroidDevice object.
600 """
601 ad.log.info("Launch GTW GPSTool and Clear all GNSS aiding data")
602 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool --es mode clear")
603 time.sleep(10)
604
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700605
606def start_gnss_by_gtw_gpstool(ad, state, type="gnss", bgdisplay=False):
jasonkmluff0d5b92019-03-21 11:24:45 +0800607 """Start or stop GNSS on GTW_GPSTool.
608
609 Args:
610 ad: An AndroidDevice object.
611 state: True to start GNSS. False to Stop GNSS.
jasonkmlu81b8b032019-06-21 15:18:27 +0800612 type: Different API for location fix. Use gnss/flp/nmea
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700613 bgdisplay: true to run GTW when Display off.
614 false to not run GTW when Display off.
jasonkmluff0d5b92019-03-21 11:24:45 +0800615 """
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700616 if state and not bgdisplay:
jasonkmlu81b8b032019-06-21 15:18:27 +0800617 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool "
618 "--es mode gps --es type %s" % type)
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700619 elif state and bgdisplay:
jasonkmlu0f546de2019-12-13 20:58:41 +0800620 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool --es mode "
621 "gps --es type {} --ez BG {}".format(type, bgdisplay))
jasonkmluff0d5b92019-03-21 11:24:45 +0800622 if not state:
jasonkmlu81b8b032019-06-21 15:18:27 +0800623 ad.log.info("Stop %s on GTW_GPSTool." % type)
jasonkmluff0d5b92019-03-21 11:24:45 +0800624 ad.adb.shell("am broadcast -a com.android.gpstool.stop_gps_action")
625 time.sleep(3)
626
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700627
jasonkmlu81b8b032019-06-21 15:18:27 +0800628def process_gnss_by_gtw_gpstool(ad, criteria, type="gnss"):
jasonkmluff0d5b92019-03-21 11:24:45 +0800629 """Launch GTW GPSTool and Clear all GNSS aiding data
630 Start GNSS tracking on GTW_GPSTool.
631
632 Args:
633 ad: An AndroidDevice object.
634 criteria: Criteria for current test item.
jasonkmlu81b8b032019-06-21 15:18:27 +0800635 type: Different API for location fix. Use gnss/flp/nmea
jasonkmluff0d5b92019-03-21 11:24:45 +0800636
637 Returns:
638 True: First fix TTFF are within criteria.
639 False: First fix TTFF exceed criteria.
640 """
641 retries = 3
642 for i in range(retries):
643 begin_time = get_current_epoch_time()
644 clear_aiding_data_by_gtw_gpstool(ad)
jasonkmlu035eee12019-10-08 17:11:20 +0800645 ad.log.info("Start %s on GTW_GPSTool - attempt %d" % (type.upper(),
646 i+1))
jasonkmlu81b8b032019-06-21 15:18:27 +0800647 start_gnss_by_gtw_gpstool(ad, True, type)
jasonkmluff0d5b92019-03-21 11:24:45 +0800648 for _ in range(10 + criteria):
649 logcat_results = ad.search_logcat("First fixed", begin_time)
650 if logcat_results:
jasonkmlu81b8b032019-06-21 15:18:27 +0800651 ad.log.debug(logcat_results[-1]["log_message"])
jasonkmluff0d5b92019-03-21 11:24:45 +0800652 first_fixed = int(logcat_results[-1]["log_message"].split()[-1])
jasonkmlu81b8b032019-06-21 15:18:27 +0800653 ad.log.info("%s First fixed = %.3f seconds" %
654 (type.upper(), first_fixed/1000))
655 if (first_fixed/1000) <= criteria:
jasonkmluff0d5b92019-03-21 11:24:45 +0800656 return True
jasonkmlu81b8b032019-06-21 15:18:27 +0800657 start_gnss_by_gtw_gpstool(ad, False, type)
jasonkmlu035eee12019-10-08 17:11:20 +0800658 raise signals.TestFailure("Fail to get %s location fixed "
659 "within %d seconds criteria."
660 % (type.upper(), criteria))
jasonkmluff0d5b92019-03-21 11:24:45 +0800661 time.sleep(1)
jasonkmlua4a569f2019-04-10 14:25:31 +0800662 if not ad.is_adb_logcat_on:
663 ad.start_adb_logcat()
jasonkmlu97ac56e2019-05-29 15:04:51 +0800664 check_currrent_focus_app(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800665 start_gnss_by_gtw_gpstool(ad, False, type)
jasonkmlu035eee12019-10-08 17:11:20 +0800666 raise signals.TestFailure("Fail to get %s location fixed within %d "
667 "attempts." % (type.upper(), retries))
jasonkmluff0d5b92019-03-21 11:24:45 +0800668
Scott Hong72269692019-12-16 16:59:56 +0800669def start_ttff_by_gtw_gpstool(ad, ttff_mode, iteration, aid_data=False):
jasonkmluff0d5b92019-03-21 11:24:45 +0800670 """Identify which TTFF mode for different test items.
671
672 Args:
673 ad: An AndroidDevice object.
674 ttff_mode: TTFF Test mode for current test item.
675 iteration: Iteration of TTFF cycles.
Scott Hong72269692019-12-16 16:59:56 +0800676 aid_data: Boolean for identify aid_data existed or not
jasonkmluff0d5b92019-03-21 11:24:45 +0800677 """
jasonkmlu97ac56e2019-05-29 15:04:51 +0800678 begin_time = get_current_epoch_time()
Scott Hong72269692019-12-16 16:59:56 +0800679 if (ttff_mode == "hs" or ttff_mode == "ws") and not aid_data:
jasonkmlu81b8b032019-06-21 15:18:27 +0800680 ad.log.info("Wait 5 minutes to start TTFF %s..." % ttff_mode.upper())
jasonkmluff0d5b92019-03-21 11:24:45 +0800681 time.sleep(300)
682 if ttff_mode == "cs":
683 ad.log.info("Start TTFF Cold Start...")
684 time.sleep(3)
jasonkmlu97ac56e2019-05-29 15:04:51 +0800685 for i in range(1, 4):
686 ad.adb.shell("am broadcast -a com.android.gpstool.ttff_action "
687 "--es ttff %s --es cycle %d" % (ttff_mode, iteration))
jasonkmlu81b8b032019-06-21 15:18:27 +0800688 time.sleep(1)
jasonkmlu97ac56e2019-05-29 15:04:51 +0800689 if ad.search_logcat("act=com.android.gpstool.start_test_action",
690 begin_time):
691 ad.log.info("Send TTFF start_test_action successfully.")
692 break
jasonkmlu035eee12019-10-08 17:11:20 +0800693 else:
694 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800695 raise signals.TestError("Fail to send TTFF start_test_action.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800696
jasonkmlu0f546de2019-12-13 20:58:41 +0800697
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800698def gnss_tracking_via_gtw_gpstool(ad, criteria, type="gnss", testtime=60):
jasonkmlu66fda532019-07-16 11:12:45 +0800699 """Start GNSS/FLP tracking tests for input testtime on GTW_GPSTool.
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800700
701 Args:
702 ad: An AndroidDevice object.
703 criteria: Criteria for current TTFF.
704 type: Different API for location fix. Use gnss/flp/nmea
705 testtime: Tracking test time for minutes. Default set to 60 minutes.
706 """
707 process_gnss_by_gtw_gpstool(ad, criteria, type)
708 ad.log.info("Start %s tracking test for %d minutes" % (type.upper(),
709 testtime))
710 begin_time = get_current_epoch_time()
711 while get_current_epoch_time() - begin_time < testtime * 60 * 1000 :
712 if not ad.is_adb_logcat_on:
713 ad.start_adb_logcat()
714 crash_result = ad.search_logcat("Force finishing activity "
715 "com.android.gpstool/.GPSTool",
716 begin_time)
717 if crash_result:
jasonkmlu78540632019-11-15 18:04:20 +0800718 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800719 ad.log.info("Successfully tested for %d minutes" % testtime)
720 start_gnss_by_gtw_gpstool(ad, False, type)
721
jasonkmlu0f546de2019-12-13 20:58:41 +0800722
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800723def parse_gtw_gpstool_log(ad, true_position, type="gnss"):
724 """Process GNSS/FLP API logs from GTW GPSTool and output track_data to
725 test_run_info for ACTS plugin to parse and display on MobileHarness as
726 Property.
727
728 Args:
729 ad: An AndroidDevice object.
730 true_position: Coordinate as [latitude, longitude] to calculate
731 position error.
732 type: Different API for location fix. Use gnss/flp/nmea
733 """
734 test_logfile = {}
735 track_data = {}
736 history_top4_cn = 0
737 history_cn = 0
jasonkmlu035eee12019-10-08 17:11:20 +0800738 l5flag = "false"
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800739 file_count = int(ad.adb.shell("find %s -type f -iname *.txt | wc -l"
740 % GNSSSTATUS_LOG_PATH))
741 if file_count != 1:
742 ad.log.error("%d API logs exist." % file_count)
743 dir = ad.adb.shell("ls %s" % GNSSSTATUS_LOG_PATH).split()
744 for path_key in dir:
745 if fnmatch.fnmatch(path_key, "*.txt"):
746 logpath = posixpath.join(GNSSSTATUS_LOG_PATH, path_key)
747 out = ad.adb.shell("wc -c %s" % logpath)
748 file_size = int(out.split(" ")[0])
749 if file_size < 2000:
750 ad.log.info("Skip log %s due to log size %d bytes" %
751 (path_key, file_size))
752 continue
753 test_logfile = logpath
754 if not test_logfile:
jasonkmlu78540632019-11-15 18:04:20 +0800755 raise signals.TestError("Failed to get test log file in device.")
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800756 lines = ad.adb.shell("cat %s" % test_logfile).split("\n")
757 for line in lines:
758 if "History Avg Top4" in line:
759 history_top4_cn = float(line.split(":")[-1].strip())
760 if "History Avg" in line:
761 history_cn = float(line.split(":")[-1].strip())
762 if "L5 used in fix" in line:
763 l5flag = line.split(":")[-1].strip()
764 if "Latitude" in line:
765 track_lat = float(line.split(":")[-1].strip())
766 if "Longitude" in line:
767 track_long = float(line.split(":")[-1].strip())
768 if "Time" in line:
769 track_utc = line.split("Time:")[-1].strip()
770 if track_utc in track_data.keys():
771 continue
772 track_pe = calculate_position_error(ad, track_lat, track_long,
773 true_position)
774 track_data[track_utc] = TRACK_REPORT(track_l5flag=l5flag,
775 track_pe=track_pe,
776 track_top4cn=history_top4_cn,
777 track_cn=history_cn)
778 ad.log.debug(track_data)
779 prop_basename = "TestResult %s_tracking_" % type.upper()
780 time_list = sorted(track_data.keys())
781 l5flag_list = [track_data[key].track_l5flag for key in time_list]
782 pe_list = [float(track_data[key].track_pe) for key in time_list]
783 top4cn_list = [float(track_data[key].track_top4cn) for key in time_list]
784 cn_list = [float(track_data[key].track_cn) for key in time_list]
785 ad.log.info(prop_basename+"StartTime %s" % time_list[0].replace(" ", "-"))
786 ad.log.info(prop_basename+"EndTime %s" % time_list[-1].replace(" ", "-"))
787 ad.log.info(prop_basename+"TotalFixPoints %d" % len(time_list))
788 ad.log.info(prop_basename+"L5FixRate "+'{percent:.2%}'.format(
789 percent=l5flag_list.count("true")/len(l5flag_list)))
790 ad.log.info(prop_basename+"AvgDis %.1f" % (sum(pe_list)/len(pe_list)))
791 ad.log.info(prop_basename+"MaxDis %.1f" % max(pe_list))
792 ad.log.info(prop_basename+"AvgTop4Signal %.1f" % top4cn_list[-1])
793 ad.log.info(prop_basename+"AvgSignal %.1f" % cn_list[-1])
794
jasonkmlu0f546de2019-12-13 20:58:41 +0800795
jasonkmlu81b8b032019-06-21 15:18:27 +0800796def process_ttff_by_gtw_gpstool(ad, begin_time, true_position, type="gnss"):
797 """Process TTFF and record results in ttff_data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800798
799 Args:
800 ad: An AndroidDevice object.
jasonkmlu903ece82019-05-16 14:56:19 +0800801 begin_time: test begin time.
jasonkmlu733738f2019-09-02 18:59:42 +0800802 true_position: Coordinate as [latitude, longitude] to calculate
803 position error.
jasonkmlu81b8b032019-06-21 15:18:27 +0800804 type: Different API for location fix. Use gnss/flp/nmea
jasonkmluff0d5b92019-03-21 11:24:45 +0800805
806 Returns:
jasonkmlu81b8b032019-06-21 15:18:27 +0800807 ttff_data: A dict of all TTFF data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800808 """
jasonkmlu903ece82019-05-16 14:56:19 +0800809 ttff_data = {}
jasonkmlu733738f2019-09-02 18:59:42 +0800810 ttff_loop_time = get_current_epoch_time()
jasonkmlu97ac56e2019-05-29 15:04:51 +0800811 while True:
jasonkmlu733738f2019-09-02 18:59:42 +0800812 if get_current_epoch_time() - ttff_loop_time >= 120000:
jasonkmlu78540632019-11-15 18:04:20 +0800813 raise signals.TestError("Fail to search specific GPSService "
814 "message in logcat. Abort test.")
jasonkmlu97ac56e2019-05-29 15:04:51 +0800815 if not ad.is_adb_logcat_on:
816 ad.start_adb_logcat()
817 stop_gps_results = ad.search_logcat("stop gps test", begin_time)
818 if stop_gps_results:
819 ad.send_keycode("HOME")
820 break
821 crash_result = ad.search_logcat("Force finishing activity "
822 "com.android.gpstool/.GPSTool",
823 begin_time)
824 if crash_result:
jasonkmlu78540632019-11-15 18:04:20 +0800825 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu97ac56e2019-05-29 15:04:51 +0800826 logcat_results = ad.search_logcat("write TTFF log", begin_time)
827 if logcat_results:
828 ttff_log = logcat_results[-1]["log_message"].split()
829 ttff_loop = int(ttff_log[8].split(":")[-1])
jasonkmlu97ac56e2019-05-29 15:04:51 +0800830 if ttff_loop in ttff_data.keys():
831 continue
jasonkmlu733738f2019-09-02 18:59:42 +0800832 ttff_loop_time = get_current_epoch_time()
jasonkmlu81b8b032019-06-21 15:18:27 +0800833 ttff_sec = float(ttff_log[11])
834 if ttff_sec != 0.0:
835 ttff_cn = float(ttff_log[18].strip("]"))
836 if type == "gnss":
jasonkmlu733738f2019-09-02 18:59:42 +0800837 gnss_results = ad.search_logcat("GPSService: Check item",
838 begin_time)
jasonkmlu81b8b032019-06-21 15:18:27 +0800839 if gnss_results:
840 ad.log.debug(gnss_results[-1]["log_message"])
jasonkmlu733738f2019-09-02 18:59:42 +0800841 gnss_location_log = \
842 gnss_results[-1]["log_message"].split()
843 ttff_lat = float(
844 gnss_location_log[8].split("=")[-1].strip(","))
845 ttff_lon = float(
846 gnss_location_log[9].split("=")[-1].strip(","))
jasonkmlu81b8b032019-06-21 15:18:27 +0800847 elif type == "flp":
jasonkmlu733738f2019-09-02 18:59:42 +0800848 flp_results = ad.search_logcat("GPSService: FLP Location",
849 begin_time)
jasonkmlu81b8b032019-06-21 15:18:27 +0800850 if flp_results:
851 ad.log.debug(flp_results[-1]["log_message"])
jasonkmlu733738f2019-09-02 18:59:42 +0800852 flp_location_log = \
853 flp_results[-1]["log_message"].split()
jasonkmlu81b8b032019-06-21 15:18:27 +0800854 ttff_lat = float(flp_location_log[8].split(",")[0])
855 ttff_lon = float(flp_location_log[8].split(",")[1])
856 else:
857 ttff_cn = float(ttff_log[19].strip("]"))
jasonkmlu97ac56e2019-05-29 15:04:51 +0800858 ttff_lat = 0.0
859 ttff_lon = 0.0
jasonkmlu2565d892019-11-12 15:31:26 +0800860 ad.log.debug("TTFF Loop %d - (Lat, Lon) = (%s, %s)" % (ttff_loop,
861 ttff_lat,
862 ttff_lon))
jasonkmlu97ac56e2019-05-29 15:04:51 +0800863 ttff_pe = calculate_position_error(ad, ttff_lat, ttff_lon,
864 true_position)
865 ttff_data[ttff_loop] = TTFF_REPORT(ttff_loop=ttff_loop,
866 ttff_sec=ttff_sec,
867 ttff_pe=ttff_pe,
868 ttff_cn=ttff_cn)
869 ad.log.info("Loop %d = %.1f seconds, "
870 "Position Error = %.1f meters, "
871 "Average Signal = %.1f dbHz"
872 % (ttff_loop, ttff_sec, ttff_pe, ttff_cn))
873 return ttff_data
jasonkmluff0d5b92019-03-21 11:24:45 +0800874
jasonkmlu0f546de2019-12-13 20:58:41 +0800875
jasonkmlu903ece82019-05-16 14:56:19 +0800876def check_ttff_data(ad, ttff_data, ttff_mode, criteria):
jasonkmlu81b8b032019-06-21 15:18:27 +0800877 """Verify all TTFF results from ttff_data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800878
879 Args:
880 ad: An AndroidDevice object.
jasonkmlu903ece82019-05-16 14:56:19 +0800881 ttff_data: TTFF data of secs, position error and signal strength.
jasonkmluff0d5b92019-03-21 11:24:45 +0800882 ttff_mode: TTFF Test mode for current test item.
883 criteria: Criteria for current test item.
884
885 Returns:
886 True: All TTFF results are within criteria.
887 False: One or more TTFF results exceed criteria or Timeout.
888 """
889 ad.log.info("%d iterations of TTFF %s tests finished."
jasonkmlu903ece82019-05-16 14:56:19 +0800890 % (len(ttff_data.keys()), ttff_mode))
jasonkmluff0d5b92019-03-21 11:24:45 +0800891 ad.log.info("%s PASS criteria is %d seconds" % (ttff_mode, criteria))
jasonkmlu81b8b032019-06-21 15:18:27 +0800892 ad.log.debug("%s TTFF data: %s" % (ttff_mode, ttff_data))
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800893 ttff_property_key_and_value(ad, ttff_data, ttff_mode)
jasonkmlu903ece82019-05-16 14:56:19 +0800894 if len(ttff_data.keys()) == 0:
jasonkmluff0d5b92019-03-21 11:24:45 +0800895 ad.log.error("GTW_GPSTool didn't process TTFF properly.")
896 return False
jasonkmlu903ece82019-05-16 14:56:19 +0800897 elif any(float(ttff_data[key].ttff_sec) == 0.0 for key in ttff_data.keys()):
jasonkmluff0d5b92019-03-21 11:24:45 +0800898 ad.log.error("One or more TTFF %s Timeout" % ttff_mode)
899 return False
jasonkmlu035eee12019-10-08 17:11:20 +0800900 elif any(float(ttff_data[key].ttff_sec) >= criteria for key in
901 ttff_data.keys()):
jasonkmluff0d5b92019-03-21 11:24:45 +0800902 ad.log.error("One or more TTFF %s are over test criteria %d seconds"
903 % (ttff_mode, criteria))
904 return False
905 ad.log.info("All TTFF %s are within test criteria %d seconds."
906 % (ttff_mode, criteria))
907 return True
908
jasonkmlu0f546de2019-12-13 20:58:41 +0800909
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800910def ttff_property_key_and_value(ad, ttff_data, ttff_mode):
jasonkmlu81b8b032019-06-21 15:18:27 +0800911 """Output ttff_data to test_run_info for ACTS plugin to parse and display
912 on MobileHarness as Property.
913
914 Args:
915 ad: An AndroidDevice object.
916 ttff_data: TTFF data of secs, position error and signal strength.
917 ttff_mode: TTFF Test mode for current test item.
918 """
919 prop_basename = "TestResult "+ttff_mode.replace(" ", "_")+"_TTFF_"
920 sec_list = [float(ttff_data[key].ttff_sec) for key in ttff_data.keys()]
921 pe_list = [float(ttff_data[key].ttff_pe) for key in ttff_data.keys()]
922 cn_list = [float(ttff_data[key].ttff_cn) for key in ttff_data.keys()]
923 timeoutcount = sec_list.count(0.0)
jasonkmluc1ec3052019-10-25 14:57:53 +0800924 if len(sec_list) == timeoutcount:
925 avgttff = 9527
926 else:
927 avgttff = sum(sec_list)/(len(sec_list) - timeoutcount)
jasonkmlu81b8b032019-06-21 15:18:27 +0800928 if timeoutcount != 0:
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800929 maxttff = 9527
jasonkmlu81b8b032019-06-21 15:18:27 +0800930 else:
931 maxttff = max(sec_list)
932 avgdis = sum(pe_list)/len(pe_list)
933 maxdis = max(pe_list)
934 avgcn = sum(cn_list)/len(cn_list)
935 ad.log.info(prop_basename+"AvgTime %.1f" % avgttff)
936 ad.log.info(prop_basename+"MaxTime %.1f" % maxttff)
937 ad.log.info(prop_basename+"TimeoutCount %d" % timeoutcount)
938 ad.log.info(prop_basename+"AvgDis %.1f" % avgdis)
939 ad.log.info(prop_basename+"MaxDis %.1f" % maxdis)
940 ad.log.info(prop_basename+"AvgSignal %.1f" % avgcn)
941
jasonkmlu0f546de2019-12-13 20:58:41 +0800942
jasonkmlu903ece82019-05-16 14:56:19 +0800943def calculate_position_error(ad, latitude, longitude, true_position):
944 """Use haversine formula to calculate position error base on true location
945 coordinate.
946
947 Args:
948 ad: An AndroidDevice object.
949 latitude: latitude of location fixed in the present.
950 longitude: longitude of location fixed in the present.
951 true_position: [latitude, longitude] of true location coordinate.
952
953 Returns:
954 position_error of location fixed in the present.
955 """
956 radius = 6371009
957 dlat = math.radians(latitude - true_position[0])
958 dlon = math.radians(longitude - true_position[1])
959 a = math.sin(dlat/2) * math.sin(dlat/2) + \
960 math.cos(math.radians(true_position[0])) * \
961 math.cos(math.radians(latitude)) * math.sin(dlon/2) * math.sin(dlon/2)
962 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
963 return radius * c
964
jasonkmlu0f546de2019-12-13 20:58:41 +0800965
jasonkmluff0d5b92019-03-21 11:24:45 +0800966def launch_google_map(ad):
967 """Launch Google Map via intent.
968
969 Args:
970 ad: An AndroidDevice object.
971 """
972 ad.log.info("Launch Google Map.")
973 try:
974 ad.adb.shell("am start -S -n com.google.android.apps.maps/"
975 "com.google.android.maps.MapsActivity")
976 ad.send_keycode("BACK")
977 ad.force_stop_apk("com.google.android.apps.maps")
978 ad.adb.shell("am start -S -n com.google.android.apps.maps/"
979 "com.google.android.maps.MapsActivity")
980 except Exception as e:
981 ad.log.error(e)
jasonkmlu78540632019-11-15 18:04:20 +0800982 raise signals.TestError("Failed to launch google map.")
jasonkmlu903ece82019-05-16 14:56:19 +0800983 check_currrent_focus_app(ad)
jasonkmlu49c32812019-04-12 18:11:10 +0800984
jasonkmlu0f546de2019-12-13 20:58:41 +0800985
jasonkmlu903ece82019-05-16 14:56:19 +0800986def check_currrent_focus_app(ad):
987 """Check to see current focused window and app.
jasonkmlu49c32812019-04-12 18:11:10 +0800988
989 Args:
990 ad: An AndroidDevice object.
jasonkmlu49c32812019-04-12 18:11:10 +0800991 """
jasonkmlu903ece82019-05-16 14:56:19 +0800992 time.sleep(1)
jasonkmlu035eee12019-10-08 17:11:20 +0800993 current = ad.adb.shell(
994 "dumpsys window | grep -E 'mCurrentFocus|mFocusedApp'")
jasonkmlu81b8b032019-06-21 15:18:27 +0800995 ad.log.debug("\n"+current)
jasonkmluff0d5b92019-03-21 11:24:45 +0800996
jasonkmlu0f546de2019-12-13 20:58:41 +0800997
jasonkmluff0d5b92019-03-21 11:24:45 +0800998def check_location_api(ad, retries):
999 """Verify if GnssLocationProvider API reports location.
1000
1001 Args:
1002 ad: An AndroidDevice object.
1003 retries: Retry time.
1004
1005 Returns:
1006 True: GnssLocationProvider API reports location.
1007 otherwise return False.
1008 """
1009 for i in range(retries):
1010 begin_time = get_current_epoch_time()
1011 ad.log.info("Try to get location report from GnssLocationProvider API "
1012 "- attempt %d" % (i+1))
1013 while get_current_epoch_time() - begin_time <= 30000:
1014 logcat_results = ad.search_logcat("REPORT_LOCATION", begin_time)
1015 if logcat_results:
1016 ad.log.info("%s" % logcat_results[-1]["log_message"])
jasonkmlu035eee12019-10-08 17:11:20 +08001017 ad.log.info("GnssLocationProvider reports location "
1018 "successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +08001019 return True
1020 if not ad.is_adb_logcat_on:
1021 ad.start_adb_logcat()
1022 ad.log.error("GnssLocationProvider is unable to report location.")
1023 return False
1024
Scott Hong72269692019-12-16 16:59:56 +08001025def check_network_location(ad, retries, location_type, criteria=30):
jasonkmluff0d5b92019-03-21 11:24:45 +08001026 """Verify if NLP reports location after requesting via GPSTool.
1027
1028 Args:
1029 ad: An AndroidDevice object.
1030 retries: Retry time.
1031 location_type: neworkLocationType of cell or wifi.
Scott Hong72269692019-12-16 16:59:56 +08001032 criteria: expected nlp return time, default 30 seconds
jasonkmluff0d5b92019-03-21 11:24:45 +08001033
1034 Returns:
1035 True: NLP reports location.
1036 otherwise return False.
1037 """
Scott Hong72269692019-12-16 16:59:56 +08001038 criteria = criteria * 1000
jasonkmluff0d5b92019-03-21 11:24:45 +08001039 for i in range(retries):
1040 time.sleep(1)
1041 begin_time = get_current_epoch_time()
1042 ad.log.info("Try to get NLP status - attempt %d" % (i+1))
jasonkmlu035eee12019-10-08 17:11:20 +08001043 ad.adb.shell(
1044 "am start -S -n com.android.gpstool/.GPSTool --es mode nlp")
Scott Hong72269692019-12-16 16:59:56 +08001045 while get_current_epoch_time() - begin_time <= criteria:
jasonkmlu035eee12019-10-08 17:11:20 +08001046 logcat_results = ad.search_logcat("LocationManagerService: "
1047 "incoming location: Location",
1048 begin_time)
jasonkmluff0d5b92019-03-21 11:24:45 +08001049 if logcat_results:
1050 for logcat_result in logcat_results:
1051 if location_type in logcat_result["log_message"]:
1052 ad.log.info(logcat_result["log_message"])
1053 ad.send_keycode("BACK")
1054 return True
1055 if not ad.is_adb_logcat_on:
1056 ad.start_adb_logcat()
1057 ad.send_keycode("BACK")
1058 ad.log.error("Unable to report network location \"%s\"." % location_type)
1059 return False
1060
jasonkmlu0f546de2019-12-13 20:58:41 +08001061
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001062def set_attenuator_gnss_signal(ad, attenuator, atten_value):
jasonkmluff0d5b92019-03-21 11:24:45 +08001063 """Set attenuation value for different GNSS signal.
1064
1065 Args:
1066 ad: An AndroidDevice object.
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001067 attenuator: The attenuator object.
jasonkmluff0d5b92019-03-21 11:24:45 +08001068 atten_value: attenuation value
1069 """
jasonkmluff0d5b92019-03-21 11:24:45 +08001070 try:
jasonkmlu035eee12019-10-08 17:11:20 +08001071 ad.log.info(
1072 "Set attenuation value to \"%d\" for GNSS signal." % atten_value)
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001073 attenuator[0].set_atten(atten_value)
jasonkmlu81b8b032019-06-21 15:18:27 +08001074 except Exception as e:
jasonkmlu4fcdcad2019-07-10 14:35:12 +08001075 ad.log.error(e)
jasonkmluff0d5b92019-03-21 11:24:45 +08001076
jasonkmlu0f546de2019-12-13 20:58:41 +08001077
jasonkmluff0d5b92019-03-21 11:24:45 +08001078def set_battery_saver_mode(ad, state):
1079 """Enable or diable battery saver mode via adb.
1080
1081 Args:
1082 ad: An AndroidDevice object.
1083 state: True is enable Battery Saver mode. False is disable.
1084 """
1085 ad.root_adb()
1086 if state:
1087 ad.log.info("Enable Battery Saver mode.")
1088 ad.adb.shell("cmd battery unplug")
1089 ad.adb.shell("settings put global low_power 1")
1090 else:
1091 ad.log.info("Disable Battery Saver mode.")
1092 ad.adb.shell("settings put global low_power 0")
1093 ad.adb.shell("cmd battery reset")
1094
jasonkmlu0f546de2019-12-13 20:58:41 +08001095
jasonkmluff0d5b92019-03-21 11:24:45 +08001096def set_gnss_qxdm_mask(ad, masks):
1097 """Find defined gnss qxdm mask and set as default logging mask.
1098
1099 Args:
1100 ad: An AndroidDevice object.
1101 masks: Defined gnss qxdm mask.
1102 """
1103 try:
1104 for mask in masks:
1105 if not tutils.find_qxdm_log_mask(ad, mask):
1106 continue
1107 tutils.set_qxdm_logger_command(ad, mask)
1108 break
1109 except Exception as e:
1110 ad.log.error(e)
jasonkmlu78540632019-11-15 18:04:20 +08001111 raise signals.TestError("Failed to set any QXDM masks.")
jasonkmlu903ece82019-05-16 14:56:19 +08001112
jasonkmlu0f546de2019-12-13 20:58:41 +08001113
jasonkmlu903ece82019-05-16 14:56:19 +08001114def start_youtube_video(ad, url=None, retries=0):
1115 """Start youtube video and verify if audio is in music state.
jasonkmlu81b8b032019-06-21 15:18:27 +08001116
jasonkmlu903ece82019-05-16 14:56:19 +08001117 Args:
1118 ad: An AndroidDevice object.
1119 url: Youtube video url.
1120 retries: Retry times if audio is not in music state.
jasonkmlu81b8b032019-06-21 15:18:27 +08001121
jasonkmlu903ece82019-05-16 14:56:19 +08001122 Returns:
1123 True if youtube video is playing normally.
1124 False if youtube video is not playing properly.
1125 """
1126 for i in range(retries):
1127 ad.log.info("Open an youtube video - attempt %d" % (i+1))
1128 ad.adb.shell("am start -a android.intent.action.VIEW -d \"%s\"" % url)
1129 time.sleep(2)
jasonkmlu035eee12019-10-08 17:11:20 +08001130 out = ad.adb.shell(
1131 "dumpsys activity | grep NewVersionAvailableActivity")
jasonkmlu903ece82019-05-16 14:56:19 +08001132 if out:
1133 ad.log.info("Skip Youtube New Version Update.")
1134 ad.send_keycode("BACK")
1135 if tutils.wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
1136 ad.log.info("Started a video in youtube, audio is in MUSIC state")
1137 return True
1138 ad.log.info("Force-Stop youtube and reopen youtube again.")
1139 ad.force_stop_apk("com.google.android.youtube")
jasonkmlu903ece82019-05-16 14:56:19 +08001140 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +08001141 raise signals.TestError("Started a video in youtube, "
1142 "but audio is not in MUSIC state")
jasonkmlu81b8b032019-06-21 15:18:27 +08001143
jasonkmlu0f546de2019-12-13 20:58:41 +08001144
jasonkmlu81b8b032019-06-21 15:18:27 +08001145def get_baseband_and_gms_version(ad, extra_msg=""):
1146 """Get current radio baseband and GMSCore version of AndroidDevice object.
1147
1148 Args:
1149 ad: An AndroidDevice object.
1150 """
1151 try:
jasonkmlud93060f2019-11-05 15:12:55 +08001152 build_version = ad.adb.getprop("ro.build.id")
jasonkmlu81b8b032019-06-21 15:18:27 +08001153 baseband_version = ad.adb.getprop("gsm.version.baseband")
jasonkmlu035eee12019-10-08 17:11:20 +08001154 gms_version = ad.adb.shell(
1155 "dumpsys package com.google.android.gms | grep versionName"
1156 ).split("\n")[0].split("=")[1]
1157 mpss_version = ad.adb.shell("cat /sys/devices/soc0/images | grep MPSS "
1158 "| cut -d ':' -f 3")
jasonkmlu81b8b032019-06-21 15:18:27 +08001159 if not extra_msg:
jasonkmlud93060f2019-11-05 15:12:55 +08001160 ad.log.info("TestResult Build_Version %s" % build_version)
jasonkmlu81b8b032019-06-21 15:18:27 +08001161 ad.log.info("TestResult Baseband_Version %s" % baseband_version)
jasonkmlu035eee12019-10-08 17:11:20 +08001162 ad.log.info(
1163 "TestResult GMS_Version %s" % gms_version.replace(" ", ""))
1164 ad.log.info("TestResult MPSS_Version %s" % mpss_version)
jasonkmlu81b8b032019-06-21 15:18:27 +08001165 else:
jasonkmlu035eee12019-10-08 17:11:20 +08001166 ad.log.info(
1167 "%s, Baseband_Version = %s" % (extra_msg, baseband_version))
jasonkmlu81b8b032019-06-21 15:18:27 +08001168 except Exception as e:
jasonkmlu035eee12019-10-08 17:11:20 +08001169 ad.log.error(e)
1170
jasonkmlu0f546de2019-12-13 20:58:41 +08001171
jasonkmlu035eee12019-10-08 17:11:20 +08001172def start_toggle_gnss_by_gtw_gpstool(ad, iteration):
1173 """Send toggle gnss off/on start_test_action
1174
1175 Args:
1176 ad: An AndroidDevice object.
1177 iteration: Iteration of toggle gnss off/on cycles.
1178 """
1179 msg_list = []
1180 begin_time = get_current_epoch_time()
1181 try:
1182 for i in range(1, 4):
1183 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool "
1184 "--es mode toggle --es cycle %d" % iteration)
1185 time.sleep(1)
1186 if ad.search_logcat("cmp=com.android.gpstool/.ToggleGPS",
1187 begin_time):
1188 ad.log.info("Send ToggleGPS start_test_action successfully.")
1189 break
1190 else:
1191 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +08001192 raise signals.TestError("Fail to send ToggleGPS "
1193 "start_test_action within 3 attempts.")
jasonkmlu035eee12019-10-08 17:11:20 +08001194 time.sleep(2)
1195 test_start = ad.search_logcat("GPSTool_ToggleGPS: startService",
1196 begin_time)
1197 if test_start:
1198 ad.log.info(test_start[-1]["log_message"].split(":")[-1].strip())
1199 else:
jasonkmlu78540632019-11-15 18:04:20 +08001200 raise signals.TestError("Fail to start toggle GPS off/on test.")
jasonkmlu035eee12019-10-08 17:11:20 +08001201 # Every iteration is expected to finish within 4 minutes.
1202 while get_current_epoch_time() - begin_time <= iteration * 240000:
1203 crash_end = ad.search_logcat("Force finishing activity "
1204 "com.android.gpstool/.GPSTool",
1205 begin_time)
1206 if crash_end:
jasonkmlu78540632019-11-15 18:04:20 +08001207 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu035eee12019-10-08 17:11:20 +08001208 toggle_results = ad.search_logcat("GPSTool : msg", begin_time)
1209 if toggle_results:
1210 for toggle_result in toggle_results:
1211 msg = toggle_result["log_message"]
1212 if not msg in msg_list:
1213 ad.log.info(msg.split(":")[-1].strip())
1214 msg_list.append(msg)
1215 if "timeout" in msg:
1216 raise signals.TestFailure("Fail to get location fixed "
1217 "within 60 seconds.")
1218 if "Test end" in msg:
1219 raise signals.TestPass("Completed quick toggle GNSS "
1220 "off/on test.")
1221 raise signals.TestFailure("Fail to finish toggle GPS off/on test "
1222 "within %d minutes" % (iteration * 4))
1223 finally:
1224 ad.send_keycode("HOME")