blob: 8b7784ed76f03c74301f9279368db0cfdf63fd0a [file] [log] [blame]
jasonkmludc430ec2020-03-27 10:40:39 +08001#!/usr/bin/env python3.7
jasonkmluff0d5b92019-03-21 11:24:45 +08002#
jasonkmludc430ec2020-03-27 10:40:39 +08003# Copyright 2020 - Google
jasonkmluff0d5b92019-03-21 11:24:45 +08004#
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
jasonkmludc430ec2020-03-27 10:40:39 +080052log.tag.GnssVisibilityControl=VERBOSE
53log.tag.NtpTimeHelper=VERBOSE
54log.tag.NtpTrustedTime=VERBOSE"""
55TEST_PACKAGE_NAME = 'com.google.android.apps.maps'
56LOCATION_PERMISSIONS = [
57 'android.permission.ACCESS_FINE_LOCATION',
58 'android.permission.ACCESS_COARSE_LOCATION'
59]
jasonkmluff0d5b92019-03-21 11:24:45 +080060
61
62class GnssTestUtilsError(Exception):
63 pass
64
jasonkmlu0f546de2019-12-13 20:58:41 +080065
jasonkmluff0d5b92019-03-21 11:24:45 +080066def remount_device(ad):
67 """Remount device file system to read and write.
68
69 Args:
70 ad: An AndroidDevice object.
71 """
jasonkmlu81b8b032019-06-21 15:18:27 +080072 for retries in range(5):
jasonkmluff0d5b92019-03-21 11:24:45 +080073 ad.root_adb()
Scott Hong7f3945f2020-02-20 18:04:56 +080074 if ad.adb.getprop("ro.boot.veritymode") == "enforcing":
75 disable_verity_result = ad.adb.disable_verity()
76 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +080077 remount_result = ad.adb.remount()
78 ad.log.info("Attempt %d - %s" % (retries + 1, remount_result))
jasonkmlu81b8b032019-06-21 15:18:27 +080079 if "remount succeeded" in remount_result:
jasonkmluff0d5b92019-03-21 11:24:45 +080080 break
jasonkmlu214f0d62019-04-08 19:53:59 +080081
jasonkmlu0f546de2019-12-13 20:58:41 +080082
jasonkmlu214f0d62019-04-08 19:53:59 +080083def reboot(ad):
84 """Reboot device and check if mobile data is available.
85
86 Args:
87 ad: An AndroidDevice object.
88 """
89 ad.log.info("Reboot device to make changes take effect.")
90 ad.reboot()
91 ad.unlock_screen(password=None)
92 if not int(ad.adb.shell("settings get global mobile_data")) == 1:
93 set_mobile_data(ad, True)
jasonkmlu49c32812019-04-12 18:11:10 +080094 utils.sync_device_time(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +080095
jasonkmlu0f546de2019-12-13 20:58:41 +080096
jasonkmluff0d5b92019-03-21 11:24:45 +080097def enable_gnss_verbose_logging(ad):
jasonkmlu81b8b032019-06-21 15:18:27 +080098 """Enable GNSS VERBOSE Logging and persistent logcat.
jasonkmluff0d5b92019-03-21 11:24:45 +080099
100 Args:
101 ad: An AndroidDevice object.
102 """
103 remount_device(ad)
jasonkmlu97ac56e2019-05-29 15:04:51 +0800104 ad.log.info("Enable GNSS VERBOSE Logging and persistent logcat.")
Scott Hongaccd8a12020-03-03 20:12:17 +0800105 ad.adb.shell("echo -e '\nDEBUG_LEVEL = 5' >> /vendor/etc/gps.conf")
jasonkmlu38bd4d12019-10-04 16:38:48 +0800106 ad.adb.shell("echo %r >> /data/local.prop" % LOCAL_PROP_FILE_CONTENTS)
jasonkmluff0d5b92019-03-21 11:24:45 +0800107 ad.adb.shell("chmod 644 /data/local.prop")
jasonkmluc1ec3052019-10-25 14:57:53 +0800108 ad.adb.shell("setprop persist.logd.logpersistd.size 20000")
jasonkmlu180a08c2019-04-23 17:24:55 +0800109 ad.adb.shell("setprop persist.logd.size 16777216")
jasonkmluff0d5b92019-03-21 11:24:45 +0800110 ad.adb.shell("setprop persist.vendor.radio.adb_log_on 1")
jasonkmlu81b8b032019-06-21 15:18:27 +0800111 ad.adb.shell("setprop persist.logd.logpersistd logcatd")
jasonkmluff0d5b92019-03-21 11:24:45 +0800112 ad.adb.shell("setprop log.tag.copresGcore VERBOSE")
113 ad.adb.shell("sync")
114
jasonkmlu0f546de2019-12-13 20:58:41 +0800115
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800116def get_am_flags(value):
117 """Returns the (value, type) flags for a given python value."""
118 if type(value) is bool:
119 return str(value).lower(), 'boolean'
120 elif type(value) is str:
121 return value, 'string'
122 raise ValueError("%s should be either 'boolean' or 'string'" % value)
123
124
jasonkmlu81b8b032019-06-21 15:18:27 +0800125def enable_compact_and_particle_fusion_log(ad):
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800126 """Enable CompactLog, FLP particle fusion log and disable gms
127 location-based quake monitoring.
jasonkmlu81b8b032019-06-21 15:18:27 +0800128
129 Args:
130 ad: An AndroidDevice object.
131 """
132 ad.root_adb()
jasonkmlu8cc1c1e2020-01-06 17:18:27 +0800133 ad.log.info("Enable FLP flags and Disable GMS location-based quake "
134 "monitoring.")
135 overrides = {
136 'compact_log_enabled': True,
137 'flp_use_particle_fusion': True,
138 'flp_particle_fusion_extended_bug_report': True,
139 'flp_event_log_size': '86400',
140 'proks_config': '28',
141 'flp_particle_fusion_bug_report_window_sec': '86400',
142 'flp_particle_fusion_bug_report_max_buffer_size': '86400',
143 'seismic_data_collection': False,
144 'Ealert__enable': False,
145 }
146 for flag, python_value in overrides.items():
147 value, type = get_am_flags(python_value)
148 cmd = ("am broadcast -a com.google.android.gms.phenotype.FLAG_OVERRIDE "
149 "--es package com.google.android.location --es user \* "
150 "--esa flags %s --esa values %s --esa types %s "
151 "com.google.android.gms" % (flag, value, type))
152 ad.adb.shell(cmd)
jasonkmlu81b8b032019-06-21 15:18:27 +0800153 ad.adb.shell("am force-stop com.google.android.gms")
154 ad.adb.shell("am broadcast -a com.google.android.gms.INITIALIZE")
jasonkmlu81b8b032019-06-21 15:18:27 +0800155
jasonkmlu0f546de2019-12-13 20:58:41 +0800156
jasonkmluff0d5b92019-03-21 11:24:45 +0800157def disable_xtra_throttle(ad):
158 """Disable XTRA throttle will have no limit to download XTRA data.
159
160 Args:
161 ad: An AndroidDevice object.
162 """
163 remount_device(ad)
164 ad.log.info("Disable XTRA Throttle.")
Scott Hongaccd8a12020-03-03 20:12:17 +0800165 ad.adb.shell("echo -e '\nXTRA_TEST_ENABLED=1' >> /vendor/etc/gps.conf")
166 ad.adb.shell("echo -e '\nXTRA_THROTTLE_ENABLED=0' >> /vendor/etc/gps.conf")
jasonkmluff0d5b92019-03-21 11:24:45 +0800167
jasonkmlu0f546de2019-12-13 20:58:41 +0800168
jasonkmluff0d5b92019-03-21 11:24:45 +0800169def enable_supl_mode(ad):
170 """Enable SUPL back on for next test item.
171
172 Args:
173 ad: An AndroidDevice object.
174 """
175 remount_device(ad)
176 ad.log.info("Enable SUPL mode.")
Scott Hongaccd8a12020-03-03 20:12:17 +0800177 ad.adb.shell("echo -e '\nSUPL_MODE=1' >> /etc/gps_debug.conf")
jasonkmluff0d5b92019-03-21 11:24:45 +0800178
jasonkmlu0f546de2019-12-13 20:58:41 +0800179
jasonkmluff0d5b92019-03-21 11:24:45 +0800180def disable_supl_mode(ad):
181 """Kill SUPL to test XTRA only test item.
182
183 Args:
184 ad: An AndroidDevice object.
185 """
186 remount_device(ad)
187 ad.log.info("Disable SUPL mode.")
Scott Hongaccd8a12020-03-03 20:12:17 +0800188 ad.adb.shell("echo -e '\nSUPL_MODE=0' >> /etc/gps_debug.conf")
jasonkmlu214f0d62019-04-08 19:53:59 +0800189 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800190
jasonkmlu0f546de2019-12-13 20:58:41 +0800191
jasonkmluff0d5b92019-03-21 11:24:45 +0800192def kill_xtra_daemon(ad):
193 """Kill XTRA daemon to test SUPL only test item.
194
195 Args:
196 ad: An AndroidDevice object.
197 """
198 ad.root_adb()
199 ad.log.info("Disable XTRA-daemon until next reboot.")
200 ad.adb.shell("killall xtra-daemon")
201
jasonkmlu0f546de2019-12-13 20:58:41 +0800202
jasonkmluff0d5b92019-03-21 11:24:45 +0800203def disable_private_dns_mode(ad):
204 """Due to b/118365122, it's better to disable private DNS mode while
205 testing. 8.8.8.8 private dns sever is unstable now, sometimes server
206 will not response dns query suddenly.
207
208 Args:
209 ad: An AndroidDevice object.
210 """
211 tutils.get_operator_name(ad.log, ad, subId=None)
212 if ad.adb.shell("settings get global private_dns_mode") != "off":
213 ad.log.info("Disable Private DNS mode.")
214 ad.adb.shell("settings put global private_dns_mode off")
215
jasonkmlu0f546de2019-12-13 20:58:41 +0800216
jasonkmluff0d5b92019-03-21 11:24:45 +0800217def _init_device(ad):
218 """Init GNSS test devices.
219
220 Args:
221 ad: An AndroidDevice object.
222 """
223 enable_gnss_verbose_logging(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800224 enable_compact_and_particle_fusion_log(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800225 disable_xtra_throttle(ad)
226 enable_supl_mode(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800227 ad.adb.shell("settings put system screen_off_timeout 1800000")
228 wutils.wifi_toggle_state(ad, False)
229 ad.log.info("Setting Bluetooth state to False")
230 ad.droid.bluetoothToggleState(False)
jasonkmluff0d5b92019-03-21 11:24:45 +0800231 set_gnss_qxdm_mask(ad, QXDM_MASKS)
jasonkmluff0d5b92019-03-21 11:24:45 +0800232 check_location_service(ad)
233 set_wifi_and_bt_scanning(ad, True)
jasonkmlu214f0d62019-04-08 19:53:59 +0800234 disable_private_dns_mode(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800235 init_gtw_gpstool(ad)
jasonkmlu180a08c2019-04-23 17:24:55 +0800236 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800237
jasonkmlu0f546de2019-12-13 20:58:41 +0800238
jasonkmluff0d5b92019-03-21 11:24:45 +0800239def connect_to_wifi_network(ad, network):
240 """Connection logic for open and psk wifi networks.
241
242 Args:
243 ad: An AndroidDevice object.
244 network: Dictionary with network info.
245 """
246 SSID = network[WifiEnums.SSID_KEY]
jasonkmlub663d3e2019-12-30 15:11:07 +0800247 ad.ed.clear_all_events()
248 wutils.reset_wifi(ad)
249 wutils.start_wifi_connection_scan_and_ensure_network_found(ad, SSID)
jasonkmluff0d5b92019-03-21 11:24:45 +0800250 wutils.wifi_connect(ad, network, num_of_tries=5)
251
jasonkmlu0f546de2019-12-13 20:58:41 +0800252
jasonkmluff0d5b92019-03-21 11:24:45 +0800253def set_wifi_and_bt_scanning(ad, state=True):
254 """Set Wi-Fi and Bluetooth scanning on/off in Settings -> Location
255
256 Args:
257 ad: An AndroidDevice object.
jasonkmlu81b8b032019-06-21 15:18:27 +0800258 state: True to turn on "Wi-Fi and Bluetooth scanning".
259 False to turn off "Wi-Fi and Bluetooth scanning".
jasonkmluff0d5b92019-03-21 11:24:45 +0800260 """
261 ad.root_adb()
262 if state:
263 ad.adb.shell("settings put global wifi_scan_always_enabled 1")
264 ad.adb.shell("settings put global ble_scan_always_enabled 1")
265 ad.log.info("Wi-Fi and Bluetooth scanning are enabled")
266 else:
267 ad.adb.shell("settings put global wifi_scan_always_enabled 0")
268 ad.adb.shell("settings put global ble_scan_always_enabled 0")
269 ad.log.info("Wi-Fi and Bluetooth scanning are disabled")
270
jasonkmlu0f546de2019-12-13 20:58:41 +0800271
jasonkmluff0d5b92019-03-21 11:24:45 +0800272def check_location_service(ad):
273 """Set location service on.
274 Verify if location service is available.
275
276 Args:
277 ad: An AndroidDevice object.
jasonkmluff0d5b92019-03-21 11:24:45 +0800278 """
jasonkmlu81b8b032019-06-21 15:18:27 +0800279 remount_device(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800280 utils.set_location_service(ad, True)
jasonkmlu81b8b032019-06-21 15:18:27 +0800281 location_mode = int(ad.adb.shell("settings get secure location_mode"))
282 ad.log.info("Current Location Mode >> %d" % location_mode)
283 if location_mode != 3:
jasonkmlu78540632019-11-15 18:04:20 +0800284 raise signals.TestError("Failed to turn Location on")
jasonkmluff0d5b92019-03-21 11:24:45 +0800285
jasonkmlu0f546de2019-12-13 20:58:41 +0800286
jasonkmluff0d5b92019-03-21 11:24:45 +0800287def clear_logd_gnss_qxdm_log(ad):
288 """Clear /data/misc/logd,
289 /storage/emulated/0/Android/data/com.android.gpstool/files and
290 /data/vendor/radio/diag_logs/logs from previous test item then reboot.
291
292 Args:
293 ad: An AndroidDevice object.
294 """
295 remount_device(ad)
296 ad.log.info("Clear Logd, GNSS and QXDM Log from previous test item.")
297 ad.adb.shell("rm -rf /data/misc/logd", ignore_status=True)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800298 ad.adb.shell('find %s -name "*.txt" -type f -delete' % GNSSSTATUS_LOG_PATH)
299 output_path = posixpath.join(DEFAULT_QXDM_LOG_PATH, "logs")
jasonkmluff0d5b92019-03-21 11:24:45 +0800300 ad.adb.shell("rm -rf %s" % output_path, ignore_status=True)
jasonkmlu214f0d62019-04-08 19:53:59 +0800301 reboot(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800302
jasonkmlu0f546de2019-12-13 20:58:41 +0800303
jasonkmlu81b8b032019-06-21 15:18:27 +0800304def get_gnss_qxdm_log(ad, qdb_path):
jasonkmluff0d5b92019-03-21 11:24:45 +0800305 """Get /storage/emulated/0/Android/data/com.android.gpstool/files and
jasonkmlu81b8b032019-06-21 15:18:27 +0800306 /data/vendor/radio/diag_logs/logs for test item.
jasonkmluff0d5b92019-03-21 11:24:45 +0800307
308 Args:
309 ad: An AndroidDevice object.
jasonkmlu81b8b032019-06-21 15:18:27 +0800310 qdb_path: The path of qdsp6m.qdb on different projects.
jasonkmluff0d5b92019-03-21 11:24:45 +0800311 """
jasonkmlu903ece82019-05-16 14:56:19 +0800312 log_path = ad.device_log_path
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800313 os.makedirs(log_path, exist_ok=True)
jasonkmlu903ece82019-05-16 14:56:19 +0800314 gnss_log_name = "gnssstatus_log_%s_%s" % (ad.model, ad.serial)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800315 gnss_log_path = posixpath.join(log_path, gnss_log_name)
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800316 os.makedirs(gnss_log_path, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800317 ad.log.info("Pull GnssStatus Log to %s" % gnss_log_path)
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800318 ad.adb.pull("%s %s" % (GNSSSTATUS_LOG_PATH+".", gnss_log_path),
jasonkmluff0d5b92019-03-21 11:24:45 +0800319 timeout=PULL_TIMEOUT, ignore_status=True)
jasonkmlu903ece82019-05-16 14:56:19 +0800320 shutil.make_archive(gnss_log_path, "zip", gnss_log_path)
321 shutil.rmtree(gnss_log_path)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800322 output_path = posixpath.join(DEFAULT_QXDM_LOG_PATH, "logs/.")
jasonkmlu035eee12019-10-08 17:11:20 +0800323 file_count = ad.adb.shell(
324 "find %s -type f -iname *.qmdl | wc -l" % output_path)
jasonkmluff0d5b92019-03-21 11:24:45 +0800325 if not int(file_count) == 0:
jasonkmlu903ece82019-05-16 14:56:19 +0800326 qxdm_log_name = "QXDM_%s_%s" % (ad.model, ad.serial)
jasonkmlu670cfbc2019-11-27 18:58:21 +0800327 qxdm_log_path = posixpath.join(log_path, qxdm_log_name)
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800328 os.makedirs(qxdm_log_path, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800329 ad.log.info("Pull QXDM Log %s to %s" % (output_path, qxdm_log_path))
330 ad.adb.pull("%s %s" % (output_path, qxdm_log_path),
331 timeout=PULL_TIMEOUT, ignore_status=True)
jasonkmlu81b8b032019-06-21 15:18:27 +0800332 for path in qdb_path:
333 output = ad.adb.pull("%s %s" % (path, qxdm_log_path),
334 timeout=PULL_TIMEOUT, ignore_status=True)
335 if "No such file or directory" in output:
336 continue
337 break
jasonkmlu903ece82019-05-16 14:56:19 +0800338 shutil.make_archive(qxdm_log_path, "zip", qxdm_log_path)
339 shutil.rmtree(qxdm_log_path)
jasonkmluff0d5b92019-03-21 11:24:45 +0800340 else:
341 ad.log.error("QXDM file count is %d. There is no QXDM log on device."
342 % int(file_count))
343
jasonkmlu0f546de2019-12-13 20:58:41 +0800344
jasonkmluff0d5b92019-03-21 11:24:45 +0800345def set_mobile_data(ad, state):
346 """Set mobile data on or off and check mobile data state.
347
348 Args:
349 ad: An AndroidDevice object.
350 state: True to enable mobile data. False to disable mobile data.
351 """
352 ad.root_adb()
353 if state:
354 ad.log.info("Enable mobile data.")
355 ad.adb.shell("svc data enable")
356 else:
357 ad.log.info("Disable mobile data.")
358 ad.adb.shell("svc data disable")
359 time.sleep(5)
360 out = int(ad.adb.shell("settings get global mobile_data"))
361 if state and out == 1:
362 ad.log.info("Mobile data is enabled and set to %d" % out)
363 elif not state and out == 0:
364 ad.log.info("Mobile data is disabled and set to %d" % out)
365 else:
366 ad.log.error("Mobile data is at unknown state and set to %d" % out)
367
jasonkmlu0f546de2019-12-13 20:58:41 +0800368
jasonkmlu78540632019-11-15 18:04:20 +0800369def gnss_trigger_modem_ssr_by_adb(ad, dwelltime=60):
370 """Trigger modem SSR crash by adb and verify if modem crash and recover
jasonkmlu035eee12019-10-08 17:11:20 +0800371 successfully.
jasonkmluff0d5b92019-03-21 11:24:45 +0800372
373 Args:
374 ad: An AndroidDevice object.
jasonkmlu78540632019-11-15 18:04:20 +0800375 dwelltime: Waiting time for modem reset. Default is 60 seconds.
jasonkmluff0d5b92019-03-21 11:24:45 +0800376
377 Returns:
jasonkmlu81b8b032019-06-21 15:18:27 +0800378 True if success.
379 False if failed.
jasonkmluff0d5b92019-03-21 11:24:45 +0800380 """
jasonkmlu81b8b032019-06-21 15:18:27 +0800381 begin_time = get_current_epoch_time()
382 ad.root_adb()
383 cmds = ("echo restart > /sys/kernel/debug/msm_subsys/modem",
384 r"echo 'at+cfun=1,1\r' > /dev/at_mdm0")
385 for cmd in cmds:
386 ad.log.info("Triggering modem SSR crash by %s" % cmd)
387 output = ad.adb.shell(cmd, ignore_status=True)
388 if "No such file or directory" in output:
389 continue
390 break
391 time.sleep(dwelltime)
jasonkmluff0d5b92019-03-21 11:24:45 +0800392 ad.send_keycode("HOME")
jasonkmlu81b8b032019-06-21 15:18:27 +0800393 logcat_results = ad.search_logcat("SSRObserver", begin_time)
394 if logcat_results:
395 for ssr in logcat_results:
396 if "mSubsystem='modem', mCrashReason" in ssr["log_message"]:
397 ad.log.debug(ssr["log_message"])
398 ad.log.info("Triggering modem SSR crash successfully.")
399 return True
jasonkmlu78540632019-11-15 18:04:20 +0800400 raise signals.TestError("Failed to trigger modem SSR crash")
401 raise signals.TestError("No SSRObserver found in logcat")
402
jasonkmlu0f546de2019-12-13 20:58:41 +0800403
jasonkmlu78540632019-11-15 18:04:20 +0800404def gnss_trigger_modem_ssr_by_mds(ad, dwelltime=60):
405 """Trigger modem SSR crash by mds tool and verify if modem crash and recover
406 successfully.
407
408 Args:
409 ad: An AndroidDevice object.
410 dwelltime: Waiting time for modem reset. Default is 60 seconds.
411 """
412 mds_check = ad.adb.shell("pm path com.google.mdstest")
413 if not mds_check:
414 raise signals.TestError("MDS Tool is not properly installed.")
415 ad.root_adb()
416 cmd = ('am instrument -w -e request "4b 25 03 00" '
417 '"com.google.mdstest/com.google.mdstest.instrument'
418 '.ModemCommandInstrumentation"')
419 ad.log.info("Triggering modem SSR crash by MDS")
420 output = ad.adb.shell(cmd, ignore_status=True)
421 ad.log.debug(output)
422 time.sleep(dwelltime)
423 ad.send_keycode("HOME")
424 if "SUCCESS" in output:
425 ad.log.info("Triggering modem SSR crash by MDS successfully.")
426 else:
427 raise signals.TestError(
428 "Failed to trigger modem SSR crash by MDS. \n%s" % output)
429
jasonkmlu0f546de2019-12-13 20:58:41 +0800430
jasonkmlu78540632019-11-15 18:04:20 +0800431def pull_mdstool(ad):
432 """Pull ModemDiagnosticSystemTest.apk from device.
433
434 Args:
435 ad: An AndroidDevice object.
436 """
437 out = ad.adb.shell("pm path com.google.mdstest")
438 result = re.search(r"package:(.*)", out)
439 if not result:
440 raise signals.TestError("No ModemDiagnosticSystemTest.apk found.")
441 else:
442 mds_tool = result.group(1)
443 ad.log.info("Get ModemDiagnosticSystemTest.apk from %s" % mds_tool)
444 apkdir = "/tmp/MDS/"
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800445 os.makedirs(apkdir, exist_ok=True)
jasonkmlu78540632019-11-15 18:04:20 +0800446 ad.pull_files([mds_tool], apkdir)
447
jasonkmlu0f546de2019-12-13 20:58:41 +0800448
jasonkmlu78540632019-11-15 18:04:20 +0800449def reinstall_mdstool(ad):
450 """Reinstall ModemDiagnosticSystemTest.apk.
451
452 Args:
453 ad: An AndroidDevice object.
454 """
455 ad.log.info("Re-install ModemDiagnosticSystemTest.apk")
456 ad.adb.install("-r -g -t /tmp/MDS/base.apk")
457 mds_check = ad.adb.shell("pm path com.google.mdstest")
458 if not mds_check:
459 raise signals.TestError("MDS Tool is not properly re-installed.")
460 ad.log.info("MDS Tool is re-installed successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800461
jasonkmlu0f546de2019-12-13 20:58:41 +0800462
jasonkmluff0d5b92019-03-21 11:24:45 +0800463def check_xtra_download(ad, begin_time):
464 """Verify XTRA download success log message in logcat.
465
466 Args:
467 ad: An AndroidDevice object.
468 begin_time: test begin time
469
470 Returns:
471 True: xtra_download if XTRA downloaded and injected successfully
472 otherwise return False.
473 """
474 ad.send_keycode("HOME")
475 logcat_results = ad.search_logcat("XTRA download success. "
476 "inject data into modem", begin_time)
477 if logcat_results:
jasonkmlu81b8b032019-06-21 15:18:27 +0800478 ad.log.debug("%s" % logcat_results[-1]["log_message"])
jasonkmluff0d5b92019-03-21 11:24:45 +0800479 ad.log.info("XTRA downloaded and injected successfully.")
480 return True
481 ad.log.error("XTRA downloaded FAIL.")
482 return False
483
jasonkmlu0f546de2019-12-13 20:58:41 +0800484
jasonkmluff0d5b92019-03-21 11:24:45 +0800485def pull_gtw_gpstool(ad):
486 """Pull GTW_GPSTool apk from device.
487
488 Args:
489 ad: An AndroidDevice object.
490 """
491 out = ad.adb.shell("pm path com.android.gpstool")
492 result = re.search(r"package:(.*)", out)
493 if not result:
494 tutils.abort_all_tests(ad.log, "Couldn't find GTW GPSTool apk")
495 else:
496 GTW_GPSTool_apk = result.group(1)
497 ad.log.info("Get GTW GPSTool apk from %s" % GTW_GPSTool_apk)
498 apkdir = "/tmp/GNSS/"
Mark De Ruyter72f8df92020-02-12 13:44:49 -0800499 os.makedirs(apkdir, exist_ok=True)
jasonkmluff0d5b92019-03-21 11:24:45 +0800500 ad.pull_files([GTW_GPSTool_apk], apkdir)
501
jasonkmlu0f546de2019-12-13 20:58:41 +0800502
jasonkmluff0d5b92019-03-21 11:24:45 +0800503def reinstall_gtw_gpstool(ad):
504 """Reinstall GTW_GPSTool apk.
505
506 Args:
507 ad: An AndroidDevice object.
508 """
509 ad.log.info("Re-install GTW GPSTool")
jasonkmlu903ece82019-05-16 14:56:19 +0800510 ad.adb.install("-r -g -t /tmp/GNSS/base.apk")
jasonkmlu78540632019-11-15 18:04:20 +0800511 gpstool_check = ad.adb.shell("pm path com.android.gpstool")
512 if not gpstool_check:
513 raise signals.TestError("GTW GPSTool is not properly re-installed.")
514 ad.log.info("GTW GPSTool is re-installed successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800515
jasonkmlu0f546de2019-12-13 20:58:41 +0800516
jasonkmlu180a08c2019-04-23 17:24:55 +0800517def init_gtw_gpstool(ad):
518 """Init GTW_GPSTool apk.
519
520 Args:
521 ad: An AndroidDevice object.
522 """
523 remount_device(ad)
524 pull_gtw_gpstool(ad)
525 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
jasonkmlu180a08c2019-04-23 17:24:55 +0800526 reinstall_gtw_gpstool(ad)
527
jasonkmlu0f546de2019-12-13 20:58:41 +0800528
jasonkmluff0d5b92019-03-21 11:24:45 +0800529def fastboot_factory_reset(ad):
530 """Factory reset the device in fastboot mode.
531 Pull sl4a apk from device. Terminate all sl4a sessions,
532 Reboot the device to bootloader,
533 factory reset the device by fastboot.
534 Reboot the device. wait for device to complete booting
535 Re-install and start an sl4a session.
536
537 Args:
538 ad: An AndroidDevice object.
539
540 Returns:
541 True if factory reset process complete.
542 """
543 status = True
544 skip_setup_wizard = True
545 out = ad.adb.shell("pm path %s" % SL4A_APK_NAME)
546 result = re.search(r"package:(.*)", out)
547 if not result:
548 tutils.abort_all_tests(ad.log, "Couldn't find sl4a apk")
549 else:
550 sl4a_apk = result.group(1)
551 ad.log.info("Get sl4a apk from %s" % sl4a_apk)
552 ad.pull_files([sl4a_apk], "/tmp/")
553 pull_gtw_gpstool(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800554 pull_mdstool(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800555 tutils.stop_qxdm_logger(ad)
556 ad.stop_services()
557 attempts = 3
558 for i in range(1, attempts + 1):
559 try:
560 if ad.serial in list_adb_devices():
561 ad.log.info("Reboot to bootloader")
562 ad.adb.reboot("bootloader", ignore_status=True)
563 time.sleep(10)
564 if ad.serial in list_fastboot_devices():
565 ad.log.info("Factory reset in fastboot")
566 ad.fastboot._w(timeout=300, ignore_status=True)
567 time.sleep(30)
568 ad.log.info("Reboot in fastboot")
569 ad.fastboot.reboot()
570 ad.wait_for_boot_completion()
571 ad.root_adb()
572 if ad.skip_sl4a:
573 break
574 if ad.is_sl4a_installed():
575 break
576 ad.log.info("Re-install sl4a")
577 ad.adb.shell("settings put global verifier_verify_adb_installs 0")
jasonkmlu903ece82019-05-16 14:56:19 +0800578 ad.adb.install("-r -g -t /tmp/base.apk")
jasonkmluff0d5b92019-03-21 11:24:45 +0800579 reinstall_gtw_gpstool(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800580 reinstall_mdstool(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800581 time.sleep(10)
582 break
583 except Exception as e:
584 ad.log.error(e)
585 if i == attempts:
586 tutils.abort_all_tests(ad.log, str(e))
587 time.sleep(5)
588 try:
589 ad.start_adb_logcat()
590 except Exception as e:
591 ad.log.error(e)
592 if skip_setup_wizard:
593 ad.exit_setup_wizard()
594 if ad.skip_sl4a:
595 return status
596 tutils.bring_up_sl4a(ad)
jasonkmluff0d5b92019-03-21 11:24:45 +0800597 return status
598
jasonkmlu0f546de2019-12-13 20:58:41 +0800599
jasonkmluff0d5b92019-03-21 11:24:45 +0800600def clear_aiding_data_by_gtw_gpstool(ad):
601 """Launch GTW GPSTool and Clear all GNSS aiding data.
602 Wait 5 seconds for GTW GPStool to clear all GNSS aiding
603 data properly.
604
605 Args:
606 ad: An AndroidDevice object.
607 """
608 ad.log.info("Launch GTW GPSTool and Clear all GNSS aiding data")
609 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool --es mode clear")
610 time.sleep(10)
611
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700612
613def start_gnss_by_gtw_gpstool(ad, state, type="gnss", bgdisplay=False):
jasonkmluff0d5b92019-03-21 11:24:45 +0800614 """Start or stop GNSS on GTW_GPSTool.
615
616 Args:
617 ad: An AndroidDevice object.
618 state: True to start GNSS. False to Stop GNSS.
jasonkmlu81b8b032019-06-21 15:18:27 +0800619 type: Different API for location fix. Use gnss/flp/nmea
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700620 bgdisplay: true to run GTW when Display off.
621 false to not run GTW when Display off.
jasonkmluff0d5b92019-03-21 11:24:45 +0800622 """
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700623 if state and not bgdisplay:
jasonkmlu81b8b032019-06-21 15:18:27 +0800624 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool "
625 "--es mode gps --es type %s" % type)
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700626 elif state and bgdisplay:
jasonkmlu0f546de2019-12-13 20:58:41 +0800627 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool --es mode "
628 "gps --es type {} --ez BG {}".format(type, bgdisplay))
jasonkmluff0d5b92019-03-21 11:24:45 +0800629 if not state:
jasonkmlu81b8b032019-06-21 15:18:27 +0800630 ad.log.info("Stop %s on GTW_GPSTool." % type)
jasonkmluff0d5b92019-03-21 11:24:45 +0800631 ad.adb.shell("am broadcast -a com.android.gpstool.stop_gps_action")
632 time.sleep(3)
633
Jayakumar Munuswamybc6038c2019-10-30 14:46:38 -0700634
jasonkmlu81b8b032019-06-21 15:18:27 +0800635def process_gnss_by_gtw_gpstool(ad, criteria, type="gnss"):
jasonkmluff0d5b92019-03-21 11:24:45 +0800636 """Launch GTW GPSTool and Clear all GNSS aiding data
637 Start GNSS tracking on GTW_GPSTool.
638
639 Args:
640 ad: An AndroidDevice object.
641 criteria: Criteria for current test item.
jasonkmlu81b8b032019-06-21 15:18:27 +0800642 type: Different API for location fix. Use gnss/flp/nmea
jasonkmluff0d5b92019-03-21 11:24:45 +0800643
644 Returns:
645 True: First fix TTFF are within criteria.
646 False: First fix TTFF exceed criteria.
647 """
648 retries = 3
649 for i in range(retries):
650 begin_time = get_current_epoch_time()
651 clear_aiding_data_by_gtw_gpstool(ad)
jasonkmlu035eee12019-10-08 17:11:20 +0800652 ad.log.info("Start %s on GTW_GPSTool - attempt %d" % (type.upper(),
653 i+1))
jasonkmlu81b8b032019-06-21 15:18:27 +0800654 start_gnss_by_gtw_gpstool(ad, True, type)
jasonkmluff0d5b92019-03-21 11:24:45 +0800655 for _ in range(10 + criteria):
656 logcat_results = ad.search_logcat("First fixed", begin_time)
657 if logcat_results:
jasonkmlu81b8b032019-06-21 15:18:27 +0800658 ad.log.debug(logcat_results[-1]["log_message"])
jasonkmluff0d5b92019-03-21 11:24:45 +0800659 first_fixed = int(logcat_results[-1]["log_message"].split()[-1])
jasonkmlu81b8b032019-06-21 15:18:27 +0800660 ad.log.info("%s First fixed = %.3f seconds" %
661 (type.upper(), first_fixed/1000))
662 if (first_fixed/1000) <= criteria:
jasonkmluff0d5b92019-03-21 11:24:45 +0800663 return True
jasonkmlu81b8b032019-06-21 15:18:27 +0800664 start_gnss_by_gtw_gpstool(ad, False, type)
jasonkmlu035eee12019-10-08 17:11:20 +0800665 raise signals.TestFailure("Fail to get %s location fixed "
666 "within %d seconds criteria."
667 % (type.upper(), criteria))
jasonkmluff0d5b92019-03-21 11:24:45 +0800668 time.sleep(1)
jasonkmlua4a569f2019-04-10 14:25:31 +0800669 if not ad.is_adb_logcat_on:
670 ad.start_adb_logcat()
jasonkmlu97ac56e2019-05-29 15:04:51 +0800671 check_currrent_focus_app(ad)
jasonkmlu81b8b032019-06-21 15:18:27 +0800672 start_gnss_by_gtw_gpstool(ad, False, type)
jasonkmlu035eee12019-10-08 17:11:20 +0800673 raise signals.TestFailure("Fail to get %s location fixed within %d "
674 "attempts." % (type.upper(), retries))
jasonkmluff0d5b92019-03-21 11:24:45 +0800675
Scott Hong72269692019-12-16 16:59:56 +0800676def start_ttff_by_gtw_gpstool(ad, ttff_mode, iteration, aid_data=False):
jasonkmluff0d5b92019-03-21 11:24:45 +0800677 """Identify which TTFF mode for different test items.
678
679 Args:
680 ad: An AndroidDevice object.
681 ttff_mode: TTFF Test mode for current test item.
682 iteration: Iteration of TTFF cycles.
Scott Hong72269692019-12-16 16:59:56 +0800683 aid_data: Boolean for identify aid_data existed or not
jasonkmluff0d5b92019-03-21 11:24:45 +0800684 """
jasonkmlu97ac56e2019-05-29 15:04:51 +0800685 begin_time = get_current_epoch_time()
Scott Hong72269692019-12-16 16:59:56 +0800686 if (ttff_mode == "hs" or ttff_mode == "ws") and not aid_data:
jasonkmlu81b8b032019-06-21 15:18:27 +0800687 ad.log.info("Wait 5 minutes to start TTFF %s..." % ttff_mode.upper())
jasonkmluff0d5b92019-03-21 11:24:45 +0800688 time.sleep(300)
689 if ttff_mode == "cs":
690 ad.log.info("Start TTFF Cold Start...")
691 time.sleep(3)
jasonkmlu97ac56e2019-05-29 15:04:51 +0800692 for i in range(1, 4):
693 ad.adb.shell("am broadcast -a com.android.gpstool.ttff_action "
694 "--es ttff %s --es cycle %d" % (ttff_mode, iteration))
jasonkmlu81b8b032019-06-21 15:18:27 +0800695 time.sleep(1)
jasonkmlu97ac56e2019-05-29 15:04:51 +0800696 if ad.search_logcat("act=com.android.gpstool.start_test_action",
697 begin_time):
698 ad.log.info("Send TTFF start_test_action successfully.")
699 break
jasonkmlu035eee12019-10-08 17:11:20 +0800700 else:
701 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +0800702 raise signals.TestError("Fail to send TTFF start_test_action.")
jasonkmluff0d5b92019-03-21 11:24:45 +0800703
jasonkmlu0f546de2019-12-13 20:58:41 +0800704
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800705def gnss_tracking_via_gtw_gpstool(ad, criteria, type="gnss", testtime=60):
jasonkmlu66fda532019-07-16 11:12:45 +0800706 """Start GNSS/FLP tracking tests for input testtime on GTW_GPSTool.
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800707
708 Args:
709 ad: An AndroidDevice object.
710 criteria: Criteria for current TTFF.
711 type: Different API for location fix. Use gnss/flp/nmea
712 testtime: Tracking test time for minutes. Default set to 60 minutes.
713 """
714 process_gnss_by_gtw_gpstool(ad, criteria, type)
715 ad.log.info("Start %s tracking test for %d minutes" % (type.upper(),
716 testtime))
717 begin_time = get_current_epoch_time()
718 while get_current_epoch_time() - begin_time < testtime * 60 * 1000 :
719 if not ad.is_adb_logcat_on:
720 ad.start_adb_logcat()
721 crash_result = ad.search_logcat("Force finishing activity "
722 "com.android.gpstool/.GPSTool",
723 begin_time)
724 if crash_result:
jasonkmlu78540632019-11-15 18:04:20 +0800725 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800726 ad.log.info("Successfully tested for %d minutes" % testtime)
727 start_gnss_by_gtw_gpstool(ad, False, type)
728
jasonkmlu0f546de2019-12-13 20:58:41 +0800729
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800730def parse_gtw_gpstool_log(ad, true_position, type="gnss"):
731 """Process GNSS/FLP API logs from GTW GPSTool and output track_data to
732 test_run_info for ACTS plugin to parse and display on MobileHarness as
733 Property.
734
735 Args:
736 ad: An AndroidDevice object.
737 true_position: Coordinate as [latitude, longitude] to calculate
738 position error.
739 type: Different API for location fix. Use gnss/flp/nmea
740 """
741 test_logfile = {}
742 track_data = {}
743 history_top4_cn = 0
744 history_cn = 0
jasonkmlu035eee12019-10-08 17:11:20 +0800745 l5flag = "false"
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800746 file_count = int(ad.adb.shell("find %s -type f -iname *.txt | wc -l"
747 % GNSSSTATUS_LOG_PATH))
748 if file_count != 1:
749 ad.log.error("%d API logs exist." % file_count)
750 dir = ad.adb.shell("ls %s" % GNSSSTATUS_LOG_PATH).split()
751 for path_key in dir:
752 if fnmatch.fnmatch(path_key, "*.txt"):
753 logpath = posixpath.join(GNSSSTATUS_LOG_PATH, path_key)
754 out = ad.adb.shell("wc -c %s" % logpath)
755 file_size = int(out.split(" ")[0])
756 if file_size < 2000:
757 ad.log.info("Skip log %s due to log size %d bytes" %
758 (path_key, file_size))
759 continue
760 test_logfile = logpath
761 if not test_logfile:
jasonkmlu78540632019-11-15 18:04:20 +0800762 raise signals.TestError("Failed to get test log file in device.")
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800763 lines = ad.adb.shell("cat %s" % test_logfile).split("\n")
764 for line in lines:
765 if "History Avg Top4" in line:
766 history_top4_cn = float(line.split(":")[-1].strip())
767 if "History Avg" in line:
768 history_cn = float(line.split(":")[-1].strip())
769 if "L5 used in fix" in line:
770 l5flag = line.split(":")[-1].strip()
771 if "Latitude" in line:
772 track_lat = float(line.split(":")[-1].strip())
773 if "Longitude" in line:
774 track_long = float(line.split(":")[-1].strip())
775 if "Time" in line:
776 track_utc = line.split("Time:")[-1].strip()
777 if track_utc in track_data.keys():
778 continue
779 track_pe = calculate_position_error(ad, track_lat, track_long,
780 true_position)
781 track_data[track_utc] = TRACK_REPORT(track_l5flag=l5flag,
782 track_pe=track_pe,
783 track_top4cn=history_top4_cn,
784 track_cn=history_cn)
785 ad.log.debug(track_data)
786 prop_basename = "TestResult %s_tracking_" % type.upper()
787 time_list = sorted(track_data.keys())
788 l5flag_list = [track_data[key].track_l5flag for key in time_list]
789 pe_list = [float(track_data[key].track_pe) for key in time_list]
790 top4cn_list = [float(track_data[key].track_top4cn) for key in time_list]
791 cn_list = [float(track_data[key].track_cn) for key in time_list]
792 ad.log.info(prop_basename+"StartTime %s" % time_list[0].replace(" ", "-"))
793 ad.log.info(prop_basename+"EndTime %s" % time_list[-1].replace(" ", "-"))
794 ad.log.info(prop_basename+"TotalFixPoints %d" % len(time_list))
795 ad.log.info(prop_basename+"L5FixRate "+'{percent:.2%}'.format(
796 percent=l5flag_list.count("true")/len(l5flag_list)))
797 ad.log.info(prop_basename+"AvgDis %.1f" % (sum(pe_list)/len(pe_list)))
798 ad.log.info(prop_basename+"MaxDis %.1f" % max(pe_list))
799 ad.log.info(prop_basename+"AvgTop4Signal %.1f" % top4cn_list[-1])
800 ad.log.info(prop_basename+"AvgSignal %.1f" % cn_list[-1])
801
jasonkmlu0f546de2019-12-13 20:58:41 +0800802
jasonkmlu81b8b032019-06-21 15:18:27 +0800803def process_ttff_by_gtw_gpstool(ad, begin_time, true_position, type="gnss"):
804 """Process TTFF and record results in ttff_data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800805
806 Args:
807 ad: An AndroidDevice object.
jasonkmlu903ece82019-05-16 14:56:19 +0800808 begin_time: test begin time.
jasonkmlu733738f2019-09-02 18:59:42 +0800809 true_position: Coordinate as [latitude, longitude] to calculate
810 position error.
jasonkmlu81b8b032019-06-21 15:18:27 +0800811 type: Different API for location fix. Use gnss/flp/nmea
jasonkmluff0d5b92019-03-21 11:24:45 +0800812
813 Returns:
jasonkmlu81b8b032019-06-21 15:18:27 +0800814 ttff_data: A dict of all TTFF data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800815 """
jasonkmlu903ece82019-05-16 14:56:19 +0800816 ttff_data = {}
jasonkmlu733738f2019-09-02 18:59:42 +0800817 ttff_loop_time = get_current_epoch_time()
jasonkmlu97ac56e2019-05-29 15:04:51 +0800818 while True:
jasonkmlu733738f2019-09-02 18:59:42 +0800819 if get_current_epoch_time() - ttff_loop_time >= 120000:
jasonkmlu78540632019-11-15 18:04:20 +0800820 raise signals.TestError("Fail to search specific GPSService "
821 "message in logcat. Abort test.")
jasonkmlu97ac56e2019-05-29 15:04:51 +0800822 if not ad.is_adb_logcat_on:
823 ad.start_adb_logcat()
824 stop_gps_results = ad.search_logcat("stop gps test", begin_time)
825 if stop_gps_results:
826 ad.send_keycode("HOME")
827 break
828 crash_result = ad.search_logcat("Force finishing activity "
829 "com.android.gpstool/.GPSTool",
830 begin_time)
831 if crash_result:
jasonkmlu78540632019-11-15 18:04:20 +0800832 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu97ac56e2019-05-29 15:04:51 +0800833 logcat_results = ad.search_logcat("write TTFF log", begin_time)
834 if logcat_results:
835 ttff_log = logcat_results[-1]["log_message"].split()
836 ttff_loop = int(ttff_log[8].split(":")[-1])
jasonkmlu97ac56e2019-05-29 15:04:51 +0800837 if ttff_loop in ttff_data.keys():
838 continue
jasonkmlu733738f2019-09-02 18:59:42 +0800839 ttff_loop_time = get_current_epoch_time()
jasonkmlu81b8b032019-06-21 15:18:27 +0800840 ttff_sec = float(ttff_log[11])
841 if ttff_sec != 0.0:
842 ttff_cn = float(ttff_log[18].strip("]"))
843 if type == "gnss":
jasonkmlu733738f2019-09-02 18:59:42 +0800844 gnss_results = ad.search_logcat("GPSService: Check item",
845 begin_time)
jasonkmlu81b8b032019-06-21 15:18:27 +0800846 if gnss_results:
847 ad.log.debug(gnss_results[-1]["log_message"])
jasonkmlu733738f2019-09-02 18:59:42 +0800848 gnss_location_log = \
849 gnss_results[-1]["log_message"].split()
850 ttff_lat = float(
851 gnss_location_log[8].split("=")[-1].strip(","))
852 ttff_lon = float(
853 gnss_location_log[9].split("=")[-1].strip(","))
jasonkmlu81b8b032019-06-21 15:18:27 +0800854 elif type == "flp":
jasonkmlu733738f2019-09-02 18:59:42 +0800855 flp_results = ad.search_logcat("GPSService: FLP Location",
856 begin_time)
jasonkmlu81b8b032019-06-21 15:18:27 +0800857 if flp_results:
858 ad.log.debug(flp_results[-1]["log_message"])
jasonkmlu733738f2019-09-02 18:59:42 +0800859 flp_location_log = \
860 flp_results[-1]["log_message"].split()
jasonkmlu81b8b032019-06-21 15:18:27 +0800861 ttff_lat = float(flp_location_log[8].split(",")[0])
862 ttff_lon = float(flp_location_log[8].split(",")[1])
863 else:
864 ttff_cn = float(ttff_log[19].strip("]"))
jasonkmlu97ac56e2019-05-29 15:04:51 +0800865 ttff_lat = 0.0
866 ttff_lon = 0.0
jasonkmlu2565d892019-11-12 15:31:26 +0800867 ad.log.debug("TTFF Loop %d - (Lat, Lon) = (%s, %s)" % (ttff_loop,
868 ttff_lat,
869 ttff_lon))
jasonkmlu97ac56e2019-05-29 15:04:51 +0800870 ttff_pe = calculate_position_error(ad, ttff_lat, ttff_lon,
871 true_position)
872 ttff_data[ttff_loop] = TTFF_REPORT(ttff_loop=ttff_loop,
873 ttff_sec=ttff_sec,
874 ttff_pe=ttff_pe,
875 ttff_cn=ttff_cn)
876 ad.log.info("Loop %d = %.1f seconds, "
877 "Position Error = %.1f meters, "
878 "Average Signal = %.1f dbHz"
879 % (ttff_loop, ttff_sec, ttff_pe, ttff_cn))
880 return ttff_data
jasonkmluff0d5b92019-03-21 11:24:45 +0800881
jasonkmlu0f546de2019-12-13 20:58:41 +0800882
jasonkmlu903ece82019-05-16 14:56:19 +0800883def check_ttff_data(ad, ttff_data, ttff_mode, criteria):
jasonkmlu81b8b032019-06-21 15:18:27 +0800884 """Verify all TTFF results from ttff_data.
jasonkmluff0d5b92019-03-21 11:24:45 +0800885
886 Args:
887 ad: An AndroidDevice object.
jasonkmlu903ece82019-05-16 14:56:19 +0800888 ttff_data: TTFF data of secs, position error and signal strength.
jasonkmluff0d5b92019-03-21 11:24:45 +0800889 ttff_mode: TTFF Test mode for current test item.
890 criteria: Criteria for current test item.
891
892 Returns:
893 True: All TTFF results are within criteria.
894 False: One or more TTFF results exceed criteria or Timeout.
895 """
896 ad.log.info("%d iterations of TTFF %s tests finished."
jasonkmlu903ece82019-05-16 14:56:19 +0800897 % (len(ttff_data.keys()), ttff_mode))
jasonkmluff0d5b92019-03-21 11:24:45 +0800898 ad.log.info("%s PASS criteria is %d seconds" % (ttff_mode, criteria))
jasonkmlu81b8b032019-06-21 15:18:27 +0800899 ad.log.debug("%s TTFF data: %s" % (ttff_mode, ttff_data))
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800900 ttff_property_key_and_value(ad, ttff_data, ttff_mode)
jasonkmlu903ece82019-05-16 14:56:19 +0800901 if len(ttff_data.keys()) == 0:
jasonkmluff0d5b92019-03-21 11:24:45 +0800902 ad.log.error("GTW_GPSTool didn't process TTFF properly.")
903 return False
jasonkmlu903ece82019-05-16 14:56:19 +0800904 elif any(float(ttff_data[key].ttff_sec) == 0.0 for key in ttff_data.keys()):
jasonkmluff0d5b92019-03-21 11:24:45 +0800905 ad.log.error("One or more TTFF %s Timeout" % ttff_mode)
906 return False
jasonkmlu035eee12019-10-08 17:11:20 +0800907 elif any(float(ttff_data[key].ttff_sec) >= criteria for key in
908 ttff_data.keys()):
jasonkmluff0d5b92019-03-21 11:24:45 +0800909 ad.log.error("One or more TTFF %s are over test criteria %d seconds"
910 % (ttff_mode, criteria))
911 return False
912 ad.log.info("All TTFF %s are within test criteria %d seconds."
913 % (ttff_mode, criteria))
914 return True
915
jasonkmlu0f546de2019-12-13 20:58:41 +0800916
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800917def ttff_property_key_and_value(ad, ttff_data, ttff_mode):
jasonkmlu81b8b032019-06-21 15:18:27 +0800918 """Output ttff_data to test_run_info for ACTS plugin to parse and display
919 on MobileHarness as Property.
920
921 Args:
922 ad: An AndroidDevice object.
923 ttff_data: TTFF data of secs, position error and signal strength.
924 ttff_mode: TTFF Test mode for current test item.
925 """
926 prop_basename = "TestResult "+ttff_mode.replace(" ", "_")+"_TTFF_"
927 sec_list = [float(ttff_data[key].ttff_sec) for key in ttff_data.keys()]
928 pe_list = [float(ttff_data[key].ttff_pe) for key in ttff_data.keys()]
929 cn_list = [float(ttff_data[key].ttff_cn) for key in ttff_data.keys()]
930 timeoutcount = sec_list.count(0.0)
jasonkmluc1ec3052019-10-25 14:57:53 +0800931 if len(sec_list) == timeoutcount:
932 avgttff = 9527
933 else:
934 avgttff = sum(sec_list)/(len(sec_list) - timeoutcount)
jasonkmlu81b8b032019-06-21 15:18:27 +0800935 if timeoutcount != 0:
jasonkmlu4fcdcad2019-07-10 14:35:12 +0800936 maxttff = 9527
jasonkmlu81b8b032019-06-21 15:18:27 +0800937 else:
938 maxttff = max(sec_list)
939 avgdis = sum(pe_list)/len(pe_list)
940 maxdis = max(pe_list)
941 avgcn = sum(cn_list)/len(cn_list)
942 ad.log.info(prop_basename+"AvgTime %.1f" % avgttff)
943 ad.log.info(prop_basename+"MaxTime %.1f" % maxttff)
944 ad.log.info(prop_basename+"TimeoutCount %d" % timeoutcount)
945 ad.log.info(prop_basename+"AvgDis %.1f" % avgdis)
946 ad.log.info(prop_basename+"MaxDis %.1f" % maxdis)
947 ad.log.info(prop_basename+"AvgSignal %.1f" % avgcn)
948
jasonkmlu0f546de2019-12-13 20:58:41 +0800949
jasonkmlu903ece82019-05-16 14:56:19 +0800950def calculate_position_error(ad, latitude, longitude, true_position):
951 """Use haversine formula to calculate position error base on true location
952 coordinate.
953
954 Args:
955 ad: An AndroidDevice object.
956 latitude: latitude of location fixed in the present.
957 longitude: longitude of location fixed in the present.
958 true_position: [latitude, longitude] of true location coordinate.
959
960 Returns:
961 position_error of location fixed in the present.
962 """
963 radius = 6371009
964 dlat = math.radians(latitude - true_position[0])
965 dlon = math.radians(longitude - true_position[1])
966 a = math.sin(dlat/2) * math.sin(dlat/2) + \
967 math.cos(math.radians(true_position[0])) * \
968 math.cos(math.radians(latitude)) * math.sin(dlon/2) * math.sin(dlon/2)
969 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
970 return radius * c
971
jasonkmlu0f546de2019-12-13 20:58:41 +0800972
jasonkmluff0d5b92019-03-21 11:24:45 +0800973def launch_google_map(ad):
974 """Launch Google Map via intent.
975
976 Args:
977 ad: An AndroidDevice object.
978 """
979 ad.log.info("Launch Google Map.")
980 try:
981 ad.adb.shell("am start -S -n com.google.android.apps.maps/"
982 "com.google.android.maps.MapsActivity")
983 ad.send_keycode("BACK")
984 ad.force_stop_apk("com.google.android.apps.maps")
985 ad.adb.shell("am start -S -n com.google.android.apps.maps/"
986 "com.google.android.maps.MapsActivity")
987 except Exception as e:
988 ad.log.error(e)
jasonkmlu78540632019-11-15 18:04:20 +0800989 raise signals.TestError("Failed to launch google map.")
jasonkmlu903ece82019-05-16 14:56:19 +0800990 check_currrent_focus_app(ad)
jasonkmlu49c32812019-04-12 18:11:10 +0800991
jasonkmlu0f546de2019-12-13 20:58:41 +0800992
jasonkmlu903ece82019-05-16 14:56:19 +0800993def check_currrent_focus_app(ad):
994 """Check to see current focused window and app.
jasonkmlu49c32812019-04-12 18:11:10 +0800995
996 Args:
997 ad: An AndroidDevice object.
jasonkmlu49c32812019-04-12 18:11:10 +0800998 """
jasonkmlu903ece82019-05-16 14:56:19 +0800999 time.sleep(1)
jasonkmlu035eee12019-10-08 17:11:20 +08001000 current = ad.adb.shell(
1001 "dumpsys window | grep -E 'mCurrentFocus|mFocusedApp'")
jasonkmlu81b8b032019-06-21 15:18:27 +08001002 ad.log.debug("\n"+current)
jasonkmluff0d5b92019-03-21 11:24:45 +08001003
jasonkmlu0f546de2019-12-13 20:58:41 +08001004
jasonkmluff0d5b92019-03-21 11:24:45 +08001005def check_location_api(ad, retries):
1006 """Verify if GnssLocationProvider API reports location.
1007
1008 Args:
1009 ad: An AndroidDevice object.
1010 retries: Retry time.
1011
1012 Returns:
1013 True: GnssLocationProvider API reports location.
1014 otherwise return False.
1015 """
1016 for i in range(retries):
1017 begin_time = get_current_epoch_time()
1018 ad.log.info("Try to get location report from GnssLocationProvider API "
1019 "- attempt %d" % (i+1))
1020 while get_current_epoch_time() - begin_time <= 30000:
1021 logcat_results = ad.search_logcat("REPORT_LOCATION", begin_time)
1022 if logcat_results:
1023 ad.log.info("%s" % logcat_results[-1]["log_message"])
jasonkmlu035eee12019-10-08 17:11:20 +08001024 ad.log.info("GnssLocationProvider reports location "
1025 "successfully.")
jasonkmluff0d5b92019-03-21 11:24:45 +08001026 return True
1027 if not ad.is_adb_logcat_on:
1028 ad.start_adb_logcat()
1029 ad.log.error("GnssLocationProvider is unable to report location.")
1030 return False
1031
Scott Hong72269692019-12-16 16:59:56 +08001032def check_network_location(ad, retries, location_type, criteria=30):
jasonkmluff0d5b92019-03-21 11:24:45 +08001033 """Verify if NLP reports location after requesting via GPSTool.
1034
1035 Args:
1036 ad: An AndroidDevice object.
1037 retries: Retry time.
Scott Hongaccd8a12020-03-03 20:12:17 +08001038 location_type: cell or wifi.
Scott Hong72269692019-12-16 16:59:56 +08001039 criteria: expected nlp return time, default 30 seconds
jasonkmluff0d5b92019-03-21 11:24:45 +08001040
1041 Returns:
1042 True: NLP reports location.
1043 otherwise return False.
1044 """
Scott Hong72269692019-12-16 16:59:56 +08001045 criteria = criteria * 1000
Scott Hongaccd8a12020-03-03 20:12:17 +08001046 search_pattern = ("GPSTool : networkLocationType = %s" % location_type)
jasonkmluff0d5b92019-03-21 11:24:45 +08001047 for i in range(retries):
jasonkmluff0d5b92019-03-21 11:24:45 +08001048 begin_time = get_current_epoch_time()
1049 ad.log.info("Try to get NLP status - attempt %d" % (i+1))
jasonkmlu035eee12019-10-08 17:11:20 +08001050 ad.adb.shell(
1051 "am start -S -n com.android.gpstool/.GPSTool --es mode nlp")
Scott Hong72269692019-12-16 16:59:56 +08001052 while get_current_epoch_time() - begin_time <= criteria:
Scott Hongaccd8a12020-03-03 20:12:17 +08001053 # Search pattern in 1 second interval
1054 time.sleep(1)
1055 result = ad.search_logcat(search_pattern, begin_time)
1056 if result:
1057 ad.log.info("Pattern Found: %s." % result[-1]["log_message"])
1058 ad.send_keycode("BACK")
1059 return True
jasonkmluff0d5b92019-03-21 11:24:45 +08001060 if not ad.is_adb_logcat_on:
1061 ad.start_adb_logcat()
1062 ad.send_keycode("BACK")
1063 ad.log.error("Unable to report network location \"%s\"." % location_type)
1064 return False
1065
jasonkmlu0f546de2019-12-13 20:58:41 +08001066
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001067def set_attenuator_gnss_signal(ad, attenuator, atten_value):
jasonkmluff0d5b92019-03-21 11:24:45 +08001068 """Set attenuation value for different GNSS signal.
1069
1070 Args:
1071 ad: An AndroidDevice object.
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001072 attenuator: The attenuator object.
jasonkmluff0d5b92019-03-21 11:24:45 +08001073 atten_value: attenuation value
1074 """
jasonkmluff0d5b92019-03-21 11:24:45 +08001075 try:
jasonkmlu035eee12019-10-08 17:11:20 +08001076 ad.log.info(
1077 "Set attenuation value to \"%d\" for GNSS signal." % atten_value)
jasonkmlu8d6bbfc2019-03-29 15:57:43 +08001078 attenuator[0].set_atten(atten_value)
jasonkmlu81b8b032019-06-21 15:18:27 +08001079 except Exception as e:
jasonkmlu4fcdcad2019-07-10 14:35:12 +08001080 ad.log.error(e)
jasonkmluff0d5b92019-03-21 11:24:45 +08001081
jasonkmlu0f546de2019-12-13 20:58:41 +08001082
jasonkmluff0d5b92019-03-21 11:24:45 +08001083def set_battery_saver_mode(ad, state):
1084 """Enable or diable battery saver mode via adb.
1085
1086 Args:
1087 ad: An AndroidDevice object.
1088 state: True is enable Battery Saver mode. False is disable.
1089 """
1090 ad.root_adb()
1091 if state:
1092 ad.log.info("Enable Battery Saver mode.")
1093 ad.adb.shell("cmd battery unplug")
1094 ad.adb.shell("settings put global low_power 1")
1095 else:
1096 ad.log.info("Disable Battery Saver mode.")
1097 ad.adb.shell("settings put global low_power 0")
1098 ad.adb.shell("cmd battery reset")
1099
jasonkmlu0f546de2019-12-13 20:58:41 +08001100
jasonkmluff0d5b92019-03-21 11:24:45 +08001101def set_gnss_qxdm_mask(ad, masks):
1102 """Find defined gnss qxdm mask and set as default logging mask.
1103
1104 Args:
1105 ad: An AndroidDevice object.
1106 masks: Defined gnss qxdm mask.
1107 """
1108 try:
1109 for mask in masks:
1110 if not tutils.find_qxdm_log_mask(ad, mask):
1111 continue
1112 tutils.set_qxdm_logger_command(ad, mask)
1113 break
1114 except Exception as e:
1115 ad.log.error(e)
jasonkmlu78540632019-11-15 18:04:20 +08001116 raise signals.TestError("Failed to set any QXDM masks.")
jasonkmlu903ece82019-05-16 14:56:19 +08001117
jasonkmlu0f546de2019-12-13 20:58:41 +08001118
jasonkmlu903ece82019-05-16 14:56:19 +08001119def start_youtube_video(ad, url=None, retries=0):
1120 """Start youtube video and verify if audio is in music state.
jasonkmlu81b8b032019-06-21 15:18:27 +08001121
jasonkmlu903ece82019-05-16 14:56:19 +08001122 Args:
1123 ad: An AndroidDevice object.
1124 url: Youtube video url.
1125 retries: Retry times if audio is not in music state.
jasonkmlu81b8b032019-06-21 15:18:27 +08001126
jasonkmlu903ece82019-05-16 14:56:19 +08001127 Returns:
1128 True if youtube video is playing normally.
1129 False if youtube video is not playing properly.
1130 """
1131 for i in range(retries):
1132 ad.log.info("Open an youtube video - attempt %d" % (i+1))
1133 ad.adb.shell("am start -a android.intent.action.VIEW -d \"%s\"" % url)
1134 time.sleep(2)
jasonkmlu035eee12019-10-08 17:11:20 +08001135 out = ad.adb.shell(
1136 "dumpsys activity | grep NewVersionAvailableActivity")
jasonkmlu903ece82019-05-16 14:56:19 +08001137 if out:
1138 ad.log.info("Skip Youtube New Version Update.")
1139 ad.send_keycode("BACK")
1140 if tutils.wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1):
1141 ad.log.info("Started a video in youtube, audio is in MUSIC state")
1142 return True
1143 ad.log.info("Force-Stop youtube and reopen youtube again.")
1144 ad.force_stop_apk("com.google.android.youtube")
jasonkmlu903ece82019-05-16 14:56:19 +08001145 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +08001146 raise signals.TestError("Started a video in youtube, "
1147 "but audio is not in MUSIC state")
jasonkmlu81b8b032019-06-21 15:18:27 +08001148
jasonkmlu0f546de2019-12-13 20:58:41 +08001149
jasonkmlu81b8b032019-06-21 15:18:27 +08001150def get_baseband_and_gms_version(ad, extra_msg=""):
1151 """Get current radio baseband and GMSCore version of AndroidDevice object.
1152
1153 Args:
1154 ad: An AndroidDevice object.
1155 """
1156 try:
jasonkmlud93060f2019-11-05 15:12:55 +08001157 build_version = ad.adb.getprop("ro.build.id")
jasonkmlu81b8b032019-06-21 15:18:27 +08001158 baseband_version = ad.adb.getprop("gsm.version.baseband")
jasonkmlu035eee12019-10-08 17:11:20 +08001159 gms_version = ad.adb.shell(
1160 "dumpsys package com.google.android.gms | grep versionName"
1161 ).split("\n")[0].split("=")[1]
1162 mpss_version = ad.adb.shell("cat /sys/devices/soc0/images | grep MPSS "
1163 "| cut -d ':' -f 3")
jasonkmlu81b8b032019-06-21 15:18:27 +08001164 if not extra_msg:
jasonkmlud93060f2019-11-05 15:12:55 +08001165 ad.log.info("TestResult Build_Version %s" % build_version)
jasonkmlu81b8b032019-06-21 15:18:27 +08001166 ad.log.info("TestResult Baseband_Version %s" % baseband_version)
jasonkmlu035eee12019-10-08 17:11:20 +08001167 ad.log.info(
1168 "TestResult GMS_Version %s" % gms_version.replace(" ", ""))
1169 ad.log.info("TestResult MPSS_Version %s" % mpss_version)
jasonkmlu81b8b032019-06-21 15:18:27 +08001170 else:
jasonkmlu035eee12019-10-08 17:11:20 +08001171 ad.log.info(
1172 "%s, Baseband_Version = %s" % (extra_msg, baseband_version))
jasonkmlu81b8b032019-06-21 15:18:27 +08001173 except Exception as e:
jasonkmlu035eee12019-10-08 17:11:20 +08001174 ad.log.error(e)
1175
jasonkmlu0f546de2019-12-13 20:58:41 +08001176
jasonkmlu035eee12019-10-08 17:11:20 +08001177def start_toggle_gnss_by_gtw_gpstool(ad, iteration):
1178 """Send toggle gnss off/on start_test_action
1179
1180 Args:
1181 ad: An AndroidDevice object.
1182 iteration: Iteration of toggle gnss off/on cycles.
1183 """
1184 msg_list = []
1185 begin_time = get_current_epoch_time()
1186 try:
1187 for i in range(1, 4):
1188 ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool "
1189 "--es mode toggle --es cycle %d" % iteration)
1190 time.sleep(1)
1191 if ad.search_logcat("cmp=com.android.gpstool/.ToggleGPS",
1192 begin_time):
1193 ad.log.info("Send ToggleGPS start_test_action successfully.")
1194 break
1195 else:
1196 check_currrent_focus_app(ad)
jasonkmlu78540632019-11-15 18:04:20 +08001197 raise signals.TestError("Fail to send ToggleGPS "
1198 "start_test_action within 3 attempts.")
jasonkmlu035eee12019-10-08 17:11:20 +08001199 time.sleep(2)
1200 test_start = ad.search_logcat("GPSTool_ToggleGPS: startService",
1201 begin_time)
1202 if test_start:
1203 ad.log.info(test_start[-1]["log_message"].split(":")[-1].strip())
1204 else:
jasonkmlu78540632019-11-15 18:04:20 +08001205 raise signals.TestError("Fail to start toggle GPS off/on test.")
jasonkmlu035eee12019-10-08 17:11:20 +08001206 # Every iteration is expected to finish within 4 minutes.
1207 while get_current_epoch_time() - begin_time <= iteration * 240000:
1208 crash_end = ad.search_logcat("Force finishing activity "
1209 "com.android.gpstool/.GPSTool",
1210 begin_time)
1211 if crash_end:
jasonkmlu78540632019-11-15 18:04:20 +08001212 raise signals.TestError("GPSTool crashed. Abort test.")
jasonkmlu035eee12019-10-08 17:11:20 +08001213 toggle_results = ad.search_logcat("GPSTool : msg", begin_time)
1214 if toggle_results:
1215 for toggle_result in toggle_results:
1216 msg = toggle_result["log_message"]
1217 if not msg in msg_list:
1218 ad.log.info(msg.split(":")[-1].strip())
1219 msg_list.append(msg)
1220 if "timeout" in msg:
1221 raise signals.TestFailure("Fail to get location fixed "
1222 "within 60 seconds.")
1223 if "Test end" in msg:
1224 raise signals.TestPass("Completed quick toggle GNSS "
1225 "off/on test.")
1226 raise signals.TestFailure("Fail to finish toggle GPS off/on test "
1227 "within %d minutes" % (iteration * 4))
1228 finally:
1229 ad.send_keycode("HOME")
jasonkmludc430ec2020-03-27 10:40:39 +08001230
1231def grant_location_permission(ad, option):
1232 """Grant or revoke location related permission.
1233
1234 Args:
1235 ad: An AndroidDevice object.
1236 option: Boolean to grant or revoke location related permissions.
1237 """
1238 action = 'grant' if option else 'revoke'
1239 for permission in LOCATION_PERMISSIONS:
1240 ad.log.info(
1241 '%s permission:%s on %s' % (action, permission, TEST_PACKAGE_NAME))
1242 ad.adb.shell('pm %s %s %s' % (action, TEST_PACKAGE_NAME, permission))